Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7888e7ff authored by David Howells's avatar David Howells Committed by Linus Torvalds
Browse files

[PATCH] Keys: Pass session keyring to call_usermodehelper()



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: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 76d8aeab
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -273,14 +273,22 @@ extern void key_fsuid_changed(struct task_struct *tsk);
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
#define key_serial(k)			0
#define key_get(k) 			NULL
#define key_get(k) 			({ NULL; })
#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)
+12 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/stddef.h>
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/compiler.h>
@@ -34,7 +35,17 @@ static inline int request_module(const char * name, ...) { return -ENOSYS; }
#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_keys(char *path, char *argv[], char *envp[],
				    struct key *session_keyring, int wait);

static inline int
call_usermodehelper(char *path, char **argv, char **envp, int wait)
{
	return call_usermodehelper_keys(path, argv, envp, NULL, wait);
}

extern void usermodehelper_init(void);

#endif /* __LINUX_KMOD_H__ */
+13 −4
Original line number Diff line number Diff line
@@ -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(&current->sighand->siglock);
	old_session = __install_session_keyring(current, sub_info->ring);
	flush_signal_handlers(current, 1);
	sigemptyset(&current->blocked);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);

	key_put(old_session);

	/* We can run anywhere, unlike our parent keventd(). */
	set_cpus_allowed(current, CPU_MASK_ALL);

@@ -211,10 +217,11 @@ static void __call_usermodehelper(void *data)
}

/**
 * call_usermodehelper - start a usermode application
 * call_usermodehelper_keys - start a usermode application
 * @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 *data)
 * 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_keys(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 **argv, char **envp, int wait)
		.path		= path,
		.argv		= argv,
		.envp		= envp,
		.ring		= session_keyring,
		.wait		= wait,
		.retval		= 0,
	};
@@ -247,7 +256,7 @@ int call_usermodehelper(char *path, char **argv, char **envp, int wait)
	wait_for_completion(&done);
	return sub_info.retval;
}
EXPORT_SYMBOL(call_usermodehelper);
EXPORT_SYMBOL(call_usermodehelper_keys);

void __init usermodehelper_init(void)
{
+1 −1
Original line number Diff line number Diff line
@@ -88,7 +88,7 @@ static int call_request_key(struct key *key,
	argv[i] = NULL;

	/* do it */
	return call_usermodehelper(argv[0], argv, envp, 1);
	return call_usermodehelper_keys(argv[0], argv, envp, NULL, 1);

} /* end call_request_key() */