mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-07 13:43:51 +00:00
bpf: Only allow sleepable program for resched-able iterator
When a sleepable program is attached to a hash map iterator, might_fault() will report "BUG: sleeping function called from invalid context..." if CONFIG_DEBUG_ATOMIC_SLEEP is enabled. The reason is that rcu_read_lock() is held in bpf_hash_map_seq_next() and won't be released until all elements are traversed or bpf_hash_map_seq_stop() is called. Fixing it by reusing BPF_ITER_RESCHED to indicate that only non-sleepable program is allowed for iterator without BPF_ITER_RESCHED. We can revise bpf_iter_link_attach() later if there are other conditions which may cause rcu_read_lock() or spin_lock() issues. Signed-off-by: Hou Tao <houtao1@huawei.com> Acked-by: Yonghong Song <yhs@fb.com> Link: https://lore.kernel.org/r/20220810080538.1845898-7-houtao@huaweicloud.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
52bd05eb7c
commit
d247049f4f
@ -68,13 +68,18 @@ static void bpf_iter_done_stop(struct seq_file *seq)
|
||||
iter_priv->done_stop = true;
|
||||
}
|
||||
|
||||
static inline bool bpf_iter_target_support_resched(const struct bpf_iter_target_info *tinfo)
|
||||
{
|
||||
return tinfo->reg_info->feature & BPF_ITER_RESCHED;
|
||||
}
|
||||
|
||||
static bool bpf_iter_support_resched(struct seq_file *seq)
|
||||
{
|
||||
struct bpf_iter_priv_data *iter_priv;
|
||||
|
||||
iter_priv = container_of(seq->private, struct bpf_iter_priv_data,
|
||||
target_private);
|
||||
return iter_priv->tinfo->reg_info->feature & BPF_ITER_RESCHED;
|
||||
return bpf_iter_target_support_resched(iter_priv->tinfo);
|
||||
}
|
||||
|
||||
/* maximum visited objects before bailing out */
|
||||
@ -537,6 +542,10 @@ int bpf_iter_link_attach(const union bpf_attr *attr, bpfptr_t uattr,
|
||||
if (!tinfo)
|
||||
return -ENOENT;
|
||||
|
||||
/* Only allow sleepable program for resched-able iterator */
|
||||
if (prog->aux->sleepable && !bpf_iter_target_support_resched(tinfo))
|
||||
return -EINVAL;
|
||||
|
||||
link = kzalloc(sizeof(*link), GFP_USER | __GFP_NOWARN);
|
||||
if (!link)
|
||||
return -ENOMEM;
|
||||
|
Loading…
Reference in New Issue
Block a user