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