NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/58711: linux_sys_copy_file_range writes f_offset without the vnode lock
>Number: 58711
>Category: kern
>Synopsis: linux_sys_copy_file_range writes f_offset without the vnode lock
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Oct 01 17:45:00 +0000 2024
>Originator: Taylor R Campbell
>Release: current
>Organization:
The NetBSD linux_Fileoffset
>Environment:
>Description:
The new linux_sys_copy_file_range:
1. Locks src vnode.
2. Loads src file's f_offset and reads from src vnode into buffer.
3. Unlocks src vnode.
4. Bails if read failed (or EOF).
5. Locks dst vnode.
6. Reads dst file's f_offset and writes to dst vnode from buffer.
7. Unlocks dst vnode.
8. Bails if write failed.
9. Increments src file's f_offset.
10. Increments dst file's f_offset.
11. Returns the error (from VOP_READ or VOP_WRITE) unconditionally, even if some iterations of the loop have succeeded at transferring some bytes already and a later one failed.
There are two problems with this, and potentially, a third problem:
(a) Access to a vnode file's f_offset is forbidden without the vnode lock.
(b) If _one_ call to VOP_WRITE partially succeeds (that is, consumes some but not all input), the part that succeeded is not incorporated into the dst file's f_offset.
(c) [potentially] If _any_ call to VOP_WRITE in the loop has succeeded, and then another call to either VOP_READ or VOP_WRITE fails later in the loop, the syscall will fail to report to the caller how many bytes it has advanced. (I don't know offhand what semantics Linux guarantees here, but if it's sensible it will require the syscall to accurately report the number of bytes by which it has moved both the source and the destination's offsets.)
>How-To-Repeat:
code inspection
>Fix:
Yes, please!
Home |
Main Index |
Thread Index |
Old Index