diff options
| author | Cyrill Gorcunov <gorcunov@openvz.org> | 2012-10-19 16:56:53 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-19 17:07:47 -0400 |
| commit | bbc2e3ef87851bc5430b2b4cf4ca3a2f29baeda6 (patch) | |
| tree | d9cef396c8370184f23e99480725aa8fde4bea08 /include/linux | |
| parent | dc36d7e7cd422d69b15e7ec7cc1f021f581a6b6d (diff) | |
pidns: remove recursion from free_pid_ns()
free_pid_ns() operates in a recursive fashion:
free_pid_ns(parent)
put_pid_ns(parent)
kref_put(&ns->kref, free_pid_ns);
free_pid_ns
thus if there was a huge nesting of namespaces the userspace may trigger
avalanche calling of free_pid_ns leading to kernel stack exhausting and a
panic eventually.
This patch turns the recursion into an iterative loop.
Based on a patch by Andrew Vagin.
[akpm@linux-foundation.org: export put_pid_ns() to modules]
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Andrew Vagin <avagin@openvz.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Pavel Emelyanov <xemul@parallels.com>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/pid_namespace.h | 8 |
1 files changed, 1 insertions, 7 deletions
diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h index 00474b047145..65e3e87eacc5 100644 --- a/include/linux/pid_namespace.h +++ b/include/linux/pid_namespace.h | |||
| @@ -47,15 +47,9 @@ static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns) | |||
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | extern struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *ns); | 49 | extern struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *ns); |
| 50 | extern void free_pid_ns(struct kref *kref); | ||
| 51 | extern void zap_pid_ns_processes(struct pid_namespace *pid_ns); | 50 | extern void zap_pid_ns_processes(struct pid_namespace *pid_ns); |
| 52 | extern int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd); | 51 | extern int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd); |
| 53 | 52 | extern void put_pid_ns(struct pid_namespace *ns); | |
| 54 | static inline void put_pid_ns(struct pid_namespace *ns) | ||
| 55 | { | ||
| 56 | if (ns != &init_pid_ns) | ||
| 57 | kref_put(&ns->kref, free_pid_ns); | ||
| 58 | } | ||
| 59 | 53 | ||
| 60 | #else /* !CONFIG_PID_NS */ | 54 | #else /* !CONFIG_PID_NS */ |
| 61 | #include <linux/err.h> | 55 | #include <linux/err.h> |
