aio: Fix up the opcode in aiocb32_copyin()

With lio_listio(2), the opcode is specified by userspace rather than
being hard-coded by the system call (e.g., aio_readv() -> LIO_READV).
kern_lio_listio() calls aio_aqueue() with an opcode of LIO_NOP, which
gets fixed up when the aiocb is copied in.

When copying in a job request for vectored I/O, we need to dynamically
allocate a uio to wrap an iovec.  So aiocb_copyin() needs to get the
opcode from the aiocb and then decide whether an allocation is required.
We failed to do this in the COMPAT_FREEBSD32 case.  Fix it.

Reported by:	syzbot+27eab6f2c2162f2885ee@syzkaller.appspotmail.com
Reviewed by:	kib, asomers
Fixes:	f30a1ae8d529 ("lio_listio(2):  Allow LIO_READV and LIO_WRITEV.")
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D31914
This commit is contained in:
Mark Johnston 2021-09-11 12:55:32 -04:00
parent 2d5c48eccd
commit 2884918c73

View File

@ -2826,6 +2826,8 @@ aiocb32_copyin(struct aiocb *ujob, struct kaiocb *kjob, int type)
CP(job32, *kcb, aio_fildes);
CP(job32, *kcb, aio_offset);
CP(job32, *kcb, aio_lio_opcode);
if (type == LIO_NOP)
type = kcb->aio_lio_opcode;
if (type & LIO_VECTORED) {
iov32 = PTRIN(job32.aio_iov);
CP(job32, *kcb, aio_iovcnt);