From: Andrew Morton <akpm@linux-foundation.org>
To: Neil Horman <nhorman@tuxdriver.com>
Cc: jmoskovc@redhat.com, neilb@suse.de, benh@kernel.crashing.org,
gregkh@suse.de, takedakn@nttdata.co.jp,
linux-kernel@vger.kernel.org, spock@gentoo.org, mingo@redhat.com,
viro@zeniv.linux.org.uk, mfasheh@suse.com, menage@google.com,
drbd-dev@lists.linbit.com, shemminger@linux-foundation.org,
abelay@mit.edu, t.sailer@alumni.ethz.ch
Subject: Re: [Drbd-dev] [PATCH] exec: allow core_pipe recursion check to look for a value of 1 rather than 0
Date: Tue, 26 Jan 2010 15:53:59 -0800 [thread overview]
Message-ID: <20100126155359.c5ad7cd3.akpm@linux-foundation.org> (raw)
In-Reply-To: <20100121200806.GA29801@shamino.rdu.redhat.com>
On Thu, 21 Jan 2010 15:08:06 -0500
Neil Horman <nhorman@tuxdriver.com> wrote:
> Hey all-
> So, about 6 months ago, I made a set of changes to how the
> core-dump-to-a-pipe feature in the kernel works. We had reports of several
> races, including some reports of apps bypassing our recursion check so that a
> process that was forked as part of a core_pattern setup could infinitely crash
> and refork until the system crashed.
>
> We fixes those by improving our recursion checks. The new check
> basically refuses to fork a process if its core limit is zero, which works well.
>
> Unfortunately, I've been getting grief from maintainer of user space
> programs that are inserted as the forked process of core_pattern. They contend
> that in order for their programs (such as abrt and apport) to work, all the
> running processes in a system must have their core limits set to a non-zero
> value, to which I say 'yes'. I did this by design, and think thats the right
> way to do things.
>
> But I've been asked to ease this burden on user space enough times that
> I thought I would take a look at it. The first suggestion was to make the
> recursion check fail on a non-zero 'special' number, like one. That way the
> core collector process could set its core size ulimit to 1, and enable the
> kernel's recursion detection. This isn't a bad idea on the surface, but I don't
> like it since its opt-in, in that if a program like abrt or apport has a bug and
> fails to set such a core limit, we're left with a recursively crashing system
> again.
>
> So I've come up with this. What I've done is modify the
> call_usermodehelper api such that an extra parameter is added, a function
> pointer which will be called by the user helper task, after it forks, but before
> it exec's the required process. This will give the caller the opportunity to
> get a call back in the processes context, allowing it to do whatever it needs to
> to the process in the kernel prior to exec-ing the user space code. In the case
> of do_coredump, this callback is ues to set the core ulimit of the helper
> process to 1. This elimnates the opt-in problem that I had above, as it allows
> the ulimit for core sizes to be set to the value of 1, which is what the
> recursion check looks for in do_coredump.
>
> This patch has been tested successfully by some of the Abrt maintainers
> in fedora, with good results. Patch applies to the latest -mm tree as of this
> AM.
>
hrm. Fair enough, I guess..
> +/*
> + * This is used as a helper to set up the task that execs
> + * our user space core collector application
> + * Its called in the context of the task thats going to
> + * exec itself to be the helper, so we can modify current here
> + */
It's worth spending another 15 seconds on the comments. That way, they
end up looking like they're written in English.
> +void core_pipe_setup(void)
> +{
> + task_lock(current->group_leader);
> + current->signal->rlim[RLIMIT_CORE].rlim_cur = 1;
> + task_unlock(current->group_leader);
> +}
I'll make this static.
> --- a/fs/nfs/cache_lib.c
> +++ b/fs/nfs/cache_lib.c
> @@ -46,7 +46,7 @@ int nfs_cache_upcall(struct cache_detail *cd, char *entry_name)
>
> if (nfs_cache_getent_prog[0] == '\0')
> goto out;
> - ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
> + ret = call_usermodehelper(argv[0], argv, envp, NULL, UMH_WAIT_EXEC);
> /*
> * Disable the upcall mechanism if we're getting an ENOENT or
> * EACCES error. The admin can re-enable it on the fly by using
> diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c
> index f3df0ba..dddf780 100644
> --- a/fs/ocfs2/stackglue.c
> +++ b/fs/ocfs2/stackglue.c
> @@ -407,7 +407,7 @@ static void ocfs2_leave_group(const char *group)
> envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
> envp[2] = NULL;
>
> - ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
> + ret = call_usermodehelper(argv[0], argv, envp, NULL, UMH_WAIT_PROC);
> if (ret < 0) {
> printk(KERN_ERR
> "ocfs2: Error %d running user helper "
> diff --git a/include/linux/kmod.h b/include/linux/kmod.h
> index 384ca8b..ca5e531 100644
> --- a/include/linux/kmod.h
> +++ b/include/linux/kmod.h
> @@ -48,7 +48,9 @@ struct subprocess_info;
>
> /* Allocate a subprocess_info structure */
> struct subprocess_info *call_usermodehelper_setup(char *path, char **argv,
> - char **envp, gfp_t gfp_mask);
> + char **envp,
> + void (*finit)(void),
> + gfp_t gfp_mask);
What does "finit" mean? Doesn't seem very intuitive.
> /* Set various pieces of state into the subprocess_info structure */
> void call_usermodehelper_setkeys(struct subprocess_info *info,
> @@ -72,12 +74,13 @@ int call_usermodehelper_exec(struct subprocess_info *info, enum umh_wait wait);
> void call_usermodehelper_freeinfo(struct subprocess_info *info);
>
> static inline int
> -call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait)
> +call_usermodehelper(char *path, char **argv, char **envp,
> + void (*finit)(void), enum umh_wait wait)
> {
> struct subprocess_info *info;
> gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
>
> - info = call_usermodehelper_setup(path, argv, envp, gfp_mask);
> + info = call_usermodehelper_setup(path, argv, envp, finit, gfp_mask);
> if (info == NULL)
> return -ENOMEM;
> return call_usermodehelper_exec(info, wait);
The semantics of the `finit' callback should be documented here. It's
a kernel-wide interface and others might want to use it.
You're not a big fan of checkpatch, it seems.
WARNING: multiple messages have this Message-ID (diff)
From: Andrew Morton <akpm@linux-foundation.org>
To: Neil Horman <nhorman@tuxdriver.com>
Cc: linux-kernel@vger.kernel.org, jmoskovc@redhat.com,
mingo@redhat.com, drbd-dev@lists.linbit.com,
benh@kernel.crashing.org, t.sailer@alumni.ethz.ch,
abelay@mit.edu, gregkh@suse.de, spock@gentoo.org,
viro@zeniv.linux.org.uk, neilb@suse.de, mfasheh@suse.com,
menage@google.com, shemminger@linux-foundation.org,
takedakn@nttdata.co.jp
Subject: Re: [PATCH] exec: allow core_pipe recursion check to look for a value of 1 rather than 0
Date: Tue, 26 Jan 2010 15:53:59 -0800 [thread overview]
Message-ID: <20100126155359.c5ad7cd3.akpm@linux-foundation.org> (raw)
In-Reply-To: <20100121200806.GA29801@shamino.rdu.redhat.com>
On Thu, 21 Jan 2010 15:08:06 -0500
Neil Horman <nhorman@tuxdriver.com> wrote:
> Hey all-
> So, about 6 months ago, I made a set of changes to how the
> core-dump-to-a-pipe feature in the kernel works. We had reports of several
> races, including some reports of apps bypassing our recursion check so that a
> process that was forked as part of a core_pattern setup could infinitely crash
> and refork until the system crashed.
>
> We fixes those by improving our recursion checks. The new check
> basically refuses to fork a process if its core limit is zero, which works well.
>
> Unfortunately, I've been getting grief from maintainer of user space
> programs that are inserted as the forked process of core_pattern. They contend
> that in order for their programs (such as abrt and apport) to work, all the
> running processes in a system must have their core limits set to a non-zero
> value, to which I say 'yes'. I did this by design, and think thats the right
> way to do things.
>
> But I've been asked to ease this burden on user space enough times that
> I thought I would take a look at it. The first suggestion was to make the
> recursion check fail on a non-zero 'special' number, like one. That way the
> core collector process could set its core size ulimit to 1, and enable the
> kernel's recursion detection. This isn't a bad idea on the surface, but I don't
> like it since its opt-in, in that if a program like abrt or apport has a bug and
> fails to set such a core limit, we're left with a recursively crashing system
> again.
>
> So I've come up with this. What I've done is modify the
> call_usermodehelper api such that an extra parameter is added, a function
> pointer which will be called by the user helper task, after it forks, but before
> it exec's the required process. This will give the caller the opportunity to
> get a call back in the processes context, allowing it to do whatever it needs to
> to the process in the kernel prior to exec-ing the user space code. In the case
> of do_coredump, this callback is ues to set the core ulimit of the helper
> process to 1. This elimnates the opt-in problem that I had above, as it allows
> the ulimit for core sizes to be set to the value of 1, which is what the
> recursion check looks for in do_coredump.
>
> This patch has been tested successfully by some of the Abrt maintainers
> in fedora, with good results. Patch applies to the latest -mm tree as of this
> AM.
>
hrm. Fair enough, I guess..
> +/*
> + * This is used as a helper to set up the task that execs
> + * our user space core collector application
> + * Its called in the context of the task thats going to
> + * exec itself to be the helper, so we can modify current here
> + */
It's worth spending another 15 seconds on the comments. That way, they
end up looking like they're written in English.
> +void core_pipe_setup(void)
> +{
> + task_lock(current->group_leader);
> + current->signal->rlim[RLIMIT_CORE].rlim_cur = 1;
> + task_unlock(current->group_leader);
> +}
I'll make this static.
> --- a/fs/nfs/cache_lib.c
> +++ b/fs/nfs/cache_lib.c
> @@ -46,7 +46,7 @@ int nfs_cache_upcall(struct cache_detail *cd, char *entry_name)
>
> if (nfs_cache_getent_prog[0] == '\0')
> goto out;
> - ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
> + ret = call_usermodehelper(argv[0], argv, envp, NULL, UMH_WAIT_EXEC);
> /*
> * Disable the upcall mechanism if we're getting an ENOENT or
> * EACCES error. The admin can re-enable it on the fly by using
> diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c
> index f3df0ba..dddf780 100644
> --- a/fs/ocfs2/stackglue.c
> +++ b/fs/ocfs2/stackglue.c
> @@ -407,7 +407,7 @@ static void ocfs2_leave_group(const char *group)
> envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
> envp[2] = NULL;
>
> - ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
> + ret = call_usermodehelper(argv[0], argv, envp, NULL, UMH_WAIT_PROC);
> if (ret < 0) {
> printk(KERN_ERR
> "ocfs2: Error %d running user helper "
> diff --git a/include/linux/kmod.h b/include/linux/kmod.h
> index 384ca8b..ca5e531 100644
> --- a/include/linux/kmod.h
> +++ b/include/linux/kmod.h
> @@ -48,7 +48,9 @@ struct subprocess_info;
>
> /* Allocate a subprocess_info structure */
> struct subprocess_info *call_usermodehelper_setup(char *path, char **argv,
> - char **envp, gfp_t gfp_mask);
> + char **envp,
> + void (*finit)(void),
> + gfp_t gfp_mask);
What does "finit" mean? Doesn't seem very intuitive.
> /* Set various pieces of state into the subprocess_info structure */
> void call_usermodehelper_setkeys(struct subprocess_info *info,
> @@ -72,12 +74,13 @@ int call_usermodehelper_exec(struct subprocess_info *info, enum umh_wait wait);
> void call_usermodehelper_freeinfo(struct subprocess_info *info);
>
> static inline int
> -call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait)
> +call_usermodehelper(char *path, char **argv, char **envp,
> + void (*finit)(void), enum umh_wait wait)
> {
> struct subprocess_info *info;
> gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
>
> - info = call_usermodehelper_setup(path, argv, envp, gfp_mask);
> + info = call_usermodehelper_setup(path, argv, envp, finit, gfp_mask);
> if (info == NULL)
> return -ENOMEM;
> return call_usermodehelper_exec(info, wait);
The semantics of the `finit' callback should be documented here. It's
a kernel-wide interface and others might want to use it.
You're not a big fan of checkpatch, it seems.
next prev parent reply other threads:[~2010-01-26 23:57 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-01-21 20:08 [Drbd-dev] [PATCH] exec: allow core_pipe recursion check to look for a value of 1 rather than 0 Neil Horman
2010-01-21 20:08 ` Neil Horman
2010-01-21 21:29 ` Thomas Sailer
2010-01-25 21:13 ` Neil Horman
2010-01-26 23:53 ` Andrew Morton [this message]
2010-01-26 23:53 ` Andrew Morton
2010-01-29 15:10 ` [Drbd-dev] [PATCH 0/2] exec: allow core_pipe recursion check to look for a value of 1 rather than 0 (v2) Neil Horman
2010-01-29 15:10 ` Neil Horman
2010-01-29 15:13 ` [Drbd-dev] [PATCH 1/2] " Neil Horman
2010-01-29 15:13 ` Neil Horman
2010-01-31 14:46 ` [Drbd-dev] " Oleg Nesterov
2010-01-31 14:46 ` Oleg Nesterov
2010-01-31 15:41 ` [Drbd-dev] " Neil Horman
2010-01-31 15:41 ` Neil Horman
2010-01-29 15:14 ` [Drbd-dev] [PATCH 2/2] " Neil Horman
2010-01-29 15:14 ` Neil Horman
2010-01-31 15:50 ` [Drbd-dev] " Oleg Nesterov
2010-01-31 15:50 ` Oleg Nesterov
2010-01-31 17:41 ` [Drbd-dev] " Neil Horman
2010-01-31 17:41 ` Neil Horman
2010-02-01 10:29 ` [Drbd-dev] " Oleg Nesterov
2010-02-01 10:29 ` Oleg Nesterov
2010-02-01 10:39 ` [Drbd-dev] " Oleg Nesterov
2010-02-01 10:39 ` Oleg Nesterov
2010-02-01 13:16 ` [Drbd-dev] " Neil Horman
2010-02-01 13:16 ` Neil Horman
2010-02-01 14:18 ` [Drbd-dev] " Oleg Nesterov
2010-02-01 14:18 ` Oleg Nesterov
2010-02-02 19:19 ` [Drbd-dev] [PATCH 0/2] exec: refactor how call_usermodehelper works, and update the sense of the core_pipe recursion check (v3) Neil Horman
2010-02-02 19:19 ` Neil Horman
2010-02-02 19:20 ` [Drbd-dev] [PATCH 1/2] " Neil Horman
2010-02-02 19:20 ` Neil Horman
2010-02-03 20:09 ` [Drbd-dev] " Oleg Nesterov
2010-02-03 20:09 ` Oleg Nesterov
2010-02-02 19:21 ` [Drbd-dev] [PATCH 2/2] " Neil Horman
2010-02-02 19:21 ` Neil Horman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100126155359.c5ad7cd3.akpm@linux-foundation.org \
--to=akpm@linux-foundation.org \
--cc=abelay@mit.edu \
--cc=benh@kernel.crashing.org \
--cc=drbd-dev@lists.linbit.com \
--cc=gregkh@suse.de \
--cc=jmoskovc@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=menage@google.com \
--cc=mfasheh@suse.com \
--cc=mingo@redhat.com \
--cc=neilb@suse.de \
--cc=nhorman@tuxdriver.com \
--cc=shemminger@linux-foundation.org \
--cc=spock@gentoo.org \
--cc=t.sailer@alumni.ethz.ch \
--cc=takedakn@nttdata.co.jp \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.