ext4: in ext4_seek_{hole,data}, return -ENXIO for negative offsets

Message ID 20170712173232.GB4212@magnolia
State Awaiting Upstream
Headers show

Commit Message

Darrick J. Wong July 12, 2017, 5:32 p.m.
NOTE: The pending iomap SEEK_HOLE/DATA conversion patch will make all this
obsolete; this is a fix more appropriate for pre-4.13 ext4.
---
In the ext4 implementations of SEEK_HOLE and SEEK_DATA, make sure we
return -ENXIO for negative offsets instead of banging around inside
the extent code and returning -EFSCORRUPTED.

Reported-by: Mateusz S <muttdini@gmail.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/ext4/file.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Theodore Ts'o Aug. 24, 2017, 5:27 p.m. | #1
On Wed, Jul 12, 2017 at 10:32:32AM -0700, Darrick J. Wong wrote:
> NOTE: The pending iomap SEEK_HOLE/DATA conversion patch will make all this
> obsolete; this is a fix more appropriate for pre-4.13 ext4.
> ---
> In the ext4 implementations of SEEK_HOLE and SEEK_DATA, make sure we
> return -ENXIO for negative offsets instead of banging around inside
> the extent code and returning -EFSCORRUPTED.
> 
> Reported-by: Mateusz S <muttdini@gmail.com>
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Sorry, I missed this patch earlier.  It's not going to make the 4.13
final, but I'll apply it with a "cc: stable@vger.kernel.org # 4.6" tag
so it can land in 4.13.x as well as older LTS kernels.

     	       	       	  	    - Ted

Patch

diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 02ce7e7..923e765 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -576,7 +576,7 @@  static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize)
 	inode_lock(inode);
 
 	isize = i_size_read(inode);
-	if (offset >= isize) {
+	if (offset < 0 || offset >= isize) {
 		inode_unlock(inode);
 		return -ENXIO;
 	}
@@ -639,7 +639,7 @@  static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize)
 	inode_lock(inode);
 
 	isize = i_size_read(inode);
-	if (offset >= isize) {
+	if (offset < 0 || offset >= isize) {
 		inode_unlock(inode);
 		return -ENXIO;
 	}