*/
#include <linux/module.h>
+#include <linux/security.h>
#include "internal.h"
/*****************************************************************************/
key = key_ref_to_ptr(key_ref);
- /* use the top 8-bits of permissions for keys the caller possesses */
- if (is_key_possessed(key_ref)) {
- kperm = key->perm >> 24;
- goto use_these_perms;
- }
-
/* use the second 8-bits of permissions for keys the caller owns */
if (key->uid == context->fsuid) {
kperm = key->perm >> 16;
kperm = key->perm;
use_these_perms:
+ /* use the top 8-bits of permissions for keys the caller possesses
+ * - possessor permissions are additive with other permissions
+ */
+ if (is_key_possessed(key_ref))
+ kperm |= key->perm >> 24;
+
kperm = kperm & perm & KEY_ALL;
- return kperm == perm;
+ if (kperm != perm)
+ return -EACCES;
+
+ /* let LSM be the final arbiter */
+ return security_key_permission(key_ref, context, perm);
} /* end key_task_permission() */
EXPORT_SYMBOL(key_task_permission);
+
+/*****************************************************************************/
+/*
+ * validate a key
+ */
+int key_validate(struct key *key)
+{
+ struct timespec now;
+ int ret = 0;
+
+ if (key) {
+ /* check it's still accessible */
+ ret = -EKEYREVOKED;
+ if (test_bit(KEY_FLAG_REVOKED, &key->flags) ||
+ test_bit(KEY_FLAG_DEAD, &key->flags))
+ goto error;
+
+ /* check it hasn't expired */
+ ret = 0;
+ if (key->expiry) {
+ now = current_kernel_time();
+ if (now.tv_sec >= key->expiry)
+ ret = -EKEYEXPIRED;
+ }
+ }
+
+ error:
+ return ret;
+
+} /* end key_validate() */
+
+EXPORT_SYMBOL(key_validate);