aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/keyctl.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-04-29 04:01:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:06:16 -0400
commit70a5bb72b55e82fbfbf1e22cae6975fac58a1e2d (patch)
tree8e6dcaf5630388d81b23845f293789f2d6a3596b /security/keys/keyctl.c
parent4a38e122e2cc6294779021ff4ccc784a3997059e (diff)
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>
Diffstat (limited to 'security/keys/keyctl.c')
-rw-r--r--security/keys/keyctl.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 1698bf90ee84..56e963b700b9 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -20,6 +20,7 @@
20#include <linux/string.h> 20#include <linux/string.h>
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/vmalloc.h> 22#include <linux/vmalloc.h>
23#include <linux/security.h>
23#include <asm/uaccess.h> 24#include <asm/uaccess.h>
24#include "internal.h" 25#include "internal.h"
25 26
@@ -1080,6 +1081,66 @@ error:
1080 1081
1081} /* end keyctl_assume_authority() */ 1082} /* end keyctl_assume_authority() */
1082 1083
1084/*
1085 * get the security label of a key
1086 * - the key must grant us view permission
1087 * - if there's a buffer, we place up to buflen bytes of data into it
1088 * - unless there's an error, we return the amount of information available,
1089 * irrespective of how much we may have copied (including the terminal NUL)
1090 * - implements keyctl(KEYCTL_GET_SECURITY)
1091 */
1092long keyctl_get_security(key_serial_t keyid,
1093 char __user *buffer,
1094 size_t buflen)
1095{
1096 struct key *key, *instkey;
1097 key_ref_t key_ref;
1098 char *context;
1099 long ret;
1100
1101 key_ref = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW);
1102 if (IS_ERR(key_ref)) {
1103 if (PTR_ERR(key_ref) != -EACCES)
1104 return PTR_ERR(key_ref);
1105
1106 /* viewing a key under construction is also permitted if we
1107 * have the authorisation token handy */
1108 instkey = key_get_instantiation_authkey(keyid);
1109 if (IS_ERR(instkey))
1110 return PTR_ERR(key_ref);
1111 key_put(instkey);
1112
1113 key_ref = lookup_user_key(NULL, keyid, 0, 1, 0);
1114 if (IS_ERR(key_ref))
1115 return PTR_ERR(key_ref);
1116 }
1117
1118 key = key_ref_to_ptr(key_ref);
1119 ret = security_key_getsecurity(key, &context);
1120 if (ret == 0) {
1121 /* if no information was returned, give userspace an empty
1122 * string */
1123 ret = 1;
1124 if (buffer && buflen > 0 &&
1125 copy_to_user(buffer, "", 1) != 0)
1126 ret = -EFAULT;
1127 } else if (ret > 0) {
1128 /* return as much data as there's room for */
1129 if (buffer && buflen > 0) {
1130 if (buflen > ret)
1131 buflen = ret;
1132
1133 if (copy_to_user(buffer, context, buflen) != 0)
1134 ret = -EFAULT;
1135 }
1136
1137 kfree(context);
1138 }
1139
1140 key_ref_put(key_ref);
1141 return ret;
1142}
1143
1083/*****************************************************************************/ 1144/*****************************************************************************/
1084/* 1145/*
1085 * the key control system call 1146 * the key control system call
@@ -1160,6 +1221,11 @@ asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
1160 case KEYCTL_ASSUME_AUTHORITY: 1221 case KEYCTL_ASSUME_AUTHORITY:
1161 return keyctl_assume_authority((key_serial_t) arg2); 1222 return keyctl_assume_authority((key_serial_t) arg2);
1162 1223
1224 case KEYCTL_GET_SECURITY:
1225 return keyctl_get_security((key_serial_t) arg2,
1226 (char *) arg3,
1227 (size_t) arg4);
1228
1163 default: 1229 default:
1164 return -EOPNOTSUPP; 1230 return -EOPNOTSUPP;
1165 } 1231 }