Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cccb5a1e authored by Al Viro's avatar Al Viro
Browse files

fix signedness mess in rw_verify_area() on 64bit architectures



... and clean the unsigned-f_pos code, while we are at it.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 208898c1
Loading
Loading
Loading
Loading
+11 −16
Original line number Diff line number Diff line
@@ -30,18 +30,9 @@ const struct file_operations generic_ro_fops = {

EXPORT_SYMBOL(generic_ro_fops);

static int
__negative_fpos_check(struct file *file, loff_t pos, size_t count)
static inline int unsigned_offsets(struct file *file)
{
	/*
	 * pos or pos+count is negative here, check overflow.
	 * too big "count" will be caught in rw_verify_area().
	 */
	if ((pos < 0) && (pos + count < pos))
		return -EOVERFLOW;
	if (file->f_mode & FMODE_UNSIGNED_OFFSET)
		return 0;
	return -EINVAL;
	return file->f_mode & FMODE_UNSIGNED_OFFSET;
}

/**
@@ -75,7 +66,7 @@ generic_file_llseek_unlocked(struct file *file, loff_t offset, int origin)
		break;
	}

	if (offset < 0 && __negative_fpos_check(file, offset, 0))
	if (offset < 0 && !unsigned_offsets(file))
		return -EINVAL;
	if (offset > inode->i_sb->s_maxbytes)
		return -EINVAL;
@@ -152,7 +143,7 @@ loff_t default_llseek(struct file *file, loff_t offset, int origin)
			offset += file->f_pos;
	}
	retval = -EINVAL;
	if (offset >= 0 || !__negative_fpos_check(file, offset, 0)) {
	if (offset >= 0 || unsigned_offsets(file)) {
		if (offset != file->f_pos) {
			file->f_pos = offset;
			file->f_version = 0;
@@ -252,9 +243,13 @@ int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count
	if (unlikely((ssize_t) count < 0))
		return retval;
	pos = *ppos;
	if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) {
		retval = __negative_fpos_check(file, pos, count);
		if (retval)
	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;
	}