1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* Key permission checking 3 * 4 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8 #include <linux/export.h> 9 #include <linux/security.h> 10 #include <linux/user_namespace.h> 11 #include <linux/uaccess.h> 12 #include "internal.h" 13 14 struct key_acl default_key_acl = { 15 .usage = REFCOUNT_INIT(1), 16 .nr_ace = 2, 17 .possessor_viewable = true, 18 .aces = { 19 KEY_POSSESSOR_ACE(KEY_ACE__PERMS & ~KEY_ACE_JOIN), 20 KEY_OWNER_ACE(KEY_ACE_VIEW), 21 } 22 }; 23 EXPORT_SYMBOL(default_key_acl); 24 25 struct key_acl joinable_keyring_acl = { 26 .usage = REFCOUNT_INIT(1), 27 .nr_ace = 2, 28 .possessor_viewable = true, 29 .aces = { 30 KEY_POSSESSOR_ACE(KEY_ACE__PERMS & ~KEY_ACE_JOIN), 31 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_LINK | KEY_ACE_JOIN), 32 } 33 }; 34 EXPORT_SYMBOL(joinable_keyring_acl); 35 36 struct key_acl internal_key_acl = { 37 .usage = REFCOUNT_INIT(1), 38 .nr_ace = 2, 39 .aces = { 40 KEY_POSSESSOR_ACE(KEY_ACE_SEARCH), 41 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_SEARCH), 42 } 43 }; 44 EXPORT_SYMBOL(internal_key_acl); 45 46 struct key_acl internal_keyring_acl = { 47 .usage = REFCOUNT_INIT(1), 48 .nr_ace = 2, 49 .aces = { 50 KEY_POSSESSOR_ACE(KEY_ACE_SEARCH), 51 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_SEARCH), 52 } 53 }; 54 EXPORT_SYMBOL(internal_keyring_acl); 55 56 struct key_acl internal_writable_keyring_acl = { 57 .usage = REFCOUNT_INIT(1), 58 .nr_ace = 2, 59 .aces = { 60 KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_WRITE), 61 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_WRITE | KEY_ACE_SEARCH), 62 } 63 }; 64 EXPORT_SYMBOL(internal_writable_keyring_acl); 65 66 /** 67 * key_task_permission - Check a key can be used 68 * @key_ref: The key to check. 69 * @cred: The credentials to use. 70 * @desired_perm: The permission to check for. 71 * 72 * Check to see whether permission is granted to use a key in the desired way, 73 * but permit the security modules to override. 74 * 75 * The caller must hold either a ref on cred or must hold the RCU readlock. 76 * 77 * Returns 0 if successful, -EACCES if access is denied based on the 78 * permissions bits or the LSM check. 79 */ 80 int key_task_permission(const key_ref_t key_ref, const struct cred *cred, 81 unsigned int desired_perm) 82 { 83 const struct key_acl *acl; 84 const struct key *key; 85 unsigned int allow = 0; 86 int i; 87 88 BUILD_BUG_ON(KEY_NEED_VIEW != KEY_ACE_VIEW || 89 KEY_NEED_READ != KEY_ACE_READ || 90 KEY_NEED_WRITE != KEY_ACE_WRITE || 91 KEY_NEED_SEARCH != KEY_ACE_SEARCH || 92 KEY_NEED_LINK != KEY_ACE_LINK || 93 KEY_NEED_SETSEC != KEY_ACE_SET_SECURITY || 94 KEY_NEED_INVAL != KEY_ACE_INVAL || 95 KEY_NEED_REVOKE != KEY_ACE_REVOKE || 96 KEY_NEED_JOIN != KEY_ACE_JOIN || 97 KEY_NEED_CLEAR != KEY_ACE_CLEAR); 98 99 key = key_ref_to_ptr(key_ref); 100 101 rcu_read_lock(); 102 103 acl = rcu_dereference(key->acl); 104 if (!acl || acl->nr_ace == 0) 105 goto no_access_rcu; 106 107 for (i = 0; i < acl->nr_ace; i++) { 108 const struct key_ace *ace = &acl->aces[i]; 109 110 switch (ace->type) { 111 case KEY_ACE_SUBJ_STANDARD: 112 switch (ace->subject_id) { 113 case KEY_ACE_POSSESSOR: 114 if (is_key_possessed(key_ref)) 115 allow |= ace->perm; 116 break; 117 case KEY_ACE_OWNER: 118 if (uid_eq(key->uid, cred->fsuid)) 119 allow |= ace->perm; 120 break; 121 case KEY_ACE_GROUP: 122 if (gid_valid(key->gid)) { 123 if (gid_eq(key->gid, cred->fsgid)) 124 allow |= ace->perm; 125 else if (groups_search(cred->group_info, key->gid)) 126 allow |= ace->perm; 127 } 128 break; 129 case KEY_ACE_EVERYONE: 130 allow |= ace->perm; 131 break; 132 } 133 break; 134 } 135 } 136 137 rcu_read_unlock(); 138 139 if (!(allow & desired_perm)) 140 goto no_access; 141 142 return security_key_permission(key_ref, cred, desired_perm); 143 144 no_access_rcu: 145 rcu_read_unlock(); 146 no_access: 147 return -EACCES; 148 } 149 EXPORT_SYMBOL(key_task_permission); 150 151 /** 152 * key_validate - Validate a key. 153 * @key: The key to be validated. 154 * 155 * Check that a key is valid, returning 0 if the key is okay, -ENOKEY if the 156 * key is invalidated, -EKEYREVOKED if the key's type has been removed or if 157 * the key has been revoked or -EKEYEXPIRED if the key has expired. 158 */ 159 int key_validate(const struct key *key) 160 { 161 unsigned long flags = READ_ONCE(key->flags); 162 time64_t expiry = READ_ONCE(key->expiry); 163 164 if (flags & (1 << KEY_FLAG_INVALIDATED)) 165 return -ENOKEY; 166 167 /* check it's still accessible */ 168 if (flags & ((1 << KEY_FLAG_REVOKED) | 169 (1 << KEY_FLAG_DEAD))) 170 return -EKEYREVOKED; 171 172 /* check it hasn't expired */ 173 if (expiry) { 174 if (ktime_get_real_seconds() >= expiry) 175 return -EKEYEXPIRED; 176 } 177 178 return 0; 179 } 180 EXPORT_SYMBOL(key_validate); 181 182 /* 183 * Roughly render an ACL to an old-style permissions mask. We cannot 184 * accurately render what the ACL, particularly if it has ACEs that represent 185 * subjects outside of { poss, user, group, other }. 186 */ 187 unsigned int key_acl_to_perm(const struct key_acl *acl) 188 { 189 unsigned int perm = 0, tperm; 190 int i; 191 192 BUILD_BUG_ON(KEY_OTH_VIEW != KEY_ACE_VIEW || 193 KEY_OTH_READ != KEY_ACE_READ || 194 KEY_OTH_WRITE != KEY_ACE_WRITE || 195 KEY_OTH_SEARCH != KEY_ACE_SEARCH || 196 KEY_OTH_LINK != KEY_ACE_LINK || 197 KEY_OTH_SETATTR != KEY_ACE_SET_SECURITY); 198 199 if (!acl || acl->nr_ace == 0) 200 return 0; 201 202 for (i = 0; i < acl->nr_ace; i++) { 203 const struct key_ace *ace = &acl->aces[i]; 204 205 switch (ace->type) { 206 case KEY_ACE_SUBJ_STANDARD: 207 tperm = ace->perm & KEY_OTH_ALL; 208 209 /* Invalidation and joining were allowed by SEARCH */ 210 if (ace->perm & (KEY_ACE_INVAL | KEY_ACE_JOIN)) 211 tperm |= KEY_OTH_SEARCH; 212 213 /* Revocation was allowed by either SETATTR or WRITE */ 214 if ((ace->perm & KEY_ACE_REVOKE) && !(tperm & KEY_OTH_SETATTR)) 215 tperm |= KEY_OTH_WRITE; 216 217 /* Clearing was allowed by WRITE */ 218 if (ace->perm & KEY_ACE_CLEAR) 219 tperm |= KEY_OTH_WRITE; 220 221 switch (ace->subject_id) { 222 case KEY_ACE_POSSESSOR: 223 perm |= tperm << 24; 224 break; 225 case KEY_ACE_OWNER: 226 perm |= tperm << 16; 227 break; 228 case KEY_ACE_GROUP: 229 perm |= tperm << 8; 230 break; 231 case KEY_ACE_EVERYONE: 232 perm |= tperm << 0; 233 break; 234 } 235 } 236 } 237 238 return perm; 239 } 240 241 /* 242 * Destroy a key's ACL. 243 */ 244 void key_put_acl(struct key_acl *acl) 245 { 246 if (acl && refcount_dec_and_test(&acl->usage)) 247 kfree_rcu(acl, rcu); 248 } 249 250 /* 251 * Try to set the ACL. This either attaches or discards the proposed ACL. 252 */ 253 long key_set_acl(struct key *key, struct key_acl *acl) 254 { 255 int i; 256 257 /* If we're not the sysadmin, we can only change a key that we own. */ 258 if (!capable(CAP_SYS_ADMIN) && !uid_eq(key->uid, current_fsuid())) { 259 key_put_acl(acl); 260 return -EACCES; 261 } 262 263 for (i = 0; i < acl->nr_ace; i++) { 264 const struct key_ace *ace = &acl->aces[i]; 265 if (ace->type == KEY_ACE_SUBJ_STANDARD && 266 ace->subject_id == KEY_ACE_POSSESSOR) { 267 if (ace->perm & KEY_ACE_VIEW) 268 acl->possessor_viewable = true; 269 break; 270 } 271 } 272 273 rcu_swap_protected(key->acl, acl, lockdep_is_held(&key->sem)); 274 key_put_acl(acl); 275 return 0; 276 } 277 278 /* 279 * Allocate a new ACL with an extra ACE slot. 280 */ 281 static struct key_acl *key_alloc_acl(const struct key_acl *old_acl, int nr, int skip) 282 { 283 struct key_acl *acl; 284 int nr_ace, i, j = 0; 285 286 nr_ace = old_acl->nr_ace + nr; 287 if (nr_ace > 16) 288 return ERR_PTR(-EINVAL); 289 290 acl = kzalloc(struct_size(acl, aces, nr_ace), GFP_KERNEL); 291 if (!acl) 292 return ERR_PTR(-ENOMEM); 293 294 refcount_set(&acl->usage, 1); 295 acl->nr_ace = nr_ace; 296 for (i = 0; i < old_acl->nr_ace; i++) { 297 if (i == skip) 298 continue; 299 acl->aces[j] = old_acl->aces[i]; 300 j++; 301 } 302 return acl; 303 } 304 305 /* 306 * Generate the revised ACL. 307 */ 308 static long key_change_acl(struct key *key, struct key_ace *new_ace) 309 { 310 struct key_acl *acl, *old; 311 int i; 312 313 old = rcu_dereference_protected(key->acl, lockdep_is_held(&key->sem)); 314 315 for (i = 0; i < old->nr_ace; i++) 316 if (old->aces[i].type == new_ace->type && 317 old->aces[i].subject_id == new_ace->subject_id) 318 goto found_match; 319 320 if (new_ace->perm == 0) 321 return 0; /* No permissions to remove. Add deny record? */ 322 323 acl = key_alloc_acl(old, 1, -1); 324 if (IS_ERR(acl)) 325 return PTR_ERR(acl); 326 acl->aces[i] = *new_ace; 327 goto change; 328 329 found_match: 330 if (new_ace->perm == 0) 331 goto delete_ace; 332 if (new_ace->perm == old->aces[i].perm) 333 return 0; 334 acl = key_alloc_acl(old, 0, -1); 335 if (IS_ERR(acl)) 336 return PTR_ERR(acl); 337 acl->aces[i].perm = new_ace->perm; 338 goto change; 339 340 delete_ace: 341 acl = key_alloc_acl(old, -1, i); 342 if (IS_ERR(acl)) 343 return PTR_ERR(acl); 344 goto change; 345 346 change: 347 return key_set_acl(key, acl); 348 } 349 350 /* 351 * Add, alter or remove (if perm == 0) an ACE in a key's ACL. 352 */ 353 long keyctl_grant_permission(key_serial_t keyid, 354 enum key_ace_subject_type type, 355 unsigned int subject, 356 unsigned int perm) 357 { 358 struct key_ace new_ace; 359 struct key *key; 360 key_ref_t key_ref; 361 long ret; 362 363 new_ace.type = type; 364 new_ace.perm = perm; 365 366 switch (type) { 367 case KEY_ACE_SUBJ_STANDARD: 368 if (subject >= nr__key_ace_standard_subject) 369 return -ENOENT; 370 new_ace.subject_id = subject; 371 break; 372 373 default: 374 return -ENOENT; 375 } 376 377 key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_NEED_SETSEC); 378 if (IS_ERR(key_ref)) { 379 ret = PTR_ERR(key_ref); 380 goto error; 381 } 382 383 key = key_ref_to_ptr(key_ref); 384 385 down_write(&key->sem); 386 387 /* If we're not the sysadmin, we can only change a key that we own */ 388 ret = -EACCES; 389 if (capable(CAP_SYS_ADMIN) || uid_eq(key->uid, current_fsuid())) 390 ret = key_change_acl(key, &new_ace); 391 up_write(&key->sem); 392 key_put(key); 393 error: 394 return ret; 395 } 396