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
This commit is contained in:
parent
1baa7ea787
commit
20fb589d13
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user