diff options
author | alc <alc@FreeBSD.org> | 2002-08-05 19:14:27 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2002-08-05 19:14:27 +0000 |
commit | 98877a3b30d997a675dfdb82704cb5b5dc6b51a9 (patch) | |
tree | 7000054839bcdce103709adde7e215848855cac5 /sys | |
parent | e359326f3d680bcfd8d427667c57ada48a70f350 (diff) | |
download | FreeBSD-src-98877a3b30d997a675dfdb82704cb5b5dc6b51a9.zip FreeBSD-src-98877a3b30d997a675dfdb82704cb5b5dc6b51a9.tar.gz |
o The introduction of kevent() broke lio_listio(): _aio_aqueue() thought
that LIO_READ and LIO_WRITE were requests for kevent()-based
notification of completion. Modify _aio_aqueue() to recognize LIO_READ
and LIO_WRITE.
Notes: (1) The patch provided by the PR perpetuates a second bug in this
code, a direct access to user-space memory. This change fixes that bug
as well. (2) This change is to code that implements a deprecated interface.
It should probably be removed after an MFC.
PR: kern/39556
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/vfs_aio.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index 891f272..240140a 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -1284,7 +1284,7 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int typ struct socket *so; int s; int error; - int opcode; + int opcode, user_opcode; struct aiocblist *aiocbe; struct aiothreadlist *aiop; struct kaioinfo *ki; @@ -1318,6 +1318,7 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int typ aiocbe->uuaiocb = job; /* Get the opcode. */ + user_opcode = aiocbe->uaiocb.aio_lio_opcode; if (type != LIO_NOP) aiocbe->uaiocb.aio_lio_opcode = type; opcode = aiocbe->uaiocb.aio_lio_opcode; @@ -1389,13 +1390,12 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int typ * via aio_lio_opcode, which is an int. Use the SIGEV_KEVENT- * based method instead. */ - struct kevent *kevp; - - kevp = (struct kevent *)(uintptr_t)job->aio_lio_opcode; - if (kevp == NULL) + if (user_opcode == LIO_NOP || user_opcode == LIO_READ || + user_opcode == LIO_WRITE) goto no_kqueue; - error = copyin(kevp, &kev, sizeof(kev)); + error = copyin((struct kevent *)(uintptr_t)user_opcode, + &kev, sizeof(kev)); if (error) goto aqueue_fail; } |