1 /* permission.c: key permission determination 2 * 3 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 12 #include <linux/module.h> 13 #include <linux/security.h> 14 #include "internal.h" 15 16 /*****************************************************************************/ 17 /* 18 * check to see whether permission is granted to use a key in the desired way, 19 * but permit the security modules to override 20 */ 21 int key_task_permission(const key_ref_t key_ref, 22 struct task_struct *context, 23 key_perm_t perm) 24 { 25 struct key *key; 26 key_perm_t kperm; 27 int ret; 28 29 key = key_ref_to_ptr(key_ref); 30 31 /* use the second 8-bits of permissions for keys the caller owns */ 32 if (key->uid == context->fsuid) { 33 kperm = key->perm >> 16; 34 goto use_these_perms; 35 } 36 37 /* use the third 8-bits of permissions for keys the caller has a group 38 * membership in common with */ 39 if (key->gid != -1 && key->perm & KEY_GRP_ALL) { 40 if (key->gid == context->fsgid) { 41 kperm = key->perm >> 8; 42 goto use_these_perms; 43 } 44 45 task_lock(context); 46 ret = groups_search(context->group_info, key->gid); 47 task_unlock(context); 48 49 if (ret) { 50 kperm = key->perm >> 8; 51 goto use_these_perms; 52 } 53 } 54 55 /* otherwise use the least-significant 8-bits */ 56 kperm = key->perm; 57 58 use_these_perms: 59 /* use the top 8-bits of permissions for keys the caller possesses 60 * - possessor permissions are additive with other permissions 61 */ 62 if (is_key_possessed(key_ref)) 63 kperm |= key->perm >> 24; 64 65 kperm = kperm & perm & KEY_ALL; 66 67 if (kperm != perm) 68 return -EACCES; 69 70 /* let LSM be the final arbiter */ 71 return security_key_permission(key_ref, context, perm); 72 73 } /* end key_task_permission() */ 74 75 EXPORT_SYMBOL(key_task_permission); 76 77 /*****************************************************************************/ 78 /* 79 * validate a key 80 */ 81 int key_validate(struct key *key) 82 { 83 struct timespec now; 84 int ret = 0; 85 86 if (key) { 87 /* check it's still accessible */ 88 ret = -EKEYREVOKED; 89 if (test_bit(KEY_FLAG_REVOKED, &key->flags) || 90 test_bit(KEY_FLAG_DEAD, &key->flags)) 91 goto error; 92 93 /* check it hasn't expired */ 94 ret = 0; 95 if (key->expiry) { 96 now = current_kernel_time(); 97 if (now.tv_sec >= key->expiry) 98 ret = -EKEYEXPIRED; 99 } 100 } 101 102 error: 103 return ret; 104 105 } /* end key_validate() */ 106 107 EXPORT_SYMBOL(key_validate); 108