On Tue, Oct 09, 2012 at 11:48:34AM -0700, [email protected] wrote:
> 
> The patch titled
>      Subject: pidns: remove recursion from free_pid_ns()
> has been added to the -mm tree.  Its filename is
>      pidns-remove-recursion-from-free_pid_ns-v3.patch
> 
> Before you just go and hit "reply", please:
>    a) Consider who else should be cc'ed
>    b) Prefer to cc a suitable mailing list as well
>    c) Ideally: find the original patch on the mailing list and do a
>       reply-to-all to that, adding suitable additional cc's
> 
> *** Remember to use Documentation/SubmitChecklist when testing your code ***
> 
> The -mm tree is included into linux-next and is updated
> there every 3-4 working days
> 
> ------------------------------------------------------
> From: Andrew Vagin <[email protected]>
> Subject: pidns: remove recursion from free_pid_ns()
> 
> Here is a stack trace of recursion:
> free_pid_ns(parent)
>   put_pid_ns(parent)
>     kref_put(&ns->kref, free_pid_ns);
>       free_pid_ns
> 
> This patch turns the recursion into loops.
> 
> pidns can be nested many times, so in case of recursion a simple userspace
> program can provoke a kernel panic due to exceed of a kernel stack.
> 
> Acked-by: Cyrill Gorcunov <[email protected]>
> Reviewed-by: Oleg Nesterov <[email protected]>
> Cc: "Eric W. Biederman" <[email protected]>
> Cc: Pavel Emelyanov <[email protected]>
> Signed-off-by: Andrew Vagin <[email protected]>
> Cc: Greg KH <[email protected]>
> Cc: <[email protected]>
> Signed-off-by: Andrew Morton <[email protected]>
> ---
> 
>  include/linux/kref.h   |   12 ++++++++++++
>  kernel/pid_namespace.c |   16 ++++++++++++----
>  2 files changed, 24 insertions(+), 4 deletions(-)
> 
> diff -puN include/linux/kref.h~pidns-remove-recursion-from-free_pid_ns-v3 
> include/linux/kref.h
> --- a/include/linux/kref.h~pidns-remove-recursion-from-free_pid_ns-v3
> +++ a/include/linux/kref.h
> @@ -95,6 +95,18 @@ static inline int kref_put(struct kref *
>       return kref_sub(kref, 1, release);
>  }
>  
> +/**
> + * kref_put - decrement refcount for object.
> + * @kref: object.
> + *
> + * Decrement the refcount.
> + * Return 1 if refcount is zero.
> + */
> +static inline int __kref_put(struct kref *kref)
> +{
> +     return atomic_dec_and_test(&kref->refcount);
> +}


No, this isn't ok, what happened to the release function?  Why is this
needed?

> +
>  static inline int kref_put_mutex(struct kref *kref,
>                                void (*release)(struct kref *kref),
>                                struct mutex *lock)
> diff -puN kernel/pid_namespace.c~pidns-remove-recursion-from-free_pid_ns-v3 
> kernel/pid_namespace.c
> --- a/kernel/pid_namespace.c~pidns-remove-recursion-from-free_pid_ns-v3
> +++ a/kernel/pid_namespace.c
> @@ -139,11 +139,19 @@ void free_pid_ns(struct kref *kref)
>  
>       ns = container_of(kref, struct pid_namespace, kref);
>  
> -     parent = ns->parent;
> -     destroy_pid_namespace(ns);
> +     while (1) {
> +             parent = ns->parent;
> +             destroy_pid_namespace(ns);
>  
> -     if (parent != NULL)
> -             put_pid_ns(parent);
> +             if (parent == &init_pid_ns)
> +                     break;
> +
> +             /* kref_put cannot be used for avoiding recursion */
> +             if (__kref_put(&parent->kref) == 0)
> +                     break;

Someone is abusing something here, please don't change the kref api to
work around someone using it improperly.

So no, please don't apply this at all.

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to