/* * rw_verify_area doesn't like huge counts. We limit * them to something that fits in "int" so that others * won't have to do range checks all the time. */ int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count) { struct inode *inode; loff_t pos; int retval = -EINVAL; inode = file_inode(file); if (unlikely((ssize_t) count < 0)) return retval; pos = *ppos; if (unlikely(pos < 0)) { if (!unsigned_offsets(file)) return retval; if (count >= -pos) /* both values are in 0..LLONG_MAX */ return -EOVERFLOW; } else if (unlikely((loff_t) (pos + count) < 0)) { if (!unsigned_offsets(file)) return retval; } if (unlikely(inode->i_flock && mandatory_lock(inode))) { retval = locks_mandatory_area( read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, inode, file, pos, count); if (retval < 0) return retval; } retval = security_file_permission(file, read_write == READ ? MAY_READ : MAY_WRITE); if (retval) return retval; return count > MAX_RW_COUNT ? MAX_RW_COUNT : count; }
int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count) { struct inode *inode; loff_t pos; int retval = -EINVAL; inode = file->f_path.dentry->d_inode; if (unlikely((ssize_t) count < 0)) return retval; pos = *ppos; if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) return retval; if (unlikely(inode->i_flock && mandatory_lock(inode))) { retval = locks_mandatory_area( read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, inode, file, pos, count); if (retval < 0) return retval; } retval = security_file_permission(file, read_write == READ ? MAY_READ : MAY_WRITE); if (retval) return retval; return count > MAX_RW_COUNT ? MAX_RW_COUNT : count; }
int locks_verify_area(int read_write, struct inode *inode, struct file *filp, unsigned int offset, unsigned int count) { /* Candidates for mandatory locking have the setgid bit set * but no group execute bit - an otherwise meaningless combination. */ if (IS_MANDLOCK(inode) && (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) return (locks_mandatory_area(read_write, inode, filp, offset, count)); return (0); }
int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count) { struct inode *inode; loff_t pos; if (unlikely(count > INT_MAX)) goto Einval; pos = *ppos; if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) goto Einval; inode = file->f_dentry->d_inode; if (inode->i_flock && MANDATORY_LOCK(inode)) return locks_mandatory_area(read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, inode, file, pos, count); return 0; Einval: return -EINVAL; }
static int clone_verify_area(struct file *file, loff_t pos, u64 len, bool write) { struct inode *inode = file_inode(file); if (unlikely(pos < 0)) return -EINVAL; if (unlikely((loff_t) (pos + len) < 0)) return -EINVAL; if (unlikely(inode->i_flctx && mandatory_lock(inode))) { loff_t end = len ? pos + len - 1 : OFFSET_MAX; int retval; retval = locks_mandatory_area(inode, file, pos, end, write ? F_WRLCK : F_RDLCK); if (retval < 0) return retval; } return security_file_permission(file, write ? MAY_WRITE : MAY_READ); }
int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count) { struct inode *inode; loff_t pos; if (unlikely((ssize_t) count < 0)) goto Einval; pos = *ppos; if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) goto Einval; inode = file->f_dentry->d_inode; if (unlikely(inode->i_flock && MANDATORY_LOCK(inode))) { int retval = locks_mandatory_area( read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, inode, file, pos, count); if (retval < 0) return retval; } return count > MAX_RW_COUNT ? MAX_RW_COUNT : count; Einval: return -EINVAL; }