Message ID | 20240701032110.3601345-1-hui81.qi@samsung.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Fixes: ec16b147a55bfa14e858 ("fs: Fix rw_hint validation") | expand |
On 6/30/24 8:21 PM, Hui Qi wrote: > The high 32 bits is filled with arbitrary value. Which application does this? This is a user space bug. Additionally, the patch title looks weird. Please improve the patch title. > If hint is set WRITE_LIFE_SHORT (2) by fcntl, the value is > 0xf6d1374000000002, This is a user space bug. The fcntl() man page clearly mentions that F_SET_RW_HINT accepts a 64-bit value. See also https://www.man7.org/linux/man-pages/man2/fcntl.2.html. > which causes rw_hint_valid always returns false. i_write_hint of inode and > bi_write_hint of bio are both enum rw_hint. The value would be truncated > only if the element value exceeds 2^32. > > Signed-off-by: Hui Qi <hui81.qi@samsung.com> If you want this patch to be merged you will have to add Fixes: and Cc: stable tags. Bart.
diff --git a/fs/fcntl.c b/fs/fcntl.c index 300e5d9ad913..bab45c5586c6 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -269,7 +269,7 @@ static int f_getowner_uids(struct file *filp, unsigned long arg) } #endif -static bool rw_hint_valid(u64 hint) +static bool rw_hint_valid(enum rw_hint hint) { BUILD_BUG_ON(WRITE_LIFE_NOT_SET != RWH_WRITE_LIFE_NOT_SET); BUILD_BUG_ON(WRITE_LIFE_NONE != RWH_WRITE_LIFE_NONE); @@ -295,8 +295,8 @@ static long fcntl_get_rw_hint(struct file *file, unsigned int cmd, unsigned long arg) { struct inode *inode = file_inode(file); - u64 __user *argp = (u64 __user *)arg; - u64 hint = READ_ONCE(inode->i_write_hint); + enum rw_hint __user *argp = (enum rw_hint __user *)arg; + enum rw_hint hint = READ_ONCE(inode->i_write_hint); if (copy_to_user(argp, &hint, sizeof(*argp))) return -EFAULT; @@ -307,8 +307,8 @@ static long fcntl_set_rw_hint(struct file *file, unsigned int cmd, unsigned long arg) { struct inode *inode = file_inode(file); - u64 __user *argp = (u64 __user *)arg; - u64 hint; + enum rw_hint __user *argp = (enum rw_hint __user *)arg; + enum rw_hint hint; if (copy_from_user(&hint, argp, sizeof(hint))) return -EFAULT;
The high 32 bits is filled with arbitrary value. If hint is set WRITE_LIFE_SHORT (2) by fcntl, the value is 0xf6d1374000000002, which causes rw_hint_valid always returns false. i_write_hint of inode and bi_write_hint of bio are both enum rw_hint. The value would be truncated only if the element value exceeds 2^32. Signed-off-by: Hui Qi <hui81.qi@samsung.com> --- fs/fcntl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)