summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_aio.c
diff options
context:
space:
mode:
authordumbbell <dumbbell@FreeBSD.org>2008-01-24 17:10:19 +0000
committerdumbbell <dumbbell@FreeBSD.org>2008-01-24 17:10:19 +0000
commitba3df23cb8fa4355a16820390afdd590e0a58be7 (patch)
tree7068fef549babbf1bf671437caf732a4825b963a /sys/kern/vfs_aio.c
parent17d99001fab69e948489158a3aa6caf948b0b996 (diff)
downloadFreeBSD-src-ba3df23cb8fa4355a16820390afdd590e0a58be7.zip
FreeBSD-src-ba3df23cb8fa4355a16820390afdd590e0a58be7.tar.gz
When asked to use kqueue, AIO stores its internal state in the
`kn_sdata' member of the newly registered knote. The problem is that this member is overwritten by a call to kevent(2) with the EV_ADD flag, targetted at the same kevent/knote. For instance, a userland application may set the pointer to NULL, leading to a panic. A testcase was provided by the submitter. PR: kern/118911 Submitted by: MOROHOSHI Akihiko <moro@remus.dti.ne.jp> MFC after: 1 day
Diffstat (limited to 'sys/kern/vfs_aio.c')
-rw-r--r--sys/kern/vfs_aio.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
index e958d54..877ddf1 100644
--- a/sys/kern/vfs_aio.c
+++ b/sys/kern/vfs_aio.c
@@ -2251,6 +2251,7 @@ filt_aioattach(struct knote *kn)
*/
if ((kn->kn_flags & EV_FLAG1) == 0)
return (EPERM);
+ kn->kn_ptr.p_aio = aiocbe;
kn->kn_flags &= ~EV_FLAG1;
knlist_add(&aiocbe->klist, kn, 0);
@@ -2262,7 +2263,7 @@ filt_aioattach(struct knote *kn)
static void
filt_aiodetach(struct knote *kn)
{
- struct aiocblist *aiocbe = (struct aiocblist *)kn->kn_sdata;
+ struct aiocblist *aiocbe = kn->kn_ptr.p_aio;
if (!knlist_empty(&aiocbe->klist))
knlist_remove(&aiocbe->klist, kn, 0);
@@ -2273,7 +2274,7 @@ filt_aiodetach(struct knote *kn)
static int
filt_aio(struct knote *kn, long hint)
{
- struct aiocblist *aiocbe = (struct aiocblist *)kn->kn_sdata;
+ struct aiocblist *aiocbe = kn->kn_ptr.p_aio;
kn->kn_data = aiocbe->uaiocb._aiocb_private.error;
if (aiocbe->jobstate != JOBST_JOBFINISHED)
@@ -2295,6 +2296,7 @@ filt_lioattach(struct knote *kn)
*/
if ((kn->kn_flags & EV_FLAG1) == 0)
return (EPERM);
+ kn->kn_ptr.p_lio = lj;
kn->kn_flags &= ~EV_FLAG1;
knlist_add(&lj->klist, kn, 0);
@@ -2306,7 +2308,7 @@ filt_lioattach(struct knote *kn)
static void
filt_liodetach(struct knote *kn)
{
- struct aioliojob * lj = (struct aioliojob *)kn->kn_sdata;
+ struct aioliojob * lj = kn->kn_ptr.p_lio;
if (!knlist_empty(&lj->klist))
knlist_remove(&lj->klist, kn, 0);
@@ -2317,7 +2319,7 @@ filt_liodetach(struct knote *kn)
static int
filt_lio(struct knote *kn, long hint)
{
- struct aioliojob * lj = (struct aioliojob *)kn->kn_sdata;
+ struct aioliojob * lj = kn->kn_ptr.p_lio;
return (lj->lioj_flags & LIOJ_KEVENT_POSTED);
}
OpenPOWER on IntegriCloud