On Fri, 10 Dec 2010 12:09:42 +0530 Harsh Bora <harsh@xxxxxxxxxxxxxxxxxx> wrote: return -EINVAL; > > + } > > + /* > > + * The file supports 'unsigned long' offset. (but loff_t is signed) > > + * When pos is negative, -1 is the biggest number. So if pos + count > > + * is larger than pos, it's overflow. > > + * (ex) -1 + 10 = 9 ...means > > + * 0xffff + 0xa = 0x9 => overflow. > > + */ > > + if ((pos< 0)&& (pos + count> 0)) > > Well, that works fine for what I am concerned but I think there is a > mismatch in the code and the comment above. As per the comments above, > it should be like: > if ((pos < 0) && (pos + count > pos)) > Ah, yes. updated. Thank you for review and test. -Kame == commit 4a3956c790290efeb647bbb0c3a90476bb57800e adds support for negative (unsigned) page offset for very large files as /proc/<pid>/mem and /dev/mem. In that patch, overlap check routine is added but it was wrong. Considering 'pos' is loff_t, a signed value, In usual case, at comparing 'pos' and 'pos+count' (positive) / (positive) OK (positive) / (nevative) EOVERFLOW (negative) / (positive) EINVAL (negative) / (negative) EINVAL In FMODE_UNSIGNED_OFFSET case, (positive) / (positive) OK (positive) / (nevative) OK (ex. 0x7fff -> 0x8000) (nevative) / (negative) OK (negative) / (positive) EOVERFLOW (ex. 0xffff -> 0x1) Changelog: - fixed a comment. Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx> --- fs/read_write.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) Index: linux-2.6.37-rc5/fs/read_write.c =================================================================== --- linux-2.6.37-rc5.orig/fs/read_write.c +++ linux-2.6.37-rc5/fs/read_write.c @@ -37,11 +37,24 @@ __negative_fpos_check(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)) + /* negative pos is allowed only when the flag is set */ + if (!(file->f_mode & FMODE_UNSIGNED_OFFSET)) { + if ((pos > 0) && (pos + count > 0)) + return 0; + if ((pos > 0) && (pos + count < 0)) + return -EOVERFLOW; + return -EINVAL; + } + /* + * The file supports 'unsigned long' offset. (but loff_t is signed) + * When pos is negative, -1 is the biggest number. So if pos + count + * is larger than 0, it's overflow. + * (ex) -1 + 10 = 9 ...means + * 0xffff + 0xa = 0x9 => overflow. + */ + if ((pos < 0) && (pos + count > 0)) return -EOVERFLOW; - if (file->f_mode & FMODE_UNSIGNED_OFFSET) - return 0; - return -EINVAL; + return 0; } /** -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html