FAILED: patch "[PATCH] shm: extend forced shm destroy to support objects from" failed to apply to 4.19-stable tree
[email protected]
maintainerThe patch below does not apply to the 4.19-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 85b6d24646e4125c591639841169baa98a2da503 Mon Sep 17 00:00:00 2001
From: Alexander Mikhalitsyn <[email protected]>
Date: Fri, 19 Nov 2021 16:43:21 -0800
Subject: [PATCH] shm: extend forced shm destroy to support objects from
several IPC nses
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.
include/linux/ipc_namespace.h +15 -0
@@ -131,6 +131,16 @@ static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)return ns; } +static inline struct ipc_namespace *get_ipc_ns_not_zero (struct ipc_namespace *ns) +{ +if (ns) { +if (refcount_inc_not_zero (&ns->ns.count)) +return ns; + } + +return NULL ; +} +extern void put_ipc_ns (struct ipc_namespace *ns);#else static inline struct ipc_namespace *copy_ipcs(unsigned long flags,
@@ -147,6 +157,11 @@ static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)return ns; } +static inline struct ipc_namespace *get_ipc_ns_not_zero (struct ipc_namespace *ns) +{ +return ns; +} +static inline void put_ipc_ns (struct ipc_namespace *ns) { }
include/linux/sched/task.h +1 -1
@@ -158,7 +158,7 @@ static inline struct vm_struct *task_stack_vm_area(const struct task_struct *t)* Protects ->fs, ->files, ->mm, ->group_info, ->comm, keyring * subscriptions and synchronises with wait4(). Also used in procfs. Also * pins the final release of task.io_context. Also protects ->cpuset and -* ->cgroup.subsys[]. And ->vfork_done. +* ->cgroup.subsys[]. And ->vfork_done. And ->sysvshm.shm_clist. * * Nests both inside and outside of read_lock(&tasklist_lock). * It must not be nested with write_lock_irq(&tasklist_lock),
ipc/shm.c +143 -46
264 lines not on this page · raw message
PATCH 1/1 shm: extend forced shm destroy to support objects from several IPC nses
From: Alexander Mikhalitsyn <[email protected]>
For 4.19.y:
Upstream commit 85b6d24646e4 ("shm: extend forced shm destroy to support objects from several IPC nses")
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.
--- include/linux/ipc_namespace.h | 15 +++ include/linux/sched/task.h | 2 +- ipc/shm.c | 189 +++++++++++++++++++++++++--------- 3 files changed, 159 insertions(+), 47 deletions(-)
include/linux/ipc_namespace.h +15 -0
@@ -129,6 +129,16 @@ static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)return ns; } +static inline struct ipc_namespace *get_ipc_ns_not_zero (struct ipc_namespace *ns) +{ +if (ns) { +if (refcount_inc_not_zero (&ns->count)) +return ns; + } + +return NULL ; +} +extern void put_ipc_ns (struct ipc_namespace *ns);#else static inline struct ipc_namespace *copy_ipcs(unsigned long flags,
@@ -145,6 +155,11 @@ static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)return ns; } +static inline struct ipc_namespace *get_ipc_ns_not_zero (struct ipc_namespace *ns) +{ +return ns; +} +static inline void put_ipc_ns (struct ipc_namespace *ns) { }
include/linux/sched/task.h +1 -1
@@ -136,7 +136,7 @@ static inline struct vm_struct *task_stack_vm_area(const struct task_struct *t)* Protects ->fs, ->files, ->mm, ->group_info, ->comm, keyring * subscriptions and synchronises with wait4(). Also used in procfs. Also * pins the final release of task.io_context. Also protects ->cpuset and -* ->cgroup.subsys[]. And ->vfork_done. +* ->cgroup.subsys[]. And ->vfork_done. And ->sysvshm.shm_clist. * * Nests both inside and outside of read_lock(&tasklist_lock). * It must not be nested with write_lock_irq(&tasklist_lock),
ipc/shm.c +143 -46
264 lines not on this page · raw message
Signature · 1 line
2.31.1
Greg KH
maintainerRe: [PATCH] shm: extend forced shm destroy to support objects from several IPC nses
Quoted 5 lines · Manfred Spraul
From: Alexander Mikhalitsyn <[email protected]>
For 4.19.y:
Upstream commit
85b6d24646e4("shm: extend forced shm destroy to support objects from several IPC nses")
Now queued up, thanks.
greg k-h