diff options
-rw-r--r-- | include/linux/key.h | 10 | ||||
-rw-r--r-- | include/linux/kmod.h | 13 | ||||
-rw-r--r-- | kernel/kmod.c | 17 | ||||
-rw-r--r-- | security/keys/request_key.c | 2 |
4 files changed, 35 insertions, 7 deletions
diff --git a/include/linux/key.h b/include/linux/key.h index 2c24ffaca86f..2bfbf88d2740 100644 --- a/include/linux/key.h +++ b/include/linux/key.h | |||
@@ -273,14 +273,22 @@ extern void key_fsuid_changed(struct task_struct *tsk); | |||
273 | extern void key_fsgid_changed(struct task_struct *tsk); | 273 | extern void key_fsgid_changed(struct task_struct *tsk); |
274 | extern void key_init(void); | 274 | extern void key_init(void); |
275 | 275 | ||
276 | #define __install_session_keyring(tsk, keyring) \ | ||
277 | ({ \ | ||
278 | struct key *old_session = tsk->signal->session_keyring; \ | ||
279 | tsk->signal->session_keyring = keyring; \ | ||
280 | old_session; \ | ||
281 | }) | ||
282 | |||
276 | #else /* CONFIG_KEYS */ | 283 | #else /* CONFIG_KEYS */ |
277 | 284 | ||
278 | #define key_validate(k) 0 | 285 | #define key_validate(k) 0 |
279 | #define key_serial(k) 0 | 286 | #define key_serial(k) 0 |
280 | #define key_get(k) NULL | 287 | #define key_get(k) ({ NULL; }) |
281 | #define key_put(k) do { } while(0) | 288 | #define key_put(k) do { } while(0) |
282 | #define alloc_uid_keyring(u) 0 | 289 | #define alloc_uid_keyring(u) 0 |
283 | #define switch_uid_keyring(u) do { } while(0) | 290 | #define switch_uid_keyring(u) do { } while(0) |
291 | #define __install_session_keyring(t, k) ({ NULL; }) | ||
284 | #define copy_keys(f,t) 0 | 292 | #define copy_keys(f,t) 0 |
285 | #define copy_thread_group_keys(t) 0 | 293 | #define copy_thread_group_keys(t) 0 |
286 | #define exit_keys(t) do { } while(0) | 294 | #define exit_keys(t) do { } while(0) |
diff --git a/include/linux/kmod.h b/include/linux/kmod.h index 95d0e4b0814d..e4a231549407 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h | |||
@@ -19,6 +19,7 @@ | |||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/stddef.h> | ||
22 | #include <linux/config.h> | 23 | #include <linux/config.h> |
23 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
24 | #include <linux/compiler.h> | 25 | #include <linux/compiler.h> |
@@ -34,7 +35,17 @@ static inline int request_module(const char * name, ...) { return -ENOSYS; } | |||
34 | #endif | 35 | #endif |
35 | 36 | ||
36 | #define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x))) | 37 | #define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x))) |
37 | extern int call_usermodehelper(char *path, char *argv[], char *envp[], int wait); | 38 | |
39 | struct key; | ||
40 | extern int call_usermodehelper_keys(char *path, char *argv[], char *envp[], | ||
41 | struct key *session_keyring, int wait); | ||
42 | |||
43 | static inline int | ||
44 | call_usermodehelper(char *path, char **argv, char **envp, int wait) | ||
45 | { | ||
46 | return call_usermodehelper_keys(path, argv, envp, NULL, wait); | ||
47 | } | ||
48 | |||
38 | extern void usermodehelper_init(void); | 49 | extern void usermodehelper_init(void); |
39 | 50 | ||
40 | #endif /* __LINUX_KMOD_H__ */ | 51 | #endif /* __LINUX_KMOD_H__ */ |
diff --git a/kernel/kmod.c b/kernel/kmod.c index eed53d4f5230..44166e3bb8af 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -120,6 +120,7 @@ struct subprocess_info { | |||
120 | char *path; | 120 | char *path; |
121 | char **argv; | 121 | char **argv; |
122 | char **envp; | 122 | char **envp; |
123 | struct key *ring; | ||
123 | int wait; | 124 | int wait; |
124 | int retval; | 125 | int retval; |
125 | }; | 126 | }; |
@@ -130,16 +131,21 @@ struct subprocess_info { | |||
130 | static int ____call_usermodehelper(void *data) | 131 | static int ____call_usermodehelper(void *data) |
131 | { | 132 | { |
132 | struct subprocess_info *sub_info = data; | 133 | struct subprocess_info *sub_info = data; |
134 | struct key *old_session; | ||
133 | int retval; | 135 | int retval; |
134 | 136 | ||
135 | /* Unblock all signals. */ | 137 | /* Unblock all signals and set the session keyring. */ |
138 | key_get(sub_info->ring); | ||
136 | flush_signals(current); | 139 | flush_signals(current); |
137 | spin_lock_irq(¤t->sighand->siglock); | 140 | spin_lock_irq(¤t->sighand->siglock); |
141 | old_session = __install_session_keyring(current, sub_info->ring); | ||
138 | flush_signal_handlers(current, 1); | 142 | flush_signal_handlers(current, 1); |
139 | sigemptyset(¤t->blocked); | 143 | sigemptyset(¤t->blocked); |
140 | recalc_sigpending(); | 144 | recalc_sigpending(); |
141 | spin_unlock_irq(¤t->sighand->siglock); | 145 | spin_unlock_irq(¤t->sighand->siglock); |
142 | 146 | ||
147 | key_put(old_session); | ||
148 | |||
143 | /* We can run anywhere, unlike our parent keventd(). */ | 149 | /* We can run anywhere, unlike our parent keventd(). */ |
144 | set_cpus_allowed(current, CPU_MASK_ALL); | 150 | set_cpus_allowed(current, CPU_MASK_ALL); |
145 | 151 | ||
@@ -211,10 +217,11 @@ static void __call_usermodehelper(void *data) | |||
211 | } | 217 | } |
212 | 218 | ||
213 | /** | 219 | /** |
214 | * call_usermodehelper - start a usermode application | 220 | * call_usermodehelper_keys - start a usermode application |
215 | * @path: pathname for the application | 221 | * @path: pathname for the application |
216 | * @argv: null-terminated argument list | 222 | * @argv: null-terminated argument list |
217 | * @envp: null-terminated environment list | 223 | * @envp: null-terminated environment list |
224 | * @session_keyring: session keyring for process (NULL for an empty keyring) | ||
218 | * @wait: wait for the application to finish and return status. | 225 | * @wait: wait for the application to finish and return status. |
219 | * | 226 | * |
220 | * Runs a user-space application. The application is started | 227 | * Runs a user-space application. The application is started |
@@ -224,7 +231,8 @@ static void __call_usermodehelper(void *data) | |||
224 | * Must be called from process context. Returns a negative error code | 231 | * Must be called from process context. Returns a negative error code |
225 | * if program was not execed successfully, or 0. | 232 | * if program was not execed successfully, or 0. |
226 | */ | 233 | */ |
227 | int call_usermodehelper(char *path, char **argv, char **envp, int wait) | 234 | int call_usermodehelper_keys(char *path, char **argv, char **envp, |
235 | struct key *session_keyring, int wait) | ||
228 | { | 236 | { |
229 | DECLARE_COMPLETION(done); | 237 | DECLARE_COMPLETION(done); |
230 | struct subprocess_info sub_info = { | 238 | struct subprocess_info sub_info = { |
@@ -232,6 +240,7 @@ int call_usermodehelper(char *path, char **argv, char **envp, int wait) | |||
232 | .path = path, | 240 | .path = path, |
233 | .argv = argv, | 241 | .argv = argv, |
234 | .envp = envp, | 242 | .envp = envp, |
243 | .ring = session_keyring, | ||
235 | .wait = wait, | 244 | .wait = wait, |
236 | .retval = 0, | 245 | .retval = 0, |
237 | }; | 246 | }; |
@@ -247,7 +256,7 @@ int call_usermodehelper(char *path, char **argv, char **envp, int wait) | |||
247 | wait_for_completion(&done); | 256 | wait_for_completion(&done); |
248 | return sub_info.retval; | 257 | return sub_info.retval; |
249 | } | 258 | } |
250 | EXPORT_SYMBOL(call_usermodehelper); | 259 | EXPORT_SYMBOL(call_usermodehelper_keys); |
251 | 260 | ||
252 | void __init usermodehelper_init(void) | 261 | void __init usermodehelper_init(void) |
253 | { | 262 | { |
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 1f6c0940297f..1919540f047d 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
@@ -88,7 +88,7 @@ static int call_request_key(struct key *key, | |||
88 | argv[i] = NULL; | 88 | argv[i] = NULL; |
89 | 89 | ||
90 | /* do it */ | 90 | /* do it */ |
91 | return call_usermodehelper(argv[0], argv, envp, 1); | 91 | return call_usermodehelper_keys(argv[0], argv, envp, NULL, 1); |
92 | 92 | ||
93 | } /* end call_request_key() */ | 93 | } /* end call_request_key() */ |
94 | 94 | ||