Re: git: 9a7d03c7df35 - main - sendfile: cover the entire sendfile operation under CURVNET_SET()
Date: Tue, 06 May 2025 19:40:09 UTC
On Tue, May 6, 2025 at 12:34 PM Gleb Smirnoff <glebius@freebsd.org> wrote:
>
> The branch main has been updated by glebius:
>
> URL: https://cgit.FreeBSD.org/src/commit/?id=9a7d03c7df3536cdb5faf0848c6dab4a5d7bcef8
>
> commit 9a7d03c7df3536cdb5faf0848c6dab4a5d7bcef8
> Author: Gleb Smirnoff <glebius@FreeBSD.org>
> AuthorDate: 2025-05-06 18:15:15 +0000
> Commit: Gleb Smirnoff <glebius@FreeBSD.org>
> CommitDate: 2025-05-06 19:34:26 +0000
>
> sendfile: cover the entire sendfile operation under CURVNET_SET()
>
> There is no reason to set/restore for every single pr_send(), as it never
> changes. Also, cover call into pr_sendfile_wait with CURVNET_SET() fixing
> recent regression in unix(4).
>
> Now we would enter sendfile_iodone() with curvnet set, when called
> synchronously. Although, it is easy to tell a syncronous call from I/O
> completion, unfortunately the vnet(9) macros do not support conditional
> invocation, so just change CURVNET_SET() to CURVNET_SET_QUIET() and add a
> comment that we are aware of the recursion.
Seeing a build error on main with this
--- kern_sendfile.o ---
/usr/src/sys/kern/kern_sendfile.c:788:6: error: variable 'saved_vnet'
is used uninitialized whenever 'if' condition is true [
-Werror,-Wsometimes-uninitialized]
788 | if (error != 0)
| ^~~~~~~~~~
/usr/src/sys/kern/kern_sendfile.c:1273:2: note: uninitialized use occurs here
1273 | CURVNET_RESTORE();
and
/usr/src/sys/kern/kern_sendfile.c:788:2: note: remove the 'if' if its
condition is always false
788 | if (error != 0)
| ^~~~~~~~~~~~~~~
789 | goto out;
| ~~~~~~~~
> Reported-by: syzbot+7b0b20cf2c672c181d98@syzkaller.appspotmail.com
> ---
> sys/kern/kern_sendfile.c | 13 ++++++++-----
> 1 file changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/sys/kern/kern_sendfile.c b/sys/kern/kern_sendfile.c
> index 1fd1828c37c7..c428d80e0e1a 100644
> --- a/sys/kern/kern_sendfile.c
> +++ b/sys/kern/kern_sendfile.c
> @@ -285,6 +285,11 @@ sendfile_iowait(struct sf_io *sfio, const char *wmesg)
>
> /*
> * I/O completion callback.
> + *
> + * When called via I/O path, the curvnet is not set and should be obtained
> + * from the socket. When called synchronously from vn_sendfile(), usually
> + * to report error or just release the reference (all pages are valid), then
> + * curvnet shall be already set.
> */
> static void
> sendfile_iodone(void *arg, vm_page_t *pa, int count, int error)
> @@ -365,7 +370,7 @@ sendfile_iodone(void *arg, vm_page_t *pa, int count, int error)
> ("non-ext_pgs mbuf with TLS session"));
> #endif
> so = sfio->so;
> - CURVNET_SET(so->so_vnet);
> + CURVNET_SET_QUIET(so->so_vnet);
> if (__predict_false(sfio->error)) {
> /*
> * I/O operation failed. The state of data in the socket
> @@ -782,6 +787,7 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio,
> error = sendfile_getsock(td, sockfd, &sock_fp, &so);
> if (error != 0)
> goto out;
> + CURVNET_SET(so->so_vnet);
> pr = so->so_proto;
>
> #ifdef MAC
> @@ -1161,7 +1167,6 @@ prepend_header:
> ("%s: mlen %u space %d hdrlen %d",
> __func__, m_length(m, NULL), space, hdrlen));
>
> - CURVNET_SET(so->so_vnet);
> #ifdef KERN_TLS
> if (tls != NULL)
> ktls_frame(m, tls, &tls_enq_cnt, TLS_RLTYPE_APP);
> @@ -1203,8 +1208,6 @@ prepend_header:
> tcp_log_sendfile(so, offset, nbytes, flags);
> }
> #endif
> - CURVNET_RESTORE();
> -
> m = NULL;
> if (error)
> goto done;
> @@ -1265,9 +1268,9 @@ out:
> if (tls != NULL)
> ktls_free(tls);
> #endif
> -
> if (error == ERESTART)
> error = EINTR;
> + CURVNET_RESTORE();
>
> return (error);
> }