[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20231201115051.2209084-1-aliceryhl@google.com>
Date: Fri, 1 Dec 2023 11:50:51 +0000
From: Alice Ryhl <aliceryhl@...gle.com>
To: boqun.feng@...il.com
Cc: a.hindborg@...sung.com, alex.gaynor@...il.com,
aliceryhl@...gle.com, arve@...roid.com, benno.lossin@...ton.me,
bjorn3_gh@...tonmail.com, brauner@...nel.org, cmllamas@...gle.com,
dan.j.williams@...el.com, dxu@...uu.xyz, gary@...yguo.net,
gregkh@...uxfoundation.org, joel@...lfernandes.org,
keescook@...omium.org, linux-fsdevel@...r.kernel.org,
linux-kernel@...r.kernel.org, maco@...roid.com, ojeda@...nel.org,
peterz@...radead.org, rust-for-linux@...r.kernel.org,
surenb@...gle.com, tglx@...utronix.de, tkjos@...roid.com,
viro@...iv.linux.org.uk, wedsonaf@...il.com, willy@...radead.org
Subject: Re: [PATCH 7/7] rust: file: add abstraction for `poll_table`
Boqun Feng <boqun.feng@...il.com> writes:
>> That said, `synchronize_rcu` is rather expensive and is not needed in
>> all cases: If we have never registered a `poll_table` with the
>> `wait_list`, then we don't need to call `synchronize_rcu`. (And this is
>> a common case in Binder - not all processes use Binder with epoll.) The
>> current implementation does not account for this, but we could change it
>> to store a boolean next to the `wait_list` to keep track of whether a
>> `poll_table` has ever been registered. It is up to discussion whether
>> this is desireable.
>>
>> It is not clear to me whether we can implement the above without storing
>> an extra boolean. We could check whether the `wait_list` is empty, but
>> it is not clear that this is sufficient. Perhaps someone knows the
>> answer? If a `poll_table` has previously been registered with a
>
> That won't be sufficient, considering this:
>
> CPU 0 CPU 1
> ep_remove_wait_queue():
> whead = smp_load_acquire(&pwq->whead); // whead is not NULL
> PollCondVar::drop():
> self.inner.notify():
> <for each wait entry in the list>
> ep_poll_callback():
> <remove wait entry>
> smp_store_release(&ep_pwq_from_wait(wait)->whead, NULL);
> <lock the waitqueue>
> waitqueue_active() // return false, since the queue is emtpy
> <unlock>
> ...
> <free the waitqueue>
> if (whead) {
> remove_wait_queue(whead, &pwq->wait); // Use-after-free BOOM!
> }
>
>
> Note that moving the `wait_list` empty checking before
> `self.inner.notify()` won't change the result, since there might be a
> `notify` called by users before `PollCondVar::drop()`, hence the same
> result.
>
> Regards,
> Boqun
Thank you for confirming my suspicion.
Alice
Powered by blists - more mailing lists