Thank you for your contribution! Sashiko AI review found 1 potential issue(s) 
to consider:
- [High] rhashtable: UAF in standard walkers and inserts due to Tasks Rude RCU 
mismatch
--

commit 72dce4af7330e16ac9fafbde35eaffd5f5d340ca
Author: Masami Hiramatsu (Google) <[email protected]>

rhashtable: Add use_tasks_rude parameter to defer bucket table free

This commit adds a use_tasks_rude boolean flag to struct rhashtable_params.
When enabled, old bucket tables are freed using call_rcu_tasks_rude()
instead of call_rcu() to support callers that operate under preempt_disable()
without holding rcu_read_lock().

> diff --git a/lib/rhashtable.c b/lib/rhashtable.c
> index 6362896e4f099..b183fb112a705 100644
> --- a/lib/rhashtable.c
> +++ b/lib/rhashtable.c
> @@ -359,7 +359,10 @@ static int rhashtable_rehash_table(struct rhashtable *ht)
>        * rhashtable_walk_stop() can use rcu_head_after_call_rcu()
>        * to check if it should not re-link the table.
>        */
> -     call_rcu(&old_tbl->rcu, bucket_table_free_rcu);
> +     if (ht->p.use_tasks_rude)
> +             call_rcu_tasks_rude(&old_tbl->rcu, bucket_table_free_rcu);

[Severity: High]
Does this create a use-after-free for standard readers when
CONFIG_PREEMPT_RCU=y is enabled?

Standard rhashtable operations like __rhashtable_insert_fast() and
rhashtable_walk_start_check() acquire standard RCU read locks:

lib/rhashtable.c:rhashtable_walk_start_check() {
    ...
    rcu_read_lock();
    iter->walker.tbl = rht_dereference_rcu(ht->tbl, ht);
    ...
}

include/linux/rhashtable.h:__rhashtable_insert_fast() {
    ...
    rcu_read_lock();
    tbl = rht_dereference_rcu(ht->tbl, ht);
    ...
}

Under CONFIG_PREEMPT_RCU, rcu_read_lock() does not disable preemption. If a
task is preempted during an insert or walk, a Tasks Rude RCU grace period
can complete while the preempted task is still accessing the old bucket
table. Since Tasks Rude RCU only waits for preempt-disabled regions and not
standard RCU read-side critical sections, the bucket table could be freed
before the preempted standard reader finishes.

> +     else
> +             call_rcu(&old_tbl->rcu, bucket_table_free_rcu);
>       spin_unlock(&ht->lock);
>  
>       return rht_dereference(new_tbl->future_tbl, ht) ? -EAGAIN : 0;

-- 
Sashiko AI review ยท 
https://sashiko.dev/#/patchset/179060575297.372125.10581329083761385407.stgit@devnote2?part=2

Reply via email to