From: David Howells The attached patch adds some bits to make the key management API more usable. Signed-Off-By: David Howells Signed-off-by: Andrew Morton --- 25-akpm/Documentation/keys.txt | 24 ++++++++++++++++++++++-- 25-akpm/include/linux/key.h | 15 ++++++++++++++- 25-akpm/security/keys/request_key.c | 24 +++++++++++++----------- 3 files changed, 49 insertions(+), 14 deletions(-) diff -puN Documentation/keys.txt~bits-to-make-the-key-management-api-more-usable Documentation/keys.txt --- 25/Documentation/keys.txt~bits-to-make-the-key-management-api-more-usable Fri Sep 24 17:17:43 2004 +++ 25-akpm/Documentation/keys.txt Fri Sep 24 17:17:43 2004 @@ -630,7 +630,26 @@ locked, or else the data may be changed void key_put(struct key *key); - This can be called from interrupt context. + This can be called from interrupt context. If CONFIG_KEYS is not set then + the argument will not be parsed. + + +(*) Extra references can be made to a key by calling the following function: + + struct key *key_get(struct key *key); + + These need to be disposed of by calling key_put() when they've been + finished with. The key pointer passed in will be returned. If the pointer + is NULL or CONFIG_KEYS is not set then the key will not be dereferenced and + no increment will take place. + + +(*) A key's serial number can be obtained by calling: + + key_serial_t key_serial(struct key *key); + + If key is NULL or if CONFIG_KEYS is not set then 0 will be returned (in the + latter case without parsing the argument). (*) If a keyring was found in the search, this can be further searched by: @@ -650,7 +669,8 @@ locked, or else the data may be changed This checks that the key in question hasn't expired or and hasn't been revoked. Should the key be invalid, error EKEYEXPIRED or EKEYREVOKED will - be returned. + be returned. If the key is NULL or if CONFIG_KEYS is not set then 0 will be + returned (in the latter case without parsing the argument). (*) To register a key type, the following function should be called: diff -puN include/linux/key.h~bits-to-make-the-key-management-api-more-usable include/linux/key.h --- 25/include/linux/key.h~bits-to-make-the-key-management-api-more-usable Fri Sep 24 17:17:43 2004 +++ 25-akpm/include/linux/key.h Fri Sep 24 17:17:43 2004 @@ -29,6 +29,8 @@ typedef int32_t key_serial_t; /* key handle permissions mask */ typedef uint32_t key_perm_t; +struct key; + #ifdef CONFIG_KEYS #undef KEY_DEBUGGING @@ -57,7 +59,6 @@ typedef uint32_t key_perm_t; struct seq_file; struct user_struct; -struct key; struct key_type; struct key_owner; struct keyring_list; @@ -201,6 +202,13 @@ extern int key_negate_and_link(struct ke extern void key_revoke(struct key *key); extern void key_put(struct key *key); +static inline struct key *key_get(struct key *key) +{ + if (key) + atomic_inc(&key->usage); + return key; +} + extern struct key *request_key(struct key_type *type, const char *description, const char *callout_info); @@ -241,6 +249,8 @@ extern int keyring_add_key(struct key *k extern struct key *key_lookup(key_serial_t id); +#define key_serial(key) ((key) ? (key)->serial : 0) + /* * the userspace interface */ @@ -256,6 +266,9 @@ extern void key_fsgid_changed(struct tas #else /* CONFIG_KEYS */ +#define key_validate(k) 0 +#define key_serial(k) 0 +#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) diff -puN security/keys/request_key.c~bits-to-make-the-key-management-api-more-usable security/keys/request_key.c --- 25/security/keys/request_key.c~bits-to-make-the-key-management-api-more-usable Fri Sep 24 17:17:43 2004 +++ 25-akpm/security/keys/request_key.c Fri Sep 24 17:17:43 2004 @@ -312,19 +312,21 @@ EXPORT_SYMBOL(request_key); int key_validate(struct key *key) { struct timespec now; - int ret; + int ret = 0; - /* check it's still accessible */ - ret = -EKEYREVOKED; - if (key->flags & (KEY_FLAG_REVOKED | KEY_FLAG_DEAD)) - goto error; + if (key) { + /* check it's still accessible */ + ret = -EKEYREVOKED; + if (key->flags & (KEY_FLAG_REVOKED | KEY_FLAG_DEAD)) + goto error; - /* check it hasn't expired */ - ret = 0; - if (key->expiry) { - now = current_kernel_time(); - if (now.tv_sec >= key->expiry) - ret = -EKEYEXPIRED; + /* check it hasn't expired */ + ret = 0; + if (key->expiry) { + now = current_kernel_time(); + if (now.tv_sec >= key->expiry) + ret = -EKEYEXPIRED; + } } error: _