ipc: introduce shm_rmid_forced sysctl
RFC 1/1 ipc: introduce shm_rmid_forced sysctl
This patch adds support for shm_rmid_forced sysctl. If set to 1, all shared memory objects in current ipc namespace will be automatically forced to use IPC_RMID. POSIX way of handling shmem allows to create shm objects and call shmdt() leaving shm object associated with no process, thus consuming memory not counted via rlimits. With shm_rmid_forced=1 the shared memory object is counted at least for one process, so OOM killer may effectively kill the fat process holding the shared memory.
It obviously breaks POSIX, some programs relying on the feature would stop working. So, set shm_rmid_forced=1 only if you're sure nobody uses "orphaned" memory. shm_rmid_forced=0 by default for compatability reasons.
The feature was previously impemented in -ow as a configure option.
---
Documentation/sysctl/kernel.txt | 22 ++++++++++ include/linux/ipc_namespace.h | 3 + include/linux/shm.h | 5 ++ ipc/ipc_sysctl.c | 33 +++++++++++++++ ipc/shm.c | 87 +++++++++++++++++++++++++++++++++++++-- kernel/exit.c | 1 + 6 files changed, 147 insertions(+), 4 deletions(-)
---
Documentation/sysctl/kernel.txt +22 -0
@@ -62,6 +62,7 @@ show up in /proc/sys/kernel: - shmall - shmmax [ sysv ipc ] - shmmni +- shm_rmid_forced - stop-a [ SPARC only ] - sysrq ==> Documentation/sysrq.txt - tainted
@@ -475,6 +476,27 @@ kernel. This value defaults to SHMMAX. ============================================================== +shm_rmid_forced: + +Linux lets you set resource limits, including on how much memory one +process can consume, via setrlimit(2). Unfortunately, shared memory +segments are allowed to exist without association with any process, and +thus might not be counted against any resource limits. If enabled, +shared memory segments are automatically destroyed when their attach +count becomes zero after a detach or a process termination. It will +also destroy segments that were created, but never attached to, on exit +from the process. The only use left for IPC_RMID is to immediately +destroy an unattached segment. Of course, this breaks the way things are +defined, so some applications might stop working. Note that this +feature will do you no good unless you also configure your resource +limits (in particular, RLIMIT_AS and RLIMIT_NPROC). Most systems don't +need this. + +Note that if you change this from 0 to 1, already created segments +without users and with a dead originative process will be destroyed. + +============================================================== + softlockup_thresh: This value can be used to lower the softlockup tolerance threshold. The
include/linux/ipc_namespace.h +3 -0
@@ -44,6 +44,7 @@ struct ipc_namespace {size_t shm_ctlall;int shm_ctlmni;int shm_tot; +int shm_rmid_forced;struct notifier_block ipcns_nb;
@@ -72,6 +73,7 @@ extern int register_ipcns_notifier(struct ipc_namespace *);extern int cond_register_ipcns_notifier (struct ipc_namespace *);extern void unregister_ipcns_notifier (struct ipc_namespace *);extern int ipcns_notify (unsigned long ); +extern void shm_destroy_orphaned (struct ipc_namespace *ns);#else /* CONFIG_SYSVIPC */ static inline int register_ipcns_notifier (struct ipc_namespace *ns) {return 0 ; }
@@ -79,6 +81,7 @@ static inline int cond_register_ipcns_notifier(struct ipc_namespace *ns) {return 0 ; }static inline void unregister_ipcns_notifier (struct ipc_namespace *ns) { }static inline int ipcns_notify (unsigned long l) {return 0 ; } +static inline void shm_destroy_orphaned (struct ipc_namespace *ns) {}#endif /* CONFIG_SYSVIPC */ #ifdef CONFIG_POSIX_MQUEUE
include/linux/shm.h +5 -0
@@ -106,6 +106,7 @@ struct shmid_kernel /* private to the kernel */#ifdef CONFIG_SYSVIPC long do_shmat (int shmid,char __user *shmaddr,int shmflg,unsigned long *addr);extern int is_file_shm_hugepages (struct file *file); +extern void exit_shm (struct task_struct *task);#else static inline long do_shmat (int shmid,char __user *shmaddr,int shmflg,unsigned long *addr)
@@ -116,6 +117,10 @@ static inline int is_file_shm_hugepages(struct file *file) {return 0 ; } +static inline void exit_shm (struct task_struct *task) +{ +return 0 ; +}#endif #endif /* __KERNEL__ */
ipc/ipc_sysctl.c +33 -0
@@ -37,6 +37,28 @@ static int proc_ipc_dointvec(ctl_table *table, int write,return proc_dointvec (&ipc_table, write, buffer, lenp, ppos); } +static int proc_ipc_dointvec_minmax (ctl_table *table,int write, +void __user *buffer,size_t *lenp,loff_t *ppos) +{ +struct ctl_table ipc_table; +memcpy (&ipc_table, table,sizeof (ipc_table)); + ipc_table.data =get_ipc (table); + +return proc_dointvec_minmax (&ipc_table, write, buffer, lenp, ppos); +} + +static int proc_ipc_dointvec_minmax_orphans (ctl_table *table,int write, +void __user *buffer,size_t *lenp,loff_t *ppos) +{ +struct ipc_namespace *ns = current->nsproxy->ipc_ns; +int err =proc_ipc_dointvec_minmax (table, write, buffer, lenp, ppos); +if (err <0 ) +return err; +if (ns->shm_rmid_forced) +shm_destroy_orphaned (ns); +return err; +} +static int proc_ipc_callback_dointvec (ctl_table *table,int write,void __user *buffer,size_t *lenp,loff_t *ppos) {
@@ -125,6 +147,8 @@ static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write,#else #define proc_ipc_doulongvec_minmax NULL#define proc_ipc_dointvec NULL +#define proc_ipc_dointvec_minmax NULL +#define proc_ipc_dointvec_minmax_orphans NULL#define proc_ipc_callback_dointvec NULL#define proc_ipcauto_dointvec_minmax NULL#endif
@@ -155,6 +179,15 @@ static struct ctl_table ipc_kern_table[] = { .proc_handler = proc_ipc_dointvec, }, { + .procname = "shm_rmid_forced", + .data = &init_ipc_ns.shm_rmid_forced, + .maxlen = sizeof(init_ipc_ns.shm_rmid_forced), + .mode = 0644, + .proc_handler = proc_ipc_dointvec_minmax_orphans, + .extra1 = &zero, + .extra2 = &one, + }, + { .procname = "msgmax", .data = &init_ipc_ns.msg_ctlmax, .maxlen = sizeof (init_ipc_ns.msg_ctlmax),
ipc/shm.c +83 -4
114 lines not on this page · raw message
kernel/exit.c +1 -0
@@ -991,6 +991,7 @@ NORET_TYPE void do_exit(long code)trace_sched_process_exit (tsk);exit_sem (tsk); +exit_shm (tsk);exit_files (tsk);exit_fs (tsk);check_stack_usage ();
---
Quoted 25 lines · On Wed, 22 Jun 2011 19:25:14 +0400 Vasiliy Kulikov wrote:
Signed-off-by Vasiliy Kulikov <[email protected]>---
Documentation/sysctl/kernel.txt | 22 ++++++++++ include/linux/ipc_namespace.h | 3 + include/linux/shm.h | 5 ++ ipc/ipc_sysctl.c | 33 +++++++++++++++ ipc/shm.c | 87 +++++++++++++++++++++++++++++++++++++-- kernel/exit.c | 1 + 6 files changed, 147 insertions(+), 4 deletions(-)---
Documentation/sysctl/kernel.txt +1
-0@@ -62,6 +62,7 @@ show up in /proc/sys/kernel: - shmall - shmmax [ sysv ipc ] - shmmni +- shm_rmid_forced - stop-a [ SPARC only ] - sysrq ==> Documentation/sysrq.txt - tainted
Documentation/sysctl/kernel.txt kernel. This value defaults to SHMMAX. · line 481
Quoted 6 lines
Documentation/sysctl/kernel.txt +3
-0@@ -475,6 +476,27 @@ kernel. This value defaults to SHMMAX. ============================================================== +shm_rmid_forced: + +Linux lets you set resource limits, including on how much memory one
including how much memory one
Quoted 5 lines
Documentation/sysctl/kernel.txt +5
-0+process can consume, via setrlimit(2). Unfortunately, shared memory +segments are allowed to exist without association with any process, and +thus might not be counted against any resource limits. If enabled, +shared memory segments are automatically destroyed when their attach +count becomes zero after a detach or a process termination. It will
Documentation/sysctl/kernel.txt kernel. This value defaults to SHMMAX. · line 496
Quoted 10 lines
Documentation/sysctl/kernel.txt +10
-0+also destroy segments that were created, but never attached to, on exit +from the process. The only use left for IPC_RMID is to immediately +destroy an unattached segment. Of course, this breaks the way things are +defined, so some applications might stop working. Note that this +feature will do you no good unless you also configure your resource +limits (in particular, RLIMIT_AS and RLIMIT_NPROC). Most systems don't +need this. + +Note that if you change this from 0 to 1, already created segments +without users and with a dead originative process will be destroyed.
originating (?)
Documentation/sysctl/kernel.txt kernel. This value defaults to SHMMAX. · line 502
Quoted 6 lines
Documentation/sysctl/kernel.txt +3
-0+ +============================================================== + softlockup_thresh: This value can be used to lower the softlockup tolerance threshold. The
---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
Quoted 9 lines · On Wed, 22 Jun 2011 19:25:14 +0400 Vasiliy Kulikov <[email protected]> wrote:
This patch adds support for
shm_rmid_forcedsysctl. If set to 1, all shared memory objects in current ipc namespace will be automatically forced to useIPC_RMID. POSIX way of handling shmem allows to create shm objects and callshmdt()leaving shm object associated with no process, thus consuming memory not counted via rlimits. With shm_rmid_forced=1 the shared memory object is counted at least for one process, so OOM killer may effectively kill the fat process holding the shared memory.
Quoted 7 lines
It obviously breaks POSIX, some programs relying on the feature would stop working. So, set shm_rmid_forced=1 only if you're sure nobody uses "orphaned" memory. shm_rmid_forced=0 by default for compatability reasons.
The feature was previously impemented in -ow as a configure option.
What a horrid patch. But given the POSIX (mis?)feature I don't see a better way, and the feature seems desirable. Sigh.
What sort of users would want to turn this on, and why?
include/linux/ipc_namespace.h struct ipc_namespace { · line 49
Quoted 9 lines
include/linux/ipc_namespace.h +1
-0@@ -44,6 +44,7 @@ struct ipc_namespace {size_t shm_ctlall;int shm_ctlmni;int shm_tot; +int shm_rmid_forced;struct notifier_block ipcns_nb;
Please send a patch which adds a nice comment to this field.
Perhaps shm_rmid_forced should have had bool type.
ipc/shm.c void shm_init_ns(struct ipc_namespace *ns) · line 80
Quoted 10 lines
ipc/shm.c +1
-0@@ -74,6 +74,7 @@ void shm_init_ns(struct ipc_namespace *ns) ns->shm_ctlmax =SHMMAX ; ns->shm_ctlall =SHMALL ; ns->shm_ctlmni =SHMMNI ; + ns->shm_rmid_forced =0 ; ns->shm_tot =0 ;ipc_init_ids (&shm_ids (ns)); }
The problem is that nobody will test your feature. So for testing purposes, let's enable the feature by default. I assume this:
ipc/shm.c renamed from ipc/shm.c~ipc-introduce-shm_rmid_forced-sysctl-ipc-introduce-shm_rmid_forced-sysctl-testing +1 -1
@@ -74,7 +74,7 @@ void shm_init_ns(struct ipc_namespace *n ns->shm_ctlmax =SHMMAX ; ns->shm_ctlall =SHMALL ; ns->shm_ctlmni =SHMMNI ; - ns->shm_rmid_forced =0 ; + ns->shm_rmid_forced =1 ; ns->shm_tot =0 ;ipc_init_ids (&shm_ids (ns)); }
will do that?
ipc/shm.c
Quoted 6 lines
ipc/shm.c +6
-0+static bool shm_may_destroy (struct ipc_namespace *ns,struct shmid_kernel *shp) +{ +return (shp->shm_nattch ==0 ) && + (ns->shm_rmid_forced || + (shp->shm_perm.mode &SHM_DEST )); +}
Just because the existing code is crappily documented doesn't mean that we have to copy that ;)
Quoted 4 lines · Andrew Morton
What a horrid patch. But given the POSIX (mis?)feature I don't see a better way, and the feature seems desirable. Sigh.
What sort of users would want to turn this on, and why?
A shared environment, e.g. a shared web hosting. With multiple ipc namespaces (on a VPS) each namespace can steal a few megabytes of memory without any per user accounting. Even if all user's processes are killed, the orphaned shm is still kept in RAM. It doesn't lead to OOM, but it prevents from creating new segments and just annoys.
Quoted 11 lines
include/linux/ipc_namespace.h struct ipc_namespace { · line 49
Quoted 9 lines
include/linux/ipc_namespace.h +1
-0@@ -44,6 +44,7 @@ struct ipc_namespace {size_t shm_ctlall;int shm_ctlmni;int shm_tot; +int shm_rmid_forced;struct notifier_block ipcns_nb;Please send a patch which adds a nice comment to this field.
OK.
Quoted 1 line
Perhaps
shm_rmid_forcedshould have had bool type.
OK. The sysctl handler should parse it OK if feed it with sizeof(bool).
Quoted 26 lines
ipc/shm.c void shm_init_ns(struct ipc_namespace *ns) · line 80
Quoted 10 lines
ipc/shm.c +1
-0@@ -74,6 +74,7 @@ void shm_init_ns(struct ipc_namespace *ns) ns->shm_ctlmax =SHMMAX ; ns->shm_ctlall =SHMALL ; ns->shm_ctlmni =SHMMNI ; + ns->shm_rmid_forced =0 ; ns->shm_tot =0 ;ipc_init_ids (&shm_ids (ns)); }The problem is that nobody will test your feature. So for testing purposes, let's enable the feature by default. I assume this:
ipc/shm.c renamed from ipc/shm.c~ipc-introduce-shm_rmid_forced-sysctl-ipc-introduce-shm_rmid_forced-sysctl-testing +1
-1@@ -74,7 +74,7 @@ void shm_init_ns(struct ipc_namespace *n ns->shm_ctlmax =SHMMAX ; ns->shm_ctlall =SHMALL ; ns->shm_ctlmni =SHMMNI ; - ns->shm_rmid_forced =0 ; + ns->shm_rmid_forced =1 ; ns->shm_tot =0 ;ipc_init_ids (&shm_ids (ns)); }
Quoted 1 line
will do that?
Sure if it helps testing :)
Quoted 9 lines
ipc/shm.c
Quoted 6 lines
ipc/shm.c +6
-0+static bool shm_may_destroy (struct ipc_namespace *ns,struct shmid_kernel *shp) +{ +return (shp->shm_nattch ==0 ) && + (ns->shm_rmid_forced || + (shp->shm_perm.mode &SHM_DEST )); +}Just because the existing code is crappily documented doesn't mean that we have to copy that ;)
OK ;)
Thank you!
Signature · 2 lines
Vasiliy Kulikov http://www.openwall.com - bringing security into open computing environments
Quoted 3 lines · Vasiliy Kulikov
Quoted 1 line
Perhaps
shm_rmid_forcedshould have had bool type.OK. The sysctl handler should parse it OK if feed it with sizeof(bool).
I was wrong, maxlen must not be less than sizeof(int), it makes sense for arrays only. So, it is kept being int.
Signature · 2 lines
Vasiliy Kulikov http://www.openwall.com - bringing security into open computing environments
Quoted 5 lines · Andrew Morton
Quoted 5 lines
ipc/shm.c +0
-0@@ -74,6 +74,7 @@ void shm_init_ns(struct ipc_namespace *ns) ns->shm_ctlmax =SHMMAX ; ns->shm_ctlall =SHMALL ;
Quoted 8 lines
ipc/shm.c void shm_init_ns(struct ipc_namespace *n · line 80
Quoted 5 lines
ipc/shm.c +1
-0ns->shm_ctlmni =SHMMNI ; + ns->shm_rmid_forced =0 ; ns->shm_tot =0 ;ipc_init_ids (&shm_ids (ns)); }The problem is that nobody will test your feature. So for testing purposes, let's enable the feature by default. I assume this:
I'd also strongly argue to keep this as a default. OOM-kills are not part of POSIX and violate POSIX in a number of ways already.
Furthermore, if testing shows that this is not actually breaking anything in a serious way we could also in theory simplify the patch and just make this the default behavior with no runtime ability to switch it off.
Thanks,
Ingo
Quoted 4 lines · Ingo Molnar
Furthermore, if testing shows that this is not actually breaking anything in a serious way we could also in theory simplify the patch and just make this the default behavior with no runtime ability to switch it off.
I'm afraid it's impossible. From -ow readme:
"Of course, this breaks the way things are defined, so some applications might stop working. In particular, expect most commercial databases to break. Apache and PostgreSQL are known to work, though. :-)"
http://www.openwall.com/linux/README.shtml
But as it was written in days of Linux 2.4.x, the situation could have changed. A desktop system seems to work.
Thanks,
Signature · 2 lines
Vasiliy Kulikov http://www.openwall.com - bringing security into open computing environments
Quoted 13 lines · Vasiliy Kulikov
Quoted 4 lines · Ingo Molnar
Furthermore, if testing shows that this is not actually breaking anything in a serious way we could also in theory simplify the patch and just make this the default behavior with no runtime ability to switch it off.
I'm afraid it's impossible. From -ow readme:
"Of course, this breaks the way things are defined, so some applications might stop working. In particular, expect most commercial databases to break. Apache and PostgreSQL are known to work, though. :-)"
Quoted 4 lines
http://www.openwall.com/linux/README.shtml
But as it was written in days of Linux 2.4.x, the situation could have changed. A desktop system seems to work.
As we really prefer working systems over non-working ones (and lots of unattached shm segments can clearly result in a non-working system) we can only accept the "this will break stuff" argument if it's *demonstrated* to break stuff and if the failure scenario is carefully described in the commit.
It would take a serious breakage to override a "system locks up swapping itself to death" failure scenario.
Thanks,
Ingo
Quoted 8 lines
As we really prefer working systems over non-working ones (and lots of unattached shm segments can clearly result in a non-working system) we can only accept the "this will break stuff" argument if it's *demonstrated* to break stuff and if the failure scenario is carefully described in the commit.
It would take a serious breakage to override a "system locks up swapping itself to death" failure scenario.
Ths shared memory interface is defined to be persistent for good reason and all sorts of apps rely upon that so no you can't just ignore that. As a configurable alternative it makes sense (indeed many SYS5 admins used to run shared memory segment sweepers to clean up long idle ones)
However if it's locking the machine up and not being properly handled by resource management then
a) your resource management is broken so fix that instead
b) if your resource management is busted or you are not properly tracking resource commits then the user is going to be able to achieve the same result by other means (eg a unix domain socket bomb)
If you've got no overcommit set you shouldn't be able to swap to death, it may be the sysv shared memory objects need to be accounted for specifically somewhere but that would be the right thing to fix and the mechanisms to do it exist.
Quoted 23 lines · Alan Cox
Quoted 8 lines
As we really prefer working systems over non-working ones (and lots of unattached shm segments can clearly result in a non-working system) we can only accept the "this will break stuff" argument if it's *demonstrated* to break stuff and if the failure scenario is carefully described in the commit.
It would take a serious breakage to override a "system locks up swapping itself to death" failure scenario.
Ths shared memory interface is defined to be persistent for good reason and all sorts of apps rely upon that so no you can't just ignore that. As a configurable alternative it makes sense (indeed many SYS5 admins used to run shared memory segment sweepers to clean up long idle ones)
However if it's locking the machine up and not being properly handled by resource management then
a) your resource management is broken so fix that instead
b) if your resource management is busted or you are not properly tracking resource commits then the user is going to be able to achieve the same result by other means (eg a unix domain socket bomb)
Quoted 4 lines
If you've got no overcommit set you shouldn't be able to swap to death, it may be the sysv shared memory objects need to be accounted for specifically somewhere but that would be the right thing to fix and the mechanisms to do it exist.
But the majority of systems have overcommit enabled - that is our default.
This is a simple extension of the OOM killer being able to ... kill things on OOM, ok? 'to kill' implies 'to break'.
Thanks,
Ingo
Quoted 2 lines
This is a simple extension of the OOM killer being able to ... kill things on OOM, ok? 'to kill' implies 'to break'.
If you do it on the OOM killer then yes that aspect makes sense. The real problem is that Linux has shipped a broken default for the past ten years.
The number of times I have to explain to industrial and business customers that Linux doesn't suck but the defaults are stupid is astounding, and they then wonder why either the authors or their vendor is a complete and utter moron.
But yes from an OOM perspective killing an unattached SHM segment makes as much sense as killing anything else.
Alan
Quoted 10 lines · Vasiliy Kulikov
From -ow readme:
"Of course, this breaks the way things are defined, so some applications might stop working. In particular, expect most commercial databases to break. Apache and PostgreSQL are known to work, though. :-)"
http://www.openwall.com/linux/README.shtml
But as it was written in days of Linux 2.4.x, the situation could have changed. A desktop system seems to work.
I wrote the above in 2.0.x days (circa 1998) and it was based on FUD rather than on any real evidence of any breakage. Apache and PostgreSQL were a couple of known users of shared memory segments, and these did not break. I was not aware of any programs that presumably did break. Of course, those probably do exist, but I don't recall anyone ever reporting any to me (as maintainer of -ow patches), although the warning quoted above might have played a role in such non-reporting.
Alexander
Quoted 4 lines · Andrew Morton
What a horrid patch. But given the POSIX (mis?)feature I don't see a better way, and the feature seems desirable. Sigh.
What sort of users would want to turn this on, and why?
Originally, I introduced it into Linux 2.0.x-ow to allow for resource limits to be enforced on shared servers, such as with shared web hosting. A user is supposed to be limited by RLIMIT_AS * RLIMIT_NPROC. (This is awfully inflexible, lacking a separate per-user memory limit, but at least it's something.) However, with shared memory segments a user could bypass that limit, because those segments don't have to be tied to a process. So the patch changed that, requiring that any shm segment be tied to a process, or be destroyed.
Alexander
ipc/shm.c static void shm_close(struct vm_area_struct *vma) · line 288
Quoted 10 lines · Vasiliy Kulikov
ipc/shm.c +9
-0+void exit_shm (struct task_struct *task) +{ +struct nsproxy *nsp = task->nsproxy; +struct ipc_namespace *ns; + +if (!nsp) +return ; + ns = nsp->ipc_ns; +if (!ns || !ns->shm_rmid_forced)
This looks confusing, imho. How it is possible that ->nsproxy or ->ipc_ns is NULL?
ipc/shm.c static void shm_close(struct vm_area_struct *vma) · line 294
Quoted 6 lines
ipc/shm.c +5
-0+return ; + +/* Destroy all already created segments, but not mapped yet */ +down_write (&shm_ids (ns).rw_mutex); +idr_for_each (&shm_ids (ns).ipcs_idr, &shm_try_destroy_current, ns);up_write (&shm_ids (ns).rw_mutex);
Again, I do not pretend I understand ipc/, but it seems we can check ns->ipc_ids[].in_use != 0 before the slow path, no?
Oleg.
Quoted 14 lines · Oleg Nesterov
ipc/shm.c static void shm_close(struct vm_area_struct *vma) · line 288
Quoted 10 lines · Vasiliy Kulikov
ipc/shm.c +9
-0+void exit_shm (struct task_struct *task) +{ +struct nsproxy *nsp = task->nsproxy; +struct ipc_namespace *ns; + +if (!nsp) +return ; + ns = nsp->ipc_ns; +if (!ns || !ns->shm_rmid_forced)This looks confusing, imho. How it is possible that ->nsproxy or ->ipc_ns is NULL?
I spotted the same checking logic in other places. I don't know whether it is redundant, I guess it can happen when the namespace is dying. Probably it cannot happed inside of task do_exit(), only for extern observers.
Quoted 9 lines
ipc/shm.c static void shm_close(struct vm_area_struct *vma) · line 294
Quoted 6 lines
ipc/shm.c +5
-0+return ; + +/* Destroy all already created segments, but not mapped yet */ +down_write (&shm_ids (ns).rw_mutex); +idr_for_each (&shm_ids (ns).ipcs_idr, &shm_try_destroy_current, ns);up_write (&shm_ids (ns).rw_mutex);Again, I do not pretend I understand
ipc/, but it seems we can check ns->ipc_ids[].in_use != 0 before the slow path, no?
Looks like you're right. Given it is do_exit(), the boost is significant.
I'll send the patch for this thing and the locking part.
Thank you!
Signature · 2 lines
Vasiliy Kulikov http://www.openwall.com - bringing security into open computing environments
Quoted 17 lines · Vasiliy Kulikov
Quoted 14 lines · Oleg Nesterov
ipc/shm.c static void shm_close(struct vm_area_struct *vma) · line 288
Quoted 10 lines · Vasiliy Kulikov
ipc/shm.c +9
-0+void exit_shm (struct task_struct *task) +{ +struct nsproxy *nsp = task->nsproxy; +struct ipc_namespace *ns; + +if (!nsp) +return ; + ns = nsp->ipc_ns; +if (!ns || !ns->shm_rmid_forced)This looks confusing, imho. How it is possible that ->nsproxy or ->ipc_ns is NULL?
Quoted 4 lines
I spotted the same checking logic in other places. I don't know whether it is redundant, I guess it can happen when the namespace is dying. Probably it cannot happed inside of task
do_exit(), only for extern observers.
No, afaics it can't happen in do_exit() until we call exit_notify(). Otherwise, for example, any dying child will OOPS in do_notify_parent(). Or please look at exit_sem()->sem_lock_check(tsk->nsproxy->ipc_ns).
Oleg.
Quoted 18 lines · Oleg Nesterov
Quoted 17 lines · Vasiliy Kulikov
Quoted 14 lines · Oleg Nesterov
ipc/shm.c static void shm_close(struct vm_area_struct *vma) · line 288
Quoted 10 lines · Vasiliy Kulikov
ipc/shm.c +9
-0+void exit_shm (struct task_struct *task) +{ +struct nsproxy *nsp = task->nsproxy; +struct ipc_namespace *ns; + +if (!nsp) +return ; + ns = nsp->ipc_ns; +if (!ns || !ns->shm_rmid_forced)This looks confusing, imho. How it is possible that ->nsproxy or ->ipc_ns is NULL?
Quoted 8 lines
Quoted 4 lines
I spotted the same checking logic in other places. I don't know whether it is redundant, I guess it can happen when the namespace is dying. Probably it cannot happed inside of task
do_exit(), only for extern observers.No, afaics it can't happen in
do_exit()until we callexit_notify(). Otherwise, for example, any dying child will OOPS indo_notify_parent(). Or please look at exit_sem()->sem_lock_check(tsk->nsproxy->ipc_ns).
Looks you're still right :)
Signature · 2 lines
Vasiliy Kulikov http://www.openwall.com - bringing security into open computing environments