From nobody Sun Sep 13 08:42:38 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 4hjMH23vtzz6s404 for ; Sun, 13 Sep 2026 08:42:38 +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 "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hjMH23Gsfz4HgL for ; Sun, 13 Sep 2026 08:42:38 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1789288958; 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=FIY90pjn4dcqJYCpUW7Hh1dEFUgpG+V+5kQqrezSYUE=; b=QabzUvHaS20oZn7BcOR51vHjF7xbniqFqwPPC8eRvo5ndtdEBkqa0UwsSTPX0Usn+Nw5F6 jjb2iaesx5W04lD86VLnxNJ+fLuY0tt8+Lgp9SuQ+fh3QXxdqCclokP7JVRwSk1vCp1yGb fF78Pdb7N19ZtHKGPXw+MpwKUr3Jr17Ic1PC/wP1QKlRymQWBst/YNPIs47XaGEhi0uUFI ry25EW7qWry/uPcaodnCu5UFavpJfC7LdG5oA0LmggsHBAd+XcQe7DuJ+qMAnGdHf8uwDm 8fWHKnt5jhH4i7Vg60Hx7e96QggJwn9WEEYZMeRRI36IJYDV6MdlBI19Gpu3Mw== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1789288958; b=SaI74IRfhY+D+mpvT7oFgyhb+dgUk/cIRMjMeanZ1byqu8aI18zoT8qSDrg7wA+iXVx2cH 8yesZlu7NxRZf+r5X05xm4toYqabQpYYcwMno+Lzkq6cruz67S7X8ZntQ53TRCX4CnZZTW zX1fgy3FDUvMSnRvBK+0W8GZbDtNcMI3s4lvN6K+FNNxVnw4/IKW+7f6/wsICIm6XEwi1+ +B90q/5x+Cvhr/J6kieu8LZvEnS3bki2mO0VQDK/2p5Z7gW64PrSnLl14M68v5iuDBLSb1 H4rZ5dEvZZD/tz1MliduydZSeHrQEjBD9mgPOTFid4kYbG/ZrsG7hbUi0BDivw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1789288958; 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=FIY90pjn4dcqJYCpUW7Hh1dEFUgpG+V+5kQqrezSYUE=; b=JzwM+ugGpfQ0Mpcf0aksOeB4veC6aBDTR83/yTMrFTxrLKyoPHG3N6PQN6HvSoF7JMC4/E 2fxoucIWmnLsG7v38OuD5CcjxQLterk0i+36moUvmaaLhGdGYRW0q2Y9YN17Dfxg0poT7T PZ4xd0Q0XrTIAB0GQYFYTavBSC4ifwZcFk4YVZ/ZGqm/Gg0YyBM79WUQLrWnmiF3kZM02b 0pX6/DAW6iUrNumFYWvtFl+FK4ykISvkitVHENtbYL/PtyR/dNVXRAr1Fl1+LC2RDeXEyC MpLlKV7hGuF50aoLapFXyAU6wt2yXxAxRQOWSw3X6HSLyX7ALCsXUT5GfB9s4g== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hjMH22LtSzcFG for ; Sun, 13 Sep 2026 08:42:38 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 23e31 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 13 Sep 2026 08:42:38 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Brooks Davis Subject: git: c1e733258770 - main - sendfile(2): rework compat implementation 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: brooks X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: c1e73325877038655236930534253572ec4a0317 Auto-Submitted: auto-generated Date: Sun, 13 Sep 2026 08:42:38 +0000 Message-Id: <6aa661fe.23e31.3eec7a69@gitrepo.freebsd.org> The branch main has been updated by brooks: URL: https://cgit.FreeBSD.org/src/commit/?id=c1e73325877038655236930534253572ec4a0317 commit c1e73325877038655236930534253572ec4a0317 Author: Brooks Davis AuthorDate: 2026-09-13 08:41:38 +0000 Commit: Brooks Davis CommitDate: 2026-09-13 08:41:59 +0000 sendfile(2): rework compat implementation Rename the sendfile() function to kern_sendfile(), expand the arguments previously passed in struct sendfile_args, and extend with two function pointer arguments to copy in the header/trailer structure and the create uio's for the header and trailer as required. Use this to allow the removal of freebsd32_do_sendfile() which was a nearly identical duplicate of sendfile() with attendant maintenance cost. Reviewed by: kib, markj Effort: CHERI upstreaming Sponsored by: Innovate UK Differential Revision: https://reviews.freebsd.org/D59034 --- sys/compat/freebsd32/freebsd32_misc.c | 93 +++++++---------------------------- sys/kern/kern_sendfile.c | 57 ++++++++++----------- sys/sys/syscallsubr.h | 18 +++++++ 3 files changed, 64 insertions(+), 104 deletions(-) diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index bb4548660278..7b4b0cdcfa4b 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -2222,83 +2222,20 @@ struct sf_hdtr32 { }; static int -freebsd32_do_sendfile(struct thread *td, - struct freebsd32_sendfile_args *uap, int compat) +freebsd32_copyin_hdtr(const void *uhdtr, struct sf_hdtr *hdtr) { struct sf_hdtr32 hdtr32; - struct sf_hdtr hdtr; - struct uio *hdr_uio, *trl_uio; - struct file *fp; - cap_rights_t rights; - struct iovec32 *iov32; - off_t offset, sbytes; int error; - offset = PAIR32TO64(off_t, uap->offset); - if (offset < 0) - return (EINVAL); - - hdr_uio = trl_uio = NULL; - - if (uap->hdtr != NULL) { - error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32)); - if (error) - goto out; - PTRIN_CP(hdtr32, hdtr, headers); - CP(hdtr32, hdtr, hdr_cnt); - PTRIN_CP(hdtr32, hdtr, trailers); - CP(hdtr32, hdtr, trl_cnt); - - if (hdtr.headers != NULL) { - iov32 = PTRIN(hdtr32.headers); - error = freebsd32_copyinuio(iov32, - hdtr32.hdr_cnt, &hdr_uio); - if (error) - goto out; -#ifdef COMPAT_FREEBSD4 - /* - * In FreeBSD < 5.0 the nbytes to send also included - * the header. If compat is specified subtract the - * header size from nbytes. - */ - if (compat) { - if (uap->nbytes > hdr_uio->uio_resid) - uap->nbytes -= hdr_uio->uio_resid; - else - uap->nbytes = 0; - } -#endif - } - if (hdtr.trailers != NULL) { - iov32 = PTRIN(hdtr32.trailers); - error = freebsd32_copyinuio(iov32, - hdtr32.trl_cnt, &trl_uio); - if (error) - goto out; - trl_uio->uio_rw = UIO_WRITE; - trl_uio->uio_td = td; - } - } - - AUDIT_ARG_FD(uap->fd); - - if ((error = fget_read(td, uap->fd, - cap_rights_init_one(&rights, CAP_PREAD), &fp)) != 0) - goto out; - - error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, offset, - uap->nbytes, &sbytes, uap->flags, td); - fdrop(fp, td); - - if (uap->sbytes != NULL) - (void)copyout(&sbytes, uap->sbytes, sizeof(off_t)); + error = copyin(uhdtr, &hdtr32, sizeof(hdtr32)); + if (error != 0) + return (error); + hdtr->headers = PTRIN(hdtr32.headers); + hdtr->hdr_cnt = hdtr32.hdr_cnt; + hdtr->trailers = PTRIN(hdtr32.trailers); + hdtr->trl_cnt = hdtr32.trl_cnt; -out: - if (hdr_uio) - freeuio(hdr_uio); - if (trl_uio) - freeuio(trl_uio); - return (error); + return (0); } #ifdef COMPAT_FREEBSD4 @@ -2306,16 +2243,20 @@ int freebsd4_freebsd32_sendfile(struct thread *td, struct freebsd4_freebsd32_sendfile_args *uap) { - return (freebsd32_do_sendfile(td, - (struct freebsd32_sendfile_args *)uap, 1)); + return (kern_sendfile(td, uap->fd, uap->s, + PAIR32TO64(off_t, uap->offset), uap->nbytes, + (struct sf_hdtr *)uap->hdtr, uap->sbytes, uap->flags, + true, freebsd32_copyin_hdtr, (copyinuio_t *)freebsd32_copyinuio)); } #endif int freebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) { - - return (freebsd32_do_sendfile(td, uap, 0)); + return (kern_sendfile(td, uap->fd, uap->s, + PAIR32TO64(off_t, uap->offset), uap->nbytes, + (struct sf_hdtr *)uap->hdtr, uap->sbytes, uap->flags, + false, freebsd32_copyin_hdtr, (copyinuio_t *)freebsd32_copyinuio)); } static void diff --git a/sys/kern/kern_sendfile.c b/sys/kern/kern_sendfile.c index f975470e6dcf..b4ad28b27b36 100644 --- a/sys/kern/kern_sendfile.c +++ b/sys/kern/kern_sendfile.c @@ -1209,7 +1209,15 @@ out: } static int -sendfile(struct thread *td, struct sendfile_args *uap, int compat) +copyin_hdtr(const struct sf_hdtr *uhdtr, struct sf_hdtr *hdtr) +{ + return (copyin(uhdtr, hdtr, sizeof(*hdtr))); +} + +int +kern_sendfile(struct thread *td, int fd, int s, off_t offset, size_t nbytes, + struct sf_hdtr *uhdtr, off_t *usbytes, int flags, bool compat, + copyin_hdtr_t *copyin_hdtr_f, copyinuio_t *copyinuio_f) { struct sf_hdtr hdtr; struct uio *hdr_uio, *trl_uio; @@ -1221,18 +1229,18 @@ sendfile(struct thread *td, struct sendfile_args *uap, int compat) * File offset must be positive. If it goes beyond EOF * we send only the header/trailer and no payload data. */ - if (uap->offset < 0) + if (offset < 0) return (EINVAL); sbytes = 0; hdr_uio = trl_uio = NULL; - if (uap->hdtr != NULL) { - error = copyin(uap->hdtr, &hdtr, sizeof(hdtr)); + if (uhdtr != NULL) { + error = copyin_hdtr_f(uhdtr, &hdtr); if (error != 0) goto out; if (hdtr.headers != NULL) { - error = copyinuio(hdtr.headers, hdtr.hdr_cnt, + error = copyinuio_f(hdtr.headers, hdtr.hdr_cnt, &hdr_uio); if (error != 0) goto out; @@ -1243,15 +1251,15 @@ sendfile(struct thread *td, struct sendfile_args *uap, int compat) * header size from nbytes. */ if (compat) { - if (uap->nbytes > hdr_uio->uio_resid) - uap->nbytes -= hdr_uio->uio_resid; + if (nbytes > hdr_uio->uio_resid) + nbytes -= hdr_uio->uio_resid; else - uap->nbytes = 0; + nbytes = 0; } #endif } if (hdtr.trailers != NULL) { - error = copyinuio(hdtr.trailers, hdtr.trl_cnt, + error = copyinuio_f(hdtr.trailers, hdtr.trl_cnt, &trl_uio); if (error != 0) goto out; @@ -1260,21 +1268,21 @@ sendfile(struct thread *td, struct sendfile_args *uap, int compat) } } - AUDIT_ARG_FD(uap->fd); + AUDIT_ARG_FD(fd); /* * sendfile(2) can start at any offset within a file so we require * CAP_READ+CAP_SEEK = CAP_PREAD. */ - if ((error = fget_read(td, uap->fd, &cap_pread_rights, &fp)) != 0) + if ((error = fget_read(td, fd, &cap_pread_rights, &fp)) != 0) goto out; - error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, uap->offset, - uap->nbytes, &sbytes, uap->flags, td); + error = fo_sendfile(fp, s, hdr_uio, trl_uio, offset, + nbytes, &sbytes, flags, td); fdrop(fp, td); - if (uap->sbytes != NULL) - (void)copyout(&sbytes, uap->sbytes, sizeof(off_t)); + if (usbytes != NULL) + (void)copyout(&sbytes, usbytes, sizeof(off_t)); out: freeuio(hdr_uio); @@ -1296,24 +1304,17 @@ out: int sys_sendfile(struct thread *td, struct sendfile_args *uap) { - - return (sendfile(td, uap, 0)); + return (kern_sendfile(td, uap->fd, uap->s, uap->offset, + uap->nbytes, uap->hdtr, uap->sbytes, uap->flags, false, + (copyin_hdtr_t *)copyin_hdtr, (copyinuio_t *)copyinuio)); } #ifdef COMPAT_FREEBSD4 int freebsd4_sendfile(struct thread *td, struct freebsd4_sendfile_args *uap) { - struct sendfile_args args; - - args.fd = uap->fd; - args.s = uap->s; - args.offset = uap->offset; - args.nbytes = uap->nbytes; - args.hdtr = uap->hdtr; - args.sbytes = uap->sbytes; - args.flags = uap->flags; - - return (sendfile(td, &args, 1)); + return (kern_sendfile(td, uap->fd, uap->s, uap->offset, + uap->nbytes, uap->hdtr, uap->sbytes, uap->flags, true, + (copyin_hdtr_t *)copyin_hdtr, (copyinuio_t *)copyinuio)); } #endif /* COMPAT_FREEBSD4 */ diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index 190dd41ce6ee..3a30c9cd984d 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -82,6 +82,20 @@ struct mmap_req { mmap_check_fp_fn mr_check_fp_fn; }; +/* + * A copyin_hdtr_t takes a pointer to a sendfile header/trailer in + * userspace and storage for on in the kernel and copies it in. + */ +typedef int (copyin_hdtr_t)(const void *hdtrp, struct sf_hdtr *hdtr); + +/* + * A copyinuio_t takes a pointer to an iovec in userspace along with a + * count and allocates a struct uio containing a copy of the iovec. + * The uio should be freed with freeuio(). + */ +typedef int (copyinuio_t)(const void *iovp, unsigned int iovcnt, + struct uio **iov); + uint64_t at2cnpflags(u_int at_flags, u_int mask); int kern___getcwd(struct thread *td, char *buf, enum uio_seg bufseg, size_t buflen, size_t path_max); @@ -334,6 +348,10 @@ int kern_sched_rr_get_interval_td(struct thread *td, struct thread *targettd, struct timespec *ts); int kern_semctl(struct thread *td, int semid, int semnum, int cmd, union semun *arg, register_t *rval); +int kern_sendfile(struct thread *td, int fd, int s, off_t offset, + size_t nbytes, struct sf_hdtr *hdtr, off_t *sbytes, int flags, + bool compat, copyin_hdtr_t *copyin_hdtr_f, + copyinuio_t *copyinuio_f); int kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou, fd_set *fd_ex, struct timeval *tvp, int abi_nfdbits); int kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,