Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 201844
b: refs/heads/master
c: 927942a
h: refs/heads/master
v: v3
  • Loading branch information
David Howells authored and James Morris committed Aug 2, 2010
1 parent ad33001 commit da0e307
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 24 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9156235b3427d6f01c5c95022f72f381f07583f5
refs/heads/master: 927942aabbbe506bf9bc70a16dc5460ecc64c148
5 changes: 5 additions & 0 deletions trunk/security/keys/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ extern key_ref_t keyring_search_aux(key_ref_t keyring_ref,
const void *description,
key_match_func_t match);

extern key_ref_t search_my_process_keyrings(struct key_type *type,
const void *description,
key_match_func_t match,
const struct cred *cred);
extern key_ref_t search_process_keyrings(struct key_type *type,
const void *description,
key_match_func_t match,
Expand All @@ -134,6 +138,7 @@ extern struct key *request_key_and_link(struct key_type *type,
struct key *dest_keyring,
unsigned long flags);

extern int lookup_user_key_possessed(const struct key *key, const void *target);
extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
key_perm_t perm);
#define KEY_LOOKUP_CREATE 0x01
Expand Down
20 changes: 18 additions & 2 deletions trunk/security/keys/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,20 +184,36 @@ static void proc_keys_stop(struct seq_file *p, void *v)

static int proc_keys_show(struct seq_file *m, void *v)
{
const struct cred *cred = current_cred();
struct rb_node *_p = v;
struct key *key = rb_entry(_p, struct key, serial_node);
struct timespec now;
unsigned long timo;
key_ref_t key_ref, skey_ref;
char xbuf[12];
int rc;

key_ref = make_key_ref(key, 0);

/* determine if the key is possessed by this process (a test we can
* skip if the key does not indicate the possessor can view it
*/
if (key->perm & KEY_POS_VIEW) {
skey_ref = search_my_process_keyrings(key->type, key,
lookup_user_key_possessed,
cred);
if (!IS_ERR(skey_ref)) {
key_ref_put(skey_ref);
key_ref = make_key_ref(key, 1);
}
}

/* check whether the current task is allowed to view the key (assuming
* non-possession)
* - the caller holds a spinlock, and thus the RCU read lock, making our
* access to __current_cred() safe
*/
rc = key_task_permission(make_key_ref(key, 0), current_cred(),
KEY_VIEW);
rc = key_task_permission(key_ref, cred, KEY_VIEW);
if (rc < 0)
return 0;

Expand Down
64 changes: 43 additions & 21 deletions trunk/security/keys/process_keys.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,22 +309,19 @@ void key_fsgid_changed(struct task_struct *tsk)

/*****************************************************************************/
/*
* search the process keyrings for the first matching key
* search only my process keyrings for the first matching key
* - we use the supplied match function to see if the description (or other
* feature of interest) matches
* - we return -EAGAIN if we didn't find any matching key
* - we return -ENOKEY if we found only negative matching keys
*/
key_ref_t search_process_keyrings(struct key_type *type,
const void *description,
key_match_func_t match,
const struct cred *cred)
key_ref_t search_my_process_keyrings(struct key_type *type,
const void *description,
key_match_func_t match,
const struct cred *cred)
{
struct request_key_auth *rka;
key_ref_t key_ref, ret, err;

might_sleep();

/* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
* searchable, but we failed to find a key or we found a negative key;
* otherwise we want to return a sample error (probably -EACCES) if
Expand Down Expand Up @@ -424,6 +421,36 @@ key_ref_t search_process_keyrings(struct key_type *type,
}
}

/* no key - decide on the error we're going to go for */
key_ref = ret ? ret : err;

found:
return key_ref;
}

/*****************************************************************************/
/*
* search the process keyrings for the first matching key
* - we use the supplied match function to see if the description (or other
* feature of interest) matches
* - we return -EAGAIN if we didn't find any matching key
* - we return -ENOKEY if we found only negative matching keys
*/
key_ref_t search_process_keyrings(struct key_type *type,
const void *description,
key_match_func_t match,
const struct cred *cred)
{
struct request_key_auth *rka;
key_ref_t key_ref, ret = ERR_PTR(-EACCES), err;

might_sleep();

key_ref = search_my_process_keyrings(type, description, match, cred);
if (!IS_ERR(key_ref))
goto found;
err = key_ref;

/* if this process has an instantiation authorisation key, then we also
* search the keyrings of the process mentioned there
* - we don't permit access to request_key auth keys via this method
Expand All @@ -446,24 +473,19 @@ key_ref_t search_process_keyrings(struct key_type *type,
if (!IS_ERR(key_ref))
goto found;

switch (PTR_ERR(key_ref)) {
case -EAGAIN: /* no key */
if (ret)
break;
case -ENOKEY: /* negative key */
ret = key_ref;
break;
default:
err = key_ref;
break;
}
ret = key_ref;
} else {
up_read(&cred->request_key_auth->sem);
}
}

/* no key - decide on the error we're going to go for */
key_ref = ret ? ret : err;
if (err == ERR_PTR(-ENOKEY) || ret == ERR_PTR(-ENOKEY))
key_ref = ERR_PTR(-ENOKEY);
else if (err == ERR_PTR(-EACCES))
key_ref = ret;
else
key_ref = err;

found:
return key_ref;
Expand All @@ -474,7 +496,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
/*
* see if the key we're looking at is the target key
*/
static int lookup_user_key_possessed(const struct key *key, const void *target)
int lookup_user_key_possessed(const struct key *key, const void *target)
{
return key == target;

Expand Down

0 comments on commit da0e307

Please sign in to comment.