NetBSD Problem Report #58711

From www@netbsd.org  Tue Oct  1 17:44:06 2024
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (2048 bits)
	 client-signature RSA-PSS (2048 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id E04ED1A923B
	for <gnats-bugs@gnats.NetBSD.org>; Tue,  1 Oct 2024 17:44:05 +0000 (UTC)
Message-Id: <20241001174404.7B53E1A923D@mollari.NetBSD.org>
Date: Tue,  1 Oct 2024 17:44:04 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: linux_sys_copy_file_range writes f_offset without the vnode lock
X-Send-Pr-Version: www-1.0

>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!

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.49 2026/05/14 01:52:41 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.