| From dc73766b7cdbdf92707a90b0053b0f340bb68bf6 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 30 Apr 2020 07:57:46 -0700 |
| Subject: fibmap: Warn and return an error in case of block > INT_MAX |
| |
| From: Ritesh Harjani <riteshh@linux.ibm.com> |
| |
| [ Upstream commit b75dfde1212991b24b220c3995101c60a7b8ae74 ] |
| |
| We better warn the fibmap user and not return a truncated and therefore |
| an incorrect block map address if the bmap() returned block address |
| is greater than INT_MAX (since user supplied integer pointer). |
| |
| It's better to pr_warn() all user of ioctl_fibmap() and return a proper |
| error code rather than silently letting a FS corruption happen if the |
| user tries to fiddle around with the returned block map address. |
| |
| We fix this by returning an error code of -ERANGE and returning 0 as the |
| block mapping address in case if it is > INT_MAX. |
| |
| Now iomap_bmap() could be called from either of these two paths. |
| Either when a user is calling an ioctl_fibmap() interface to get |
| the block mapping address or by some filesystem via use of bmap() |
| internal kernel API. |
| bmap() kernel API is well equipped with handling of u64 addresses. |
| |
| WARN condition in iomap_bmap_actor() was mainly added to warn all |
| the fibmap users. But now that we have directly added this warning |
| for all fibmap users and also made sure to return 0 as block map address |
| in case if addr > INT_MAX. |
| So we can now remove this logic from iomap_bmap_actor(). |
| |
| Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com> |
| Reviewed-by: Christoph Hellwig <hch@lst.de> |
| Reviewed-by: Jan Kara <jack@suse.cz> |
| Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> |
| Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/ioctl.c | 8 ++++++++ |
| fs/iomap/fiemap.c | 5 +---- |
| 2 files changed, 9 insertions(+), 4 deletions(-) |
| |
| diff --git a/fs/ioctl.c b/fs/ioctl.c |
| index 282d45be6f453..5e80b40bc1b5c 100644 |
| --- a/fs/ioctl.c |
| +++ b/fs/ioctl.c |
| @@ -55,6 +55,7 @@ EXPORT_SYMBOL(vfs_ioctl); |
| static int ioctl_fibmap(struct file *filp, int __user *p) |
| { |
| struct inode *inode = file_inode(filp); |
| + struct super_block *sb = inode->i_sb; |
| int error, ur_block; |
| sector_t block; |
| |
| @@ -71,6 +72,13 @@ static int ioctl_fibmap(struct file *filp, int __user *p) |
| block = ur_block; |
| error = bmap(inode, &block); |
| |
| + if (block > INT_MAX) { |
| + error = -ERANGE; |
| + pr_warn_ratelimited("[%s/%d] FS: %s File: %pD4 would truncate fibmap result\n", |
| + current->comm, task_pid_nr(current), |
| + sb->s_id, filp); |
| + } |
| + |
| if (error) |
| ur_block = 0; |
| else |
| diff --git a/fs/iomap/fiemap.c b/fs/iomap/fiemap.c |
| index bccf305ea9ce2..d55e8f491a5e5 100644 |
| --- a/fs/iomap/fiemap.c |
| +++ b/fs/iomap/fiemap.c |
| @@ -117,10 +117,7 @@ iomap_bmap_actor(struct inode *inode, loff_t pos, loff_t length, |
| |
| if (iomap->type == IOMAP_MAPPED) { |
| addr = (pos - iomap->offset + iomap->addr) >> inode->i_blkbits; |
| - if (addr > INT_MAX) |
| - WARN(1, "would truncate bmap result\n"); |
| - else |
| - *bno = addr; |
| + *bno = addr; |
| } |
| return 0; |
| } |
| -- |
| 2.20.1 |
| |