Re: [PATCH v2] kernel: bpf: stackmap: fix a possible sleep-in-atomic bug in bpf_mmap_unlock_get_irq_work()

From: Alexei Starovoitov
Date: Sun Mar 19 2023 - 12:47:27 EST


On Sun, Mar 19, 2023 at 02:12:49AM +0800, Teng Qi wrote:
> Regarding the first problem, our tool discovered a possible code path that
>
> starts from mmap_read_unlock() and leads to sleep in kernel v6.3-rc2 source
>
> code.
>
>
>
> kernel/bpf/mmap_unlock_work.h:52 mmap_read_unlock(mm);
>
> include/linux/mmap_lock.h:144 up_read(&mm->mmap_lock);
>
> kernel/locking/rwsem.c:1616 __up_read(sem);
>
> kernel/locking/rwsem.c:1352 rwsem_wake(sem);
>
> kernel/locking/rwsem.c:1211 rwsem_mark_wake(sem, RWSEM_WAKE_ANY, &wake_q);
>
> kernel/locking/rwsem.c:566 wake_q_add_safe(wake_q, tsk);
>
> kernel/sched/core.c:990 put_task_struct(task);
>
> include/linux/sched/task.h:119 __put_task_struct(t);
>
> kernel/fork.c:857 exit_creds(tsk);
>
> kernel/cred.c:172 put_cred(cred);
>
> include/linux/cred.h:288 __put_cred(cred);
>
> kernel/cred.c:151 put_cred_rcu(&cred->rcu);
>
> kernel/cred.c:121 put_group_info(cred->group_info);
>
> include/linux/cred.h:53 groups_free(group_info);
>
> kernel/groups.c:31 kvfree(group_info);
>
> mm/util.c:647 vfree(addr); <- oops, sleep when size of group_info is large
>
>
>
> However, we cannot guarantee that this code path will be triggered during
>
> runtime since it was generated by a static analysis tool.

So it is a purely theoretical issue and out of thousands users of up_read()
you've decided to fix one where it is called form mmap_read_unlock().
Why?

You also see that __up_read is doing preempt_disable and then calls rwsem_wake()
which will theoretically can call vfree() with "oops", right?
So agian, why target mmap_read_unlock() ?