On Tue, Jul 07, 2026 at 09:47:35PM +0000, Konstantin Belousov wrote:
> The branch main has been updated by kib:
> 
> URL: 
> https://cgit.FreeBSD.org/src/commit/?id=dfad790c8ccad05ff603ceaa5b2efe4205b38e1c
> 
> commit dfad790c8ccad05ff603ceaa5b2efe4205b38e1c
> Author:     Konstantin Belousov <[email protected]>
> AuthorDate: 2026-07-04 02:29:56 +0000
> Commit:     Konstantin Belousov <[email protected]>
> 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) {

cloneuio() does not set uio_rw.  sendfile() was relying on kern_writev()
to do that.  A GENERIC-KMSAN kernel panics when running the test suite:

panic: MSan: Uninitialized malloc memory from copyinuio+0x11d
cpuid = 5
time = 1783537112
KDB: stack backtrace:
db_trace_self_wrapper() at db_trace_self_wrapper+0xa7/frame 0xfffffe00764d7840
vpanic() at vpanic+0x538/frame 0xfffffe00764d79c0
panic() at panic+0x1dd/frame 0xfffffe00764d7ad0
__msan_warning() at __msan_warning+0x25d/frame 0xfffffe00764d7c20
sendfile() at sendfile+0xcb6/frame 0xfffffe00764d7d50
amd64_syscall() at amd64_syscall+0x837/frame 0xfffffe00764d7f30
fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe00764d7f30
--- syscall (393, FreeBSD ELF64, sendfile), rip = 0x21aad2ea3b0a, rsp = 
0x21aad1d706c8, rbp = 0x21aad1d70760 ---
KDB: enter: panic

Reply via email to