From: Alice Ryhl <aliceryhl@google.com>
To: benno.lossin@proton.me, brauner@kernel.org
Cc: a.hindborg@samsung.com, alex.gaynor@gmail.com, arve@android.com,
bjorn3_gh@protonmail.com, boqun.feng@gmail.com,
cmllamas@google.com, dan.j.williams@intel.com, dxu@dxuuu.xyz,
gary@garyguo.net, gregkh@linuxfoundation.org,
joel@joelfernandes.org, keescook@chromium.org,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
maco@android.com, ojeda@kernel.org, peterz@infradead.org,
rust-for-linux@vger.kernel.org, surenb@google.com,
tglx@linutronix.de, tkjos@android.com, viro@zeniv.linux.org.uk,
wedsonaf@gmail.com, willy@infradead.org
Subject: Re: [PATCH 6/7] rust: file: add `DeferredFdCloser`
Date: Tue, 5 Dec 2023 19:16:27 +0100 [thread overview]
Message-ID: <CAH5fLggz5ArqX076OgBaqFF57-f9h1E_hGOeiXfhcfe-neW_jQ@mail.gmail.com> (raw)
In-Reply-To: <20231205144345.308820-1-aliceryhl@google.com>
On Tue, Dec 5, 2023 at 3:43 PM Alice Ryhl <aliceryhl@google.com> wrote:
>
> Benno Lossin <benno.lossin@proton.me> writes:
> > On 12/1/23 12:35, Alice Ryhl wrote:
> >> Benno Lossin <benno.lossin@proton.me> writes:
> >>>> + // SAFETY: The `inner` pointer points at a valid and fully initialized task work that is
> >>>> + // ready to be scheduled.
> >>>> + unsafe { bindings::task_work_add(current, inner, TWA_RESUME) };
> >>>
> >>> I am a bit confused, when does `do_close_fd` actually run? Does
> >>> `TWA_RESUME` mean that `inner` is scheduled to run after the current
> >>> task has been completed?
> >>
> >> When the current syscall returns to userspace.
> >
> > What happens when I use `DeferredFdCloser` outside of a syscall? Will
> > it never run? Maybe add some documentation about that?
>
> Christian Brauner, I think I need your help here.
>
> I spent a bunch of time today trying to understand the correct way of
> closing an fd held with fdget, and I'm unsure what the best way is.
>
> So, first, `task_work_add` only really works when we're called from a
> syscall. For one, it's fallible, and for another, you shouldn't even
> attempt to use it from a kthread. (See e.g., the implementation of
> `fput` in `fs/file_table.c`.)
>
> To handle the above, we could fall back to the workqueue and schedule
> the `fput` there when we are on a kthread or `task_work_add` fails. And
> since I don't really care about the performance of this utility, let's
> say we just unconditionally use the workqueue to simplify the
> implementation.
>
> However, it's not clear to me that this is okay. Consider this
> execution: (please compare to `binder_deferred_fd_close`)
>
> Thread A Thread B (workqueue)
> fdget()
> close_fd_get_file()
> get_file()
> filp_close()
> schedule_work(do_close_fd)
> // we are preempted
> fput()
> fdput()
>
> And now, since the workqueue can run before thread A returns to
> userspace, we are in trouble again, right? Unless I missed an upgrade
> to shared file descriptor somewhere that somehow makes this okay? I
> looked around the C code and couldn't find one and I guess such an
> upgrade has to happen before the call to `fdget` anyway?
>
> In Binder, the above is perfectly fine since it closes the fd from a
> context where `task_work_add` will always work, and a task work
> definitely runs after the `fdput`. But I added this as a utility in the
> shared kernel crate, and I want to avoid the situation where someone
> comes along later and uses it from a kthread, gets the fallback to
> workqueue, and then has an UAF due to the previously mentioned
> execution...
>
> What do you advise that I do?
>
> Maybe the answer is just that, if you're in a context where it makes
> sense to talk about an fd of the current task, then task_work_add will
> also definitely work? So if `task_work_add` won't work, then
> `close_fd_get_file` will return a null pointer and we never reach the
> `task_work_add`. This seems fragile though.
>
> Alice
Ah! I realized that there's another option: Report an error if we
can't schedule the task work.
I didn't suggest this originally because I didn't want to leak the
file in the error path, and I couldn't think of anything else sane to
do.
But! We can schedule the task work *first*, then attempt to close the
file. This way, the file doesn't get closed in the error path. And
there's no race condition since the task work is guaranteed to get
scheduled later on the same thread, so there's no way for it to get
executed in between us scheduling it and closing the file.
Thoughts?
Alice
next prev parent reply other threads:[~2023-12-05 18:16 UTC|newest]
Thread overview: 96+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-29 12:51 [PATCH 0/7] File abstractions needed by Rust Binder Alice Ryhl
2023-11-29 12:51 ` [PATCH 1/7] rust: file: add Rust abstraction for `struct file` Alice Ryhl
2023-11-29 15:13 ` Matthew Wilcox
2023-11-29 15:23 ` Peter Zijlstra
2023-11-29 17:08 ` Boqun Feng
2023-11-30 10:42 ` Peter Zijlstra
2023-11-30 15:25 ` Boqun Feng
2023-12-01 8:53 ` Peter Zijlstra
2023-12-01 9:19 ` Boqun Feng
2023-12-01 9:40 ` Peter Zijlstra
2023-12-01 10:36 ` Boqun Feng
2023-12-01 11:05 ` Peter Zijlstra
2023-12-01 9:00 ` Peter Zijlstra
2023-12-01 9:52 ` Boqun Feng
2023-11-29 16:42 ` Alice Ryhl
2023-11-29 16:45 ` Peter Zijlstra
2023-11-30 15:02 ` Benno Lossin
2023-11-29 17:06 ` Christian Brauner
2023-11-29 21:27 ` Alice Ryhl
2023-11-29 23:17 ` Benno Lossin
2023-11-30 10:48 ` Christian Brauner
2023-11-30 12:10 ` Alice Ryhl
2023-11-30 12:36 ` Christian Brauner
2023-11-30 14:53 ` Benno Lossin
2023-11-30 14:59 ` Greg Kroah-Hartman
2023-11-30 15:46 ` Benno Lossin
2023-11-30 15:56 ` Greg Kroah-Hartman
2023-11-30 15:58 ` Theodore Ts'o
2023-11-30 16:12 ` Benno Lossin
2023-12-01 1:16 ` Theodore Ts'o
2023-12-01 12:11 ` David Laight
2023-12-01 12:27 ` Alice Ryhl
2023-12-01 15:04 ` Theodore Ts'o
2023-12-01 15:14 ` Benno Lossin
2023-12-01 17:25 ` David Laight
2023-12-01 17:37 ` Benno Lossin
2023-11-29 12:51 ` [PATCH 2/7] rust: cred: add Rust abstraction for `struct cred` Alice Ryhl
2023-11-30 16:17 ` Benno Lossin
2023-12-01 9:06 ` Alice Ryhl
2023-12-01 10:27 ` Christian Brauner
2023-12-04 15:42 ` Alice Ryhl
2023-11-29 13:11 ` [PATCH 3/7] rust: security: add abstraction for secctx Alice Ryhl
2023-11-30 16:26 ` Benno Lossin
2023-12-01 10:48 ` Alice Ryhl
2023-12-02 10:03 ` Benno Lossin
2023-11-29 13:11 ` [PATCH 4/7] rust: file: add `FileDescriptorReservation` Alice Ryhl
2023-11-29 16:14 ` Christian Brauner
2023-11-29 16:55 ` Alice Ryhl
2023-11-29 17:14 ` Alice Ryhl
2023-11-30 9:12 ` Christian Brauner
2023-11-30 9:23 ` Alice Ryhl
2023-11-30 9:09 ` Christian Brauner
2023-11-30 9:17 ` Alice Ryhl
2023-11-30 10:51 ` Christian Brauner
2023-11-30 11:54 ` Alice Ryhl
2023-11-30 12:17 ` Benno Lossin
2023-11-30 12:33 ` Christian Brauner
2023-11-30 16:40 ` Benno Lossin
2023-12-01 11:32 ` Alice Ryhl
2023-11-29 13:12 ` [PATCH 5/7] rust: file: add `Kuid` wrapper Alice Ryhl
2023-11-29 16:28 ` Christian Brauner
2023-11-29 16:48 ` Peter Zijlstra
2023-11-30 12:46 ` Christian Brauner
2023-12-06 19:59 ` Kent Overstreet
2023-12-08 16:26 ` Peter Zijlstra
2023-12-08 19:58 ` Kent Overstreet
2023-12-08 5:28 ` comex
2023-12-08 16:19 ` Miguel Ojeda
2023-12-08 17:08 ` Nick Desaulniers
2023-12-08 17:37 ` Miguel Ojeda
2023-12-08 17:43 ` Boqun Feng
2023-12-08 20:43 ` Matthew Wilcox
2023-12-09 7:24 ` comex
2023-11-30 9:36 ` Alice Ryhl
2023-11-30 10:52 ` Christian Brauner
2023-11-30 10:36 ` Peter Zijlstra
2023-12-06 20:02 ` Kent Overstreet
2023-12-07 7:18 ` Greg Kroah-Hartman
2023-12-07 7:46 ` Kent Overstreet
2023-11-30 16:48 ` Benno Lossin
2023-11-29 13:12 ` [PATCH 6/7] rust: file: add `DeferredFdCloser` Alice Ryhl
2023-11-30 17:12 ` Benno Lossin
2023-12-01 11:35 ` Alice Ryhl
2023-12-02 10:16 ` Benno Lossin
2023-12-05 14:43 ` Alice Ryhl
2023-12-05 18:16 ` Alice Ryhl [this message]
2023-11-29 13:12 ` [PATCH 7/7] rust: file: add abstraction for `poll_table` Alice Ryhl
2023-11-30 17:42 ` Benno Lossin
2023-12-01 11:47 ` Alice Ryhl
2023-11-30 22:39 ` Boqun Feng
2023-12-01 11:50 ` Alice Ryhl
2023-11-30 22:50 ` Boqun Feng
2023-11-29 16:31 ` [PATCH 0/7] File abstractions needed by Rust Binder Christian Brauner
2023-11-29 16:48 ` Miguel Ojeda
2023-12-06 20:05 ` Kent Overstreet
2023-12-08 16:59 ` Miguel Ojeda
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=CAH5fLggz5ArqX076OgBaqFF57-f9h1E_hGOeiXfhcfe-neW_jQ@mail.gmail.com \
--to=aliceryhl@google.com \
--cc=a.hindborg@samsung.com \
--cc=alex.gaynor@gmail.com \
--cc=arve@android.com \
--cc=benno.lossin@proton.me \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=brauner@kernel.org \
--cc=cmllamas@google.com \
--cc=dan.j.williams@intel.com \
--cc=dxu@dxuuu.xyz \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=joel@joelfernandes.org \
--cc=keescook@chromium.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maco@android.com \
--cc=ojeda@kernel.org \
--cc=peterz@infradead.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=surenb@google.com \
--cc=tglx@linutronix.de \
--cc=tkjos@android.com \
--cc=viro@zeniv.linux.org.uk \
--cc=wedsonaf@gmail.com \
--cc=willy@infradead.org \
/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).