From ca185571c62b662f519152b61a2656c0d3965781 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 17 Jun 2011 11:25:59 +0100 Subject: [PATCH] --- yaml --- r: 253735 b: refs/heads/master c: 879669961b11e7f40b518784863a259f735a72bf h: refs/heads/master i: 253733: 4135c7273da7eb2579f4689bcae822efdabcddac 253731: 60958c3e407a6a6dd8904ef463dfa57ee2b9f977 253727: 3f3c0de8d0deb312f75a8ade05f3eed21db9ee03 v: v3 --- [refs] | 2 +- trunk/fs/exec.c | 2 +- trunk/include/linux/kmod.h | 8 ++++---- trunk/kernel/kmod.c | 16 +++++++++------- trunk/security/keys/request_key.c | 3 +-- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/[refs] b/[refs] index 29b420d07b24..90401e164403 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: eb96c925152fc289311e5d7e956b919e9b60ab53 +refs/heads/master: 879669961b11e7f40b518784863a259f735a72bf diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 97e0d52d72fd..6075a1e727ae 100644 --- a/trunk/fs/exec.c +++ b/trunk/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/trunk/include/linux/kmod.h b/trunk/include/linux/kmod.h index d4a5c84c503d..0da38cf7db7b 100644 --- a/trunk/include/linux/kmod.h +++ b/trunk/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/trunk/kernel/kmod.c b/trunk/kernel/kmod.c index ad6a81c58b44..47613dfb7b28 100644 --- a/trunk/kernel/kmod.c +++ b/trunk/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/trunk/security/keys/request_key.c b/trunk/security/keys/request_key.c index d31862e0aa1c..8e319a416eec 100644 --- a/trunk/security/keys/request_key.c +++ b/trunk/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);