Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

keys: add keyctl function to get a security label

Add a keyctl() function to get the security label of a key.

The following is added to Documentation/keys.txt:

(*) Get the LSM security context attached to a key.

long keyctl(KEYCTL_GET_SECURITY, key_serial_t key, char *buffer,
size_t buflen)

This function returns a string that represents the LSM security context
attached to a key in the buffer provided.

Unless there's an error, it always returns the amount of data it could
produce, even if that's too big for the buffer, but it won't copy more
than requested to userspace. If the buffer pointer is NULL then no copy
will take place.

A NUL character is included at the end of the string if the buffer is
sufficiently big. This is included in the returned count. If no LSM is
in force then an empty string will be returned.

A process must have view permission on the key for this function to be
successful.

[akpm@linux-foundation.org: declare keyctl_get_security()]
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Cc: Paul Moore <paul.moore@hp.com>
Cc: Chris Wright <chrisw@sous-sol.org>
Cc: James Morris <jmorris@namei.org>
Cc: Kevin Coffman <kwc@citi.umich.edu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

David Howells and committed by
Linus Torvalds
70a5bb72 4a38e122

+140 -2
+21
Documentation/keys.txt
··· 711 711 The assumed authoritative key is inherited across fork and exec. 712 712 713 713 714 + (*) Get the LSM security context attached to a key. 715 + 716 + long keyctl(KEYCTL_GET_SECURITY, key_serial_t key, char *buffer, 717 + size_t buflen) 718 + 719 + This function returns a string that represents the LSM security context 720 + attached to a key in the buffer provided. 721 + 722 + Unless there's an error, it always returns the amount of data it could 723 + produce, even if that's too big for the buffer, but it won't copy more 724 + than requested to userspace. If the buffer pointer is NULL then no copy 725 + will take place. 726 + 727 + A NUL character is included at the end of the string if the buffer is 728 + sufficiently big. This is included in the returned count. If no LSM is 729 + in force then an empty string will be returned. 730 + 731 + A process must have view permission on the key for this function to be 732 + successful. 733 + 734 + 714 735 =============== 715 736 KERNEL SERVICES 716 737 ===============
+1
include/linux/keyctl.h
··· 49 49 #define KEYCTL_SET_REQKEY_KEYRING 14 /* set default request-key keyring */ 50 50 #define KEYCTL_SET_TIMEOUT 15 /* set key timeout */ 51 51 #define KEYCTL_ASSUME_AUTHORITY 16 /* assume request_key() authorisation */ 52 + #define KEYCTL_GET_SECURITY 17 /* get key security label */ 52 53 53 54 #endif /* _LINUX_KEYCTL_H */
+19 -1
include/linux/security.h
··· 1009 1009 * @perm describes the combination of permissions required of this key. 1010 1010 * Return 1 if permission granted, 0 if permission denied and -ve it the 1011 1011 * normal permissions model should be effected. 1012 + * @key_getsecurity: 1013 + * Get a textual representation of the security context attached to a key 1014 + * for the purposes of honouring KEYCTL_GETSECURITY. This function 1015 + * allocates the storage for the NUL-terminated string and the caller 1016 + * should free it. 1017 + * @key points to the key to be queried. 1018 + * @_buffer points to a pointer that should be set to point to the 1019 + * resulting string (if no label or an error occurs). 1020 + * Return the length of the string (including terminating NUL) or -ve if 1021 + * an error. 1022 + * May also return 0 (and a NULL buffer pointer) if there is no label. 1012 1023 * 1013 1024 * Security hooks affecting all System V IPC operations. 1014 1025 * ··· 1549 1538 int (*key_permission) (key_ref_t key_ref, 1550 1539 struct task_struct *context, 1551 1540 key_perm_t perm); 1552 - 1541 + int (*key_getsecurity)(struct key *key, char **_buffer); 1553 1542 #endif /* CONFIG_KEYS */ 1554 1543 1555 1544 #ifdef CONFIG_AUDIT ··· 2743 2732 void security_key_free(struct key *key); 2744 2733 int security_key_permission(key_ref_t key_ref, 2745 2734 struct task_struct *context, key_perm_t perm); 2735 + int security_key_getsecurity(struct key *key, char **_buffer); 2746 2736 2747 2737 #else 2748 2738 ··· 2762 2750 struct task_struct *context, 2763 2751 key_perm_t perm) 2764 2752 { 2753 + return 0; 2754 + } 2755 + 2756 + static inline int security_key_getsecurity(struct key *key, char **_buffer) 2757 + { 2758 + *_buffer = NULL; 2765 2759 return 0; 2766 2760 } 2767 2761
+8
security/dummy.c
··· 994 994 { 995 995 return 0; 996 996 } 997 + 998 + static int dummy_key_getsecurity(struct key *key, char **_buffer) 999 + { 1000 + *_buffer = NULL; 1001 + return 0; 1002 + } 1003 + 997 1004 #endif /* CONFIG_KEYS */ 998 1005 999 1006 #ifdef CONFIG_AUDIT ··· 1217 1210 set_to_dummy_if_null(ops, key_alloc); 1218 1211 set_to_dummy_if_null(ops, key_free); 1219 1212 set_to_dummy_if_null(ops, key_permission); 1213 + set_to_dummy_if_null(ops, key_getsecurity); 1220 1214 #endif /* CONFIG_KEYS */ 1221 1215 #ifdef CONFIG_AUDIT 1222 1216 set_to_dummy_if_null(ops, audit_rule_init);
+3
security/keys/compat.c
··· 79 79 case KEYCTL_ASSUME_AUTHORITY: 80 80 return keyctl_assume_authority(arg2); 81 81 82 + case KEYCTL_GET_SECURITY: 83 + return keyctl_get_security(arg2, compat_ptr(arg3), arg4); 84 + 82 85 default: 83 86 return -EOPNOTSUPP; 84 87 }
+2 -1
security/keys/internal.h
··· 155 155 extern long keyctl_set_reqkey_keyring(int); 156 156 extern long keyctl_set_timeout(key_serial_t, unsigned); 157 157 extern long keyctl_assume_authority(key_serial_t); 158 - 158 + extern long keyctl_get_security(key_serial_t keyid, char __user *buffer, 159 + size_t buflen); 159 160 160 161 /* 161 162 * debugging key validation
+66
security/keys/keyctl.c
··· 20 20 #include <linux/string.h> 21 21 #include <linux/err.h> 22 22 #include <linux/vmalloc.h> 23 + #include <linux/security.h> 23 24 #include <asm/uaccess.h> 24 25 #include "internal.h" 25 26 ··· 1081 1080 1082 1081 } /* end keyctl_assume_authority() */ 1083 1082 1083 + /* 1084 + * get the security label of a key 1085 + * - the key must grant us view permission 1086 + * - if there's a buffer, we place up to buflen bytes of data into it 1087 + * - unless there's an error, we return the amount of information available, 1088 + * irrespective of how much we may have copied (including the terminal NUL) 1089 + * - implements keyctl(KEYCTL_GET_SECURITY) 1090 + */ 1091 + long keyctl_get_security(key_serial_t keyid, 1092 + char __user *buffer, 1093 + size_t buflen) 1094 + { 1095 + struct key *key, *instkey; 1096 + key_ref_t key_ref; 1097 + char *context; 1098 + long ret; 1099 + 1100 + key_ref = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW); 1101 + if (IS_ERR(key_ref)) { 1102 + if (PTR_ERR(key_ref) != -EACCES) 1103 + return PTR_ERR(key_ref); 1104 + 1105 + /* viewing a key under construction is also permitted if we 1106 + * have the authorisation token handy */ 1107 + instkey = key_get_instantiation_authkey(keyid); 1108 + if (IS_ERR(instkey)) 1109 + return PTR_ERR(key_ref); 1110 + key_put(instkey); 1111 + 1112 + key_ref = lookup_user_key(NULL, keyid, 0, 1, 0); 1113 + if (IS_ERR(key_ref)) 1114 + return PTR_ERR(key_ref); 1115 + } 1116 + 1117 + key = key_ref_to_ptr(key_ref); 1118 + ret = security_key_getsecurity(key, &context); 1119 + if (ret == 0) { 1120 + /* if no information was returned, give userspace an empty 1121 + * string */ 1122 + ret = 1; 1123 + if (buffer && buflen > 0 && 1124 + copy_to_user(buffer, "", 1) != 0) 1125 + ret = -EFAULT; 1126 + } else if (ret > 0) { 1127 + /* return as much data as there's room for */ 1128 + if (buffer && buflen > 0) { 1129 + if (buflen > ret) 1130 + buflen = ret; 1131 + 1132 + if (copy_to_user(buffer, context, buflen) != 0) 1133 + ret = -EFAULT; 1134 + } 1135 + 1136 + kfree(context); 1137 + } 1138 + 1139 + key_ref_put(key_ref); 1140 + return ret; 1141 + } 1142 + 1084 1143 /*****************************************************************************/ 1085 1144 /* 1086 1145 * the key control system call ··· 1220 1159 1221 1160 case KEYCTL_ASSUME_AUTHORITY: 1222 1161 return keyctl_assume_authority((key_serial_t) arg2); 1162 + 1163 + case KEYCTL_GET_SECURITY: 1164 + return keyctl_get_security((key_serial_t) arg2, 1165 + (char *) arg3, 1166 + (size_t) arg4); 1223 1167 1224 1168 default: 1225 1169 return -EOPNOTSUPP;
+5
security/security.c
··· 1156 1156 return security_ops->key_permission(key_ref, context, perm); 1157 1157 } 1158 1158 1159 + int security_key_getsecurity(struct key *key, char **_buffer) 1160 + { 1161 + return security_ops->key_getsecurity(key, _buffer); 1162 + } 1163 + 1159 1164 #endif /* CONFIG_KEYS */ 1160 1165 1161 1166 #ifdef CONFIG_AUDIT
+15
security/selinux/hooks.c
··· 5300 5300 SECCLASS_KEY, perm, NULL); 5301 5301 } 5302 5302 5303 + static int selinux_key_getsecurity(struct key *key, char **_buffer) 5304 + { 5305 + struct key_security_struct *ksec = key->security; 5306 + char *context = NULL; 5307 + unsigned len; 5308 + int rc; 5309 + 5310 + rc = security_sid_to_context(ksec->sid, &context, &len); 5311 + if (!rc) 5312 + rc = len; 5313 + *_buffer = context; 5314 + return rc; 5315 + } 5316 + 5303 5317 #endif 5304 5318 5305 5319 static struct security_operations selinux_ops = { ··· 5502 5488 .key_alloc = selinux_key_alloc, 5503 5489 .key_free = selinux_key_free, 5504 5490 .key_permission = selinux_key_permission, 5491 + .key_getsecurity = selinux_key_getsecurity, 5505 5492 #endif 5506 5493 5507 5494 #ifdef CONFIG_AUDIT