0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/export.h>
0009 #include <linux/security.h>
0010 #include "internal.h"
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 int key_task_permission(const key_ref_t key_ref, const struct cred *cred,
0027 enum key_need_perm need_perm)
0028 {
0029 struct key *key;
0030 key_perm_t kperm, mask;
0031 int ret;
0032
0033 switch (need_perm) {
0034 default:
0035 WARN_ON(1);
0036 return -EACCES;
0037 case KEY_NEED_UNLINK:
0038 case KEY_SYSADMIN_OVERRIDE:
0039 case KEY_AUTHTOKEN_OVERRIDE:
0040 case KEY_DEFER_PERM_CHECK:
0041 goto lsm;
0042
0043 case KEY_NEED_VIEW: mask = KEY_OTH_VIEW; break;
0044 case KEY_NEED_READ: mask = KEY_OTH_READ; break;
0045 case KEY_NEED_WRITE: mask = KEY_OTH_WRITE; break;
0046 case KEY_NEED_SEARCH: mask = KEY_OTH_SEARCH; break;
0047 case KEY_NEED_LINK: mask = KEY_OTH_LINK; break;
0048 case KEY_NEED_SETATTR: mask = KEY_OTH_SETATTR; break;
0049 }
0050
0051 key = key_ref_to_ptr(key_ref);
0052
0053
0054 if (uid_eq(key->uid, cred->fsuid)) {
0055 kperm = key->perm >> 16;
0056 goto use_these_perms;
0057 }
0058
0059
0060
0061 if (gid_valid(key->gid) && key->perm & KEY_GRP_ALL) {
0062 if (gid_eq(key->gid, cred->fsgid)) {
0063 kperm = key->perm >> 8;
0064 goto use_these_perms;
0065 }
0066
0067 ret = groups_search(cred->group_info, key->gid);
0068 if (ret) {
0069 kperm = key->perm >> 8;
0070 goto use_these_perms;
0071 }
0072 }
0073
0074
0075 kperm = key->perm;
0076
0077 use_these_perms:
0078
0079
0080
0081
0082 if (is_key_possessed(key_ref))
0083 kperm |= key->perm >> 24;
0084
0085 if ((kperm & mask) != mask)
0086 return -EACCES;
0087
0088
0089 lsm:
0090 return security_key_permission(key_ref, cred, need_perm);
0091 }
0092 EXPORT_SYMBOL(key_task_permission);
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102 int key_validate(const struct key *key)
0103 {
0104 unsigned long flags = READ_ONCE(key->flags);
0105 time64_t expiry = READ_ONCE(key->expiry);
0106
0107 if (flags & (1 << KEY_FLAG_INVALIDATED))
0108 return -ENOKEY;
0109
0110
0111 if (flags & ((1 << KEY_FLAG_REVOKED) |
0112 (1 << KEY_FLAG_DEAD)))
0113 return -EKEYREVOKED;
0114
0115
0116 if (expiry) {
0117 if (ktime_get_real_seconds() >= expiry)
0118 return -EKEYEXPIRED;
0119 }
0120
0121 return 0;
0122 }
0123 EXPORT_SYMBOL(key_validate);