summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/exec.c2
-rw-r--r--include/linux/kmod.h8
-rw-r--r--kernel/kmod.c16
-rw-r--r--security/keys/request_key.c3
4 files changed, 15 insertions, 14 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 97e0d52d72fd..6075a1e727ae 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1996,7 +1996,7 @@ static void wait_for_dump_helpers(struct file *file)
* is a special value that we use to trap recursive
* core dumps
*/
-static int umh_pipe_setup(struct subprocess_info *info)
+static int umh_pipe_setup(struct subprocess_info *info, struct cred *new)
{
struct file *rp, *wp;
struct fdtable *fdt;
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index d4a5c84c503d..0da38cf7db7b 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -45,7 +45,7 @@ static inline int request_module_nowait(const char *name, ...) { return -ENOSYS;
#endif
-struct key;
+struct cred;
struct file;
enum umh_wait {
@@ -62,7 +62,7 @@ struct subprocess_info {
char **envp;
enum umh_wait wait;
int retval;
- int (*init)(struct subprocess_info *info);
+ int (*init)(struct subprocess_info *info, struct cred *new);
void (*cleanup)(struct subprocess_info *info);
void *data;
};
@@ -73,7 +73,7 @@ struct subprocess_info *call_usermodehelper_setup(char *path, char **argv,
/* Set various pieces of state into the subprocess_info structure */
void call_usermodehelper_setfns(struct subprocess_info *info,
- int (*init)(struct subprocess_info *info),
+ int (*init)(struct subprocess_info *info, struct cred *new),
void (*cleanup)(struct subprocess_info *info),
void *data);
@@ -87,7 +87,7 @@ void call_usermodehelper_freeinfo(struct subprocess_info *info);
static inline int
call_usermodehelper_fns(char *path, char **argv, char **envp,
enum umh_wait wait,
- int (*init)(struct subprocess_info *info),
+ int (*init)(struct subprocess_info *info, struct cred *new),
void (*cleanup)(struct subprocess_info *), void *data)
{
struct subprocess_info *info;
diff --git a/kernel/kmod.c b/kernel/kmod.c
index ad6a81c58b44..47613dfb7b28 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -156,12 +156,6 @@ static int ____call_usermodehelper(void *data)
*/
set_user_nice(current, 0);
- if (sub_info->init) {
- retval = sub_info->init(sub_info);
- if (retval)
- goto fail;
- }
-
retval = -ENOMEM;
new = prepare_kernel_cred(current);
if (!new)
@@ -173,6 +167,14 @@ static int ____call_usermodehelper(void *data)
new->cap_inheritable);
spin_unlock(&umh_sysctl_lock);
+ if (sub_info->init) {
+ retval = sub_info->init(sub_info, new);
+ if (retval) {
+ abort_creds(new);
+ goto fail;
+ }
+ }
+
commit_creds(new);
retval = kernel_execve(sub_info->path,
@@ -388,7 +390,7 @@ EXPORT_SYMBOL(call_usermodehelper_setup);
* context in which call_usermodehelper_exec is called.
*/
void call_usermodehelper_setfns(struct subprocess_info *info,
- int (*init)(struct subprocess_info *info),
+ int (*init)(struct subprocess_info *info, struct cred *new),
void (*cleanup)(struct subprocess_info *info),
void *data)
{
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index d31862e0aa1c..8e319a416eec 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -71,9 +71,8 @@ EXPORT_SYMBOL(complete_request_key);
* This is called in context of freshly forked kthread before kernel_execve(),
* so we can simply install the desired session_keyring at this point.
*/
-static int umh_keys_init(struct subprocess_info *info)
+static int umh_keys_init(struct subprocess_info *info, struct cred *cred)
{
- struct cred *cred = (struct cred*)current_cred();
struct key *keyring = info->data;
return install_session_keyring_to_cred(cred, keyring);