diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-06-08 19:40:08 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-06-08 19:40:08 +0100 |
commit | 76962be8491b18ae7ff4fd6a4accd398bdb402a2 (patch) | |
tree | 976958bf8e4989a69901bfbb25dd6463728c6cb5 /security/keys | |
parent | 5e27fb78df95e027723af2c90ecc9b4527ae59e9 (diff) | |
parent | d30e5d897c3da7c2d17c8112331b66ed953eec78 (diff) | |
download | kernel_goldelico_gta04-76962be8491b18ae7ff4fd6a4accd398bdb402a2.zip kernel_goldelico_gta04-76962be8491b18ae7ff4fd6a4accd398bdb402a2.tar.gz kernel_goldelico_gta04-76962be8491b18ae7ff4fd6a4accd398bdb402a2.tar.bz2 |
Merge branch 'fix' of git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6
Diffstat (limited to 'security/keys')
-rw-r--r-- | security/keys/internal.h | 1 | ||||
-rw-r--r-- | security/keys/keyctl.c | 2 | ||||
-rw-r--r-- | security/keys/process_keys.c | 3 | ||||
-rw-r--r-- | security/keys/request_key.c | 32 |
4 files changed, 35 insertions, 3 deletions
diff --git a/security/keys/internal.h b/security/keys/internal.h index 5d4402a..38783dc 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -124,6 +124,7 @@ extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check); extern int install_user_keyrings(void); extern int install_thread_keyring_to_cred(struct cred *); extern int install_process_keyring_to_cred(struct cred *); +extern int install_session_keyring_to_cred(struct cred *, struct key *); extern struct key *request_key_and_link(struct key_type *type, const char *description, diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 8f4dce1..13074b4 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -1269,7 +1269,7 @@ long keyctl_session_to_parent(void) goto not_permitted; /* the parent must be single threaded */ - if (atomic_read(&parent->signal->count) != 1) + if (!thread_group_empty(parent)) goto not_permitted; /* the parent and the child must have different session keyrings or diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 20a38fe..6b8e4ff 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c @@ -216,8 +216,7 @@ static int install_process_keyring(void) /* * install a session keyring directly to a credentials struct */ -static int install_session_keyring_to_cred(struct cred *cred, - struct key *keyring) +int install_session_keyring_to_cred(struct cred *cred, struct key *keyring) { unsigned long flags; struct key *old; diff --git a/security/keys/request_key.c b/security/keys/request_key.c index f656e9c..f5ec9ac 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -58,6 +58,38 @@ void complete_request_key(struct key_construction *cons, int error) } EXPORT_SYMBOL(complete_request_key); +static int umh_keys_init(struct subprocess_info *info) +{ + struct cred *cred = (struct cred*)current_cred(); + struct key *keyring = info->data; + /* + * This is called in context of freshly forked kthread before + * kernel_execve(), we can just change our ->session_keyring. + */ + return install_session_keyring_to_cred(cred, keyring); +} + +static void umh_keys_cleanup(struct subprocess_info *info) +{ + struct key *keyring = info->data; + key_put(keyring); +} + +static int call_usermodehelper_keys(char *path, char **argv, char **envp, + struct key *session_keyring, enum umh_wait wait) +{ + gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL; + struct subprocess_info *info = + call_usermodehelper_setup(path, argv, envp, gfp_mask); + + if (!info) + return -ENOMEM; + + call_usermodehelper_setfns(info, umh_keys_init, umh_keys_cleanup, + key_get(session_keyring)); + return call_usermodehelper_exec(info, wait); +} + /* * request userspace finish the construction of a key * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>" |