* [PATCH] pidns: remove recursion from free_pid_ns() v5
@ 2012-10-10 20:42 Cyrill Gorcunov
2012-10-10 20:54 ` Andrew Morton
0 siblings, 1 reply; 4+ messages in thread
From: Cyrill Gorcunov @ 2012-10-10 20:42 UTC (permalink / raw)
To: LKML
Cc: Pavel Emelyanov, Andrew Vagin, Andrew Morton, Eric W. Biederman,
Oleg Nesterov, Greg KH
The free_pid_ns function done in recursion 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 iterative loop.
v5 (from oleg@):
- Drop @ret variable
- Make put_pid_ns non-inline since it grows in size,
in turn make free_pid_ns static
Based-on-patch-by: Andrew Vagin <avagin@openvz.org>
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Cc: Andrew Morton <akpm@linux-foundation.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>
---
include/linux/pid_namespace.h | 8 +-------
kernel/pid_namespace.c | 19 +++++++++++++------
2 files changed, 14 insertions(+), 13 deletions(-)
Index: linux-2.6.git/include/linux/pid_namespace.h
===================================================================
--- linux-2.6.git.orig/include/linux/pid_namespace.h
+++ linux-2.6.git/include/linux/pid_namespace.h
@@ -47,15 +47,9 @@ static inline struct pid_namespace *get_
}
extern struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *ns);
-extern void free_pid_ns(struct kref *kref);
extern void zap_pid_ns_processes(struct pid_namespace *pid_ns);
extern int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd);
-
-static inline void put_pid_ns(struct pid_namespace *ns)
-{
- if (ns != &init_pid_ns)
- kref_put(&ns->kref, free_pid_ns);
-}
+extern void put_pid_ns(struct pid_namespace *ns);
#else /* !CONFIG_PID_NS */
#include <linux/err.h>
Index: linux-2.6.git/kernel/pid_namespace.c
===================================================================
--- linux-2.6.git.orig/kernel/pid_namespace.c
+++ linux-2.6.git/kernel/pid_namespace.c
@@ -132,17 +132,24 @@ struct pid_namespace *copy_pid_ns(unsign
return create_pid_namespace(old_ns);
}
-void free_pid_ns(struct kref *kref)
+static void free_pid_ns(struct kref *kref)
{
- struct pid_namespace *ns, *parent;
+ struct pid_namespace *ns;
ns = container_of(kref, struct pid_namespace, kref);
-
- parent = ns->parent;
destroy_pid_namespace(ns);
+}
+
+void put_pid_ns(struct pid_namespace *ns)
+{
+ struct pid_namespace *parent;
- if (parent != NULL)
- put_pid_ns(parent);
+ while (ns != &init_pid_ns) {
+ parent = ns->parent;
+ if (!kref_put(&ns->kref, free_pid_ns))
+ break;
+ ns = parent;
+ }
}
void zap_pid_ns_processes(struct pid_namespace *pid_ns)
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] pidns: remove recursion from free_pid_ns() v5
2012-10-10 20:42 [PATCH] pidns: remove recursion from free_pid_ns() v5 Cyrill Gorcunov
@ 2012-10-10 20:54 ` Andrew Morton
2012-10-10 20:59 ` Eric W. Biederman
2012-10-10 21:14 ` Cyrill Gorcunov
0 siblings, 2 replies; 4+ messages in thread
From: Andrew Morton @ 2012-10-10 20:54 UTC (permalink / raw)
To: Cyrill Gorcunov
Cc: LKML, Pavel Emelyanov, Andrew Vagin, Eric W. Biederman,
Oleg Nesterov, Greg KH
On Thu, 11 Oct 2012 00:42:56 +0400
Cyrill Gorcunov <gorcunov@openvz.org> wrote:
> The free_pid_ns function done in recursion 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 iterative loop.
>
> v5 (from oleg@):
> - Drop @ret variable
> - Make put_pid_ns non-inline since it grows in size,
> in turn make free_pid_ns static
OK, let's try that. I'll sit on this until -rc2 to give it a bit of
time to cook.
A -stable backport might be needed. What capabilities does userspace
need to be able to trigger the kernel stack overflow?
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] pidns: remove recursion from free_pid_ns() v5
2012-10-10 20:54 ` Andrew Morton
@ 2012-10-10 20:59 ` Eric W. Biederman
2012-10-10 21:14 ` Cyrill Gorcunov
1 sibling, 0 replies; 4+ messages in thread
From: Eric W. Biederman @ 2012-10-10 20:59 UTC (permalink / raw)
To: Andrew Morton
Cc: Cyrill Gorcunov, LKML, Pavel Emelyanov, Andrew Vagin,
Oleg Nesterov, Greg KH
Andrew Morton <akpm@linux-foundation.org> writes:
> On Thu, 11 Oct 2012 00:42:56 +0400
> Cyrill Gorcunov <gorcunov@openvz.org> wrote:
>
>> The free_pid_ns function done in recursion 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 iterative loop.
>>
>> v5 (from oleg@):
>> - Drop @ret variable
>> - Make put_pid_ns non-inline since it grows in size,
>> in turn make free_pid_ns static
>
> OK, let's try that. I'll sit on this until -rc2 to give it a bit of
> time to cook.
>
> A -stable backport might be needed. What capabilities does userspace
> need to be able to trigger the kernel stack overflow?
CAP_SYS_ADMIN is required to create a new pid namespace today.
With a little luck the user namespace bits that allow unprivelged
creation of pid namespaces will be ready for 3.8.
Eric
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] pidns: remove recursion from free_pid_ns() v5
2012-10-10 20:54 ` Andrew Morton
2012-10-10 20:59 ` Eric W. Biederman
@ 2012-10-10 21:14 ` Cyrill Gorcunov
1 sibling, 0 replies; 4+ messages in thread
From: Cyrill Gorcunov @ 2012-10-10 21:14 UTC (permalink / raw)
To: Andrew Morton
Cc: LKML, Pavel Emelyanov, Andrew Vagin, Eric W. Biederman,
Oleg Nesterov, Greg KH
On Wed, Oct 10, 2012 at 01:54:08PM -0700, Andrew Morton wrote:
> On Thu, 11 Oct 2012 00:42:56 +0400
> Cyrill Gorcunov <gorcunov@openvz.org> wrote:
>
> > The free_pid_ns function done in recursion 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 iterative loop.
> >
> > v5 (from oleg@):
> > - Drop @ret variable
> > - Make put_pid_ns non-inline since it grows in size,
> > in turn make free_pid_ns static
>
> OK, let's try that. I'll sit on this until -rc2 to give it a bit of
> time to cook.
>
> A -stable backport might be needed. What capabilities does userspace
> need to be able to trigger the kernel stack overflow?
I believe it'll apply on stable even in current form. As Eric mentioned
CAP_SYS_ADMIN is required (so it's not that urgent i think).
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2012-10-10 21:14 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-10 20:42 [PATCH] pidns: remove recursion from free_pid_ns() v5 Cyrill Gorcunov
2012-10-10 20:54 ` Andrew Morton
2012-10-10 20:59 ` Eric W. Biederman
2012-10-10 21:14 ` Cyrill Gorcunov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox