• Alexander Mikhalitsyn's avatar
    shm: extend forced shm destroy to support objects from several IPC nses · 85b6d246
    Alexander Mikhalitsyn authored
    Currently, the exit_shm() function not designed to work properly when
    task->sysvshm.shm_clist holds shm objects from different IPC namespaces.
    
    This is a real pain when sysctl kernel.shm_rmid_forced = 1, because it
    leads to use-after-free (reproducer exists).
    
    This is an attempt to fix the problem by extending exit_shm mechanism to
    handle shm's destroy from several IPC ns'es.
    
    To achieve that we do several things:
    
    1. add a namespace (non-refcounted) pointer to the struct shmid_kernel
    
    2. during new shm object creation (newseg()/shmget syscall) we
       initialize this pointer by current task IPC ns
    
    3. exit_shm() fully reworked such that it traverses over all shp's in
       task->sysvshm.shm_clist and gets IPC namespace not from current task
       as it was before but from shp's object itself, then call
       shm_destroy(shp, ns).
    
    Note: We need to be really careful here, because as it was said before
    (1), our pointer to IPC ns non-refcnt'ed.  To be on the safe side we
    using special helper get_ipc_ns_not_zero() which allows to get IPC ns
    refcounter only if IPC ns not in the "state of destruction".
    
    Q/A
    
    Q: Why can we access shp->ns memory using non-refcounted pointer?
    A: Because shp object lifetime is always shorther than IPC namespace
       lifetime, so, if we get shp object from the task->sysvshm.shm_clist
       while holding task_lock(task) nobody can steal our namespace.
    
    Q: Does this patch change semantics of unshare/setns/clone syscalls?
    A: No. It's just fixes non-covered case when process may leave IPC
       namespace without getting task->sysvshm.shm_clist list cleaned up.
    
    Link: https://lkml.kernel.org/r/67bb03e5-f79c-1815-e2bf-949c67047418@colorfullife.com
    Link: https://lkml.kernel.org/r/20211109151501.4921-1-manfred@colorfullife.com
    Fixes: ab602f79 ("shm: make exit_shm work proportional to task activity")
    Co-developed-by: default avatarManfred Spraul <manfred@colorfullife.com>
    Signed-off-by: default avatarManfred Spraul <manfred@colorfullife.com>
    Signed-off-by: default avatarAlexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>
    Cc: "Eric W. Biederman" <ebiederm@xmission.com>
    Cc: Davidlohr Bueso <dave@stgolabs.net>
    Cc: Greg KH <gregkh@linuxfoundation.org>
    Cc: Andrei Vagin <avagin@gmail.com>
    Cc: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
    Cc: Vasily Averin <vvs@virtuozzo.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    85b6d246
shm.c 44.8 KB