All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Jose A. Perez de Azpillaga" <azpijr@gmail.com>
To: Tal Zussman <tz2294@columbia.edu>,
	Andrew Morton <akpm@linux-foundation.org>,
	Mike Rapoport <rppt@kernel.org>, Peter Xu <peterx@redhat.com>
Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] mm/userfaultfd: store the child's new uffd context in the wait queue entry
Date: Sat, 31 Oct 2026 21:13:25 +0100	[thread overview]
Message-ID: <751f878c-1a2f-4fbe-a255-3520ffaa2f28@gmail.com> (raw)
In-Reply-To: <20261031-uffd-fork-ctx-v1-1-a837fd576ffc@columbia.edu>

On 10/31/26 4:47 PM, Tal Zussman wrote:
> A UFFD_EVENT_FORK message cannot carry the child's fd when it is queued,
> because the fd has to be installed in the fd table of whichever task
> reads the event. The forking task has to hand the reader the new context
> itself. It does that by casting the child's userfaultfd_ctx pointer into
> the arg.reserved.reserved1 field of the UAPI struct uffd_msg, which the
> readers cast back.
> 
> That temporarily puts a kernel pointer in a struct that is copied to
> userspace, and results in ugly casts when passing the uffd context
> around. While resolve_userfault_fork() currently zeroes reserved1 before
> it is exposed to userspace, this unnecessarily risks leaking a kernel
> pointer to userspace if future modifications are buggy.
> 
> Store the fork_ctx pointer in struct userfaultfd_wait_queue instead,
> which is kernel-internal and passed around anyway. The casts and the
> zeroing go away, at the (negligible) cost of 8 more bytes on the
> stack.
> 
> No functional change.
> 
> Signed-off-by: Tal Zussman <tz2294@columbia.edu>
> ---
>  mm/userfaultfd.c | 19 ++++++-------------
>  1 file changed, 6 insertions(+), 13 deletions(-)
> 
> diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
> index 3b71712edab4..cae70df89c00 100644
> --- a/mm/userfaultfd.c
> +++ b/mm/userfaultfd.c
> @@ -2430,6 +2430,8 @@ struct userfaultfd_wait_queue {
>  	struct uffd_msg msg;
>  	wait_queue_entry_t wq;
>  	struct userfaultfd_ctx *ctx;
> +	/* UFFD_EVENT_FORK: the context created for the child */
> +	struct userfaultfd_ctx *fork_ctx;
>  	bool waken;
>  };
>  
> @@ -3006,14 +3008,8 @@ static void userfaultfd_event_wait_completion(struct userfaultfd_ctx *ctx,
>  			 * didn't.
>  			 */
>  			__remove_wait_queue(&ctx->event_wqh, &ewq->wq);
> -			if (ewq->msg.event == UFFD_EVENT_FORK) {
> -				struct userfaultfd_ctx *new;
> -
> -				new = (struct userfaultfd_ctx *)
> -					(unsigned long)
> -					ewq->msg.arg.reserved.reserved1;
> -				release_new_ctx = new;
> -			}
> +			if (ewq->msg.event == UFFD_EVENT_FORK)
> +				release_new_ctx = ewq->fork_ctx;
>  			break;
>  		}
>  
> @@ -3111,7 +3107,7 @@ static void dup_fctx(struct userfaultfd_fork_ctx *fctx)
>  	msg_init(&ewq.msg);
>  
>  	ewq.msg.event = UFFD_EVENT_FORK;
> -	ewq.msg.arg.reserved.reserved1 = (unsigned long)fctx->new;
> +	ewq.fork_ctx = fctx->new;
>  
>  	userfaultfd_event_wait_completion(ctx, &ewq);
>  }
> @@ -3404,7 +3400,6 @@ static int resolve_userfault_fork(struct userfaultfd_ctx *new,
>  	if (fd < 0)
>  		return fd;
>  
> -	msg->arg.reserved.reserved1 = 0;
>  	msg->arg.fork.ufd = fd;
>  	return 0;
>  }
> @@ -3482,9 +3477,7 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,
>  			*msg = uwq->msg;
>  
>  			if (uwq->msg.event == UFFD_EVENT_FORK) {
> -				fork_nctx = (struct userfaultfd_ctx *)
> -					(unsigned long)
> -					uwq->msg.arg.reserved.reserved1;
> +				fork_nctx = uwq->fork_ctx;
>  				list_move(&uwq->wq.entry, &fork_event);
>  				/*
>  				 * fork_nctx can be freed as soon as
> 
this LGTM:

Reviewed-by: Jose A. Perez de Azpillaga <azpijr@gmail.com>

-- 
cheers,
jose a. p-a


  reply	other threads:[~2026-10-31 20:13 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-31 15:47 [PATCH] mm/userfaultfd: store the child's new uffd context in the wait queue entry Tal Zussman
2026-10-31 20:13 ` Jose A. Perez de Azpillaga [this message]
2026-11-01  8:26 ` Mike Rapoport

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=751f878c-1a2f-4fbe-a255-3520ffaa2f28@gmail.com \
    --to=azpijr@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=peterx@redhat.com \
    --cc=rppt@kernel.org \
    --cc=tz2294@columbia.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.