From: Alice Ryhl <aliceryhl@google.com>
To: Oleg Nesterov <oleg@redhat.com>
Cc: "Christian Brauner" <christian@brauner.io>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Trevor Gross" <tmgross@umich.edu>,
"Danilo Krummrich" <dakr@kernel.org>,
"Panagiotis Foliadis" <pfoliadis@posteo.net>,
"Shankari Anand" <shankari.ak0208@gmail.com>,
"FUJITA Tomonori" <fujita.tomonori@gmail.com>,
"Alexey Gladkov" <legion@kernel.org>,
rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: rust: wrong SAFETY comments in group_leader() and pid() + questions
Date: Fri, 5 Dec 2025 18:17:09 +0000 [thread overview]
Message-ID: <aTMhpX-_H4Y4J7Ud@google.com> (raw)
In-Reply-To: <aTMUqp5pXzAscrdZ@redhat.com>
On Fri, Dec 05, 2025 at 06:21:46PM +0100, Oleg Nesterov wrote:
> On 12/05, Alice Ryhl wrote:
> >
> > pub fn group_leader(&self) -> &Task {
> > // SAFETY: The lifetime of the returned task reference is tied to
> > // the lifetime of `self`, and given that a task has a reference to
> > // its group leader, we know it must be valid for the lifetime of
> > // the returned task reference.
> > unsafe { &*bindings::task_group_leader(self.as_ptr()).cast::<Task>() }
> > }
>
> Thanks again Alice, but the comment still looks misleading to me...
> OK, quite possibly this is because I don't understand what does the
> "lifetime of the returned task reference" actually mean in the rust code.
> Does it mean "lifetime of task_struct" of "lifetime of the process/thread" ?
To start with, it's likely that this comment is not the right choice
for this function, given our discussion. Most likely group_leader()
needs to be moved to `impl CurrentTask {}` and the safety comment needs
to explain why being the current task ensures that the returned &Task
lives for long enough. I just took the safety comment from the code we
have today.
To explain "lifetime of the returned task reference" it may be useful to
show you the long form of this function signature:
fn group_leader<'a>(&'a self) -> &'a Task;
By "lifetime of the returned task reference" I am referring to 'a, which
is some region of code in the caller. For example, 'a might be:
* The region of code until I put the task I called group_leader() on.
* The region of code between a rcu_read_lock() / rcu_read_unlock() pair.
* The region of code until I release a mutex.
* The region of code inside a scope or function.
So for example, with the code as it is today, this example:
let leader = task.group_leader();
drop(task); // put refcount
do_something(leader); // COMPILE ERROR
Rust will see that `task` may no longer be valid after the second line,
so 'a becomes the region of code until drop(task), and the use of
leader after the end of 'a is a compilation error.
Now, the above example is not really valid. It works today, but once we
fix group_leader() to require the task to be the current task, then the
example might look like this:
let leader;
{
let current = current!();
leader = current.leader();
do_something(leader); // OK
}
do_something(leader); // COMPILE ERROR
And ok, this example isn't great because the last line is actually OK.
However, the way that I designed current!() to work is that it gives you
an `&'a CurrentTask` where 'a is the duration of the current scope. So
any use of `leader` after the end of the current scope is a compile
error.
> Let me provide the artificial example. Suppose we have something like
>
> struct task_struct *TASK = NULL;
>
> void stupid_example(void)
> {
> TASK = get_task_struct(current);
>
> do_exit(0);
> }
>
> and a non-leader task calls stupid_example().
>
> After that the global TASK pointer is still valid, it is safe to
> dereference it, task_struct itself can't go away.
This would not compile in Rust. The &CurrentTask obtained using
current!() can't leave the scope it is created in.
> But! Right after that TASK->group_leader can point to nowhere (to the freed memory)
> if another thread does do_group_exit() or sys_execve().
>
> So. Perhaps the the comment should say something like
>
> SAFETY: The lifetime of the returned task reference is tied to
> the lifetime of the THREAD represented by `self`
>
> ?
I think the safety comment should make some reference to the fact that
we know it was obtained from the current task. After all, that's why we
know it's ok.
impl CurrentTask {
fn group_leader(&self) -> &Task {
// SAFETY: This is the current task, so the task must be alive.
// Therefore the group leader cannot change, and thus it will
// stay valid as long as self is the current task.
unsafe { &*bindings::task_group_leader(self.as_ptr()).cast::<Task>() }
}
}
Alice
next prev parent reply other threads:[~2025-12-05 18:17 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-05 14:08 rust: wrong SAFETY comments in group_leader() and pid() + questions Oleg Nesterov
2025-12-05 14:19 ` Alice Ryhl
2025-12-05 14:29 ` Alice Ryhl
2025-12-05 17:21 ` Oleg Nesterov
2025-12-05 18:17 ` Alice Ryhl [this message]
2025-12-08 14:30 ` Oleg Nesterov
2025-12-11 1:20 ` Alice Ryhl
2025-12-08 15:43 ` Gary Guo
2025-12-11 1:16 ` Alice Ryhl
2025-12-05 15:35 ` Oleg Nesterov
2025-12-05 16:28 ` Alice Ryhl
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=aTMhpX-_H4Y4J7Ud@google.com \
--to=aliceryhl@google.com \
--cc=a.hindborg@kernel.org \
--cc=alex.gaynor@gmail.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=christian@brauner.io \
--cc=dakr@kernel.org \
--cc=fujita.tomonori@gmail.com \
--cc=gary@garyguo.net \
--cc=legion@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=oleg@redhat.com \
--cc=pfoliadis@posteo.net \
--cc=rust-for-linux@vger.kernel.org \
--cc=shankari.ak0208@gmail.com \
--cc=tmgross@umich.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).