• Roman Gushchin's avatar
    bpf: fix cgroup bpf release synchronization · e5c891a3
    Roman Gushchin authored
    Since commit 4bfc0bb2 ("bpf: decouple the lifetime of cgroup_bpf
    from cgroup itself"), cgroup_bpf release occurs asynchronously
    (from a worker context), and before the release of the cgroup itself.
    
    This introduced a previously non-existing race between the release
    and update paths. E.g. if a leaf's cgroup_bpf is released and a new
    bpf program is attached to the one of ancestor cgroups at the same
    time. The race may result in double-free and other memory corruptions.
    
    To fix the problem, let's protect the body of cgroup_bpf_release()
    with cgroup_mutex, as it was effectively previously, when all this
    code was called from the cgroup release path with cgroup mutex held.
    
    Also let's skip cgroups, which have no chances to invoke a bpf
    program, on the update path. If the cgroup bpf refcnt reached 0,
    it means that the cgroup is offline (no attached processes), and
    there are no associated sockets left. It means there is no point
    in updating effective progs array! And it can lead to a leak,
    if it happens after the release. So, let's skip such cgroups.
    
    Big thanks for Tejun Heo for discovering and debugging of this problem!
    
    Fixes: 4bfc0bb2 ("bpf: decouple the lifetime of cgroup_bpf from cgroup itself")
    Reported-by: default avatarTejun Heo <tj@kernel.org>
    Signed-off-by: default avatarRoman Gushchin <guro@fb.com>
    Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    e5c891a3
cgroup.c 31.2 KB