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

Commit 6b79ccb5 authored by Arun Raghavan's avatar Arun Raghavan Committed by Linus Torvalds
Browse files

keys: allow clients to set key perms in key_create_or_update()



The key_create_or_update() function provided by the keyring code has a default
set of permissions that are always applied to the key when created.  This
might not be desirable to all clients.

Here's a patch that adds a "perm" parameter to the function to address this,
which can be set to KEY_PERM_UNDEF to revert to the current behaviour.

Signed-off-by: default avatarArun Raghavan <arunsr@cse.iitk.ac.in>
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Cc: Satyam Sharma <ssatyam@cse.iitk.ac.in>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent da91d2ef
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -67,6 +67,8 @@ struct key;
#define KEY_OTH_SETATTR	0x00000020
#define KEY_OTH_SETATTR	0x00000020
#define KEY_OTH_ALL	0x0000003f
#define KEY_OTH_ALL	0x0000003f


#define KEY_PERM_UNDEF	0xffffffff

struct seq_file;
struct seq_file;
struct user_struct;
struct user_struct;
struct signal_struct;
struct signal_struct;
@@ -232,6 +234,7 @@ extern key_ref_t key_create_or_update(key_ref_t keyring,
				      const char *description,
				      const char *description,
				      const void *payload,
				      const void *payload,
				      size_t plen,
				      size_t plen,
				      key_perm_t perm,
				      unsigned long flags);
				      unsigned long flags);


extern int key_update(key_ref_t key,
extern int key_update(key_ref_t key,
+10 −8
Original line number Original line Diff line number Diff line
@@ -757,11 +757,11 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
			       const char *description,
			       const char *description,
			       const void *payload,
			       const void *payload,
			       size_t plen,
			       size_t plen,
			       key_perm_t perm,
			       unsigned long flags)
			       unsigned long flags)
{
{
	struct key_type *ktype;
	struct key_type *ktype;
	struct key *keyring, *key = NULL;
	struct key *keyring, *key = NULL;
	key_perm_t perm;
	key_ref_t key_ref;
	key_ref_t key_ref;
	int ret;
	int ret;


@@ -806,7 +806,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
			goto found_matching_key;
			goto found_matching_key;
	}
	}


	/* decide on the permissions we want */
	/* if the client doesn't provide, decide on the permissions we want */
	if (perm == KEY_PERM_UNDEF) {
		perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
		perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
		perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK | KEY_USR_SETATTR;
		perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK | KEY_USR_SETATTR;


@@ -815,6 +816,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,


		if (ktype == &key_type_keyring || ktype->update)
		if (ktype == &key_type_keyring || ktype->update)
			perm |= KEY_USR_WRITE;
			perm |= KEY_USR_WRITE;
	}


	/* allocate a new key */
	/* allocate a new key */
	key = key_alloc(ktype, description, current->fsuid, current->fsgid,
	key = key_alloc(ktype, description, current->fsuid, current->fsgid,
+2 −1
Original line number Original line Diff line number Diff line
@@ -112,7 +112,8 @@ asmlinkage long sys_add_key(const char __user *_type,
	/* create or update the requested key and add it to the target
	/* create or update the requested key and add it to the target
	 * keyring */
	 * keyring */
	key_ref = key_create_or_update(keyring_ref, type, description,
	key_ref = key_create_or_update(keyring_ref, type, description,
				       payload, plen, KEY_ALLOC_IN_QUOTA);
				       payload, plen, KEY_PERM_UNDEF,
				       KEY_ALLOC_IN_QUOTA);
	if (!IS_ERR(key_ref)) {
	if (!IS_ERR(key_ref)) {
		ret = key_ref_to_ptr(key_ref)->serial;
		ret = key_ref_to_ptr(key_ref)->serial;
		key_ref_put(key_ref);
		key_ref_put(key_ref);