aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2006-01-12 17:47:08 -0500
committerSteve French <sfrench@us.ibm.com>2006-01-12 17:47:08 -0500
commit94bc2be31a01a3055ec94176e595dfe208e92d3b (patch)
treeebfbe81c6718a6390bfa1b99c6d228237d818576 /security
parentc32a0b689cb9cc160cfcd19735bbf50bb70c6ef4 (diff)
parent58cba4650a7a414eabd2b40cc9d8e45fcdf192d9 (diff)
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'security')
-rw-r--r--security/Kconfig13
-rw-r--r--security/capability.c6
-rw-r--r--security/commoncap.c1
-rw-r--r--security/dummy.c46
-rw-r--r--security/inode.c8
-rw-r--r--security/keys/compat.c6
-rw-r--r--security/keys/internal.h6
-rw-r--r--security/keys/key.c58
-rw-r--r--security/keys/keyctl.c152
-rw-r--r--security/keys/keyring.c198
-rw-r--r--security/keys/permission.c32
-rw-r--r--security/keys/process_keys.c71
-rw-r--r--security/keys/request_key.c108
-rw-r--r--security/keys/request_key_auth.c192
-rw-r--r--security/keys/user_defined.c33
-rw-r--r--security/security.c1
-rw-r--r--security/selinux/Makefile2
-rw-r--r--security/selinux/hooks.c41
-rw-r--r--security/selinux/include/av_perm_to_string.h1
-rw-r--r--security/selinux/include/av_permissions.h1
-rw-r--r--security/selinux/include/xfrm.h54
-rw-r--r--security/selinux/selinuxfs.c6
-rw-r--r--security/selinux/ss/avtab.c2
-rw-r--r--security/selinux/ss/policydb.c2
-rw-r--r--security/selinux/ss/services.c6
-rw-r--r--security/selinux/xfrm.c305
26 files changed, 922 insertions, 429 deletions
diff --git a/security/Kconfig b/security/Kconfig
index 64d3f1e9ca85..34f593410d57 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -54,6 +54,19 @@ config SECURITY_NETWORK
54 implement socket and networking access controls. 54 implement socket and networking access controls.
55 If you are unsure how to answer this question, answer N. 55 If you are unsure how to answer this question, answer N.
56 56
57config SECURITY_NETWORK_XFRM
58 bool "XFRM (IPSec) Networking Security Hooks"
59 depends on XFRM && SECURITY_NETWORK
60 help
61 This enables the XFRM (IPSec) networking security hooks.
62 If enabled, a security module can use these hooks to
63 implement per-packet access controls based on labels
64 derived from IPSec policy. Non-IPSec communications are
65 designated as unlabelled, and only sockets authorized
66 to communicate unlabelled data can send without using
67 IPSec.
68 If you are unsure how to answer this question, answer N.
69
57config SECURITY_CAPABILITIES 70config SECURITY_CAPABILITIES
58 tristate "Default Linux Capabilities" 71 tristate "Default Linux Capabilities"
59 depends on SECURITY 72 depends on SECURITY
diff --git a/security/capability.c b/security/capability.c
index ec18d6075625..f9b35cc0b248 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -49,8 +49,6 @@ static struct security_operations capability_ops = {
49 .vm_enough_memory = cap_vm_enough_memory, 49 .vm_enough_memory = cap_vm_enough_memory,
50}; 50};
51 51
52#define MY_NAME __stringify(KBUILD_MODNAME)
53
54/* flag to keep track of how we were registered */ 52/* flag to keep track of how we were registered */
55static int secondary; 53static int secondary;
56 54
@@ -67,7 +65,7 @@ static int __init capability_init (void)
67 /* register ourselves with the security framework */ 65 /* register ourselves with the security framework */
68 if (register_security (&capability_ops)) { 66 if (register_security (&capability_ops)) {
69 /* try registering with primary module */ 67 /* try registering with primary module */
70 if (mod_reg_security (MY_NAME, &capability_ops)) { 68 if (mod_reg_security (KBUILD_MODNAME, &capability_ops)) {
71 printk (KERN_INFO "Failure registering capabilities " 69 printk (KERN_INFO "Failure registering capabilities "
72 "with primary security module.\n"); 70 "with primary security module.\n");
73 return -EINVAL; 71 return -EINVAL;
@@ -85,7 +83,7 @@ static void __exit capability_exit (void)
85 return; 83 return;
86 /* remove ourselves from the security framework */ 84 /* remove ourselves from the security framework */
87 if (secondary) { 85 if (secondary) {
88 if (mod_unreg_security (MY_NAME, &capability_ops)) 86 if (mod_unreg_security (KBUILD_MODNAME, &capability_ops))
89 printk (KERN_INFO "Failure unregistering capabilities " 87 printk (KERN_INFO "Failure unregistering capabilities "
90 "with primary module.\n"); 88 "with primary module.\n");
91 return; 89 return;
diff --git a/security/commoncap.c b/security/commoncap.c
index 04c12f58d656..8a6e097f99ea 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -7,6 +7,7 @@
7 * 7 *
8 */ 8 */
9 9
10#include <linux/capability.h>
10#include <linux/config.h> 11#include <linux/config.h>
11#include <linux/module.h> 12#include <linux/module.h>
12#include <linux/init.h> 13#include <linux/init.h>
diff --git a/security/dummy.c b/security/dummy.c
index 3ca5f2b828a0..f1a5bd98bf10 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -14,6 +14,7 @@
14 14
15#undef DEBUG 15#undef DEBUG
16 16
17#include <linux/capability.h>
17#include <linux/config.h> 18#include <linux/config.h>
18#include <linux/module.h> 19#include <linux/module.h>
19#include <linux/kernel.h> 20#include <linux/kernel.h>
@@ -776,8 +777,42 @@ static inline int dummy_sk_alloc_security (struct sock *sk, int family, gfp_t pr
776static inline void dummy_sk_free_security (struct sock *sk) 777static inline void dummy_sk_free_security (struct sock *sk)
777{ 778{
778} 779}
780
781static unsigned int dummy_sk_getsid(struct sock *sk, struct flowi *fl, u8 dir)
782{
783 return 0;
784}
779#endif /* CONFIG_SECURITY_NETWORK */ 785#endif /* CONFIG_SECURITY_NETWORK */
780 786
787#ifdef CONFIG_SECURITY_NETWORK_XFRM
788static int dummy_xfrm_policy_alloc_security(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
789{
790 return 0;
791}
792
793static inline int dummy_xfrm_policy_clone_security(struct xfrm_policy *old, struct xfrm_policy *new)
794{
795 return 0;
796}
797
798static void dummy_xfrm_policy_free_security(struct xfrm_policy *xp)
799{
800}
801
802static int dummy_xfrm_state_alloc_security(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)
803{
804 return 0;
805}
806
807static void dummy_xfrm_state_free_security(struct xfrm_state *x)
808{
809}
810
811static int dummy_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir)
812{
813 return 0;
814}
815#endif /* CONFIG_SECURITY_NETWORK_XFRM */
781static int dummy_register_security (const char *name, struct security_operations *ops) 816static int dummy_register_security (const char *name, struct security_operations *ops)
782{ 817{
783 return -EINVAL; 818 return -EINVAL;
@@ -970,7 +1005,16 @@ void security_fixup_ops (struct security_operations *ops)
970 set_to_dummy_if_null(ops, socket_getpeersec); 1005 set_to_dummy_if_null(ops, socket_getpeersec);
971 set_to_dummy_if_null(ops, sk_alloc_security); 1006 set_to_dummy_if_null(ops, sk_alloc_security);
972 set_to_dummy_if_null(ops, sk_free_security); 1007 set_to_dummy_if_null(ops, sk_free_security);
973#endif /* CONFIG_SECURITY_NETWORK */ 1008 set_to_dummy_if_null(ops, sk_getsid);
1009 #endif /* CONFIG_SECURITY_NETWORK */
1010#ifdef CONFIG_SECURITY_NETWORK_XFRM
1011 set_to_dummy_if_null(ops, xfrm_policy_alloc_security);
1012 set_to_dummy_if_null(ops, xfrm_policy_clone_security);
1013 set_to_dummy_if_null(ops, xfrm_policy_free_security);
1014 set_to_dummy_if_null(ops, xfrm_state_alloc_security);
1015 set_to_dummy_if_null(ops, xfrm_state_free_security);
1016 set_to_dummy_if_null(ops, xfrm_policy_lookup);
1017#endif /* CONFIG_SECURITY_NETWORK_XFRM */
974#ifdef CONFIG_KEYS 1018#ifdef CONFIG_KEYS
975 set_to_dummy_if_null(ops, key_alloc); 1019 set_to_dummy_if_null(ops, key_alloc);
976 set_to_dummy_if_null(ops, key_free); 1020 set_to_dummy_if_null(ops, key_free);
diff --git a/security/inode.c b/security/inode.c
index a5964502ae30..0f77b0223662 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -172,7 +172,7 @@ static int create_by_name(const char *name, mode_t mode,
172 return -EFAULT; 172 return -EFAULT;
173 } 173 }
174 174
175 down(&parent->d_inode->i_sem); 175 mutex_lock(&parent->d_inode->i_mutex);
176 *dentry = lookup_one_len(name, parent, strlen(name)); 176 *dentry = lookup_one_len(name, parent, strlen(name));
177 if (!IS_ERR(dentry)) { 177 if (!IS_ERR(dentry)) {
178 if ((mode & S_IFMT) == S_IFDIR) 178 if ((mode & S_IFMT) == S_IFDIR)
@@ -181,7 +181,7 @@ static int create_by_name(const char *name, mode_t mode,
181 error = create(parent->d_inode, *dentry, mode); 181 error = create(parent->d_inode, *dentry, mode);
182 } else 182 } else
183 error = PTR_ERR(dentry); 183 error = PTR_ERR(dentry);
184 up(&parent->d_inode->i_sem); 184 mutex_unlock(&parent->d_inode->i_mutex);
185 185
186 return error; 186 return error;
187} 187}
@@ -302,7 +302,7 @@ void securityfs_remove(struct dentry *dentry)
302 if (!parent || !parent->d_inode) 302 if (!parent || !parent->d_inode)
303 return; 303 return;
304 304
305 down(&parent->d_inode->i_sem); 305 mutex_lock(&parent->d_inode->i_mutex);
306 if (positive(dentry)) { 306 if (positive(dentry)) {
307 if (dentry->d_inode) { 307 if (dentry->d_inode) {
308 if (S_ISDIR(dentry->d_inode->i_mode)) 308 if (S_ISDIR(dentry->d_inode->i_mode))
@@ -312,7 +312,7 @@ void securityfs_remove(struct dentry *dentry)
312 dput(dentry); 312 dput(dentry);
313 } 313 }
314 } 314 }
315 up(&parent->d_inode->i_sem); 315 mutex_unlock(&parent->d_inode->i_mutex);
316 simple_release_fs(&mount, &mount_count); 316 simple_release_fs(&mount, &mount_count);
317} 317}
318EXPORT_SYMBOL_GPL(securityfs_remove); 318EXPORT_SYMBOL_GPL(securityfs_remove);
diff --git a/security/keys/compat.c b/security/keys/compat.c
index 3303673c636e..bcdb28533733 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -74,6 +74,12 @@ asmlinkage long compat_sys_keyctl(u32 option,
74 case KEYCTL_SET_REQKEY_KEYRING: 74 case KEYCTL_SET_REQKEY_KEYRING:
75 return keyctl_set_reqkey_keyring(arg2); 75 return keyctl_set_reqkey_keyring(arg2);
76 76
77 case KEYCTL_SET_TIMEOUT:
78 return keyctl_set_timeout(arg2, arg3);
79
80 case KEYCTL_ASSUME_AUTHORITY:
81 return keyctl_assume_authority(arg2);
82
77 default: 83 default:
78 return -EOPNOTSUPP; 84 return -EOPNOTSUPP;
79 } 85 }
diff --git a/security/keys/internal.h b/security/keys/internal.h
index db99ed434f3a..e066e6057955 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -25,7 +25,6 @@
25#define kdebug(FMT, a...) do {} while(0) 25#define kdebug(FMT, a...) do {} while(0)
26#endif 26#endif
27 27
28extern struct key_type key_type_dead;
29extern struct key_type key_type_user; 28extern struct key_type key_type_user;
30 29
31/*****************************************************************************/ 30/*****************************************************************************/
@@ -108,12 +107,13 @@ extern struct key *request_key_and_link(struct key_type *type,
108struct request_key_auth { 107struct request_key_auth {
109 struct key *target_key; 108 struct key *target_key;
110 struct task_struct *context; 109 struct task_struct *context;
110 const char *callout_info;
111 pid_t pid; 111 pid_t pid;
112}; 112};
113 113
114extern struct key_type key_type_request_key_auth; 114extern struct key_type key_type_request_key_auth;
115extern struct key *request_key_auth_new(struct key *target, 115extern struct key *request_key_auth_new(struct key *target,
116 struct key **_rkakey); 116 const char *callout_info);
117 117
118extern struct key *key_get_instantiation_authkey(key_serial_t target_id); 118extern struct key *key_get_instantiation_authkey(key_serial_t target_id);
119 119
@@ -137,6 +137,8 @@ extern long keyctl_instantiate_key(key_serial_t, const void __user *,
137 size_t, key_serial_t); 137 size_t, key_serial_t);
138extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t); 138extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t);
139extern long keyctl_set_reqkey_keyring(int); 139extern long keyctl_set_reqkey_keyring(int);
140extern long keyctl_set_timeout(key_serial_t, unsigned);
141extern long keyctl_assume_authority(key_serial_t);
140 142
141 143
142/* 144/*
diff --git a/security/keys/key.c b/security/keys/key.c
index 01bcfecb7eae..99781b798312 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -36,7 +36,7 @@ static DECLARE_WORK(key_cleanup_task, key_cleanup, NULL);
36DECLARE_RWSEM(key_construction_sem); 36DECLARE_RWSEM(key_construction_sem);
37 37
38/* any key who's type gets unegistered will be re-typed to this */ 38/* any key who's type gets unegistered will be re-typed to this */
39struct key_type key_type_dead = { 39static struct key_type key_type_dead = {
40 .name = "dead", 40 .name = "dead",
41}; 41};
42 42
@@ -240,9 +240,9 @@ static inline void key_alloc_serial(struct key *key)
240/* 240/*
241 * allocate a key of the specified type 241 * allocate a key of the specified type
242 * - update the user's quota to reflect the existence of the key 242 * - update the user's quota to reflect the existence of the key
243 * - called from a key-type operation with key_types_sem read-locked by either 243 * - called from a key-type operation with key_types_sem read-locked by
244 * key_create_or_update() or by key_duplicate(); this prevents unregistration 244 * key_create_or_update()
245 * of the key type 245 * - this prevents unregistration of the key type
246 * - upon return the key is as yet uninstantiated; the caller needs to either 246 * - upon return the key is as yet uninstantiated; the caller needs to either
247 * instantiate the key or discard it before returning 247 * instantiate the key or discard it before returning
248 */ 248 */
@@ -889,56 +889,6 @@ EXPORT_SYMBOL(key_update);
889 889
890/*****************************************************************************/ 890/*****************************************************************************/
891/* 891/*
892 * duplicate a key, potentially with a revised description
893 * - must be supported by the keytype (keyrings for instance can be duplicated)
894 */
895struct key *key_duplicate(struct key *source, const char *desc)
896{
897 struct key *key;
898 int ret;
899
900 key_check(source);
901
902 if (!desc)
903 desc = source->description;
904
905 down_read(&key_types_sem);
906
907 ret = -EINVAL;
908 if (!source->type->duplicate)
909 goto error;
910
911 /* allocate and instantiate a key */
912 key = key_alloc(source->type, desc, current->fsuid, current->fsgid,
913 source->perm, 0);
914 if (IS_ERR(key))
915 goto error_k;
916
917 down_read(&source->sem);
918 ret = key->type->duplicate(key, source);
919 up_read(&source->sem);
920 if (ret < 0)
921 goto error2;
922
923 atomic_inc(&key->user->nikeys);
924 set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
925
926 error_k:
927 up_read(&key_types_sem);
928 out:
929 return key;
930
931 error2:
932 key_put(key);
933 error:
934 up_read(&key_types_sem);
935 key = ERR_PTR(ret);
936 goto out;
937
938} /* end key_duplicate() */
939
940/*****************************************************************************/
941/*
942 * revoke a key 892 * revoke a key
943 */ 893 */
944void key_revoke(struct key *key) 894void key_revoke(struct key *key)
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index b7a468fabdf9..90db5c76cf6e 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -16,6 +16,7 @@
16#include <linux/syscalls.h> 16#include <linux/syscalls.h>
17#include <linux/keyctl.h> 17#include <linux/keyctl.h>
18#include <linux/fs.h> 18#include <linux/fs.h>
19#include <linux/capability.h>
19#include <linux/err.h> 20#include <linux/err.h>
20#include <asm/uaccess.h> 21#include <asm/uaccess.h>
21#include "internal.h" 22#include "internal.h"
@@ -834,6 +835,17 @@ long keyctl_instantiate_key(key_serial_t id,
834 if (plen > 32767) 835 if (plen > 32767)
835 goto error; 836 goto error;
836 837
838 /* the appropriate instantiation authorisation key must have been
839 * assumed before calling this */
840 ret = -EPERM;
841 instkey = current->request_key_auth;
842 if (!instkey)
843 goto error;
844
845 rka = instkey->payload.data;
846 if (rka->target_key->serial != id)
847 goto error;
848
837 /* pull the payload in if one was supplied */ 849 /* pull the payload in if one was supplied */
838 payload = NULL; 850 payload = NULL;
839 851
@@ -848,15 +860,6 @@ long keyctl_instantiate_key(key_serial_t id,
848 goto error2; 860 goto error2;
849 } 861 }
850 862
851 /* find the instantiation authorisation key */
852 instkey = key_get_instantiation_authkey(id);
853 if (IS_ERR(instkey)) {
854 ret = PTR_ERR(instkey);
855 goto error2;
856 }
857
858 rka = instkey->payload.data;
859
860 /* find the destination keyring amongst those belonging to the 863 /* find the destination keyring amongst those belonging to the
861 * requesting task */ 864 * requesting task */
862 keyring_ref = NULL; 865 keyring_ref = NULL;
@@ -865,7 +868,7 @@ long keyctl_instantiate_key(key_serial_t id,
865 KEY_WRITE); 868 KEY_WRITE);
866 if (IS_ERR(keyring_ref)) { 869 if (IS_ERR(keyring_ref)) {
867 ret = PTR_ERR(keyring_ref); 870 ret = PTR_ERR(keyring_ref);
868 goto error3; 871 goto error2;
869 } 872 }
870 } 873 }
871 874
@@ -874,11 +877,17 @@ long keyctl_instantiate_key(key_serial_t id,
874 key_ref_to_ptr(keyring_ref), instkey); 877 key_ref_to_ptr(keyring_ref), instkey);
875 878
876 key_ref_put(keyring_ref); 879 key_ref_put(keyring_ref);
877 error3: 880
878 key_put(instkey); 881 /* discard the assumed authority if it's just been disabled by
879 error2: 882 * instantiation of the key */
883 if (ret == 0) {
884 key_put(current->request_key_auth);
885 current->request_key_auth = NULL;
886 }
887
888error2:
880 kfree(payload); 889 kfree(payload);
881 error: 890error:
882 return ret; 891 return ret;
883 892
884} /* end keyctl_instantiate_key() */ 893} /* end keyctl_instantiate_key() */
@@ -895,14 +904,16 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
895 key_ref_t keyring_ref; 904 key_ref_t keyring_ref;
896 long ret; 905 long ret;
897 906
898 /* find the instantiation authorisation key */ 907 /* the appropriate instantiation authorisation key must have been
899 instkey = key_get_instantiation_authkey(id); 908 * assumed before calling this */
900 if (IS_ERR(instkey)) { 909 ret = -EPERM;
901 ret = PTR_ERR(instkey); 910 instkey = current->request_key_auth;
911 if (!instkey)
902 goto error; 912 goto error;
903 }
904 913
905 rka = instkey->payload.data; 914 rka = instkey->payload.data;
915 if (rka->target_key->serial != id)
916 goto error;
906 917
907 /* find the destination keyring if present (which must also be 918 /* find the destination keyring if present (which must also be
908 * writable) */ 919 * writable) */
@@ -911,7 +922,7 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
911 keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE); 922 keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
912 if (IS_ERR(keyring_ref)) { 923 if (IS_ERR(keyring_ref)) {
913 ret = PTR_ERR(keyring_ref); 924 ret = PTR_ERR(keyring_ref);
914 goto error2; 925 goto error;
915 } 926 }
916 } 927 }
917 928
@@ -920,9 +931,15 @@ long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
920 key_ref_to_ptr(keyring_ref), instkey); 931 key_ref_to_ptr(keyring_ref), instkey);
921 932
922 key_ref_put(keyring_ref); 933 key_ref_put(keyring_ref);
923 error2: 934
924 key_put(instkey); 935 /* discard the assumed authority if it's just been disabled by
925 error: 936 * instantiation of the key */
937 if (ret == 0) {
938 key_put(current->request_key_auth);
939 current->request_key_auth = NULL;
940 }
941
942error:
926 return ret; 943 return ret;
927 944
928} /* end keyctl_negate_key() */ 945} /* end keyctl_negate_key() */
@@ -967,6 +984,88 @@ long keyctl_set_reqkey_keyring(int reqkey_defl)
967 984
968/*****************************************************************************/ 985/*****************************************************************************/
969/* 986/*
987 * set or clear the timeout for a key
988 */
989long keyctl_set_timeout(key_serial_t id, unsigned timeout)
990{
991 struct timespec now;
992 struct key *key;
993 key_ref_t key_ref;
994 time_t expiry;
995 long ret;
996
997 key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR);
998 if (IS_ERR(key_ref)) {
999 ret = PTR_ERR(key_ref);
1000 goto error;
1001 }
1002
1003 key = key_ref_to_ptr(key_ref);
1004
1005 /* make the changes with the locks held to prevent races */
1006 down_write(&key->sem);
1007
1008 expiry = 0;
1009 if (timeout > 0) {
1010 now = current_kernel_time();
1011 expiry = now.tv_sec + timeout;
1012 }
1013
1014 key->expiry = expiry;
1015
1016 up_write(&key->sem);
1017 key_put(key);
1018
1019 ret = 0;
1020error:
1021 return ret;
1022
1023} /* end keyctl_set_timeout() */
1024
1025/*****************************************************************************/
1026/*
1027 * assume the authority to instantiate the specified key
1028 */
1029long keyctl_assume_authority(key_serial_t id)
1030{
1031 struct key *authkey;
1032 long ret;
1033
1034 /* special key IDs aren't permitted */
1035 ret = -EINVAL;
1036 if (id < 0)
1037 goto error;
1038
1039 /* we divest ourselves of authority if given an ID of 0 */
1040 if (id == 0) {
1041 key_put(current->request_key_auth);
1042 current->request_key_auth = NULL;
1043 ret = 0;
1044 goto error;
1045 }
1046
1047 /* attempt to assume the authority temporarily granted to us whilst we
1048 * instantiate the specified key
1049 * - the authorisation key must be in the current task's keyrings
1050 * somewhere
1051 */
1052 authkey = key_get_instantiation_authkey(id);
1053 if (IS_ERR(authkey)) {
1054 ret = PTR_ERR(authkey);
1055 goto error;
1056 }
1057
1058 key_put(current->request_key_auth);
1059 current->request_key_auth = authkey;
1060 ret = authkey->serial;
1061
1062error:
1063 return ret;
1064
1065} /* end keyctl_assume_authority() */
1066
1067/*****************************************************************************/
1068/*
970 * the key control system call 1069 * the key control system call
971 */ 1070 */
972asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, 1071asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
@@ -1038,6 +1137,13 @@ asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
1038 case KEYCTL_SET_REQKEY_KEYRING: 1137 case KEYCTL_SET_REQKEY_KEYRING:
1039 return keyctl_set_reqkey_keyring(arg2); 1138 return keyctl_set_reqkey_keyring(arg2);
1040 1139
1140 case KEYCTL_SET_TIMEOUT:
1141 return keyctl_set_timeout((key_serial_t) arg2,
1142 (unsigned) arg3);
1143
1144 case KEYCTL_ASSUME_AUTHORITY:
1145 return keyctl_assume_authority((key_serial_t) arg2);
1146
1041 default: 1147 default:
1042 return -EOPNOTSUPP; 1148 return -EOPNOTSUPP;
1043 } 1149 }
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 4e9fa8be44b8..d65a180f888d 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -48,7 +48,6 @@ static inline unsigned keyring_hash(const char *desc)
48 */ 48 */
49static int keyring_instantiate(struct key *keyring, 49static int keyring_instantiate(struct key *keyring,
50 const void *data, size_t datalen); 50 const void *data, size_t datalen);
51static int keyring_duplicate(struct key *keyring, const struct key *source);
52static int keyring_match(const struct key *keyring, const void *criterion); 51static int keyring_match(const struct key *keyring, const void *criterion);
53static void keyring_destroy(struct key *keyring); 52static void keyring_destroy(struct key *keyring);
54static void keyring_describe(const struct key *keyring, struct seq_file *m); 53static void keyring_describe(const struct key *keyring, struct seq_file *m);
@@ -59,7 +58,6 @@ struct key_type key_type_keyring = {
59 .name = "keyring", 58 .name = "keyring",
60 .def_datalen = sizeof(struct keyring_list), 59 .def_datalen = sizeof(struct keyring_list),
61 .instantiate = keyring_instantiate, 60 .instantiate = keyring_instantiate,
62 .duplicate = keyring_duplicate,
63 .match = keyring_match, 61 .match = keyring_match,
64 .destroy = keyring_destroy, 62 .destroy = keyring_destroy,
65 .describe = keyring_describe, 63 .describe = keyring_describe,
@@ -70,7 +68,7 @@ struct key_type key_type_keyring = {
70 * semaphore to serialise link/link calls to prevent two link calls in parallel 68 * semaphore to serialise link/link calls to prevent two link calls in parallel
71 * introducing a cycle 69 * introducing a cycle
72 */ 70 */
73DECLARE_RWSEM(keyring_serialise_link_sem); 71static DECLARE_RWSEM(keyring_serialise_link_sem);
74 72
75/*****************************************************************************/ 73/*****************************************************************************/
76/* 74/*
@@ -120,68 +118,6 @@ static int keyring_instantiate(struct key *keyring,
120 118
121/*****************************************************************************/ 119/*****************************************************************************/
122/* 120/*
123 * duplicate the list of subscribed keys from a source keyring into this one
124 */
125static int keyring_duplicate(struct key *keyring, const struct key *source)
126{
127 struct keyring_list *sklist, *klist;
128 unsigned max;
129 size_t size;
130 int loop, ret;
131
132 const unsigned limit =
133 (PAGE_SIZE - sizeof(*klist)) / sizeof(struct key *);
134
135 ret = 0;
136
137 /* find out how many keys are currently linked */
138 rcu_read_lock();
139 sklist = rcu_dereference(source->payload.subscriptions);
140 max = 0;
141 if (sklist)
142 max = sklist->nkeys;
143 rcu_read_unlock();
144
145 /* allocate a new payload and stuff load with key links */
146 if (max > 0) {
147 BUG_ON(max > limit);
148
149 max = (max + 3) & ~3;
150 if (max > limit)
151 max = limit;
152
153 ret = -ENOMEM;
154 size = sizeof(*klist) + sizeof(struct key *) * max;
155 klist = kmalloc(size, GFP_KERNEL);
156 if (!klist)
157 goto error;
158
159 /* set links */
160 rcu_read_lock();
161 sklist = rcu_dereference(source->payload.subscriptions);
162
163 klist->maxkeys = max;
164 klist->nkeys = sklist->nkeys;
165 memcpy(klist->keys,
166 sklist->keys,
167 sklist->nkeys * sizeof(struct key *));
168
169 for (loop = klist->nkeys - 1; loop >= 0; loop--)
170 atomic_inc(&klist->keys[loop]->usage);
171
172 rcu_read_unlock();
173
174 rcu_assign_pointer(keyring->payload.subscriptions, klist);
175 ret = 0;
176 }
177
178 error:
179 return ret;
180
181} /* end keyring_duplicate() */
182
183/*****************************************************************************/
184/*
185 * match keyrings on their name 121 * match keyrings on their name
186 */ 122 */
187static int keyring_match(const struct key *keyring, const void *description) 123static int keyring_match(const struct key *keyring, const void *description)
@@ -545,51 +481,6 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
545 481
546/*****************************************************************************/ 482/*****************************************************************************/
547/* 483/*
548 * search for an instantiation authorisation key matching a target key
549 * - the RCU read lock must be held by the caller
550 * - a target_id of zero specifies any valid token
551 */
552struct key *keyring_search_instkey(struct key *keyring,
553 key_serial_t target_id)
554{
555 struct request_key_auth *rka;
556 struct keyring_list *klist;
557 struct key *instkey;
558 int loop;
559
560 klist = rcu_dereference(keyring->payload.subscriptions);
561 if (klist) {
562 for (loop = 0; loop < klist->nkeys; loop++) {
563 instkey = klist->keys[loop];
564
565 if (instkey->type != &key_type_request_key_auth)
566 continue;
567
568 rka = instkey->payload.data;
569 if (target_id && rka->target_key->serial != target_id)
570 continue;
571
572 /* the auth key is revoked during instantiation */
573 if (!test_bit(KEY_FLAG_REVOKED, &instkey->flags))
574 goto found;
575
576 instkey = ERR_PTR(-EKEYREVOKED);
577 goto error;
578 }
579 }
580
581 instkey = ERR_PTR(-EACCES);
582 goto error;
583
584found:
585 atomic_inc(&instkey->usage);
586error:
587 return instkey;
588
589} /* end keyring_search_instkey() */
590
591/*****************************************************************************/
592/*
593 * find a keyring with the specified name 484 * find a keyring with the specified name
594 * - all named keyrings are searched 485 * - all named keyrings are searched
595 * - only find keyrings with search permission for the process 486 * - only find keyrings with search permission for the process
@@ -748,15 +639,31 @@ static void keyring_link_rcu_disposal(struct rcu_head *rcu)
748 639
749/*****************************************************************************/ 640/*****************************************************************************/
750/* 641/*
642 * dispose of a keyring list after the RCU grace period, freeing the unlinked
643 * key
644 */
645static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
646{
647 struct keyring_list *klist =
648 container_of(rcu, struct keyring_list, rcu);
649
650 key_put(klist->keys[klist->delkey]);
651 kfree(klist);
652
653} /* end keyring_unlink_rcu_disposal() */
654
655/*****************************************************************************/
656/*
751 * link a key into to a keyring 657 * link a key into to a keyring
752 * - must be called with the keyring's semaphore write-locked 658 * - must be called with the keyring's semaphore write-locked
659 * - discard already extant link to matching key if there is one
753 */ 660 */
754int __key_link(struct key *keyring, struct key *key) 661int __key_link(struct key *keyring, struct key *key)
755{ 662{
756 struct keyring_list *klist, *nklist; 663 struct keyring_list *klist, *nklist;
757 unsigned max; 664 unsigned max;
758 size_t size; 665 size_t size;
759 int ret; 666 int loop, ret;
760 667
761 ret = -EKEYREVOKED; 668 ret = -EKEYREVOKED;
762 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) 669 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
@@ -778,6 +685,48 @@ int __key_link(struct key *keyring, struct key *key)
778 goto error2; 685 goto error2;
779 } 686 }
780 687
688 /* see if there's a matching key we can displace */
689 klist = keyring->payload.subscriptions;
690
691 if (klist && klist->nkeys > 0) {
692 struct key_type *type = key->type;
693
694 for (loop = klist->nkeys - 1; loop >= 0; loop--) {
695 if (klist->keys[loop]->type == type &&
696 strcmp(klist->keys[loop]->description,
697 key->description) == 0
698 ) {
699 /* found a match - replace with new key */
700 size = sizeof(struct key *) * klist->maxkeys;
701 size += sizeof(*klist);
702 BUG_ON(size > PAGE_SIZE);
703
704 ret = -ENOMEM;
705 nklist = kmalloc(size, GFP_KERNEL);
706 if (!nklist)
707 goto error2;
708
709 memcpy(nklist, klist, size);
710
711 /* replace matched key */
712 atomic_inc(&key->usage);
713 nklist->keys[loop] = key;
714
715 rcu_assign_pointer(
716 keyring->payload.subscriptions,
717 nklist);
718
719 /* dispose of the old keyring list and the
720 * displaced key */
721 klist->delkey = loop;
722 call_rcu(&klist->rcu,
723 keyring_unlink_rcu_disposal);
724
725 goto done;
726 }
727 }
728 }
729
781 /* check that we aren't going to overrun the user's quota */ 730 /* check that we aren't going to overrun the user's quota */
782 ret = key_payload_reserve(keyring, 731 ret = key_payload_reserve(keyring,
783 keyring->datalen + KEYQUOTA_LINK_BYTES); 732 keyring->datalen + KEYQUOTA_LINK_BYTES);
@@ -794,8 +743,6 @@ int __key_link(struct key *keyring, struct key *key)
794 smp_wmb(); 743 smp_wmb();
795 klist->nkeys++; 744 klist->nkeys++;
796 smp_wmb(); 745 smp_wmb();
797
798 ret = 0;
799 } 746 }
800 else { 747 else {
801 /* grow the key list */ 748 /* grow the key list */
@@ -833,16 +780,16 @@ int __key_link(struct key *keyring, struct key *key)
833 /* dispose of the old keyring list */ 780 /* dispose of the old keyring list */
834 if (klist) 781 if (klist)
835 call_rcu(&klist->rcu, keyring_link_rcu_disposal); 782 call_rcu(&klist->rcu, keyring_link_rcu_disposal);
836
837 ret = 0;
838 } 783 }
839 784
840 error2: 785done:
786 ret = 0;
787error2:
841 up_write(&keyring_serialise_link_sem); 788 up_write(&keyring_serialise_link_sem);
842 error: 789error:
843 return ret; 790 return ret;
844 791
845 error3: 792error3:
846 /* undo the quota changes */ 793 /* undo the quota changes */
847 key_payload_reserve(keyring, 794 key_payload_reserve(keyring,
848 keyring->datalen - KEYQUOTA_LINK_BYTES); 795 keyring->datalen - KEYQUOTA_LINK_BYTES);
@@ -873,21 +820,6 @@ EXPORT_SYMBOL(key_link);
873 820
874/*****************************************************************************/ 821/*****************************************************************************/
875/* 822/*
876 * dispose of a keyring list after the RCU grace period, freeing the unlinked
877 * key
878 */
879static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
880{
881 struct keyring_list *klist =
882 container_of(rcu, struct keyring_list, rcu);
883
884 key_put(klist->keys[klist->delkey]);
885 kfree(klist);
886
887} /* end keyring_unlink_rcu_disposal() */
888
889/*****************************************************************************/
890/*
891 * unlink the first link to a key from a keyring 823 * unlink the first link to a key from a keyring
892 */ 824 */
893int key_unlink(struct key *keyring, struct key *key) 825int key_unlink(struct key *keyring, struct key *key)
diff --git a/security/keys/permission.c b/security/keys/permission.c
index e7f579c0eaf5..3b41f9b52537 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -73,3 +73,35 @@ use_these_perms:
73} /* end key_task_permission() */ 73} /* end key_task_permission() */
74 74
75EXPORT_SYMBOL(key_task_permission); 75EXPORT_SYMBOL(key_task_permission);
76
77/*****************************************************************************/
78/*
79 * validate a key
80 */
81int 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
107EXPORT_SYMBOL(key_validate);
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 566b1cc0118a..74cb79eb917e 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -270,9 +270,14 @@ int copy_thread_group_keys(struct task_struct *tsk)
270int copy_keys(unsigned long clone_flags, struct task_struct *tsk) 270int copy_keys(unsigned long clone_flags, struct task_struct *tsk)
271{ 271{
272 key_check(tsk->thread_keyring); 272 key_check(tsk->thread_keyring);
273 key_check(tsk->request_key_auth);
273 274
274 /* no thread keyring yet */ 275 /* no thread keyring yet */
275 tsk->thread_keyring = NULL; 276 tsk->thread_keyring = NULL;
277
278 /* copy the request_key() authorisation for this thread */
279 key_get(tsk->request_key_auth);
280
276 return 0; 281 return 0;
277 282
278} /* end copy_keys() */ 283} /* end copy_keys() */
@@ -290,11 +295,12 @@ void exit_thread_group_keys(struct signal_struct *tg)
290 295
291/*****************************************************************************/ 296/*****************************************************************************/
292/* 297/*
293 * dispose of keys upon thread exit 298 * dispose of per-thread keys upon thread exit
294 */ 299 */
295void exit_keys(struct task_struct *tsk) 300void exit_keys(struct task_struct *tsk)
296{ 301{
297 key_put(tsk->thread_keyring); 302 key_put(tsk->thread_keyring);
303 key_put(tsk->request_key_auth);
298 304
299} /* end exit_keys() */ 305} /* end exit_keys() */
300 306
@@ -382,7 +388,7 @@ key_ref_t search_process_keyrings(struct key_type *type,
382 struct task_struct *context) 388 struct task_struct *context)
383{ 389{
384 struct request_key_auth *rka; 390 struct request_key_auth *rka;
385 key_ref_t key_ref, ret, err, instkey_ref; 391 key_ref_t key_ref, ret, err;
386 392
387 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were 393 /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
388 * searchable, but we failed to find a key or we found a negative key; 394 * searchable, but we failed to find a key or we found a negative key;
@@ -461,30 +467,12 @@ key_ref_t search_process_keyrings(struct key_type *type,
461 err = key_ref; 467 err = key_ref;
462 break; 468 break;
463 } 469 }
464 470 }
465 /* if this process has a session keyring and that has an 471 /* or search the user-session keyring */
466 * instantiation authorisation key in the bottom level, then we 472 else {
467 * also search the keyrings of the process mentioned there */ 473 key_ref = keyring_search_aux(
468 if (context != current) 474 make_key_ref(context->user->session_keyring, 1),
469 goto no_key; 475 context, type, description, match);
470
471 rcu_read_lock();
472 instkey_ref = __keyring_search_one(
473 make_key_ref(rcu_dereference(
474 context->signal->session_keyring),
475 1),
476 &key_type_request_key_auth, NULL, 0);
477 rcu_read_unlock();
478
479 if (IS_ERR(instkey_ref))
480 goto no_key;
481
482 rka = key_ref_to_ptr(instkey_ref)->payload.data;
483
484 key_ref = search_process_keyrings(type, description, match,
485 rka->context);
486 key_ref_put(instkey_ref);
487
488 if (!IS_ERR(key_ref)) 476 if (!IS_ERR(key_ref))
489 goto found; 477 goto found;
490 478
@@ -500,11 +488,21 @@ key_ref_t search_process_keyrings(struct key_type *type,
500 break; 488 break;
501 } 489 }
502 } 490 }
503 /* or search the user-session keyring */ 491
504 else { 492 /* if this process has an instantiation authorisation key, then we also
505 key_ref = keyring_search_aux( 493 * search the keyrings of the process mentioned there
506 make_key_ref(context->user->session_keyring, 1), 494 * - we don't permit access to request_key auth keys via this method
507 context, type, description, match); 495 */
496 if (context->request_key_auth &&
497 context == current &&
498 type != &key_type_request_key_auth &&
499 key_validate(context->request_key_auth) == 0
500 ) {
501 rka = context->request_key_auth->payload.data;
502
503 key_ref = search_process_keyrings(type, description, match,
504 rka->context);
505
508 if (!IS_ERR(key_ref)) 506 if (!IS_ERR(key_ref))
509 goto found; 507 goto found;
510 508
@@ -521,8 +519,6 @@ key_ref_t search_process_keyrings(struct key_type *type,
521 } 519 }
522 } 520 }
523 521
524
525no_key:
526 /* no key - decide on the error we're going to go for */ 522 /* no key - decide on the error we're going to go for */
527 key_ref = ret ? ret : err; 523 key_ref = ret ? ret : err;
528 524
@@ -628,6 +624,15 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
628 key = ERR_PTR(-EINVAL); 624 key = ERR_PTR(-EINVAL);
629 goto error; 625 goto error;
630 626
627 case KEY_SPEC_REQKEY_AUTH_KEY:
628 key = context->request_key_auth;
629 if (!key)
630 goto error;
631
632 atomic_inc(&key->usage);
633 key_ref = make_key_ref(key, 1);
634 break;
635
631 default: 636 default:
632 key_ref = ERR_PTR(-EINVAL); 637 key_ref = ERR_PTR(-EINVAL);
633 if (id < 1) 638 if (id < 1)
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 5cc4bba70db6..f030a0ccbb93 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -29,28 +29,36 @@ DECLARE_WAIT_QUEUE_HEAD(request_key_conswq);
29/*****************************************************************************/ 29/*****************************************************************************/
30/* 30/*
31 * request userspace finish the construction of a key 31 * request userspace finish the construction of a key
32 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring> <info>" 32 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>"
33 */ 33 */
34static int call_request_key(struct key *key, 34static int call_sbin_request_key(struct key *key,
35 const char *op, 35 struct key *authkey,
36 const char *callout_info) 36 const char *op)
37{ 37{
38 struct task_struct *tsk = current; 38 struct task_struct *tsk = current;
39 key_serial_t prkey, sskey; 39 key_serial_t prkey, sskey;
40 struct key *session_keyring, *rkakey; 40 struct key *keyring;
41 char *argv[10], *envp[3], uid_str[12], gid_str[12]; 41 char *argv[9], *envp[3], uid_str[12], gid_str[12];
42 char key_str[12], keyring_str[3][12]; 42 char key_str[12], keyring_str[3][12];
43 char desc[20];
43 int ret, i; 44 int ret, i;
44 45
45 kenter("{%d},%s,%s", key->serial, op, callout_info); 46 kenter("{%d},{%d},%s", key->serial, authkey->serial, op);
46 47
47 /* generate a new session keyring with an auth key in it */ 48 /* allocate a new session keyring */
48 session_keyring = request_key_auth_new(key, &rkakey); 49 sprintf(desc, "_req.%u", key->serial);
49 if (IS_ERR(session_keyring)) { 50
50 ret = PTR_ERR(session_keyring); 51 keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL);
51 goto error; 52 if (IS_ERR(keyring)) {
53 ret = PTR_ERR(keyring);
54 goto error_alloc;
52 } 55 }
53 56
57 /* attach the auth key to the session keyring */
58 ret = __key_link(keyring, authkey);
59 if (ret < 0)
60 goto error_link;
61
54 /* record the UID and GID */ 62 /* record the UID and GID */
55 sprintf(uid_str, "%d", current->fsuid); 63 sprintf(uid_str, "%d", current->fsuid);
56 sprintf(gid_str, "%d", current->fsgid); 64 sprintf(gid_str, "%d", current->fsgid);
@@ -95,22 +103,19 @@ static int call_request_key(struct key *key,
95 argv[i++] = keyring_str[0]; 103 argv[i++] = keyring_str[0];
96 argv[i++] = keyring_str[1]; 104 argv[i++] = keyring_str[1];
97 argv[i++] = keyring_str[2]; 105 argv[i++] = keyring_str[2];
98 argv[i++] = (char *) callout_info;
99 argv[i] = NULL; 106 argv[i] = NULL;
100 107
101 /* do it */ 108 /* do it */
102 ret = call_usermodehelper_keys(argv[0], argv, envp, session_keyring, 1); 109 ret = call_usermodehelper_keys(argv[0], argv, envp, keyring, 1);
103 110
104 /* dispose of the special keys */ 111error_link:
105 key_revoke(rkakey); 112 key_put(keyring);
106 key_put(rkakey);
107 key_put(session_keyring);
108 113
109 error: 114error_alloc:
110 kleave(" = %d", ret); 115 kleave(" = %d", ret);
111 return ret; 116 return ret;
112 117
113} /* end call_request_key() */ 118} /* end call_sbin_request_key() */
114 119
115/*****************************************************************************/ 120/*****************************************************************************/
116/* 121/*
@@ -122,9 +127,10 @@ static struct key *__request_key_construction(struct key_type *type,
122 const char *description, 127 const char *description,
123 const char *callout_info) 128 const char *callout_info)
124{ 129{
130 request_key_actor_t actor;
125 struct key_construction cons; 131 struct key_construction cons;
126 struct timespec now; 132 struct timespec now;
127 struct key *key; 133 struct key *key, *authkey;
128 int ret, negated; 134 int ret, negated;
129 135
130 kenter("%s,%s,%s", type->name, description, callout_info); 136 kenter("%s,%s,%s", type->name, description, callout_info);
@@ -143,8 +149,19 @@ static struct key *__request_key_construction(struct key_type *type,
143 /* we drop the construction sem here on behalf of the caller */ 149 /* we drop the construction sem here on behalf of the caller */
144 up_write(&key_construction_sem); 150 up_write(&key_construction_sem);
145 151
152 /* allocate an authorisation key */
153 authkey = request_key_auth_new(key, callout_info);
154 if (IS_ERR(authkey)) {
155 ret = PTR_ERR(authkey);
156 authkey = NULL;
157 goto alloc_authkey_failed;
158 }
159
146 /* make the call */ 160 /* make the call */
147 ret = call_request_key(key, "create", callout_info); 161 actor = call_sbin_request_key;
162 if (type->request_key)
163 actor = type->request_key;
164 ret = actor(key, authkey, "create");
148 if (ret < 0) 165 if (ret < 0)
149 goto request_failed; 166 goto request_failed;
150 167
@@ -153,22 +170,29 @@ static struct key *__request_key_construction(struct key_type *type,
153 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) 170 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
154 goto request_failed; 171 goto request_failed;
155 172
173 key_revoke(authkey);
174 key_put(authkey);
175
156 down_write(&key_construction_sem); 176 down_write(&key_construction_sem);
157 list_del(&cons.link); 177 list_del(&cons.link);
158 up_write(&key_construction_sem); 178 up_write(&key_construction_sem);
159 179
160 /* also give an error if the key was negatively instantiated */ 180 /* also give an error if the key was negatively instantiated */
161 check_not_negative: 181check_not_negative:
162 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { 182 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
163 key_put(key); 183 key_put(key);
164 key = ERR_PTR(-ENOKEY); 184 key = ERR_PTR(-ENOKEY);
165 } 185 }
166 186
167 out: 187out:
168 kleave(" = %p", key); 188 kleave(" = %p", key);
169 return key; 189 return key;
170 190
171 request_failed: 191request_failed:
192 key_revoke(authkey);
193 key_put(authkey);
194
195alloc_authkey_failed:
172 /* it wasn't instantiated 196 /* it wasn't instantiated
173 * - remove from construction queue 197 * - remove from construction queue
174 * - mark the key as dead 198 * - mark the key as dead
@@ -217,7 +241,7 @@ static struct key *__request_key_construction(struct key_type *type,
217 key = ERR_PTR(ret); 241 key = ERR_PTR(ret);
218 goto out; 242 goto out;
219 243
220 alloc_failed: 244alloc_failed:
221 up_write(&key_construction_sem); 245 up_write(&key_construction_sem);
222 goto out; 246 goto out;
223 247
@@ -464,35 +488,3 @@ struct key *request_key(struct key_type *type,
464} /* end request_key() */ 488} /* end request_key() */
465 489
466EXPORT_SYMBOL(request_key); 490EXPORT_SYMBOL(request_key);
467
468/*****************************************************************************/
469/*
470 * validate a key
471 */
472int key_validate(struct key *key)
473{
474 struct timespec now;
475 int ret = 0;
476
477 if (key) {
478 /* check it's still accessible */
479 ret = -EKEYREVOKED;
480 if (test_bit(KEY_FLAG_REVOKED, &key->flags) ||
481 test_bit(KEY_FLAG_DEAD, &key->flags))
482 goto error;
483
484 /* check it hasn't expired */
485 ret = 0;
486 if (key->expiry) {
487 now = current_kernel_time();
488 if (now.tv_sec >= key->expiry)
489 ret = -EKEYEXPIRED;
490 }
491 }
492
493 error:
494 return ret;
495
496} /* end key_validate() */
497
498EXPORT_SYMBOL(key_validate);
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index a8e4069d48cb..cce6ba6b0323 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -15,11 +15,13 @@
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/seq_file.h> 17#include <linux/seq_file.h>
18#include <asm/uaccess.h>
18#include "internal.h" 19#include "internal.h"
19 20
20static int request_key_auth_instantiate(struct key *, const void *, size_t); 21static int request_key_auth_instantiate(struct key *, const void *, size_t);
21static void request_key_auth_describe(const struct key *, struct seq_file *); 22static void request_key_auth_describe(const struct key *, struct seq_file *);
22static void request_key_auth_destroy(struct key *); 23static void request_key_auth_destroy(struct key *);
24static long request_key_auth_read(const struct key *, char __user *, size_t);
23 25
24/* 26/*
25 * the request-key authorisation key type definition 27 * the request-key authorisation key type definition
@@ -30,51 +32,25 @@ struct key_type key_type_request_key_auth = {
30 .instantiate = request_key_auth_instantiate, 32 .instantiate = request_key_auth_instantiate,
31 .describe = request_key_auth_describe, 33 .describe = request_key_auth_describe,
32 .destroy = request_key_auth_destroy, 34 .destroy = request_key_auth_destroy,
35 .read = request_key_auth_read,
33}; 36};
34 37
35/*****************************************************************************/ 38/*****************************************************************************/
36/* 39/*
37 * instantiate a request-key authorisation record 40 * instantiate a request-key authorisation key
38 */ 41 */
39static int request_key_auth_instantiate(struct key *key, 42static int request_key_auth_instantiate(struct key *key,
40 const void *data, 43 const void *data,
41 size_t datalen) 44 size_t datalen)
42{ 45{
43 struct request_key_auth *rka, *irka; 46 key->payload.data = (struct request_key_auth *) data;
44 struct key *instkey; 47 return 0;
45 int ret;
46
47 ret = -ENOMEM;
48 rka = kmalloc(sizeof(*rka), GFP_KERNEL);
49 if (rka) {
50 /* see if the calling process is already servicing the key
51 * request of another process */
52 instkey = key_get_instantiation_authkey(0);
53 if (!IS_ERR(instkey)) {
54 /* it is - use that instantiation context here too */
55 irka = instkey->payload.data;
56 rka->context = irka->context;
57 rka->pid = irka->pid;
58 key_put(instkey);
59 }
60 else {
61 /* it isn't - use this process as the context */
62 rka->context = current;
63 rka->pid = current->pid;
64 }
65
66 rka->target_key = key_get((struct key *) data);
67 key->payload.data = rka;
68 ret = 0;
69 }
70
71 return ret;
72 48
73} /* end request_key_auth_instantiate() */ 49} /* end request_key_auth_instantiate() */
74 50
75/*****************************************************************************/ 51/*****************************************************************************/
76/* 52/*
77 * 53 * reading a request-key authorisation key retrieves the callout information
78 */ 54 */
79static void request_key_auth_describe(const struct key *key, 55static void request_key_auth_describe(const struct key *key,
80 struct seq_file *m) 56 struct seq_file *m)
@@ -83,12 +59,40 @@ static void request_key_auth_describe(const struct key *key,
83 59
84 seq_puts(m, "key:"); 60 seq_puts(m, "key:");
85 seq_puts(m, key->description); 61 seq_puts(m, key->description);
86 seq_printf(m, " pid:%d", rka->pid); 62 seq_printf(m, " pid:%d ci:%zu", rka->pid, strlen(rka->callout_info));
87 63
88} /* end request_key_auth_describe() */ 64} /* end request_key_auth_describe() */
89 65
90/*****************************************************************************/ 66/*****************************************************************************/
91/* 67/*
68 * read the callout_info data
69 * - the key's semaphore is read-locked
70 */
71static long request_key_auth_read(const struct key *key,
72 char __user *buffer, size_t buflen)
73{
74 struct request_key_auth *rka = key->payload.data;
75 size_t datalen;
76 long ret;
77
78 datalen = strlen(rka->callout_info);
79 ret = datalen;
80
81 /* we can return the data as is */
82 if (buffer && buflen > 0) {
83 if (buflen > datalen)
84 buflen = datalen;
85
86 if (copy_to_user(buffer, rka->callout_info, buflen) != 0)
87 ret = -EFAULT;
88 }
89
90 return ret;
91
92} /* end request_key_auth_read() */
93
94/*****************************************************************************/
95/*
92 * destroy an instantiation authorisation token key 96 * destroy an instantiation authorisation token key
93 */ 97 */
94static void request_key_auth_destroy(struct key *key) 98static void request_key_auth_destroy(struct key *key)
@@ -104,56 +108,89 @@ static void request_key_auth_destroy(struct key *key)
104 108
105/*****************************************************************************/ 109/*****************************************************************************/
106/* 110/*
107 * create a session keyring to be for the invokation of /sbin/request-key and 111 * create an authorisation token for /sbin/request-key or whoever to gain
108 * stick an authorisation token in it 112 * access to the caller's security data
109 */ 113 */
110struct key *request_key_auth_new(struct key *target, struct key **_rkakey) 114struct key *request_key_auth_new(struct key *target, const char *callout_info)
111{ 115{
112 struct key *keyring, *rkakey = NULL; 116 struct request_key_auth *rka, *irka;
117 struct key *authkey = NULL;
113 char desc[20]; 118 char desc[20];
114 int ret; 119 int ret;
115 120
116 kenter("%d,", target->serial); 121 kenter("%d,", target->serial);
117 122
118 /* allocate a new session keyring */ 123 /* allocate a auth record */
119 sprintf(desc, "_req.%u", target->serial); 124 rka = kmalloc(sizeof(*rka), GFP_KERNEL);
125 if (!rka) {
126 kleave(" = -ENOMEM");
127 return ERR_PTR(-ENOMEM);
128 }
120 129
121 keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL); 130 /* see if the calling process is already servicing the key request of
122 if (IS_ERR(keyring)) { 131 * another process */
123 kleave("= %ld", PTR_ERR(keyring)); 132 if (current->request_key_auth) {
124 return keyring; 133 /* it is - use that instantiation context here too */
134 irka = current->request_key_auth->payload.data;
135 rka->context = irka->context;
136 rka->pid = irka->pid;
125 } 137 }
138 else {
139 /* it isn't - use this process as the context */
140 rka->context = current;
141 rka->pid = current->pid;
142 }
143
144 rka->target_key = key_get(target);
145 rka->callout_info = callout_info;
126 146
127 /* allocate the auth key */ 147 /* allocate the auth key */
128 sprintf(desc, "%x", target->serial); 148 sprintf(desc, "%x", target->serial);
129 149
130 rkakey = key_alloc(&key_type_request_key_auth, desc, 150 authkey = key_alloc(&key_type_request_key_auth, desc,
131 current->fsuid, current->fsgid, 151 current->fsuid, current->fsgid,
132 KEY_POS_VIEW | KEY_USR_VIEW, 1); 152 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
133 if (IS_ERR(rkakey)) { 153 KEY_USR_VIEW, 1);
134 key_put(keyring); 154 if (IS_ERR(authkey)) {
135 kleave("= %ld", PTR_ERR(rkakey)); 155 ret = PTR_ERR(authkey);
136 return rkakey; 156 goto error_alloc;
137 } 157 }
138 158
139 /* construct and attach to the keyring */ 159 /* construct and attach to the keyring */
140 ret = key_instantiate_and_link(rkakey, target, 0, keyring, NULL); 160 ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL);
141 if (ret < 0) { 161 if (ret < 0)
142 key_revoke(rkakey); 162 goto error_inst;
143 key_put(rkakey);
144 key_put(keyring);
145 kleave("= %d", ret);
146 return ERR_PTR(ret);
147 }
148 163
149 *_rkakey = rkakey; 164 kleave(" = {%d})", authkey->serial);
150 kleave(" = {%d} ({%d})", keyring->serial, rkakey->serial); 165 return authkey;
151 return keyring; 166
167error_inst:
168 key_revoke(authkey);
169 key_put(authkey);
170error_alloc:
171 key_put(rka->target_key);
172 kfree(rka);
173 kleave("= %d", ret);
174 return ERR_PTR(ret);
152 175
153} /* end request_key_auth_new() */ 176} /* end request_key_auth_new() */
154 177
155/*****************************************************************************/ 178/*****************************************************************************/
156/* 179/*
180 * see if an authorisation key is associated with a particular key
181 */
182static int key_get_instantiation_authkey_match(const struct key *key,
183 const void *_id)
184{
185 struct request_key_auth *rka = key->payload.data;
186 key_serial_t id = (key_serial_t)(unsigned long) _id;
187
188 return rka->target_key->serial == id;
189
190} /* end key_get_instantiation_authkey_match() */
191
192/*****************************************************************************/
193/*
157 * get the authorisation key for instantiation of a specific key if attached to 194 * get the authorisation key for instantiation of a specific key if attached to
158 * the current process's keyrings 195 * the current process's keyrings
159 * - this key is inserted into a keyring and that is set as /sbin/request-key's 196 * - this key is inserted into a keyring and that is set as /sbin/request-key's
@@ -162,22 +199,27 @@ struct key *request_key_auth_new(struct key *target, struct key **_rkakey)
162 */ 199 */
163struct key *key_get_instantiation_authkey(key_serial_t target_id) 200struct key *key_get_instantiation_authkey(key_serial_t target_id)
164{ 201{
165 struct task_struct *tsk = current; 202 struct key *authkey;
166 struct key *instkey; 203 key_ref_t authkey_ref;
167 204
168 /* we must have our own personal session keyring */ 205 authkey_ref = search_process_keyrings(
169 if (!tsk->signal->session_keyring) 206 &key_type_request_key_auth,
170 return ERR_PTR(-EACCES); 207 (void *) (unsigned long) target_id,
171 208 key_get_instantiation_authkey_match,
172 /* and it must contain a suitable request authorisation key 209 current);
173 * - lock RCU against session keyring changing 210
174 */ 211 if (IS_ERR(authkey_ref)) {
175 rcu_read_lock(); 212 authkey = ERR_PTR(PTR_ERR(authkey_ref));
213 goto error;
214 }
176 215
177 instkey = keyring_search_instkey( 216 authkey = key_ref_to_ptr(authkey_ref);
178 rcu_dereference(tsk->signal->session_keyring), target_id); 217 if (test_bit(KEY_FLAG_REVOKED, &authkey->flags)) {
218 key_put(authkey);
219 authkey = ERR_PTR(-EKEYREVOKED);
220 }
179 221
180 rcu_read_unlock(); 222error:
181 return instkey; 223 return authkey;
182 224
183} /* end key_get_instantiation_authkey() */ 225} /* end key_get_instantiation_authkey() */
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index cbda3b2780a1..8e71895b97a7 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -26,7 +26,6 @@
26struct key_type key_type_user = { 26struct key_type key_type_user = {
27 .name = "user", 27 .name = "user",
28 .instantiate = user_instantiate, 28 .instantiate = user_instantiate,
29 .duplicate = user_duplicate,
30 .update = user_update, 29 .update = user_update,
31 .match = user_match, 30 .match = user_match,
32 .destroy = user_destroy, 31 .destroy = user_destroy,
@@ -68,42 +67,10 @@ error:
68 return ret; 67 return ret;
69 68
70} /* end user_instantiate() */ 69} /* end user_instantiate() */
71
72EXPORT_SYMBOL_GPL(user_instantiate); 70EXPORT_SYMBOL_GPL(user_instantiate);
73 71
74/*****************************************************************************/ 72/*****************************************************************************/
75/* 73/*
76 * duplicate a user defined key
77 * - both keys' semaphores are locked against further modification
78 * - the new key cannot yet be accessed
79 */
80int user_duplicate(struct key *key, const struct key *source)
81{
82 struct user_key_payload *upayload, *spayload;
83 int ret;
84
85 /* just copy the payload */
86 ret = -ENOMEM;
87 upayload = kmalloc(sizeof(*upayload) + source->datalen, GFP_KERNEL);
88 if (upayload) {
89 spayload = rcu_dereference(source->payload.data);
90 BUG_ON(source->datalen != spayload->datalen);
91
92 upayload->datalen = key->datalen = spayload->datalen;
93 memcpy(upayload->data, spayload->data, key->datalen);
94
95 key->payload.data = upayload;
96 ret = 0;
97 }
98
99 return ret;
100
101} /* end user_duplicate() */
102
103EXPORT_SYMBOL_GPL(user_duplicate);
104
105/*****************************************************************************/
106/*
107 * dispose of the old data from an updated user defined key 74 * dispose of the old data from an updated user defined key
108 */ 75 */
109static void user_update_rcu_disposal(struct rcu_head *rcu) 76static void user_update_rcu_disposal(struct rcu_head *rcu)
diff --git a/security/security.c b/security/security.c
index ed5fb80769c3..f693e1f66b98 100644
--- a/security/security.c
+++ b/security/security.c
@@ -11,6 +11,7 @@
11 * (at your option) any later version. 11 * (at your option) any later version.
12 */ 12 */
13 13
14#include <linux/capability.h>
14#include <linux/config.h> 15#include <linux/config.h>
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/init.h> 17#include <linux/init.h>
diff --git a/security/selinux/Makefile b/security/selinux/Makefile
index b038cd0fae2e..06d54d9d20a5 100644
--- a/security/selinux/Makefile
+++ b/security/selinux/Makefile
@@ -8,5 +8,7 @@ selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o
8 8
9selinux-$(CONFIG_SECURITY_NETWORK) += netif.o 9selinux-$(CONFIG_SECURITY_NETWORK) += netif.o
10 10
11selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o
12
11EXTRA_CFLAGS += -Isecurity/selinux/include 13EXTRA_CFLAGS += -Isecurity/selinux/include
12 14
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index fc774436a264..6647204e4636 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -73,6 +73,7 @@
73#include "avc.h" 73#include "avc.h"
74#include "objsec.h" 74#include "objsec.h"
75#include "netif.h" 75#include "netif.h"
76#include "xfrm.h"
76 77
77#define XATTR_SELINUX_SUFFIX "selinux" 78#define XATTR_SELINUX_SUFFIX "selinux"
78#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX 79#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
@@ -1662,7 +1663,7 @@ static inline void flush_unauthorized_files(struct files_struct * files)
1662 continue; 1663 continue;
1663 } 1664 }
1664 if (devnull) { 1665 if (devnull) {
1665 rcuref_inc(&devnull->f_count); 1666 get_file(devnull);
1666 } else { 1667 } else {
1667 devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR); 1668 devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR);
1668 if (!devnull) { 1669 if (!devnull) {
@@ -3349,6 +3350,10 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3349 err = avc_has_perm(sock_sid, port_sid, 3350 err = avc_has_perm(sock_sid, port_sid,
3350 sock_class, recv_perm, &ad); 3351 sock_class, recv_perm, &ad);
3351 } 3352 }
3353
3354 if (!err)
3355 err = selinux_xfrm_sock_rcv_skb(sock_sid, skb);
3356
3352out: 3357out:
3353 return err; 3358 return err;
3354} 3359}
@@ -3401,6 +3406,24 @@ static void selinux_sk_free_security(struct sock *sk)
3401 sk_free_security(sk); 3406 sk_free_security(sk);
3402} 3407}
3403 3408
3409static unsigned int selinux_sk_getsid_security(struct sock *sk, struct flowi *fl, u8 dir)
3410{
3411 struct inode_security_struct *isec;
3412 u32 sock_sid = SECINITSID_ANY_SOCKET;
3413
3414 if (!sk)
3415 return selinux_no_sk_sid(fl);
3416
3417 read_lock_bh(&sk->sk_callback_lock);
3418 isec = get_sock_isec(sk);
3419
3420 if (isec)
3421 sock_sid = isec->sid;
3422
3423 read_unlock_bh(&sk->sk_callback_lock);
3424 return sock_sid;
3425}
3426
3404static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) 3427static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
3405{ 3428{
3406 int err = 0; 3429 int err = 0;
@@ -3536,6 +3559,11 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
3536 send_perm, &ad) ? NF_DROP : NF_ACCEPT; 3559 send_perm, &ad) ? NF_DROP : NF_ACCEPT;
3537 } 3560 }
3538 3561
3562 if (err != NF_ACCEPT)
3563 goto out;
3564
3565 err = selinux_xfrm_postroute_last(isec->sid, skb);
3566
3539out: 3567out:
3540 return err; 3568 return err;
3541} 3569}
@@ -4380,6 +4408,16 @@ static struct security_operations selinux_ops = {
4380 .socket_getpeersec = selinux_socket_getpeersec, 4408 .socket_getpeersec = selinux_socket_getpeersec,
4381 .sk_alloc_security = selinux_sk_alloc_security, 4409 .sk_alloc_security = selinux_sk_alloc_security,
4382 .sk_free_security = selinux_sk_free_security, 4410 .sk_free_security = selinux_sk_free_security,
4411 .sk_getsid = selinux_sk_getsid_security,
4412#endif
4413
4414#ifdef CONFIG_SECURITY_NETWORK_XFRM
4415 .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc,
4416 .xfrm_policy_clone_security = selinux_xfrm_policy_clone,
4417 .xfrm_policy_free_security = selinux_xfrm_policy_free,
4418 .xfrm_state_alloc_security = selinux_xfrm_state_alloc,
4419 .xfrm_state_free_security = selinux_xfrm_state_free,
4420 .xfrm_policy_lookup = selinux_xfrm_policy_lookup,
4383#endif 4421#endif
4384}; 4422};
4385 4423
@@ -4491,6 +4529,7 @@ static int __init selinux_nf_ip_init(void)
4491 panic("SELinux: nf_register_hook for IPv6: error %d\n", err); 4529 panic("SELinux: nf_register_hook for IPv6: error %d\n", err);
4492 4530
4493#endif /* IPV6 */ 4531#endif /* IPV6 */
4532
4494out: 4533out:
4495 return err; 4534 return err;
4496} 4535}
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h
index 1deb59e1b762..591e98d9315a 100644
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -238,3 +238,4 @@
238 S_(SECCLASS_NSCD, NSCD__SHMEMHOST, "shmemhost") 238 S_(SECCLASS_NSCD, NSCD__SHMEMHOST, "shmemhost")
239 S_(SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, "sendto") 239 S_(SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, "sendto")
240 S_(SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, "recvfrom") 240 S_(SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, "recvfrom")
241 S_(SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, "setcontext")
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
index a78b5d59c9fc..d7f02edf3930 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -908,6 +908,7 @@
908 908
909#define ASSOCIATION__SENDTO 0x00000001UL 909#define ASSOCIATION__SENDTO 0x00000001UL
910#define ASSOCIATION__RECVFROM 0x00000002UL 910#define ASSOCIATION__RECVFROM 0x00000002UL
911#define ASSOCIATION__SETCONTEXT 0x00000004UL
911 912
912#define NETLINK_KOBJECT_UEVENT_SOCKET__IOCTL 0x00000001UL 913#define NETLINK_KOBJECT_UEVENT_SOCKET__IOCTL 0x00000001UL
913#define NETLINK_KOBJECT_UEVENT_SOCKET__READ 0x00000002UL 914#define NETLINK_KOBJECT_UEVENT_SOCKET__READ 0x00000002UL
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
new file mode 100644
index 000000000000..8e87996c6dd5
--- /dev/null
+++ b/security/selinux/include/xfrm.h
@@ -0,0 +1,54 @@
1/*
2 * SELinux support for the XFRM LSM hooks
3 *
4 * Author : Trent Jaeger, <jaegert@us.ibm.com>
5 */
6#ifndef _SELINUX_XFRM_H_
7#define _SELINUX_XFRM_H_
8
9int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx);
10int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new);
11void selinux_xfrm_policy_free(struct xfrm_policy *xp);
12int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx);
13void selinux_xfrm_state_free(struct xfrm_state *x);
14int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir);
15
16/*
17 * Extract the security blob from the sock (it's actually on the socket)
18 */
19static inline struct inode_security_struct *get_sock_isec(struct sock *sk)
20{
21 if (!sk->sk_socket)
22 return NULL;
23
24 return SOCK_INODE(sk->sk_socket)->i_security;
25}
26
27
28static inline u32 selinux_no_sk_sid(struct flowi *fl)
29{
30 /* NOTE: no sock occurs on ICMP reply, forwards, ... */
31 /* icmp_reply: authorize as kernel packet */
32 if (fl && fl->proto == IPPROTO_ICMP) {
33 return SECINITSID_KERNEL;
34 }
35
36 return SECINITSID_ANY_SOCKET;
37}
38
39#ifdef CONFIG_SECURITY_NETWORK_XFRM
40int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb);
41int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb);
42#else
43static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb)
44{
45 return 0;
46}
47
48static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb)
49{
50 return NF_ACCEPT;
51}
52#endif
53
54#endif /* _SELINUX_XFRM_H_ */
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 0e1352a555c8..b5fa02d17b1e 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -376,7 +376,7 @@ static ssize_t selinux_transaction_write(struct file *file, const char __user *b
376 char *data; 376 char *data;
377 ssize_t rv; 377 ssize_t rv;
378 378
379 if (ino >= sizeof(write_op)/sizeof(write_op[0]) || !write_op[ino]) 379 if (ino >= ARRAY_SIZE(write_op) || !write_op[ino])
380 return -EINVAL; 380 return -EINVAL;
381 381
382 data = simple_transaction_get(file, buf, size); 382 data = simple_transaction_get(file, buf, size);
@@ -889,7 +889,7 @@ static void sel_remove_bools(struct dentry *de)
889 spin_lock(&dcache_lock); 889 spin_lock(&dcache_lock);
890 node = de->d_subdirs.next; 890 node = de->d_subdirs.next;
891 while (node != &de->d_subdirs) { 891 while (node != &de->d_subdirs) {
892 struct dentry *d = list_entry(node, struct dentry, d_child); 892 struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
893 list_del_init(node); 893 list_del_init(node);
894 894
895 if (d->d_inode) { 895 if (d->d_inode) {
@@ -1161,7 +1161,7 @@ static int sel_make_avc_files(struct dentry *dir)
1161#endif 1161#endif
1162 }; 1162 };
1163 1163
1164 for (i = 0; i < sizeof (files) / sizeof (files[0]); i++) { 1164 for (i = 0; i < ARRAY_SIZE(files); i++) {
1165 struct inode *inode; 1165 struct inode *inode;
1166 struct dentry *dentry; 1166 struct dentry *dentry;
1167 1167
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index dde094feb20d..d049c7acbc8b 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -359,7 +359,7 @@ int avtab_read_item(void *fp, u32 vers, struct avtab *a,
359 return -1; 359 return -1;
360 } 360 }
361 361
362 for (i = 0; i < sizeof(spec_order)/sizeof(u16); i++) { 362 for (i = 0; i < ARRAY_SIZE(spec_order); i++) {
363 if (val & spec_order[i]) { 363 if (val & spec_order[i]) {
364 key.specified = spec_order[i] | enabled; 364 key.specified = spec_order[i] | enabled;
365 datum.data = le32_to_cpu(buf32[items++]); 365 datum.data = le32_to_cpu(buf32[items++]);
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 0ac311dc8371..0111990ba837 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -103,7 +103,7 @@ static struct policydb_compat_info *policydb_lookup_compat(int version)
103 int i; 103 int i;
104 struct policydb_compat_info *info = NULL; 104 struct policydb_compat_info *info = NULL;
105 105
106 for (i = 0; i < sizeof(policydb_compat)/sizeof(*info); i++) { 106 for (i = 0; i < ARRAY_SIZE(policydb_compat); i++) {
107 if (policydb_compat[i].version == version) { 107 if (policydb_compat[i].version == version) {
108 info = &policydb_compat[i]; 108 info = &policydb_compat[i];
109 break; 109 break;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 44eb4d74908d..8a764928ff4b 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1712,11 +1712,11 @@ int security_get_bools(int *len, char ***names, int **values)
1712 goto out; 1712 goto out;
1713 } 1713 }
1714 1714
1715 *names = (char**)kcalloc(*len, sizeof(char*), GFP_ATOMIC); 1715 *names = kcalloc(*len, sizeof(char*), GFP_ATOMIC);
1716 if (!*names) 1716 if (!*names)
1717 goto err; 1717 goto err;
1718 1718
1719 *values = (int*)kcalloc(*len, sizeof(int), GFP_ATOMIC); 1719 *values = kcalloc(*len, sizeof(int), GFP_ATOMIC);
1720 if (!*values) 1720 if (!*values)
1721 goto err; 1721 goto err;
1722 1722
@@ -1724,7 +1724,7 @@ int security_get_bools(int *len, char ***names, int **values)
1724 size_t name_len; 1724 size_t name_len;
1725 (*values)[i] = policydb.bool_val_to_struct[i]->state; 1725 (*values)[i] = policydb.bool_val_to_struct[i]->state;
1726 name_len = strlen(policydb.p_bool_val_to_name[i]) + 1; 1726 name_len = strlen(policydb.p_bool_val_to_name[i]) + 1;
1727 (*names)[i] = (char*)kmalloc(sizeof(char) * name_len, GFP_ATOMIC); 1727 (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC);
1728 if (!(*names)[i]) 1728 if (!(*names)[i])
1729 goto err; 1729 goto err;
1730 strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len); 1730 strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len);
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
new file mode 100644
index 000000000000..b2af7ca496c1
--- /dev/null
+++ b/security/selinux/xfrm.c
@@ -0,0 +1,305 @@
1/*
2 * NSA Security-Enhanced Linux (SELinux) security module
3 *
4 * This file contains the SELinux XFRM hook function implementations.
5 *
6 * Authors: Serge Hallyn <sergeh@us.ibm.com>
7 * Trent Jaeger <jaegert@us.ibm.com>
8 *
9 * Copyright (C) 2005 International Business Machines Corporation
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2,
13 * as published by the Free Software Foundation.
14 */
15
16/*
17 * USAGE:
18 * NOTES:
19 * 1. Make sure to enable the following options in your kernel config:
20 * CONFIG_SECURITY=y
21 * CONFIG_SECURITY_NETWORK=y
22 * CONFIG_SECURITY_NETWORK_XFRM=y
23 * CONFIG_SECURITY_SELINUX=m/y
24 * ISSUES:
25 * 1. Caching packets, so they are not dropped during negotiation
26 * 2. Emulating a reasonable SO_PEERSEC across machines
27 * 3. Testing addition of sk_policy's with security context via setsockopt
28 */
29#include <linux/config.h>
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/init.h>
33#include <linux/security.h>
34#include <linux/types.h>
35#include <linux/netfilter.h>
36#include <linux/netfilter_ipv4.h>
37#include <linux/netfilter_ipv6.h>
38#include <linux/ip.h>
39#include <linux/tcp.h>
40#include <linux/skbuff.h>
41#include <linux/xfrm.h>
42#include <net/xfrm.h>
43#include <net/checksum.h>
44#include <net/udp.h>
45#include <asm/semaphore.h>
46
47#include "avc.h"
48#include "objsec.h"
49#include "xfrm.h"
50
51
52/*
53 * Returns true if an LSM/SELinux context
54 */
55static inline int selinux_authorizable_ctx(struct xfrm_sec_ctx *ctx)
56{
57 return (ctx &&
58 (ctx->ctx_doi == XFRM_SC_DOI_LSM) &&
59 (ctx->ctx_alg == XFRM_SC_ALG_SELINUX));
60}
61
62/*
63 * Returns true if the xfrm contains a security blob for SELinux
64 */
65static inline int selinux_authorizable_xfrm(struct xfrm_state *x)
66{
67 return selinux_authorizable_ctx(x->security);
68}
69
70/*
71 * LSM hook implementation that authorizes that a socket can be used
72 * with the corresponding xfrm_sec_ctx and direction.
73 */
74int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir)
75{
76 int rc = 0;
77 u32 sel_sid = SECINITSID_UNLABELED;
78 struct xfrm_sec_ctx *ctx;
79
80 /* Context sid is either set to label or ANY_ASSOC */
81 if ((ctx = xp->security)) {
82 if (!selinux_authorizable_ctx(ctx))
83 return -EINVAL;
84
85 sel_sid = ctx->ctx_sid;
86 }
87
88 rc = avc_has_perm(sk_sid, sel_sid, SECCLASS_ASSOCIATION,
89 ((dir == FLOW_DIR_IN) ? ASSOCIATION__RECVFROM :
90 ((dir == FLOW_DIR_OUT) ? ASSOCIATION__SENDTO :
91 (ASSOCIATION__SENDTO | ASSOCIATION__RECVFROM))),
92 NULL);
93
94 return rc;
95}
96
97/*
98 * Security blob allocation for xfrm_policy and xfrm_state
99 * CTX does not have a meaningful value on input
100 */
101static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *uctx)
102{
103 int rc = 0;
104 struct task_security_struct *tsec = current->security;
105 struct xfrm_sec_ctx *ctx;
106
107 BUG_ON(!uctx);
108 BUG_ON(uctx->ctx_doi != XFRM_SC_ALG_SELINUX);
109
110 if (uctx->ctx_len >= PAGE_SIZE)
111 return -ENOMEM;
112
113 *ctxp = ctx = kmalloc(sizeof(*ctx) +
114 uctx->ctx_len,
115 GFP_KERNEL);
116
117 if (!ctx)
118 return -ENOMEM;
119
120 ctx->ctx_doi = uctx->ctx_doi;
121 ctx->ctx_len = uctx->ctx_len;
122 ctx->ctx_alg = uctx->ctx_alg;
123
124 memcpy(ctx->ctx_str,
125 uctx+1,
126 ctx->ctx_len);
127 rc = security_context_to_sid(ctx->ctx_str,
128 ctx->ctx_len,
129 &ctx->ctx_sid);
130
131 if (rc)
132 goto out;
133
134 /*
135 * Does the subject have permission to set security or permission to
136 * do the relabel?
137 * Must be permitted to relabel from default socket type (process type)
138 * to specified context
139 */
140 rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
141 SECCLASS_ASSOCIATION,
142 ASSOCIATION__SETCONTEXT, NULL);
143 if (rc)
144 goto out;
145
146 return rc;
147
148out:
149 *ctxp = NULL;
150 kfree(ctx);
151 return rc;
152}
153
154/*
155 * LSM hook implementation that allocs and transfers uctx spec to
156 * xfrm_policy.
157 */
158int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *uctx)
159{
160 int err;
161
162 BUG_ON(!xp);
163
164 err = selinux_xfrm_sec_ctx_alloc(&xp->security, uctx);
165 return err;
166}
167
168
169/*
170 * LSM hook implementation that copies security data structure from old to
171 * new for policy cloning.
172 */
173int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
174{
175 struct xfrm_sec_ctx *old_ctx, *new_ctx;
176
177 old_ctx = old->security;
178
179 if (old_ctx) {
180 new_ctx = new->security = kmalloc(sizeof(*new_ctx) +
181 old_ctx->ctx_len,
182 GFP_KERNEL);
183
184 if (!new_ctx)
185 return -ENOMEM;
186
187 memcpy(new_ctx, old_ctx, sizeof(*new_ctx));
188 memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len);
189 }
190 return 0;
191}
192
193/*
194 * LSM hook implementation that frees xfrm_policy security information.
195 */
196void selinux_xfrm_policy_free(struct xfrm_policy *xp)
197{
198 struct xfrm_sec_ctx *ctx = xp->security;
199 if (ctx)
200 kfree(ctx);
201}
202
203/*
204 * LSM hook implementation that allocs and transfers sec_ctx spec to
205 * xfrm_state.
206 */
207int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uctx)
208{
209 int err;
210
211 BUG_ON(!x);
212
213 err = selinux_xfrm_sec_ctx_alloc(&x->security, uctx);
214 return err;
215}
216
217/*
218 * LSM hook implementation that frees xfrm_state security information.
219 */
220void selinux_xfrm_state_free(struct xfrm_state *x)
221{
222 struct xfrm_sec_ctx *ctx = x->security;
223 if (ctx)
224 kfree(ctx);
225}
226
227/*
228 * LSM hook that controls access to unlabelled packets. If
229 * a xfrm_state is authorizable (defined by macro) then it was
230 * already authorized by the IPSec process. If not, then
231 * we need to check for unlabelled access since this may not have
232 * gone thru the IPSec process.
233 */
234int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb)
235{
236 int i, rc = 0;
237 struct sec_path *sp;
238
239 sp = skb->sp;
240
241 if (sp) {
242 /*
243 * __xfrm_policy_check does not approve unless xfrm_policy_ok
244 * says that spi's match for policy and the socket.
245 *
246 * Only need to verify the existence of an authorizable sp.
247 */
248 for (i = 0; i < sp->len; i++) {
249 struct xfrm_state *x = sp->x[i].xvec;
250
251 if (x && selinux_authorizable_xfrm(x))
252 goto accept;
253 }
254 }
255
256 /* check SELinux sock for unlabelled access */
257 rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION,
258 ASSOCIATION__RECVFROM, NULL);
259 if (rc)
260 goto drop;
261
262accept:
263 return 0;
264
265drop:
266 return rc;
267}
268
269/*
270 * POSTROUTE_LAST hook's XFRM processing:
271 * If we have no security association, then we need to determine
272 * whether the socket is allowed to send to an unlabelled destination.
273 * If we do have a authorizable security association, then it has already been
274 * checked in xfrm_policy_lookup hook.
275 */
276int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb)
277{
278 struct dst_entry *dst;
279 int rc = 0;
280
281 dst = skb->dst;
282
283 if (dst) {
284 struct dst_entry *dst_test;
285
286 for (dst_test = dst; dst_test != 0;
287 dst_test = dst_test->child) {
288 struct xfrm_state *x = dst_test->xfrm;
289
290 if (x && selinux_authorizable_xfrm(x))
291 goto accept;
292 }
293 }
294
295 rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION,
296 ASSOCIATION__SENDTO, NULL);
297 if (rc)
298 goto drop;
299
300accept:
301 return NF_ACCEPT;
302
303drop:
304 return NF_DROP;
305}