From: Kees Cook <kees@kernel.org>
To: Oleg Nesterov <oleg@redhat.com>
Cc: brauner@kernel.org, viro@zeniv.linux.org.uk, jack@suse.cz,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-mm@kvack.org, syzkaller-bugs@googlegroups.com,
mjguzik@gmail.com, Michal Hocko <mhocko@suse.com>
Subject: Re: [PATCH] exec: fix the racy usage of fs_struct->in_exec
Date: Tue, 29 Apr 2025 09:57:24 -0700 [thread overview]
Message-ID: <202504290957.1D6835B89@keescook> (raw)
In-Reply-To: <20250429154944.GA18907@redhat.com>
On Tue, Apr 29, 2025 at 05:49:44PM +0200, Oleg Nesterov wrote:
> Damn, I am stupid.
>
> On 03/24, Oleg Nesterov wrote:
> >
> > check_unsafe_exec() sets fs->in_exec under cred_guard_mutex, then execve()
> > paths clear fs->in_exec lockless. This is fine if exec succeeds, but if it
> > fails we have the following race:
> >
> > T1 sets fs->in_exec = 1, fails, drops cred_guard_mutex
> >
> > T2 sets fs->in_exec = 1
> >
> > T1 clears fs->in_exec
>
> When I look at this code again, I think this race was not possible and thus
> this patch (applied as af7bb0d2ca45) was not needed.
>
> Yes, begin_new_exec() can drop cred_guard_mutex on failure, but only after
> de_thread() succeeds, when we can't race with another sub-thread.
>
> I hope this patch didn't make the things worse so we don't need to revert it.
> Plus I think it makes this (confusing) logic a bit more clear. Just, unless
> I am confused again, it wasn't really needed.
>
> -----------------------------------------------------------------------------
> But. I didn't read the original report from syzbot,
> https://lore.kernel.org/all/67dc67f0.050a0220.25ae54.001f.GAE@google.com/#t
> because I wasn't CC'ed. and then - sorry Kees!!! - I didn't bother to read
> your first reply carefully.
>
> So yes, with or without this patch the "if (fs->in_exec)" check in copy_fs()
> can obviously hit the 1 -> 0 transition.
>
> This is harmless, but should be probably fixed just to avoid another report
> from KCSAN.
>
> I do not want to add another spin_lock(fs->lock). We can change copy_fs() to
> use data_race(), but I'd prefer the patch below. Yes, it needs the additional
> comment(s) to explain READ_ONCE().
>
> What do you think? Did I miss somthing again??? Quite possibly...
>
> Mateusz, I hope you will cleanup this horror sooner or later ;)
>
> Oleg.
> ---
>
> diff --git a/fs/exec.c b/fs/exec.c
> index 5d1c0d2dc403..42a7f9b43911 100644
> --- a/fs/exec.c
> +++ b/fs/exec.c
> @@ -1495,7 +1495,7 @@ static void free_bprm(struct linux_binprm *bprm)
> free_arg_pages(bprm);
> if (bprm->cred) {
> /* in case exec fails before de_thread() succeeds */
> - current->fs->in_exec = 0;
> + WRITE_ONCE(current->fs->in_exec, 0);
> mutex_unlock(¤t->signal->cred_guard_mutex);
> abort_creds(bprm->cred);
> }
> diff --git a/kernel/fork.c b/kernel/fork.c
> index 4c2df3816728..381af8c8ece8 100644
> --- a/kernel/fork.c
> +++ b/kernel/fork.c
> @@ -1802,7 +1802,7 @@ static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
> /* tsk->fs is already what we want */
> spin_lock(&fs->lock);
> /* "users" and "in_exec" locked for check_unsafe_exec() */
> - if (fs->in_exec) {
> + if (READ_ONCE(fs->in_exec)) {
> spin_unlock(&fs->lock);
> return -EAGAIN;
> }
>
Yeah, this seems reasonable.
--
Kees Cook
next prev parent reply other threads:[~2025-04-29 16:57 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-20 19:09 [syzbot] [fs?] [mm?] KCSAN: data-race in bprm_execve / copy_fs (4) syzbot
2025-03-20 20:09 ` Kees Cook
2025-03-21 1:44 ` Al Viro
2025-03-21 8:10 ` Kees Cook
2025-03-21 8:49 ` Christian Brauner
2025-03-21 8:45 ` Christian Brauner
2025-03-22 1:00 ` Al Viro
2025-03-22 6:26 ` Kees Cook
2025-03-22 10:15 ` Mateusz Guzik
2025-03-22 10:28 ` Christian Brauner
2025-03-22 10:23 ` Christian Brauner
2025-03-22 15:55 ` Oleg Nesterov
2025-03-22 18:50 ` Al Viro
2025-03-23 18:14 ` Oleg Nesterov
2025-03-23 20:57 ` Christian Brauner
2025-03-24 16:00 ` [PATCH] exec: fix the racy usage of fs_struct->in_exec Oleg Nesterov
2025-03-24 17:01 ` Mateusz Guzik
2025-03-24 18:27 ` Oleg Nesterov
2025-03-24 18:37 ` Oleg Nesterov
2025-03-24 22:24 ` Mateusz Guzik
2025-03-25 10:09 ` Oleg Nesterov
2025-03-25 11:01 ` Mateusz Guzik
2025-03-25 13:21 ` Oleg Nesterov
2025-03-25 13:30 ` Christian Brauner
2025-03-25 14:15 ` Mateusz Guzik
2025-03-25 14:46 ` Christian Brauner
2025-03-25 18:40 ` Kees Cook
2025-04-29 15:49 ` Oleg Nesterov
2025-04-29 16:57 ` Kees Cook [this message]
2025-04-29 17:12 ` Mateusz Guzik
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=202504290957.1D6835B89@keescook \
--to=kees@kernel.org \
--cc=brauner@kernel.org \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mhocko@suse.com \
--cc=mjguzik@gmail.com \
--cc=oleg@redhat.com \
--cc=syzkaller-bugs@googlegroups.com \
--cc=viro@zeniv.linux.org.uk \
/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.