diff options
author | kib <kib@FreeBSD.org> | 2016-01-22 20:35:20 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2016-01-22 20:35:20 +0000 |
commit | f011d9b5bd7f219f18fd8782f7c6b2debd1b182b (patch) | |
tree | 1d912d0e766b435b05ed295ee89d56c83b6e5a8d /sys/kern | |
parent | 8c188055779951abb5983c3fcac2d41096276b9b (diff) | |
download | FreeBSD-src-f011d9b5bd7f219f18fd8782f7c6b2debd1b182b.zip FreeBSD-src-f011d9b5bd7f219f18fd8782f7c6b2debd1b182b.tar.gz |
The struct file f_advice member is overlaid with the devfs f_cdevpriv
data. If vnode bypass for devfs file failed, vn_read/vn_write are
called and might try to dereference f_advice. Limit the accesses to
f_advice to VREG vnodes only, which is the type ensured by
posix_fadvise().
The f_advice for regular files is protected by mtxpool lock. Recheck
that f_advice is not NULL after lock is taken.
Reported and tested by: bde
Sponsored by: The FreeBSD Foundation
MFC after: 3 weeks
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/vfs_vnops.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 5f8bddc..4320b14 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -743,12 +743,13 @@ get_advice(struct file *fp, struct uio *uio) int ret; ret = POSIX_FADV_NORMAL; - if (fp->f_advice == NULL) + if (fp->f_advice == NULL || fp->f_vnode->v_type != VREG) return (ret); mtxp = mtx_pool_find(mtxpool_sleep, fp); mtx_lock(mtxp); - if (uio->uio_offset >= fp->f_advice->fa_start && + if (fp->f_advice != NULL && + uio->uio_offset >= fp->f_advice->fa_start && uio->uio_offset + uio->uio_resid <= fp->f_advice->fa_end) ret = fp->f_advice->fa_advice; mtx_unlock(mtxp); |