Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/vfs_vnops.c
| Show First 20 Lines • Show All 130 Lines • ▼ Show 20 Lines | SYSCTL_INT(_debug, OID_AUTO, vn_io_fault_enable, CTLFLAG_RW, | ||||
| &vn_io_fault_enable, 0, "Enable vn_io_fault lock avoidance"); | &vn_io_fault_enable, 0, "Enable vn_io_fault lock avoidance"); | ||||
| static int vn_io_fault_prefault = 0; | static int vn_io_fault_prefault = 0; | ||||
| SYSCTL_INT(_debug, OID_AUTO, vn_io_fault_prefault, CTLFLAG_RW, | SYSCTL_INT(_debug, OID_AUTO, vn_io_fault_prefault, CTLFLAG_RW, | ||||
| &vn_io_fault_prefault, 0, "Enable vn_io_fault prefaulting"); | &vn_io_fault_prefault, 0, "Enable vn_io_fault prefaulting"); | ||||
| static u_long vn_io_faults_cnt; | static u_long vn_io_faults_cnt; | ||||
| SYSCTL_ULONG(_debug, OID_AUTO, vn_io_faults, CTLFLAG_RD, | SYSCTL_ULONG(_debug, OID_AUTO, vn_io_faults, CTLFLAG_RD, | ||||
| &vn_io_faults_cnt, 0, "Count of vn_io_fault lock avoidance triggers"); | &vn_io_faults_cnt, 0, "Count of vn_io_fault lock avoidance triggers"); | ||||
| static int vfs_allow_read_dir = 0; | |||||
| SYSCTL_INT(_security_bsd, OID_AUTO, allow_read_dir, CTLFLAG_RW, | |||||
| &vfs_allow_read_dir, 0, | |||||
| "Enable read(2) of directory by root for filesystems that support it"); | |||||
| /* | /* | ||||
| * Returns true if vn_io_fault mode of handling the i/o request should | * Returns true if vn_io_fault mode of handling the i/o request should | ||||
| * be used. | * be used. | ||||
| */ | */ | ||||
| static bool | static bool | ||||
| do_vn_io_fault(struct vnode *vp, struct uio *uio) | do_vn_io_fault(struct vnode *vp, struct uio *uio) | ||||
| { | { | ||||
| struct mount *mp; | struct mount *mp; | ||||
| ▲ Show 20 Lines • Show All 1,064 Lines • ▼ Show 20 Lines | vn_io_fault(struct file *fp, struct uio *uio, struct ucred *active_cred, | ||||
| fo_rdwr_t *doio; | fo_rdwr_t *doio; | ||||
| struct vnode *vp; | struct vnode *vp; | ||||
| void *rl_cookie; | void *rl_cookie; | ||||
| struct vn_io_fault_args args; | struct vn_io_fault_args args; | ||||
| int error; | int error; | ||||
| doio = uio->uio_rw == UIO_READ ? vn_read : vn_write; | doio = uio->uio_rw == UIO_READ ? vn_read : vn_write; | ||||
| vp = fp->f_vnode; | vp = fp->f_vnode; | ||||
| /* | |||||
| * The ability to read(2) on a directory has historically been | |||||
| * allowed for all users, but this can and has been the source of | |||||
| * at least one security issue in the past. As such, it is now hidden | |||||
| * away behind a sysctl for those that actually need it to use it. | |||||
| */ | |||||
| if (vp->v_type == VDIR) { | |||||
| KASSERT(uio->uio_rw == UIO_READ, | |||||
| ("illegal write attempted on a directory")); | |||||
| if (!vfs_allow_read_dir) | |||||
| return (EISDIR); | |||||
| } | |||||
| foffset_lock_uio(fp, uio, flags); | foffset_lock_uio(fp, uio, flags); | ||||
| if (do_vn_io_fault(vp, uio)) { | if (do_vn_io_fault(vp, uio)) { | ||||
| args.kind = VN_IO_FAULT_FOP; | args.kind = VN_IO_FAULT_FOP; | ||||
| args.args.fop_args.fp = fp; | args.args.fop_args.fp = fp; | ||||
| args.args.fop_args.doio = doio; | args.args.fop_args.doio = doio; | ||||
| args.cred = active_cred; | args.cred = active_cred; | ||||
| args.flags = flags | FOF_OFFSET; | args.flags = flags | FOF_OFFSET; | ||||
| if (uio->uio_rw == UIO_READ) { | if (uio->uio_rw == UIO_READ) { | ||||
| ▲ Show 20 Lines • Show All 2,015 Lines • Show Last 20 Lines | |||||