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

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
...@@ -67,6 +67,8 @@ struct key; ...@@ -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, ...@@ -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,
......
...@@ -757,11 +757,11 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, ...@@ -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,15 +806,17 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, ...@@ -806,15 +806,17 @@ 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 */
perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR; if (perm == KEY_PERM_UNDEF) {
perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK | KEY_USR_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;
if (ktype->read) if (ktype->read)
perm |= KEY_POS_READ | KEY_USR_READ; perm |= KEY_POS_READ | KEY_USR_READ;
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,
......
...@@ -112,7 +112,8 @@ asmlinkage long sys_add_key(const char __user *_type, ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment