From nobody Tue Jul 7 21:47:35 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4gvvwD4HhLz6kXhv for ; Tue, 07 Jul 2026 21:47:40 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gvvwD3XQwz3vF8 for ; Tue, 07 Jul 2026 21:47:40 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1783460860; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=1Pplht9gj3jiP78iWLLfoDZsouRTxL3ulcmzlITEoO8=; b=YmDjH9Pm+6PCJhs6Jjook/wnB/LM05IfY4OpW7yrS+HGoZm4jtN0teKx/xLBf+zX0iHYpx xNaR4CUz4SCppor8WshAbroi6jDsp5K8bodWY/4eOc39oeD3I0LUdYab2mUfJjkheMs/9l 8hv0WxPtoBM9OotwPXxBHxtZdMoHLOqOVe8btkkbbBv3P08m1un+M0kh+viWVf535Hz1XE 6rIqjpJ6fBI2fFCO5QtuefTijyLln4SaZwpal28IXLYvfePss25gzpukGvVt/z+HIObrgg 0C+rwJjrWQ8U7C9zRVqanrzSluW8ACGVcot5M9eux7tABjC0N0Uz4jOFRcTN4g== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1783460860; a=rsa-sha256; cv=none; b=fkaC4bLiOVTyivP92gK/e3KLDiBOFCBPgd+RgctFeIxK9E6eSoCxHcPoDOPKuGdowMGS3s cjAzRz1wETEnPuUaOygV4iXBtVbDvhzLpETUxgsUOBhY2hJYCQgwJuskorJ3xjnZngcBLz SfYYI4x3IcsFypK7i0/pdCSSvuw7GziKAkFeVq0Dw8LSPmE2n01RiHtb+OVz92ebtDcaEr xsvK17W/hsdTHINoddzeqsTPj1EjS/jmSi8dLFMJr7ZKhvz6euuuk0NIKsjT5HK721Or7Z j2rM1Xwd4I33ntOK9Ygh8SZ98uDKbB/CKF8TVCuxCdDDl/QePXhYKXffMLyAbA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1783460860; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=1Pplht9gj3jiP78iWLLfoDZsouRTxL3ulcmzlITEoO8=; b=PT0LpksOd3efIfB21yh5qFIOjABrXsLPZWFP9H91lb9Wj5kDF/oCuJz7csRSqD3po8sFfG 5c0yN7qmBEExSgXlT+M895zQBYsHAWjyXEk/Eu1u86VPlnGIJXsyEHqjOph9vrvty/4/88 6bTRaRSm0GWzdZBW5hJ+Swb3FCIxcj0WpiUkiLFoqKGTJPwTnYNBqQ7LDvF5YDCSVEnBf4 nWbG/FT0YdE0Exd76lZKOj4v9FBehYcKc8nP4jE+UPF86JlBPufLf5s8zvcYZvA07GYzIp kOhPpufDoxfT5YpPOhbeicd3hNRZZht4+xQV8vA6GD0jvvDu/c40fHqH3l83oA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gvvwD2JD3zsxj for ; Tue, 07 Jul 2026 21:47:40 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1e7dd by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 07 Jul 2026 21:47:35 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: dfad790c8cca - main - sendfile: stop abusing kern_writev() List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: dfad790c8ccad05ff603ceaa5b2efe4205b38e1c Auto-Submitted: auto-generated Date: Tue, 07 Jul 2026 21:47:35 +0000 Message-Id: <6a4d73f7.1e7dd.1cbcbd60@gitrepo.freebsd.org> The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=dfad790c8ccad05ff603ceaa5b2efe4205b38e1c commit dfad790c8ccad05ff603ceaa5b2efe4205b38e1c Author: Konstantin Belousov AuthorDate: 2026-07-04 02:29:56 +0000 Commit: Konstantin Belousov CommitDate: 2026-07-07 21:47:18 +0000 sendfile: stop abusing kern_writev() Provide convenient wrapper kern_filewrite() around fo_write(). Switch to use it in vn_sendfile(). This allows to avoid duplicate fget() when we already have the reference to the file, which creates a correctness race with the userspace. Also td_retval[0] clearing hack can be removed. Reviewed by: glebius, markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D58035 --- sys/kern/kern_sendfile.c | 25 +++++++++++++------------ sys/kern/sys_generic.c | 41 ++++++++++++++++++++++++++++++----------- sys/sys/syscallsubr.h | 2 ++ 3 files changed, 45 insertions(+), 23 deletions(-) diff --git a/sys/kern/kern_sendfile.c b/sys/kern/kern_sendfile.c index cf9716560c07..1a534210ca0c 100644 --- a/sys/kern/kern_sendfile.c +++ b/sys/kern/kern_sendfile.c @@ -1168,14 +1168,17 @@ prepend_header: } /* - * Send trailers. Wimp out and use writev(2). + * Send trailers. */ if (trl_uio != NULL) { + ssize_t cnt; + SOCK_IO_SEND_UNLOCK(so); CURVNET_RESTORE(); - error = kern_writev(td, sockfd, trl_uio); + error = kern_filewrite(td, sockfd, sock_fp, trl_uio, + (off_t)-1, 0, &cnt); if (error == 0) - sbytes += td->td_retval[0]; + sbytes += cnt; goto out; } @@ -1183,15 +1186,8 @@ done: SOCK_IO_SEND_UNLOCK(so); CURVNET_RESTORE(); out: - /* - * If there was no error we have to clear td->td_retval[0] - * because it may have been set by writev. - */ - if (error == 0) { - td->td_retval[0] = 0; - if (sbytes > 0 && vp != NULL) - INOTIFY(vp, IN_ACCESS); - } + if (error == 0 && sbytes > 0 && vp != NULL) + INOTIFY(vp, IN_ACCESS); if (sent != NULL) { (*sent) = sbytes; } @@ -1260,6 +1256,11 @@ sendfile(struct thread *td, struct sendfile_args *uap, int compat) &trl_uio); if (error != 0) goto out; + if (trl_uio->uio_rw != UIO_WRITE) { + error = EINVAL; + goto out; + } + trl_uio->uio_td = td; } } diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index b84f675d1dcb..07b98613e087 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -549,21 +549,16 @@ dofilewrite(struct thread *td, int fd, struct file *fp, struct uio *auio, { ssize_t cnt; int error; -#ifdef KTRACE - struct uio *ktruio = NULL; -#endif AUDIT_ARG_FD(fd); + auio->uio_rw = UIO_WRITE; auio->uio_td = td; auio->uio_offset = offset; -#ifdef KTRACE - if (KTRPOINT(td, KTR_GENIO)) - ktruio = cloneuio(auio); -#endif - cnt = auio->uio_resid; - error = fo_write(fp, auio, td->td_ucred, flags, td); + error = kern_filewrite(td, fd, fp, auio, offset, flags, &cnt); + /* + * Handle short writes and generate SIGPIPE if needed. * Socket layer is responsible for special error handling, * see sousrsend(). */ @@ -577,15 +572,39 @@ dofilewrite(struct thread *td, int fd, struct file *fp, struct uio *auio, PROC_UNLOCK(td->td_proc); } } - cnt -= auio->uio_resid; + + if (error == 0) + td->td_retval[0] = cnt; + return (error); +} + +/* + * Write io request specified by auio into the file fp. If fd != -1, + * might generate the ktrace io point. + */ +int +kern_filewrite(struct thread *td, int fd, struct file *fp, struct uio *auio, + off_t offset, int flags, ssize_t *cntp) +{ + ssize_t cnt; + int error; +#ifdef KTRACE + struct uio *ktruio; + + ktruio = fd != -1 && KTRPOINT(td, KTR_GENIO) ? cloneuio(auio) : NULL; +#endif + cnt = auio->uio_resid; + error = fo_write(fp, auio, td->td_ucred, flags, td); #ifdef KTRACE if (ktruio != NULL) { + cnt -= auio->uio_resid; if (error == 0) ktruio->uio_resid = cnt; ktrgenio(fd, UIO_WRITE, ktruio, error); } #endif - td->td_retval[0] = cnt; + + *cntp = cnt; return (error); } diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index c6bfe89dcf35..131a8925a2d4 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -176,6 +176,8 @@ int kern_fcntl_freebsd(struct thread *td, int fd, int cmd, intptr_t arg); int kern_fhopen(struct thread *td, const struct fhandle *u_fhp, int flags); int kern_fhstat(struct thread *td, fhandle_t fh, struct stat *buf); int kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf); +int kern_filewrite(struct thread *td, int fd, struct file *fp, + struct uio *auio, off_t offset, int flags, ssize_t *cntp); int kern_fpathconf(struct thread *td, int fd, int name, long *valuep); int kern_freebsd11_getfsstat(struct thread *td, struct freebsd11_statfs *ubuf, long bufsize, int mode);