aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/integrity/ima/ima.h1
-rw-r--r--security/integrity/ima/ima_api.c21
-rw-r--r--security/integrity/ima/ima_init.c3
-rw-r--r--security/keys/big_key.c2
-rw-r--r--security/keys/key.c8
-rw-r--r--security/keys/keyring.c17
-rw-r--r--security/selinux/hooks.c177
-rw-r--r--security/selinux/include/xfrm.h8
-rw-r--r--security/selinux/ss/services.c42
-rw-r--r--security/selinux/xfrm.c62
10 files changed, 216 insertions, 125 deletions
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 9636e17c9f5d..0356e1d437ca 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -148,6 +148,7 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint,
148 int xattr_len, struct ima_template_entry **entry); 148 int xattr_len, struct ima_template_entry **entry);
149int ima_store_template(struct ima_template_entry *entry, int violation, 149int ima_store_template(struct ima_template_entry *entry, int violation,
150 struct inode *inode, const unsigned char *filename); 150 struct inode *inode, const unsigned char *filename);
151void ima_free_template_entry(struct ima_template_entry *entry);
151const char *ima_d_path(struct path *path, char **pathbuf); 152const char *ima_d_path(struct path *path, char **pathbuf);
152 153
153/* rbtree tree calls to lookup, insert, delete 154/* rbtree tree calls to lookup, insert, delete
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 80374842fe0b..c38bbce8c6a6 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -22,6 +22,19 @@
22#include "ima.h" 22#include "ima.h"
23 23
24/* 24/*
25 * ima_free_template_entry - free an existing template entry
26 */
27void ima_free_template_entry(struct ima_template_entry *entry)
28{
29 int i;
30
31 for (i = 0; i < entry->template_desc->num_fields; i++)
32 kfree(entry->template_data[i].data);
33
34 kfree(entry);
35}
36
37/*
25 * ima_alloc_init_template - create and initialize a new template entry 38 * ima_alloc_init_template - create and initialize a new template entry
26 */ 39 */
27int ima_alloc_init_template(struct integrity_iint_cache *iint, 40int ima_alloc_init_template(struct integrity_iint_cache *iint,
@@ -37,6 +50,7 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint,
37 if (!*entry) 50 if (!*entry)
38 return -ENOMEM; 51 return -ENOMEM;
39 52
53 (*entry)->template_desc = template_desc;
40 for (i = 0; i < template_desc->num_fields; i++) { 54 for (i = 0; i < template_desc->num_fields; i++) {
41 struct ima_template_field *field = template_desc->fields[i]; 55 struct ima_template_field *field = template_desc->fields[i];
42 u32 len; 56 u32 len;
@@ -51,10 +65,9 @@ int ima_alloc_init_template(struct integrity_iint_cache *iint,
51 (*entry)->template_data_len += sizeof(len); 65 (*entry)->template_data_len += sizeof(len);
52 (*entry)->template_data_len += len; 66 (*entry)->template_data_len += len;
53 } 67 }
54 (*entry)->template_desc = template_desc;
55 return 0; 68 return 0;
56out: 69out:
57 kfree(*entry); 70 ima_free_template_entry(*entry);
58 *entry = NULL; 71 *entry = NULL;
59 return result; 72 return result;
60} 73}
@@ -134,7 +147,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename,
134 } 147 }
135 result = ima_store_template(entry, violation, inode, filename); 148 result = ima_store_template(entry, violation, inode, filename);
136 if (result < 0) 149 if (result < 0)
137 kfree(entry); 150 ima_free_template_entry(entry);
138err_out: 151err_out:
139 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, 152 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
140 op, cause, result, 0); 153 op, cause, result, 0);
@@ -269,7 +282,7 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
269 if (!result || result == -EEXIST) 282 if (!result || result == -EEXIST)
270 iint->flags |= IMA_MEASURED; 283 iint->flags |= IMA_MEASURED;
271 if (result < 0) 284 if (result < 0)
272 kfree(entry); 285 ima_free_template_entry(entry);
273} 286}
274 287
275void ima_audit_measurement(struct integrity_iint_cache *iint, 288void ima_audit_measurement(struct integrity_iint_cache *iint,
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index 15f34bd40abe..37122768554a 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -63,7 +63,6 @@ static void __init ima_add_boot_aggregate(void)
63 result = ima_calc_boot_aggregate(&hash.hdr); 63 result = ima_calc_boot_aggregate(&hash.hdr);
64 if (result < 0) { 64 if (result < 0) {
65 audit_cause = "hashing_error"; 65 audit_cause = "hashing_error";
66 kfree(entry);
67 goto err_out; 66 goto err_out;
68 } 67 }
69 } 68 }
@@ -76,7 +75,7 @@ static void __init ima_add_boot_aggregate(void)
76 result = ima_store_template(entry, violation, NULL, 75 result = ima_store_template(entry, violation, NULL,
77 boot_aggregate_name); 76 boot_aggregate_name);
78 if (result < 0) 77 if (result < 0)
79 kfree(entry); 78 ima_free_template_entry(entry);
80 return; 79 return;
81err_out: 80err_out:
82 integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, boot_aggregate_name, op, 81 integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, boot_aggregate_name, op,
diff --git a/security/keys/big_key.c b/security/keys/big_key.c
index 7f44c3207a9b..8137b27d641d 100644
--- a/security/keys/big_key.c
+++ b/security/keys/big_key.c
@@ -70,7 +70,7 @@ int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
70 * 70 *
71 * TODO: Encrypt the stored data with a temporary key. 71 * TODO: Encrypt the stored data with a temporary key.
72 */ 72 */
73 file = shmem_file_setup("", datalen, 0); 73 file = shmem_kernel_file_setup("", datalen, 0);
74 if (IS_ERR(file)) { 74 if (IS_ERR(file)) {
75 ret = PTR_ERR(file); 75 ret = PTR_ERR(file);
76 goto err_quota; 76 goto err_quota;
diff --git a/security/keys/key.c b/security/keys/key.c
index 55d110f0aced..6e21c11e48bc 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -272,7 +272,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
272 } 272 }
273 273
274 /* allocate and initialise the key and its description */ 274 /* allocate and initialise the key and its description */
275 key = kmem_cache_alloc(key_jar, GFP_KERNEL); 275 key = kmem_cache_zalloc(key_jar, GFP_KERNEL);
276 if (!key) 276 if (!key)
277 goto no_memory_2; 277 goto no_memory_2;
278 278
@@ -293,18 +293,12 @@ struct key *key_alloc(struct key_type *type, const char *desc,
293 key->uid = uid; 293 key->uid = uid;
294 key->gid = gid; 294 key->gid = gid;
295 key->perm = perm; 295 key->perm = perm;
296 key->flags = 0;
297 key->expiry = 0;
298 key->payload.data = NULL;
299 key->security = NULL;
300 296
301 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) 297 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA))
302 key->flags |= 1 << KEY_FLAG_IN_QUOTA; 298 key->flags |= 1 << KEY_FLAG_IN_QUOTA;
303 if (flags & KEY_ALLOC_TRUSTED) 299 if (flags & KEY_ALLOC_TRUSTED)
304 key->flags |= 1 << KEY_FLAG_TRUSTED; 300 key->flags |= 1 << KEY_FLAG_TRUSTED;
305 301
306 memset(&key->type_data, 0, sizeof(key->type_data));
307
308#ifdef KEY_DEBUGGING 302#ifdef KEY_DEBUGGING
309 key->magic = KEY_DEBUG_MAGIC; 303 key->magic = KEY_DEBUG_MAGIC;
310#endif 304#endif
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 69f0cb7bab7e..d46cbc5e335e 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -160,7 +160,7 @@ static u64 mult_64x32_and_fold(u64 x, u32 y)
160static unsigned long hash_key_type_and_desc(const struct keyring_index_key *index_key) 160static unsigned long hash_key_type_and_desc(const struct keyring_index_key *index_key)
161{ 161{
162 const unsigned level_shift = ASSOC_ARRAY_LEVEL_STEP; 162 const unsigned level_shift = ASSOC_ARRAY_LEVEL_STEP;
163 const unsigned long level_mask = ASSOC_ARRAY_LEVEL_STEP_MASK; 163 const unsigned long fan_mask = ASSOC_ARRAY_FAN_MASK;
164 const char *description = index_key->description; 164 const char *description = index_key->description;
165 unsigned long hash, type; 165 unsigned long hash, type;
166 u32 piece; 166 u32 piece;
@@ -194,10 +194,10 @@ static unsigned long hash_key_type_and_desc(const struct keyring_index_key *inde
194 * ordinary keys by making sure the lowest level segment in the hash is 194 * ordinary keys by making sure the lowest level segment in the hash is
195 * zero for keyrings and non-zero otherwise. 195 * zero for keyrings and non-zero otherwise.
196 */ 196 */
197 if (index_key->type != &key_type_keyring && (hash & level_mask) == 0) 197 if (index_key->type != &key_type_keyring && (hash & fan_mask) == 0)
198 return hash | (hash >> (ASSOC_ARRAY_KEY_CHUNK_SIZE - level_shift)) | 1; 198 return hash | (hash >> (ASSOC_ARRAY_KEY_CHUNK_SIZE - level_shift)) | 1;
199 if (index_key->type == &key_type_keyring && (hash & level_mask) != 0) 199 if (index_key->type == &key_type_keyring && (hash & fan_mask) != 0)
200 return (hash + (hash << level_shift)) & ~level_mask; 200 return (hash + (hash << level_shift)) & ~fan_mask;
201 return hash; 201 return hash;
202} 202}
203 203
@@ -279,12 +279,11 @@ static bool keyring_compare_object(const void *object, const void *data)
279 * Compare the index keys of a pair of objects and determine the bit position 279 * Compare the index keys of a pair of objects and determine the bit position
280 * at which they differ - if they differ. 280 * at which they differ - if they differ.
281 */ 281 */
282static int keyring_diff_objects(const void *_a, const void *_b) 282static int keyring_diff_objects(const void *object, const void *data)
283{ 283{
284 const struct key *key_a = keyring_ptr_to_key(_a); 284 const struct key *key_a = keyring_ptr_to_key(object);
285 const struct key *key_b = keyring_ptr_to_key(_b);
286 const struct keyring_index_key *a = &key_a->index_key; 285 const struct keyring_index_key *a = &key_a->index_key;
287 const struct keyring_index_key *b = &key_b->index_key; 286 const struct keyring_index_key *b = data;
288 unsigned long seg_a, seg_b; 287 unsigned long seg_a, seg_b;
289 int level, i; 288 int level, i;
290 289
@@ -691,8 +690,8 @@ descend_to_node:
691 smp_read_barrier_depends(); 690 smp_read_barrier_depends();
692 ptr = ACCESS_ONCE(shortcut->next_node); 691 ptr = ACCESS_ONCE(shortcut->next_node);
693 BUG_ON(!assoc_array_ptr_is_node(ptr)); 692 BUG_ON(!assoc_array_ptr_is_node(ptr));
694 node = assoc_array_ptr_to_node(ptr);
695 } 693 }
694 node = assoc_array_ptr_to_node(ptr);
696 695
697begin_node: 696begin_node:
698 kdebug("begin_node"); 697 kdebug("begin_node");
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 794c3ca49eac..419491d8e7d2 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -53,6 +53,7 @@
53#include <net/ip.h> /* for local_port_range[] */ 53#include <net/ip.h> /* for local_port_range[] */
54#include <net/sock.h> 54#include <net/sock.h>
55#include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */ 55#include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */
56#include <net/inet_connection_sock.h>
56#include <net/net_namespace.h> 57#include <net/net_namespace.h>
57#include <net/netlabel.h> 58#include <net/netlabel.h>
58#include <linux/uaccess.h> 59#include <linux/uaccess.h>
@@ -95,10 +96,6 @@
95#include "audit.h" 96#include "audit.h"
96#include "avc_ss.h" 97#include "avc_ss.h"
97 98
98#define SB_TYPE_FMT "%s%s%s"
99#define SB_SUBTYPE(sb) (sb->s_subtype && sb->s_subtype[0])
100#define SB_TYPE_ARGS(sb) sb->s_type->name, SB_SUBTYPE(sb) ? "." : "", SB_SUBTYPE(sb) ? sb->s_subtype : ""
101
102extern struct security_operations *security_ops; 99extern struct security_operations *security_ops;
103 100
104/* SECMARK reference count */ 101/* SECMARK reference count */
@@ -413,8 +410,8 @@ static int sb_finish_set_opts(struct super_block *sb)
413 the first boot of the SELinux kernel before we have 410 the first boot of the SELinux kernel before we have
414 assigned xattr values to the filesystem. */ 411 assigned xattr values to the filesystem. */
415 if (!root_inode->i_op->getxattr) { 412 if (!root_inode->i_op->getxattr) {
416 printk(KERN_WARNING "SELinux: (dev %s, type "SB_TYPE_FMT") has no " 413 printk(KERN_WARNING "SELinux: (dev %s, type %s) has no "
417 "xattr support\n", sb->s_id, SB_TYPE_ARGS(sb)); 414 "xattr support\n", sb->s_id, sb->s_type->name);
418 rc = -EOPNOTSUPP; 415 rc = -EOPNOTSUPP;
419 goto out; 416 goto out;
420 } 417 }
@@ -422,22 +419,22 @@ static int sb_finish_set_opts(struct super_block *sb)
422 if (rc < 0 && rc != -ENODATA) { 419 if (rc < 0 && rc != -ENODATA) {
423 if (rc == -EOPNOTSUPP) 420 if (rc == -EOPNOTSUPP)
424 printk(KERN_WARNING "SELinux: (dev %s, type " 421 printk(KERN_WARNING "SELinux: (dev %s, type "
425 SB_TYPE_FMT") has no security xattr handler\n", 422 "%s) has no security xattr handler\n",
426 sb->s_id, SB_TYPE_ARGS(sb)); 423 sb->s_id, sb->s_type->name);
427 else 424 else
428 printk(KERN_WARNING "SELinux: (dev %s, type " 425 printk(KERN_WARNING "SELinux: (dev %s, type "
429 SB_TYPE_FMT") getxattr errno %d\n", sb->s_id, 426 "%s) getxattr errno %d\n", sb->s_id,
430 SB_TYPE_ARGS(sb), -rc); 427 sb->s_type->name, -rc);
431 goto out; 428 goto out;
432 } 429 }
433 } 430 }
434 431
435 if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) 432 if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
436 printk(KERN_ERR "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), unknown behavior\n", 433 printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n",
437 sb->s_id, SB_TYPE_ARGS(sb)); 434 sb->s_id, sb->s_type->name);
438 else 435 else
439 printk(KERN_DEBUG "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), %s\n", 436 printk(KERN_DEBUG "SELinux: initialized (dev %s, type %s), %s\n",
440 sb->s_id, SB_TYPE_ARGS(sb), 437 sb->s_id, sb->s_type->name,
441 labeling_behaviors[sbsec->behavior-1]); 438 labeling_behaviors[sbsec->behavior-1]);
442 439
443 sbsec->flags |= SE_SBINITIALIZED; 440 sbsec->flags |= SE_SBINITIALIZED;
@@ -600,6 +597,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
600 const struct cred *cred = current_cred(); 597 const struct cred *cred = current_cred();
601 int rc = 0, i; 598 int rc = 0, i;
602 struct superblock_security_struct *sbsec = sb->s_security; 599 struct superblock_security_struct *sbsec = sb->s_security;
600 const char *name = sb->s_type->name;
603 struct inode *inode = sbsec->sb->s_root->d_inode; 601 struct inode *inode = sbsec->sb->s_root->d_inode;
604 struct inode_security_struct *root_isec = inode->i_security; 602 struct inode_security_struct *root_isec = inode->i_security;
605 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; 603 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
@@ -658,8 +656,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
658 strlen(mount_options[i]), &sid); 656 strlen(mount_options[i]), &sid);
659 if (rc) { 657 if (rc) {
660 printk(KERN_WARNING "SELinux: security_context_to_sid" 658 printk(KERN_WARNING "SELinux: security_context_to_sid"
661 "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n", 659 "(%s) failed for (dev %s, type %s) errno=%d\n",
662 mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc); 660 mount_options[i], sb->s_id, name, rc);
663 goto out; 661 goto out;
664 } 662 }
665 switch (flags[i]) { 663 switch (flags[i]) {
@@ -806,8 +804,7 @@ out:
806out_double_mount: 804out_double_mount:
807 rc = -EINVAL; 805 rc = -EINVAL;
808 printk(KERN_WARNING "SELinux: mount invalid. Same superblock, different " 806 printk(KERN_WARNING "SELinux: mount invalid. Same superblock, different "
809 "security settings for (dev %s, type "SB_TYPE_FMT")\n", sb->s_id, 807 "security settings for (dev %s, type %s)\n", sb->s_id, name);
810 SB_TYPE_ARGS(sb));
811 goto out; 808 goto out;
812} 809}
813 810
@@ -2480,8 +2477,8 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
2480 rc = security_context_to_sid(mount_options[i], len, &sid); 2477 rc = security_context_to_sid(mount_options[i], len, &sid);
2481 if (rc) { 2478 if (rc) {
2482 printk(KERN_WARNING "SELinux: security_context_to_sid" 2479 printk(KERN_WARNING "SELinux: security_context_to_sid"
2483 "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n", 2480 "(%s) failed for (dev %s, type %s) errno=%d\n",
2484 mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc); 2481 mount_options[i], sb->s_id, sb->s_type->name, rc);
2485 goto out_free_opts; 2482 goto out_free_opts;
2486 } 2483 }
2487 rc = -EINVAL; 2484 rc = -EINVAL;
@@ -2519,8 +2516,8 @@ out_free_secdata:
2519 return rc; 2516 return rc;
2520out_bad_option: 2517out_bad_option:
2521 printk(KERN_WARNING "SELinux: unable to change security options " 2518 printk(KERN_WARNING "SELinux: unable to change security options "
2522 "during remount (dev %s, type "SB_TYPE_FMT")\n", sb->s_id, 2519 "during remount (dev %s, type=%s)\n", sb->s_id,
2523 SB_TYPE_ARGS(sb)); 2520 sb->s_type->name);
2524 goto out_free_opts; 2521 goto out_free_opts;
2525} 2522}
2526 2523
@@ -3828,7 +3825,7 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
3828 u32 nlbl_sid; 3825 u32 nlbl_sid;
3829 u32 nlbl_type; 3826 u32 nlbl_type;
3830 3827
3831 err = selinux_skb_xfrm_sid(skb, &xfrm_sid); 3828 err = selinux_xfrm_skb_sid(skb, &xfrm_sid);
3832 if (unlikely(err)) 3829 if (unlikely(err))
3833 return -EACCES; 3830 return -EACCES;
3834 err = selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid); 3831 err = selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
@@ -3846,6 +3843,30 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
3846 return 0; 3843 return 0;
3847} 3844}
3848 3845
3846/**
3847 * selinux_conn_sid - Determine the child socket label for a connection
3848 * @sk_sid: the parent socket's SID
3849 * @skb_sid: the packet's SID
3850 * @conn_sid: the resulting connection SID
3851 *
3852 * If @skb_sid is valid then the user:role:type information from @sk_sid is
3853 * combined with the MLS information from @skb_sid in order to create
3854 * @conn_sid. If @skb_sid is not valid then then @conn_sid is simply a copy
3855 * of @sk_sid. Returns zero on success, negative values on failure.
3856 *
3857 */
3858static int selinux_conn_sid(u32 sk_sid, u32 skb_sid, u32 *conn_sid)
3859{
3860 int err = 0;
3861
3862 if (skb_sid != SECSID_NULL)
3863 err = security_sid_mls_copy(sk_sid, skb_sid, conn_sid);
3864 else
3865 *conn_sid = sk_sid;
3866
3867 return err;
3868}
3869
3849/* socket security operations */ 3870/* socket security operations */
3850 3871
3851static int socket_sockcreate_sid(const struct task_security_struct *tsec, 3872static int socket_sockcreate_sid(const struct task_security_struct *tsec,
@@ -4452,7 +4473,7 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
4452 struct sk_security_struct *sksec = sk->sk_security; 4473 struct sk_security_struct *sksec = sk->sk_security;
4453 int err; 4474 int err;
4454 u16 family = sk->sk_family; 4475 u16 family = sk->sk_family;
4455 u32 newsid; 4476 u32 connsid;
4456 u32 peersid; 4477 u32 peersid;
4457 4478
4458 /* handle mapped IPv4 packets arriving via IPv6 sockets */ 4479 /* handle mapped IPv4 packets arriving via IPv6 sockets */
@@ -4462,16 +4483,11 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
4462 err = selinux_skb_peerlbl_sid(skb, family, &peersid); 4483 err = selinux_skb_peerlbl_sid(skb, family, &peersid);
4463 if (err) 4484 if (err)
4464 return err; 4485 return err;
4465 if (peersid == SECSID_NULL) { 4486 err = selinux_conn_sid(sksec->sid, peersid, &connsid);
4466 req->secid = sksec->sid; 4487 if (err)
4467 req->peer_secid = SECSID_NULL; 4488 return err;
4468 } else { 4489 req->secid = connsid;
4469 err = security_sid_mls_copy(sksec->sid, peersid, &newsid); 4490 req->peer_secid = peersid;
4470 if (err)
4471 return err;
4472 req->secid = newsid;
4473 req->peer_secid = peersid;
4474 }
4475 4491
4476 return selinux_netlbl_inet_conn_request(req, family); 4492 return selinux_netlbl_inet_conn_request(req, family);
4477} 4493}
@@ -4731,6 +4747,7 @@ static unsigned int selinux_ipv6_forward(const struct nf_hook_ops *ops,
4731static unsigned int selinux_ip_output(struct sk_buff *skb, 4747static unsigned int selinux_ip_output(struct sk_buff *skb,
4732 u16 family) 4748 u16 family)
4733{ 4749{
4750 struct sock *sk;
4734 u32 sid; 4751 u32 sid;
4735 4752
4736 if (!netlbl_enabled()) 4753 if (!netlbl_enabled())
@@ -4739,8 +4756,27 @@ static unsigned int selinux_ip_output(struct sk_buff *skb,
4739 /* we do this in the LOCAL_OUT path and not the POST_ROUTING path 4756 /* we do this in the LOCAL_OUT path and not the POST_ROUTING path
4740 * because we want to make sure we apply the necessary labeling 4757 * because we want to make sure we apply the necessary labeling
4741 * before IPsec is applied so we can leverage AH protection */ 4758 * before IPsec is applied so we can leverage AH protection */
4742 if (skb->sk) { 4759 sk = skb->sk;
4743 struct sk_security_struct *sksec = skb->sk->sk_security; 4760 if (sk) {
4761 struct sk_security_struct *sksec;
4762
4763 if (sk->sk_state == TCP_LISTEN)
4764 /* if the socket is the listening state then this
4765 * packet is a SYN-ACK packet which means it needs to
4766 * be labeled based on the connection/request_sock and
4767 * not the parent socket. unfortunately, we can't
4768 * lookup the request_sock yet as it isn't queued on
4769 * the parent socket until after the SYN-ACK is sent.
4770 * the "solution" is to simply pass the packet as-is
4771 * as any IP option based labeling should be copied
4772 * from the initial connection request (in the IP
4773 * layer). it is far from ideal, but until we get a
4774 * security label in the packet itself this is the
4775 * best we can do. */
4776 return NF_ACCEPT;
4777
4778 /* standard practice, label using the parent socket */
4779 sksec = sk->sk_security;
4744 sid = sksec->sid; 4780 sid = sksec->sid;
4745 } else 4781 } else
4746 sid = SECINITSID_KERNEL; 4782 sid = SECINITSID_KERNEL;
@@ -4810,27 +4846,36 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4810 * as fast and as clean as possible. */ 4846 * as fast and as clean as possible. */
4811 if (!selinux_policycap_netpeer) 4847 if (!selinux_policycap_netpeer)
4812 return selinux_ip_postroute_compat(skb, ifindex, family); 4848 return selinux_ip_postroute_compat(skb, ifindex, family);
4849
4850 secmark_active = selinux_secmark_enabled();
4851 peerlbl_active = selinux_peerlbl_enabled();
4852 if (!secmark_active && !peerlbl_active)
4853 return NF_ACCEPT;
4854
4855 sk = skb->sk;
4856
4813#ifdef CONFIG_XFRM 4857#ifdef CONFIG_XFRM
4814 /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec 4858 /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
4815 * packet transformation so allow the packet to pass without any checks 4859 * packet transformation so allow the packet to pass without any checks
4816 * since we'll have another chance to perform access control checks 4860 * since we'll have another chance to perform access control checks
4817 * when the packet is on it's final way out. 4861 * when the packet is on it's final way out.
4818 * NOTE: there appear to be some IPv6 multicast cases where skb->dst 4862 * NOTE: there appear to be some IPv6 multicast cases where skb->dst
4819 * is NULL, in this case go ahead and apply access control. */ 4863 * is NULL, in this case go ahead and apply access control.
4820 if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL) 4864 * NOTE: if this is a local socket (skb->sk != NULL) that is in the
4865 * TCP listening state we cannot wait until the XFRM processing
4866 * is done as we will miss out on the SA label if we do;
4867 * unfortunately, this means more work, but it is only once per
4868 * connection. */
4869 if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL &&
4870 !(sk != NULL && sk->sk_state == TCP_LISTEN))
4821 return NF_ACCEPT; 4871 return NF_ACCEPT;
4822#endif 4872#endif
4823 secmark_active = selinux_secmark_enabled();
4824 peerlbl_active = selinux_peerlbl_enabled();
4825 if (!secmark_active && !peerlbl_active)
4826 return NF_ACCEPT;
4827 4873
4828 /* if the packet is being forwarded then get the peer label from the
4829 * packet itself; otherwise check to see if it is from a local
4830 * application or the kernel, if from an application get the peer label
4831 * from the sending socket, otherwise use the kernel's sid */
4832 sk = skb->sk;
4833 if (sk == NULL) { 4874 if (sk == NULL) {
4875 /* Without an associated socket the packet is either coming
4876 * from the kernel or it is being forwarded; check the packet
4877 * to determine which and if the packet is being forwarded
4878 * query the packet directly to determine the security label. */
4834 if (skb->skb_iif) { 4879 if (skb->skb_iif) {
4835 secmark_perm = PACKET__FORWARD_OUT; 4880 secmark_perm = PACKET__FORWARD_OUT;
4836 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid)) 4881 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))
@@ -4839,7 +4884,45 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4839 secmark_perm = PACKET__SEND; 4884 secmark_perm = PACKET__SEND;
4840 peer_sid = SECINITSID_KERNEL; 4885 peer_sid = SECINITSID_KERNEL;
4841 } 4886 }
4887 } else if (sk->sk_state == TCP_LISTEN) {
4888 /* Locally generated packet but the associated socket is in the
4889 * listening state which means this is a SYN-ACK packet. In
4890 * this particular case the correct security label is assigned
4891 * to the connection/request_sock but unfortunately we can't
4892 * query the request_sock as it isn't queued on the parent
4893 * socket until after the SYN-ACK packet is sent; the only
4894 * viable choice is to regenerate the label like we do in
4895 * selinux_inet_conn_request(). See also selinux_ip_output()
4896 * for similar problems. */
4897 u32 skb_sid;
4898 struct sk_security_struct *sksec = sk->sk_security;
4899 if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
4900 return NF_DROP;
4901 /* At this point, if the returned skb peerlbl is SECSID_NULL
4902 * and the packet has been through at least one XFRM
4903 * transformation then we must be dealing with the "final"
4904 * form of labeled IPsec packet; since we've already applied
4905 * all of our access controls on this packet we can safely
4906 * pass the packet. */
4907 if (skb_sid == SECSID_NULL) {
4908 switch (family) {
4909 case PF_INET:
4910 if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
4911 return NF_ACCEPT;
4912 break;
4913 case PF_INET6:
4914 if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
4915 return NF_ACCEPT;
4916 default:
4917 return NF_DROP_ERR(-ECONNREFUSED);
4918 }
4919 }
4920 if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid))
4921 return NF_DROP;
4922 secmark_perm = PACKET__SEND;
4842 } else { 4923 } else {
4924 /* Locally generated packet, fetch the security label from the
4925 * associated socket. */
4843 struct sk_security_struct *sksec = sk->sk_security; 4926 struct sk_security_struct *sksec = sk->sk_security;
4844 peer_sid = sksec->sid; 4927 peer_sid = sksec->sid;
4845 secmark_perm = PACKET__SEND; 4928 secmark_perm = PACKET__SEND;
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index 0dec76c64cf5..48c3cc94c168 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -39,6 +39,7 @@ int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
39int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb, 39int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb,
40 struct common_audit_data *ad, u8 proto); 40 struct common_audit_data *ad, u8 proto);
41int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall); 41int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
42int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid);
42 43
43static inline void selinux_xfrm_notify_policyload(void) 44static inline void selinux_xfrm_notify_policyload(void)
44{ 45{
@@ -79,11 +80,12 @@ static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid,
79static inline void selinux_xfrm_notify_policyload(void) 80static inline void selinux_xfrm_notify_policyload(void)
80{ 81{
81} 82}
82#endif
83 83
84static inline int selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid) 84static inline int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
85{ 85{
86 return selinux_xfrm_decode_session(skb, sid, 0); 86 *sid = SECSID_NULL;
87 return 0;
87} 88}
89#endif
88 90
89#endif /* _SELINUX_XFRM_H_ */ 91#endif /* _SELINUX_XFRM_H_ */
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index ee470a0b5c27..d106733ad987 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2334,50 +2334,16 @@ int security_fs_use(struct super_block *sb)
2334 struct ocontext *c; 2334 struct ocontext *c;
2335 struct superblock_security_struct *sbsec = sb->s_security; 2335 struct superblock_security_struct *sbsec = sb->s_security;
2336 const char *fstype = sb->s_type->name; 2336 const char *fstype = sb->s_type->name;
2337 const char *subtype = (sb->s_subtype && sb->s_subtype[0]) ? sb->s_subtype : NULL;
2338 struct ocontext *base = NULL;
2339 2337
2340 read_lock(&policy_rwlock); 2338 read_lock(&policy_rwlock);
2341 2339
2342 for (c = policydb.ocontexts[OCON_FSUSE]; c; c = c->next) { 2340 c = policydb.ocontexts[OCON_FSUSE];
2343 char *sub; 2341 while (c) {
2344 int baselen; 2342 if (strcmp(fstype, c->u.name) == 0)
2345
2346 baselen = strlen(fstype);
2347
2348 /* if base does not match, this is not the one */
2349 if (strncmp(fstype, c->u.name, baselen))
2350 continue;
2351
2352 /* if there is no subtype, this is the one! */
2353 if (!subtype)
2354 break;
2355
2356 /* skip past the base in this entry */
2357 sub = c->u.name + baselen;
2358
2359 /* entry is only a base. save it. keep looking for subtype */
2360 if (sub[0] == '\0') {
2361 base = c;
2362 continue;
2363 }
2364
2365 /* entry is not followed by a subtype, so it is not a match */
2366 if (sub[0] != '.')
2367 continue;
2368
2369 /* whew, we found a subtype of this fstype */
2370 sub++; /* move past '.' */
2371
2372 /* exact match of fstype AND subtype */
2373 if (!strcmp(subtype, sub))
2374 break; 2343 break;
2344 c = c->next;
2375 } 2345 }
2376 2346
2377 /* in case we had found an fstype match but no subtype match */
2378 if (!c)
2379 c = base;
2380
2381 if (c) { 2347 if (c) {
2382 sbsec->behavior = c->v.behavior; 2348 sbsec->behavior = c->v.behavior;
2383 if (!c->sid[0]) { 2349 if (!c->sid[0]) {
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index a91d205ec0c6..0462cb3ff0a7 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -209,19 +209,26 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
209 NULL) ? 0 : 1); 209 NULL) ? 0 : 1);
210} 210}
211 211
212/* 212static u32 selinux_xfrm_skb_sid_egress(struct sk_buff *skb)
213 * LSM hook implementation that checks and/or returns the xfrm sid for the
214 * incoming packet.
215 */
216int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
217{ 213{
218 u32 sid_session = SECSID_NULL; 214 struct dst_entry *dst = skb_dst(skb);
219 struct sec_path *sp; 215 struct xfrm_state *x;
220 216
221 if (skb == NULL) 217 if (dst == NULL)
222 goto out; 218 return SECSID_NULL;
219 x = dst->xfrm;
220 if (x == NULL || !selinux_authorizable_xfrm(x))
221 return SECSID_NULL;
222
223 return x->security->ctx_sid;
224}
225
226static int selinux_xfrm_skb_sid_ingress(struct sk_buff *skb,
227 u32 *sid, int ckall)
228{
229 u32 sid_session = SECSID_NULL;
230 struct sec_path *sp = skb->sp;
223 231
224 sp = skb->sp;
225 if (sp) { 232 if (sp) {
226 int i; 233 int i;
227 234
@@ -248,6 +255,30 @@ out:
248} 255}
249 256
250/* 257/*
258 * LSM hook implementation that checks and/or returns the xfrm sid for the
259 * incoming packet.
260 */
261int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
262{
263 if (skb == NULL) {
264 *sid = SECSID_NULL;
265 return 0;
266 }
267 return selinux_xfrm_skb_sid_ingress(skb, sid, ckall);
268}
269
270int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
271{
272 int rc;
273
274 rc = selinux_xfrm_skb_sid_ingress(skb, sid, 0);
275 if (rc == 0 && *sid == SECSID_NULL)
276 *sid = selinux_xfrm_skb_sid_egress(skb);
277
278 return rc;
279}
280
281/*
251 * LSM hook implementation that allocs and transfers uctx spec to xfrm_policy. 282 * LSM hook implementation that allocs and transfers uctx spec to xfrm_policy.
252 */ 283 */
253int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, 284int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
@@ -327,19 +358,22 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
327 return rc; 358 return rc;
328 359
329 ctx = kmalloc(sizeof(*ctx) + str_len, GFP_ATOMIC); 360 ctx = kmalloc(sizeof(*ctx) + str_len, GFP_ATOMIC);
330 if (!ctx) 361 if (!ctx) {
331 return -ENOMEM; 362 rc = -ENOMEM;
363 goto out;
364 }
332 365
333 ctx->ctx_doi = XFRM_SC_DOI_LSM; 366 ctx->ctx_doi = XFRM_SC_DOI_LSM;
334 ctx->ctx_alg = XFRM_SC_ALG_SELINUX; 367 ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
335 ctx->ctx_sid = secid; 368 ctx->ctx_sid = secid;
336 ctx->ctx_len = str_len; 369 ctx->ctx_len = str_len;
337 memcpy(ctx->ctx_str, ctx_str, str_len); 370 memcpy(ctx->ctx_str, ctx_str, str_len);
338 kfree(ctx_str);
339 371
340 x->security = ctx; 372 x->security = ctx;
341 atomic_inc(&selinux_xfrm_refcount); 373 atomic_inc(&selinux_xfrm_refcount);
342 return 0; 374out:
375 kfree(ctx_str);
376 return rc;
343} 377}
344 378
345/* 379/*