summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2013-09-24 10:35:16 +0100
committerDavid Howells <dhowells@redhat.com>2013-09-24 10:35:16 +0100
commitccc3e6d9c9aea07a0b60b2b0bfc5b05a704b66d5 (patch)
treed111175934b1454fa275fe056f8c6d320e504b01
parentd0a059cac6523b23ad7d743dec8783705aab1668 (diff)
KEYS: Define a __key_get() wrapper to use rather than atomic_inc()
Define a __key_get() wrapper to use rather than atomic_inc() on the key usage count as this makes it easier to hook in refcount error debugging. Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--Documentation/security/keys.txt13
-rw-r--r--include/linux/key.h10
-rw-r--r--security/keys/key.c2
-rw-r--r--security/keys/keyring.c6
-rw-r--r--security/keys/process_keys.c16
5 files changed, 27 insertions, 20 deletions
diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index 9ede67084f0b..a4c33f1a7c6d 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -960,14 +960,17 @@ payload contents" for more information.
the argument will not be parsed.
-(*) Extra references can be made to a key by calling the following function:
+(*) Extra references can be made to a key by calling one of the following
+ functions:
+ struct key *__key_get(struct key *key);
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.
+ Keys so references will need to be disposed of by calling key_put() when
+ they've been finished with. The key pointer passed in will be returned.
+
+ In the case of key_get(), 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:
diff --git a/include/linux/key.h b/include/linux/key.h
index d573e820a23d..ef596c7af585 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -219,13 +219,17 @@ extern void key_revoke(struct key *key);
extern void key_invalidate(struct key *key);
extern void key_put(struct key *key);
-static inline struct key *key_get(struct key *key)
+static inline struct key *__key_get(struct key *key)
{
- if (key)
- atomic_inc(&key->usage);
+ atomic_inc(&key->usage);
return key;
}
+static inline struct key *key_get(struct key *key)
+{
+ return key ? __key_get(key) : key;
+}
+
static inline void key_ref_put(key_ref_t key_ref)
{
key_put(key_ref_to_ptr(key_ref));
diff --git a/security/keys/key.c b/security/keys/key.c
index 7e6bc396bb23..1e23cc288106 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -644,7 +644,7 @@ found:
/* this races with key_put(), but that doesn't matter since key_put()
* doesn't actually change the key
*/
- atomic_inc(&key->usage);
+ __key_get(key);
error:
spin_unlock(&key_serial_lock);
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index b42f2d4f7f83..87eff32b53f4 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -479,7 +479,7 @@ not_this_keyring:
/* we found a viable match */
found:
- atomic_inc(&key->usage);
+ __key_get(key);
key->last_used_at = ctx->now.tv_sec;
keyring->last_used_at = ctx->now.tv_sec;
while (sp > 0)
@@ -573,7 +573,7 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
return ERR_PTR(-ENOKEY);
found:
- atomic_inc(&key->usage);
+ __key_get(key);
keyring->last_used_at = key->last_used_at =
current_kernel_time().tv_sec;
rcu_read_unlock();
@@ -909,7 +909,7 @@ void __key_link(struct key *keyring, struct key *key,
klist = rcu_dereference_locked_keyring(keyring);
- atomic_inc(&key->usage);
+ __key_get(key);
keyring->last_used_at = key->last_used_at =
current_kernel_time().tv_sec;
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index e68a3e0e7aa0..68548ea6fe01 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -235,7 +235,7 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
if (IS_ERR(keyring))
return PTR_ERR(keyring);
} else {
- atomic_inc(&keyring->usage);
+ __key_get(keyring);
}
/* install the keyring */
@@ -544,7 +544,7 @@ try_again:
}
key = ctx.cred->thread_keyring;
- atomic_inc(&key->usage);
+ __key_get(key);
key_ref = make_key_ref(key, 1);
break;
@@ -562,7 +562,7 @@ try_again:
}
key = ctx.cred->process_keyring;
- atomic_inc(&key->usage);
+ __key_get(key);
key_ref = make_key_ref(key, 1);
break;
@@ -593,7 +593,7 @@ try_again:
rcu_read_lock();
key = rcu_dereference(ctx.cred->session_keyring);
- atomic_inc(&key->usage);
+ __key_get(key);
rcu_read_unlock();
key_ref = make_key_ref(key, 1);
break;
@@ -606,7 +606,7 @@ try_again:
}
key = ctx.cred->user->uid_keyring;
- atomic_inc(&key->usage);
+ __key_get(key);
key_ref = make_key_ref(key, 1);
break;
@@ -618,7 +618,7 @@ try_again:
}
key = ctx.cred->user->session_keyring;
- atomic_inc(&key->usage);
+ __key_get(key);
key_ref = make_key_ref(key, 1);
break;
@@ -632,7 +632,7 @@ try_again:
if (!key)
goto error;
- atomic_inc(&key->usage);
+ __key_get(key);
key_ref = make_key_ref(key, 1);
break;
@@ -648,7 +648,7 @@ try_again:
} else {
rka = ctx.cred->request_key_auth->payload.data;
key = rka->dest_keyring;
- atomic_inc(&key->usage);
+ __key_get(key);
}
up_read(&ctx.cred->request_key_auth->sem);
if (!key)