From: David Howells The attached patch makes it possible to pass a session keyring through to the process spawned by call_usermodehelper(). This allows patch 3/3 to pass an authorisation key through to /sbin/request-key, thus permitting better access controls when doing just-in-time key creation. Signed-Off-By: David Howells Signed-off-by: Andrew Morton --- 25-akpm/arch/i386/mach-voyager/voyager_thread.c | 2 +- 25-akpm/drivers/acpi/thermal.c | 2 +- 25-akpm/drivers/input/input.c | 2 +- 25-akpm/drivers/macintosh/therm_pm72.c | 2 +- 25-akpm/drivers/net/hamradio/baycom_epp.c | 2 +- 25-akpm/drivers/pnp/pnpbios/core.c | 2 +- 25-akpm/drivers/s390/crypto/z90main.c | 2 +- 25-akpm/include/linux/key.h | 8 ++++++++ 25-akpm/include/linux/kmod.h | 5 ++++- 25-akpm/kernel/cpuset.c | 2 +- 25-akpm/kernel/kmod.c | 15 ++++++++++++--- 25-akpm/lib/kobject_uevent.c | 2 +- 25-akpm/security/keys/request_key.c | 2 +- 13 files changed, 34 insertions(+), 14 deletions(-) diff -puN arch/i386/mach-voyager/voyager_thread.c~keys-pass-session-keyring-to-call_usermodehelper arch/i386/mach-voyager/voyager_thread.c --- 25/arch/i386/mach-voyager/voyager_thread.c~keys-pass-session-keyring-to-call_usermodehelper 2005-03-23 13:15:07.000000000 -0800 +++ 25-akpm/arch/i386/mach-voyager/voyager_thread.c 2005-03-23 13:15:07.000000000 -0800 @@ -73,7 +73,7 @@ execute(const char *string) NULL, }; - if ((ret = call_usermodehelper(argv[0], argv, envp, 1)) != 0) { + if ((ret = call_usermodehelper(argv[0], argv, envp, NULL, 1)) != 0) { printk(KERN_ERR "Voyager failed to run \"%s\": %i\n", string, ret); } diff -puN drivers/acpi/thermal.c~keys-pass-session-keyring-to-call_usermodehelper drivers/acpi/thermal.c --- 25/drivers/acpi/thermal.c~keys-pass-session-keyring-to-call_usermodehelper 2005-03-23 13:15:07.000000000 -0800 +++ 25-akpm/drivers/acpi/thermal.c 2005-03-23 13:15:07.000000000 -0800 @@ -441,7 +441,7 @@ acpi_thermal_call_usermode ( envp[0] = "HOME=/"; envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; - call_usermodehelper(argv[0], argv, envp, 0); + call_usermodehelper(argv[0], argv, envp, NULL, 0); return_VALUE(0); } diff -puN drivers/input/input.c~keys-pass-session-keyring-to-call_usermodehelper drivers/input/input.c --- 25/drivers/input/input.c~keys-pass-session-keyring-to-call_usermodehelper 2005-03-23 13:15:07.000000000 -0800 +++ 25-akpm/drivers/input/input.c 2005-03-23 13:15:07.000000000 -0800 @@ -415,7 +415,7 @@ static void input_call_hotplug(char *ver argv[0], argv[1], envp[0], envp[1], envp[2], envp[3], envp[4]); #endif - value = call_usermodehelper(argv [0], argv, envp, 0); + value = call_usermodehelper(argv [0], argv, envp, NULL, 0); kfree(buf); kfree(envp); diff -puN drivers/macintosh/therm_pm72.c~keys-pass-session-keyring-to-call_usermodehelper drivers/macintosh/therm_pm72.c --- 25/drivers/macintosh/therm_pm72.c~keys-pass-session-keyring-to-call_usermodehelper 2005-03-23 13:15:07.000000000 -0800 +++ 25-akpm/drivers/macintosh/therm_pm72.c 2005-03-23 13:15:07.000000000 -0800 @@ -1598,7 +1598,7 @@ static int call_critical_overtemp(void) "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; - return call_usermodehelper(critical_overtemp_path, argv, envp, 0); + return call_usermodehelper(critical_overtemp_path, argv, envp, NULL, 0); } diff -puN drivers/net/hamradio/baycom_epp.c~keys-pass-session-keyring-to-call_usermodehelper drivers/net/hamradio/baycom_epp.c --- 25/drivers/net/hamradio/baycom_epp.c~keys-pass-session-keyring-to-call_usermodehelper 2005-03-23 13:15:07.000000000 -0800 +++ 25-akpm/drivers/net/hamradio/baycom_epp.c 2005-03-23 13:15:07.000000000 -0800 @@ -323,7 +323,7 @@ static int eppconfig(struct baycom_state sprintf(portarg, "%ld", bc->pdev->port->base); printk(KERN_DEBUG "%s: %s -s -p %s -m %s\n", bc_drvname, eppconfig_path, portarg, modearg); - return call_usermodehelper(eppconfig_path, argv, envp, 1); + return call_usermodehelper(eppconfig_path, argv, envp, NULL, 1); } /* ---------------------------------------------------------------------- */ diff -puN drivers/pnp/pnpbios/core.c~keys-pass-session-keyring-to-call_usermodehelper drivers/pnp/pnpbios/core.c --- 25/drivers/pnp/pnpbios/core.c~keys-pass-session-keyring-to-call_usermodehelper 2005-03-23 13:15:07.000000000 -0800 +++ 25-akpm/drivers/pnp/pnpbios/core.c 2005-03-23 13:15:07.000000000 -0800 @@ -157,7 +157,7 @@ static int pnp_dock_event(int dock, stru info->location_id, info->serial, info->capabilities); envp[i] = NULL; - value = call_usermodehelper (argv [0], argv, envp, 0); + value = call_usermodehelper (argv [0], argv, envp, NULL, 0); kfree (buf); kfree (envp); return 0; diff -puN drivers/s390/crypto/z90main.c~keys-pass-session-keyring-to-call_usermodehelper drivers/s390/crypto/z90main.c --- 25/drivers/s390/crypto/z90main.c~keys-pass-session-keyring-to-call_usermodehelper 2005-03-23 13:15:07.000000000 -0800 +++ 25-akpm/drivers/s390/crypto/z90main.c 2005-03-23 13:15:07.000000000 -0800 @@ -3554,7 +3554,7 @@ z90crypt_hotplug_event(int dev_major, in envp[4] = minor; envp[5] = 0; - call_usermodehelper(argv[0], argv, envp, 0); + call_usermodehelper(argv[0], argv, envp, NULL, 0); #endif } #endif diff -puN include/linux/key.h~keys-pass-session-keyring-to-call_usermodehelper include/linux/key.h --- 25/include/linux/key.h~keys-pass-session-keyring-to-call_usermodehelper 2005-03-23 13:15:07.000000000 -0800 +++ 25-akpm/include/linux/key.h 2005-03-23 13:15:07.000000000 -0800 @@ -273,6 +273,13 @@ extern void key_fsuid_changed(struct tas extern void key_fsgid_changed(struct task_struct *tsk); extern void key_init(void); +#define __install_session_keyring(tsk, keyring) \ +({ \ + struct key *old_session = tsk->signal->session_keyring; \ + tsk->signal->session_keyring = keyring; \ + old_session; \ +}) + #else /* CONFIG_KEYS */ #define key_validate(k) 0 @@ -281,6 +288,7 @@ extern void key_init(void); #define key_put(k) do { } while(0) #define alloc_uid_keyring(u) 0 #define switch_uid_keyring(u) do { } while(0) +#define __install_session_keyring(t, k) NULL #define copy_keys(f,t) 0 #define copy_thread_group_keys(t) 0 #define exit_keys(t) do { } while(0) diff -puN include/linux/kmod.h~keys-pass-session-keyring-to-call_usermodehelper include/linux/kmod.h --- 25/include/linux/kmod.h~keys-pass-session-keyring-to-call_usermodehelper 2005-03-23 13:15:07.000000000 -0800 +++ 25-akpm/include/linux/kmod.h 2005-03-23 13:15:07.000000000 -0800 @@ -34,7 +34,10 @@ static inline int request_module(const c #endif #define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x))) -extern int call_usermodehelper(char *path, char *argv[], char *envp[], int wait); + +struct key; +extern int call_usermodehelper(char *path, char *argv[], char *envp[], + struct key *session_keyring, int wait); extern void usermodehelper_init(void); #endif /* __LINUX_KMOD_H__ */ diff -puN kernel/cpuset.c~keys-pass-session-keyring-to-call_usermodehelper kernel/cpuset.c --- 25/kernel/cpuset.c~keys-pass-session-keyring-to-call_usermodehelper 2005-03-23 13:15:07.000000000 -0800 +++ 25-akpm/kernel/cpuset.c 2005-03-23 13:15:07.000000000 -0800 @@ -428,7 +428,7 @@ static int cpuset_release_agent(char *cp envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; envp[i] = NULL; - return call_usermodehelper(argv[0], argv, envp, 0); + return call_usermodehelper(argv[0], argv, envp, NULL, 0); } /* diff -puN kernel/kmod.c~keys-pass-session-keyring-to-call_usermodehelper kernel/kmod.c --- 25/kernel/kmod.c~keys-pass-session-keyring-to-call_usermodehelper 2005-03-23 13:15:07.000000000 -0800 +++ 25-akpm/kernel/kmod.c 2005-03-23 13:15:07.000000000 -0800 @@ -108,7 +108,7 @@ int request_module(const char *fmt, ...) return -ENOMEM; } - ret = call_usermodehelper(modprobe_path, argv, envp, 1); + ret = call_usermodehelper(modprobe_path, argv, envp, NULL, 1); atomic_dec(&kmod_concurrent); return ret; } @@ -120,6 +120,7 @@ struct subprocess_info { char *path; char **argv; char **envp; + struct key *ring; int wait; int retval; }; @@ -130,16 +131,21 @@ struct subprocess_info { static int ____call_usermodehelper(void *data) { struct subprocess_info *sub_info = data; + struct key *old_session; int retval; - /* Unblock all signals. */ + /* Unblock all signals and set the session keyring. */ + key_get(sub_info->ring); flush_signals(current); spin_lock_irq(¤t->sighand->siglock); + old_session = __install_session_keyring(current, sub_info->ring); flush_signal_handlers(current, 1); sigemptyset(¤t->blocked); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); + key_put(old_session); + /* We can run anywhere, unlike our parent keventd(). */ set_cpus_allowed(current, CPU_MASK_ALL); @@ -215,6 +221,7 @@ static void __call_usermodehelper(void * * @path: pathname for the application * @argv: null-terminated argument list * @envp: null-terminated environment list + * @session_keyring: session keyring for process (NULL for an empty keyring) * @wait: wait for the application to finish and return status. * * Runs a user-space application. The application is started @@ -224,7 +231,8 @@ static void __call_usermodehelper(void * * Must be called from process context. Returns a negative error code * if program was not execed successfully, or 0. */ -int call_usermodehelper(char *path, char **argv, char **envp, int wait) +int call_usermodehelper(char *path, char **argv, char **envp, + struct key *session_keyring, int wait) { DECLARE_COMPLETION(done); struct subprocess_info sub_info = { @@ -232,6 +240,7 @@ int call_usermodehelper(char *path, char .path = path, .argv = argv, .envp = envp, + .ring = session_keyring, .wait = wait, .retval = 0, }; diff -puN lib/kobject_uevent.c~keys-pass-session-keyring-to-call_usermodehelper lib/kobject_uevent.c --- 25/lib/kobject_uevent.c~keys-pass-session-keyring-to-call_usermodehelper 2005-03-23 13:15:07.000000000 -0800 +++ 25-akpm/lib/kobject_uevent.c 2005-03-23 13:15:07.000000000 -0800 @@ -370,7 +370,7 @@ void kobject_hotplug(struct kobject *kob if (!hotplug_path[0]) goto exit; - retval = call_usermodehelper (argv[0], argv, envp, 0); + retval = call_usermodehelper (argv[0], argv, envp, NULL, 0); if (retval) pr_debug ("%s - call_usermodehelper returned %d\n", __FUNCTION__, retval); diff -puN security/keys/request_key.c~keys-pass-session-keyring-to-call_usermodehelper security/keys/request_key.c --- 25/security/keys/request_key.c~keys-pass-session-keyring-to-call_usermodehelper 2005-03-23 13:15:07.000000000 -0800 +++ 25-akpm/security/keys/request_key.c 2005-03-23 13:15:07.000000000 -0800 @@ -88,7 +88,7 @@ static int call_request_key(struct key * argv[i] = NULL; /* do it */ - return call_usermodehelper(argv[0], argv, envp, 1); + return call_usermodehelper(argv[0], argv, envp, NULL, 1); } /* end call_request_key() */ _