aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/vfs_vnops.c
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2016-01-22 20:35:20 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2016-01-22 20:35:20 +0000
commit6adf19481cc0dc5463b546d74c96de80eeaa1333 (patch)
tree1d912d0e766b435b05ed295ee89d56c83b6e5a8d /sys/kern/vfs_vnops.c
parent1a2dd035fbfb7a46f72d47cf179e3d87e8b48484 (diff)
downloadsrc-6adf19481cc0dc5463b546d74c96de80eeaa1333.tar.gz
src-6adf19481cc0dc5463b546d74c96de80eeaa1333.zip
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
Notes
Notes: svn path=/head/; revision=294596
Diffstat (limited to 'sys/kern/vfs_vnops.c')
-rw-r--r--sys/kern/vfs_vnops.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 5f8bddc0419d..4320b1423afb 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);