Page MenuHomeFreeBSD

copy_file_range: Fix file offset handling
Needs ReviewPublic

Authored by markj on Fri, Mar 21, 2:09 PM.

Details

Reviewers
rmacklem
kib
Summary

One can ask copy_file_range(2) to use the file offsets of the file
descriptions that it copies from and to. We were updating those offsets
without any locking, which is incorrect and can lead to unkillable loops
in the event of a race (e.g., the check for overlapping ranges in
kern_copy_file_range() is subject to a TOCTOU race with the following
loop which range-locks the input and output file).

Use foffset_lock() to serialize updates to the file descriptions, as we
do for other, similar system calls.

Reported by: syzkaller
Fixes: bbbbeca3e9a3 ("Add kernel support for a Linux compatible copy_file_range(2) syscall.")

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 63052
Build 59936: arc lint + arc unit

Event Timeline

markj requested review of this revision.Fri, Mar 21, 2:09 PM
sys/kern/vfs_syscalls.c
5015

Isn't it deadlock-prone? If one thread does c_f_r(f1, f2) and another c_f_r(f2, f1).

sys/kern/vfs_syscalls.c
5015

Yea, it looks like foffset_lock() needs a new FOF_NOBLOCK
flag, so that both locks can be acquired without deadlock.
(Returns something like -1 when it needs to sleep waiting for
the lock when FOF_NOBLOCK is passed in.)

(I'll admit I do not understand what the offset locking is for
at this point, but it certainly looks like it could deadlock.)

sys/kern/vfs_syscalls.c
5015

Yep, I need to add a trylock operation and a loop which can safely lock a pair of offsets, as we do with rangelocks below.

Avoid deadlocking when locking multiple file offsets.