Bug 135451

Summary: copy_file_range does not return -1 in case the requested range extends beyond the end of the source file
Product: File System Reporter: Christoph Reiter (reiter.christoph)
Component: VFSAssignee: fs_vfs
Status: NEW ---    
Severity: normal    
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: Linux debian 4.6.0-1-amd64 #1 SMP Debian 4.6.3-1 (2016-07-04) x86_64 GNU/Linux Subsystem:
Regression: No Bisected commit-id:

Description Christoph Reiter 2016-07-17 16:24:04 UTC
If one passes a length that extends beyond the end of the source file it returns the amount of bytes copied until the end of the file and not -1/EINVAL as suggested in the man page.

This results in user code trying to copy from the updated offset again, which results in 0 being returned, which finally results in an endless loop.

The best example is the code example in the man page [0] which passes the result of fstat as length. In case the file size changes between fstat and copy_file_range the program will never terminate. Example code + one line added to trigger the bug: https://bpaste.net/show/cbf4e20a3bbe

The only way I see to prevent this, is in case the result is 0 to compare the updated input offset with the current input file size and if it is equal then error out as we have reached the end of the file.

I've tested this on ext4 and xfs. I hope I didn't miss something..

[0] http://man7.org/linux/man-pages/man2/copy_file_range.2.html