aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/Kconfig29
-rw-r--r--security/selinux/exports.c22
-rw-r--r--security/selinux/hooks.c246
-rw-r--r--security/selinux/include/av_inherit.h1
-rw-r--r--security/selinux/include/av_perm_to_string.h3
-rw-r--r--security/selinux/include/av_permissions.h26
-rw-r--r--security/selinux/include/class_to_string.h2
-rw-r--r--security/selinux/include/flask.h2
-rw-r--r--security/selinux/include/xfrm.h4
-rw-r--r--security/selinux/selinuxfs.c66
-rw-r--r--security/selinux/xfrm.c51
11 files changed, 329 insertions, 123 deletions
diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
index f636f53ca544..814ddc42f1f4 100644
--- a/security/selinux/Kconfig
+++ b/security/selinux/Kconfig
@@ -1,6 +1,7 @@
1config SECURITY_SELINUX 1config SECURITY_SELINUX
2 bool "NSA SELinux Support" 2 bool "NSA SELinux Support"
3 depends on SECURITY_NETWORK && AUDIT && NET && INET 3 depends on SECURITY_NETWORK && AUDIT && NET && INET
4 select NETWORK_SECMARK
4 default n 5 default n
5 help 6 help
6 This selects NSA Security-Enhanced Linux (SELinux). 7 This selects NSA Security-Enhanced Linux (SELinux).
@@ -95,3 +96,31 @@ config SECURITY_SELINUX_CHECKREQPROT_VALUE
95 via /selinux/checkreqprot if authorized by policy. 96 via /selinux/checkreqprot if authorized by policy.
96 97
97 If you are unsure how to answer this question, answer 1. 98 If you are unsure how to answer this question, answer 1.
99
100config SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT
101 bool "NSA SELinux enable new secmark network controls by default"
102 depends on SECURITY_SELINUX
103 default n
104 help
105 This option determines whether the new secmark-based network
106 controls will be enabled by default. If not, the old internal
107 per-packet controls will be enabled by default, preserving
108 old behavior.
109
110 If you enable the new controls, you will need updated
111 SELinux userspace libraries, tools and policy. Typically,
112 your distribution will provide these and enable the new controls
113 in the kernel they also distribute.
114
115 Note that this option can be overriden at boot with the
116 selinux_compat_net parameter, and after boot via
117 /selinux/compat_net. See Documentation/kernel-parameters.txt
118 for details on this parameter.
119
120 If you enable the new network controls, you will likely
121 also require the SECMARK and CONNSECMARK targets, as
122 well as any conntrack helpers for protocols which you
123 wish to control.
124
125 If you are unsure what do do here, select N.
126
diff --git a/security/selinux/exports.c b/security/selinux/exports.c
index ae4c73eb3085..9d7737db5e51 100644
--- a/security/selinux/exports.c
+++ b/security/selinux/exports.c
@@ -72,3 +72,25 @@ void selinux_get_task_sid(struct task_struct *tsk, u32 *sid)
72 *sid = 0; 72 *sid = 0;
73} 73}
74 74
75int selinux_string_to_sid(char *str, u32 *sid)
76{
77 if (selinux_enabled)
78 return security_context_to_sid(str, strlen(str), sid);
79 else {
80 *sid = 0;
81 return 0;
82 }
83}
84EXPORT_SYMBOL_GPL(selinux_string_to_sid);
85
86int selinux_relabel_packet_permission(u32 sid)
87{
88 if (selinux_enabled) {
89 struct task_security_struct *tsec = current->security;
90
91 return avc_has_perm(tsec->sid, sid, SECCLASS_PACKET,
92 PACKET__RELABELTO, NULL);
93 }
94 return 0;
95}
96EXPORT_SYMBOL_GPL(selinux_relabel_packet_permission);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 90b4cdc0c948..54adc9d31e92 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -80,6 +80,7 @@
80 80
81extern unsigned int policydb_loaded_version; 81extern unsigned int policydb_loaded_version;
82extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm); 82extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
83extern int selinux_compat_net;
83 84
84#ifdef CONFIG_SECURITY_SELINUX_DEVELOP 85#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
85int selinux_enforcing = 0; 86int selinux_enforcing = 0;
@@ -696,6 +697,8 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc
696 return SECCLASS_PACKET_SOCKET; 697 return SECCLASS_PACKET_SOCKET;
697 case PF_KEY: 698 case PF_KEY:
698 return SECCLASS_KEY_SOCKET; 699 return SECCLASS_KEY_SOCKET;
700 case PF_APPLETALK:
701 return SECCLASS_APPLETALK_SOCKET;
699 } 702 }
700 703
701 return SECCLASS_SOCKET; 704 return SECCLASS_SOCKET;
@@ -3214,47 +3217,17 @@ static int selinux_socket_unix_may_send(struct socket *sock,
3214 return 0; 3217 return 0;
3215} 3218}
3216 3219
3217static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) 3220static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
3221 struct avc_audit_data *ad, u32 sock_sid, u16 sock_class,
3222 u16 family, char *addrp, int len)
3218{ 3223{
3219 u16 family; 3224 int err = 0;
3220 char *addrp;
3221 int len, err = 0;
3222 u32 netif_perm, node_perm, node_sid, if_sid, recv_perm = 0; 3225 u32 netif_perm, node_perm, node_sid, if_sid, recv_perm = 0;
3223 u32 sock_sid = 0;
3224 u16 sock_class = 0;
3225 struct socket *sock;
3226 struct net_device *dev;
3227 struct avc_audit_data ad;
3228
3229 family = sk->sk_family;
3230 if (family != PF_INET && family != PF_INET6)
3231 goto out;
3232
3233 /* Handle mapped IPv4 packets arriving via IPv6 sockets */
3234 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
3235 family = PF_INET;
3236
3237 read_lock_bh(&sk->sk_callback_lock);
3238 sock = sk->sk_socket;
3239 if (sock) {
3240 struct inode *inode;
3241 inode = SOCK_INODE(sock);
3242 if (inode) {
3243 struct inode_security_struct *isec;
3244 isec = inode->i_security;
3245 sock_sid = isec->sid;
3246 sock_class = isec->sclass;
3247 }
3248 }
3249 read_unlock_bh(&sk->sk_callback_lock);
3250 if (!sock_sid)
3251 goto out;
3252 3226
3253 dev = skb->dev; 3227 if (!skb->dev)
3254 if (!dev)
3255 goto out; 3228 goto out;
3256 3229
3257 err = sel_netif_sids(dev, &if_sid, NULL); 3230 err = sel_netif_sids(skb->dev, &if_sid, NULL);
3258 if (err) 3231 if (err)
3259 goto out; 3232 goto out;
3260 3233
@@ -3277,44 +3250,88 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3277 break; 3250 break;
3278 } 3251 }
3279 3252
3280 AVC_AUDIT_DATA_INIT(&ad, NET); 3253 err = avc_has_perm(sock_sid, if_sid, SECCLASS_NETIF, netif_perm, ad);
3281 ad.u.net.netif = dev->name;
3282 ad.u.net.family = family;
3283
3284 err = selinux_parse_skb(skb, &ad, &addrp, &len, 1);
3285 if (err)
3286 goto out;
3287
3288 err = avc_has_perm(sock_sid, if_sid, SECCLASS_NETIF, netif_perm, &ad);
3289 if (err) 3254 if (err)
3290 goto out; 3255 goto out;
3291 3256
3292 /* Fixme: this lookup is inefficient */
3293 err = security_node_sid(family, addrp, len, &node_sid); 3257 err = security_node_sid(family, addrp, len, &node_sid);
3294 if (err) 3258 if (err)
3295 goto out; 3259 goto out;
3296 3260
3297 err = avc_has_perm(sock_sid, node_sid, SECCLASS_NODE, node_perm, &ad); 3261 err = avc_has_perm(sock_sid, node_sid, SECCLASS_NODE, node_perm, ad);
3298 if (err) 3262 if (err)
3299 goto out; 3263 goto out;
3300 3264
3301 if (recv_perm) { 3265 if (recv_perm) {
3302 u32 port_sid; 3266 u32 port_sid;
3303 3267
3304 /* Fixme: make this more efficient */
3305 err = security_port_sid(sk->sk_family, sk->sk_type, 3268 err = security_port_sid(sk->sk_family, sk->sk_type,
3306 sk->sk_protocol, ntohs(ad.u.net.sport), 3269 sk->sk_protocol, ntohs(ad->u.net.sport),
3307 &port_sid); 3270 &port_sid);
3308 if (err) 3271 if (err)
3309 goto out; 3272 goto out;
3310 3273
3311 err = avc_has_perm(sock_sid, port_sid, 3274 err = avc_has_perm(sock_sid, port_sid,
3312 sock_class, recv_perm, &ad); 3275 sock_class, recv_perm, ad);
3313 } 3276 }
3314 3277
3315 if (!err) 3278out:
3316 err = selinux_xfrm_sock_rcv_skb(sock_sid, skb); 3279 return err;
3280}
3281
3282static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3283{
3284 u16 family;
3285 u16 sock_class = 0;
3286 char *addrp;
3287 int len, err = 0;
3288 u32 sock_sid = 0;
3289 struct socket *sock;
3290 struct avc_audit_data ad;
3291
3292 family = sk->sk_family;
3293 if (family != PF_INET && family != PF_INET6)
3294 goto out;
3295
3296 /* Handle mapped IPv4 packets arriving via IPv6 sockets */
3297 if (family == PF_INET6 && skb->protocol == ntohs(ETH_P_IP))
3298 family = PF_INET;
3299
3300 read_lock_bh(&sk->sk_callback_lock);
3301 sock = sk->sk_socket;
3302 if (sock) {
3303 struct inode *inode;
3304 inode = SOCK_INODE(sock);
3305 if (inode) {
3306 struct inode_security_struct *isec;
3307 isec = inode->i_security;
3308 sock_sid = isec->sid;
3309 sock_class = isec->sclass;
3310 }
3311 }
3312 read_unlock_bh(&sk->sk_callback_lock);
3313 if (!sock_sid)
3314 goto out;
3315
3316 AVC_AUDIT_DATA_INIT(&ad, NET);
3317 ad.u.net.netif = skb->dev ? skb->dev->name : "[unknown]";
3318 ad.u.net.family = family;
3319
3320 err = selinux_parse_skb(skb, &ad, &addrp, &len, 1);
3321 if (err)
3322 goto out;
3323
3324 if (selinux_compat_net)
3325 err = selinux_sock_rcv_skb_compat(sk, skb, &ad, sock_sid,
3326 sock_class, family,
3327 addrp, len);
3328 else
3329 err = avc_has_perm(sock_sid, skb->secmark, SECCLASS_PACKET,
3330 PACKET__RECV, &ad);
3331 if (err)
3332 goto out;
3317 3333
3334 err = selinux_xfrm_sock_rcv_skb(sock_sid, skb);
3318out: 3335out:
3319 return err; 3336 return err;
3320} 3337}
@@ -3454,42 +3471,18 @@ out:
3454 3471
3455#ifdef CONFIG_NETFILTER 3472#ifdef CONFIG_NETFILTER
3456 3473
3457static unsigned int selinux_ip_postroute_last(unsigned int hooknum, 3474static int selinux_ip_postroute_last_compat(struct sock *sk, struct net_device *dev,
3458 struct sk_buff **pskb, 3475 struct inode_security_struct *isec,
3459 const struct net_device *in, 3476 struct avc_audit_data *ad,
3460 const struct net_device *out, 3477 u16 family, char *addrp, int len)
3461 int (*okfn)(struct sk_buff *),
3462 u16 family)
3463{ 3478{
3464 char *addrp; 3479 int err;
3465 int len, err = NF_ACCEPT;
3466 u32 netif_perm, node_perm, node_sid, if_sid, send_perm = 0; 3480 u32 netif_perm, node_perm, node_sid, if_sid, send_perm = 0;
3467 struct sock *sk;
3468 struct socket *sock;
3469 struct inode *inode;
3470 struct sk_buff *skb = *pskb;
3471 struct inode_security_struct *isec;
3472 struct avc_audit_data ad;
3473 struct net_device *dev = (struct net_device *)out;
3474 3481
3475 sk = skb->sk;
3476 if (!sk)
3477 goto out;
3478
3479 sock = sk->sk_socket;
3480 if (!sock)
3481 goto out;
3482
3483 inode = SOCK_INODE(sock);
3484 if (!inode)
3485 goto out;
3486
3487 err = sel_netif_sids(dev, &if_sid, NULL); 3482 err = sel_netif_sids(dev, &if_sid, NULL);
3488 if (err) 3483 if (err)
3489 goto out; 3484 goto out;
3490 3485
3491 isec = inode->i_security;
3492
3493 switch (isec->sclass) { 3486 switch (isec->sclass) {
3494 case SECCLASS_UDP_SOCKET: 3487 case SECCLASS_UDP_SOCKET:
3495 netif_perm = NETIF__UDP_SEND; 3488 netif_perm = NETIF__UDP_SEND;
@@ -3509,55 +3502,88 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
3509 break; 3502 break;
3510 } 3503 }
3511 3504
3512 3505 err = avc_has_perm(isec->sid, if_sid, SECCLASS_NETIF, netif_perm, ad);
3513 AVC_AUDIT_DATA_INIT(&ad, NET); 3506 if (err)
3514 ad.u.net.netif = dev->name;
3515 ad.u.net.family = family;
3516
3517 err = selinux_parse_skb(skb, &ad, &addrp,
3518 &len, 0) ? NF_DROP : NF_ACCEPT;
3519 if (err != NF_ACCEPT)
3520 goto out;
3521
3522 err = avc_has_perm(isec->sid, if_sid, SECCLASS_NETIF,
3523 netif_perm, &ad) ? NF_DROP : NF_ACCEPT;
3524 if (err != NF_ACCEPT)
3525 goto out; 3507 goto out;
3526 3508
3527 /* Fixme: this lookup is inefficient */ 3509 err = security_node_sid(family, addrp, len, &node_sid);
3528 err = security_node_sid(family, addrp, len, 3510 if (err)
3529 &node_sid) ? NF_DROP : NF_ACCEPT;
3530 if (err != NF_ACCEPT)
3531 goto out; 3511 goto out;
3532 3512
3533 err = avc_has_perm(isec->sid, node_sid, SECCLASS_NODE, 3513 err = avc_has_perm(isec->sid, node_sid, SECCLASS_NODE, node_perm, ad);
3534 node_perm, &ad) ? NF_DROP : NF_ACCEPT; 3514 if (err)
3535 if (err != NF_ACCEPT)
3536 goto out; 3515 goto out;
3537 3516
3538 if (send_perm) { 3517 if (send_perm) {
3539 u32 port_sid; 3518 u32 port_sid;
3540 3519
3541 /* Fixme: make this more efficient */
3542 err = security_port_sid(sk->sk_family, 3520 err = security_port_sid(sk->sk_family,
3543 sk->sk_type, 3521 sk->sk_type,
3544 sk->sk_protocol, 3522 sk->sk_protocol,
3545 ntohs(ad.u.net.dport), 3523 ntohs(ad->u.net.dport),
3546 &port_sid) ? NF_DROP : NF_ACCEPT; 3524 &port_sid);
3547 if (err != NF_ACCEPT) 3525 if (err)
3548 goto out; 3526 goto out;
3549 3527
3550 err = avc_has_perm(isec->sid, port_sid, isec->sclass, 3528 err = avc_has_perm(isec->sid, port_sid, isec->sclass,
3551 send_perm, &ad) ? NF_DROP : NF_ACCEPT; 3529 send_perm, ad);
3552 } 3530 }
3531out:
3532 return err;
3533}
3534
3535static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
3536 struct sk_buff **pskb,
3537 const struct net_device *in,
3538 const struct net_device *out,
3539 int (*okfn)(struct sk_buff *),
3540 u16 family)
3541{
3542 char *addrp;
3543 int len, err = 0;
3544 struct sock *sk;
3545 struct socket *sock;
3546 struct inode *inode;
3547 struct sk_buff *skb = *pskb;
3548 struct inode_security_struct *isec;
3549 struct avc_audit_data ad;
3550 struct net_device *dev = (struct net_device *)out;
3553 3551
3554 if (err != NF_ACCEPT) 3552 sk = skb->sk;
3553 if (!sk)
3555 goto out; 3554 goto out;
3556 3555
3557 err = selinux_xfrm_postroute_last(isec->sid, skb); 3556 sock = sk->sk_socket;
3557 if (!sock)
3558 goto out;
3559
3560 inode = SOCK_INODE(sock);
3561 if (!inode)
3562 goto out;
3563
3564 isec = inode->i_security;
3565
3566 AVC_AUDIT_DATA_INIT(&ad, NET);
3567 ad.u.net.netif = dev->name;
3568 ad.u.net.family = family;
3569
3570 err = selinux_parse_skb(skb, &ad, &addrp, &len, 0);
3571 if (err)
3572 goto out;
3573
3574 if (selinux_compat_net)
3575 err = selinux_ip_postroute_last_compat(sk, dev, isec, &ad,
3576 family, addrp, len);
3577 else
3578 err = avc_has_perm(isec->sid, skb->secmark, SECCLASS_PACKET,
3579 PACKET__SEND, &ad);
3558 3580
3581 if (err)
3582 goto out;
3583
3584 err = selinux_xfrm_postroute_last(isec->sid, skb);
3559out: 3585out:
3560 return err; 3586 return err ? NF_DROP : NF_ACCEPT;
3561} 3587}
3562 3588
3563static unsigned int selinux_ipv4_postroute_last(unsigned int hooknum, 3589static unsigned int selinux_ipv4_postroute_last(unsigned int hooknum,
@@ -4374,8 +4400,10 @@ static struct security_operations selinux_ops = {
4374 .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, 4400 .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc,
4375 .xfrm_policy_clone_security = selinux_xfrm_policy_clone, 4401 .xfrm_policy_clone_security = selinux_xfrm_policy_clone,
4376 .xfrm_policy_free_security = selinux_xfrm_policy_free, 4402 .xfrm_policy_free_security = selinux_xfrm_policy_free,
4403 .xfrm_policy_delete_security = selinux_xfrm_policy_delete,
4377 .xfrm_state_alloc_security = selinux_xfrm_state_alloc, 4404 .xfrm_state_alloc_security = selinux_xfrm_state_alloc,
4378 .xfrm_state_free_security = selinux_xfrm_state_free, 4405 .xfrm_state_free_security = selinux_xfrm_state_free,
4406 .xfrm_state_delete_security = selinux_xfrm_state_delete,
4379 .xfrm_policy_lookup = selinux_xfrm_policy_lookup, 4407 .xfrm_policy_lookup = selinux_xfrm_policy_lookup,
4380#endif 4408#endif
4381}; 4409};
diff --git a/security/selinux/include/av_inherit.h b/security/selinux/include/av_inherit.h
index b0e6b12931c9..a68fdd55597f 100644
--- a/security/selinux/include/av_inherit.h
+++ b/security/selinux/include/av_inherit.h
@@ -29,3 +29,4 @@
29 S_(SECCLASS_NETLINK_IP6FW_SOCKET, socket, 0x00400000UL) 29 S_(SECCLASS_NETLINK_IP6FW_SOCKET, socket, 0x00400000UL)
30 S_(SECCLASS_NETLINK_DNRT_SOCKET, socket, 0x00400000UL) 30 S_(SECCLASS_NETLINK_DNRT_SOCKET, socket, 0x00400000UL)
31 S_(SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET, socket, 0x00400000UL) 31 S_(SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET, socket, 0x00400000UL)
32 S_(SECCLASS_APPLETALK_SOCKET, socket, 0x00400000UL)
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h
index 591e98d9315a..70ee65a58817 100644
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -239,3 +239,6 @@
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") 241 S_(SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, "setcontext")
242 S_(SECCLASS_PACKET, PACKET__SEND, "send")
243 S_(SECCLASS_PACKET, PACKET__RECV, "recv")
244 S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto")
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
index d7f02edf3930..1d9cf3d306bc 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -933,3 +933,29 @@
933#define NETLINK_KOBJECT_UEVENT_SOCKET__SEND_MSG 0x00100000UL 933#define NETLINK_KOBJECT_UEVENT_SOCKET__SEND_MSG 0x00100000UL
934#define NETLINK_KOBJECT_UEVENT_SOCKET__NAME_BIND 0x00200000UL 934#define NETLINK_KOBJECT_UEVENT_SOCKET__NAME_BIND 0x00200000UL
935 935
936#define APPLETALK_SOCKET__IOCTL 0x00000001UL
937#define APPLETALK_SOCKET__READ 0x00000002UL
938#define APPLETALK_SOCKET__WRITE 0x00000004UL
939#define APPLETALK_SOCKET__CREATE 0x00000008UL
940#define APPLETALK_SOCKET__GETATTR 0x00000010UL
941#define APPLETALK_SOCKET__SETATTR 0x00000020UL
942#define APPLETALK_SOCKET__LOCK 0x00000040UL
943#define APPLETALK_SOCKET__RELABELFROM 0x00000080UL
944#define APPLETALK_SOCKET__RELABELTO 0x00000100UL
945#define APPLETALK_SOCKET__APPEND 0x00000200UL
946#define APPLETALK_SOCKET__BIND 0x00000400UL
947#define APPLETALK_SOCKET__CONNECT 0x00000800UL
948#define APPLETALK_SOCKET__LISTEN 0x00001000UL
949#define APPLETALK_SOCKET__ACCEPT 0x00002000UL
950#define APPLETALK_SOCKET__GETOPT 0x00004000UL
951#define APPLETALK_SOCKET__SETOPT 0x00008000UL
952#define APPLETALK_SOCKET__SHUTDOWN 0x00010000UL
953#define APPLETALK_SOCKET__RECVFROM 0x00020000UL
954#define APPLETALK_SOCKET__SENDTO 0x00040000UL
955#define APPLETALK_SOCKET__RECV_MSG 0x00080000UL
956#define APPLETALK_SOCKET__SEND_MSG 0x00100000UL
957#define APPLETALK_SOCKET__NAME_BIND 0x00200000UL
958
959#define PACKET__SEND 0x00000001UL
960#define PACKET__RECV 0x00000002UL
961#define PACKET__RELABELTO 0x00000004UL
diff --git a/security/selinux/include/class_to_string.h b/security/selinux/include/class_to_string.h
index 77b2c5996f35..3aec75fee4f7 100644
--- a/security/selinux/include/class_to_string.h
+++ b/security/selinux/include/class_to_string.h
@@ -58,3 +58,5 @@
58 S_("nscd") 58 S_("nscd")
59 S_("association") 59 S_("association")
60 S_("netlink_kobject_uevent_socket") 60 S_("netlink_kobject_uevent_socket")
61 S_("appletalk_socket")
62 S_("packet")
diff --git a/security/selinux/include/flask.h b/security/selinux/include/flask.h
index eb9f50823f6e..a0eb9e281d18 100644
--- a/security/selinux/include/flask.h
+++ b/security/selinux/include/flask.h
@@ -60,6 +60,8 @@
60#define SECCLASS_NSCD 53 60#define SECCLASS_NSCD 53
61#define SECCLASS_ASSOCIATION 54 61#define SECCLASS_ASSOCIATION 54
62#define SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET 55 62#define SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET 55
63#define SECCLASS_APPLETALK_SOCKET 56
64#define SECCLASS_PACKET 57
63 65
64/* 66/*
65 * Security identifier indices for initial entities 67 * Security identifier indices for initial entities
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index c10f1fc41502..c96498a10eb8 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -9,8 +9,10 @@
9int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx); 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); 10int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new);
11void selinux_xfrm_policy_free(struct xfrm_policy *xp); 11void selinux_xfrm_policy_free(struct xfrm_policy *xp);
12int selinux_xfrm_policy_delete(struct xfrm_policy *xp);
12int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx); 13int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx);
13void selinux_xfrm_state_free(struct xfrm_state *x); 14void selinux_xfrm_state_free(struct xfrm_state *x);
15int selinux_xfrm_state_delete(struct xfrm_state *x);
14int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir); 16int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir);
15 17
16/* 18/*
@@ -49,7 +51,7 @@ static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb)
49 51
50static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb) 52static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb)
51{ 53{
52 return NF_ACCEPT; 54 return 0;
53} 55}
54 56
55static inline int selinux_socket_getpeer_stream(struct sock *sk) 57static inline int selinux_socket_getpeer_stream(struct sock *sk)
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index a4efc966f065..2e73d3279f2d 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -38,6 +38,14 @@
38 38
39unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; 39unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
40 40
41#ifdef CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT
42#define SELINUX_COMPAT_NET_VALUE 0
43#else
44#define SELINUX_COMPAT_NET_VALUE 1
45#endif
46
47int selinux_compat_net = SELINUX_COMPAT_NET_VALUE;
48
41static int __init checkreqprot_setup(char *str) 49static int __init checkreqprot_setup(char *str)
42{ 50{
43 selinux_checkreqprot = simple_strtoul(str,NULL,0) ? 1 : 0; 51 selinux_checkreqprot = simple_strtoul(str,NULL,0) ? 1 : 0;
@@ -45,6 +53,13 @@ static int __init checkreqprot_setup(char *str)
45} 53}
46__setup("checkreqprot=", checkreqprot_setup); 54__setup("checkreqprot=", checkreqprot_setup);
47 55
56static int __init selinux_compat_net_setup(char *str)
57{
58 selinux_compat_net = simple_strtoul(str,NULL,0) ? 1 : 0;
59 return 1;
60}
61__setup("selinux_compat_net=", selinux_compat_net_setup);
62
48 63
49static DEFINE_MUTEX(sel_mutex); 64static DEFINE_MUTEX(sel_mutex);
50 65
@@ -85,6 +100,7 @@ enum sel_inos {
85 SEL_AVC, /* AVC management directory */ 100 SEL_AVC, /* AVC management directory */
86 SEL_MEMBER, /* compute polyinstantiation membership decision */ 101 SEL_MEMBER, /* compute polyinstantiation membership decision */
87 SEL_CHECKREQPROT, /* check requested protection, not kernel-applied one */ 102 SEL_CHECKREQPROT, /* check requested protection, not kernel-applied one */
103 SEL_COMPAT_NET, /* whether to use old compat network packet controls */
88}; 104};
89 105
90#define TMPBUFLEN 12 106#define TMPBUFLEN 12
@@ -364,6 +380,55 @@ static struct file_operations sel_checkreqprot_ops = {
364 .write = sel_write_checkreqprot, 380 .write = sel_write_checkreqprot,
365}; 381};
366 382
383static ssize_t sel_read_compat_net(struct file *filp, char __user *buf,
384 size_t count, loff_t *ppos)
385{
386 char tmpbuf[TMPBUFLEN];
387 ssize_t length;
388
389 length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_compat_net);
390 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
391}
392
393static ssize_t sel_write_compat_net(struct file * file, const char __user * buf,
394 size_t count, loff_t *ppos)
395{
396 char *page;
397 ssize_t length;
398 int new_value;
399
400 length = task_has_security(current, SECURITY__LOAD_POLICY);
401 if (length)
402 return length;
403
404 if (count >= PAGE_SIZE)
405 return -ENOMEM;
406 if (*ppos != 0) {
407 /* No partial writes. */
408 return -EINVAL;
409 }
410 page = (char*)get_zeroed_page(GFP_KERNEL);
411 if (!page)
412 return -ENOMEM;
413 length = -EFAULT;
414 if (copy_from_user(page, buf, count))
415 goto out;
416
417 length = -EINVAL;
418 if (sscanf(page, "%d", &new_value) != 1)
419 goto out;
420
421 selinux_compat_net = new_value ? 1 : 0;
422 length = count;
423out:
424 free_page((unsigned long) page);
425 return length;
426}
427static struct file_operations sel_compat_net_ops = {
428 .read = sel_read_compat_net,
429 .write = sel_write_compat_net,
430};
431
367/* 432/*
368 * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c 433 * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c
369 */ 434 */
@@ -1219,6 +1284,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
1219 [SEL_DISABLE] = {"disable", &sel_disable_ops, S_IWUSR}, 1284 [SEL_DISABLE] = {"disable", &sel_disable_ops, S_IWUSR},
1220 [SEL_MEMBER] = {"member", &transaction_ops, S_IRUGO|S_IWUGO}, 1285 [SEL_MEMBER] = {"member", &transaction_ops, S_IRUGO|S_IWUGO},
1221 [SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR}, 1286 [SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR},
1287 [SEL_COMPAT_NET] = {"compat_net", &sel_compat_net_ops, S_IRUGO|S_IWUSR},
1222 /* last one */ {""} 1288 /* last one */ {""}
1223 }; 1289 };
1224 ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files); 1290 ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index abe99d881376..6633fb059313 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -132,10 +132,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_us
132 goto out; 132 goto out;
133 133
134 /* 134 /*
135 * Does the subject have permission to set security or permission to 135 * Does the subject have permission to set security context?
136 * do the relabel?
137 * Must be permitted to relabel from default socket type (process type)
138 * to specified context
139 */ 136 */
140 rc = avc_has_perm(tsec->sid, ctx->ctx_sid, 137 rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
141 SECCLASS_ASSOCIATION, 138 SECCLASS_ASSOCIATION,
@@ -201,6 +198,23 @@ void selinux_xfrm_policy_free(struct xfrm_policy *xp)
201} 198}
202 199
203/* 200/*
201 * LSM hook implementation that authorizes deletion of labeled policies.
202 */
203int selinux_xfrm_policy_delete(struct xfrm_policy *xp)
204{
205 struct task_security_struct *tsec = current->security;
206 struct xfrm_sec_ctx *ctx = xp->security;
207 int rc = 0;
208
209 if (ctx)
210 rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
211 SECCLASS_ASSOCIATION,
212 ASSOCIATION__SETCONTEXT, NULL);
213
214 return rc;
215}
216
217/*
204 * LSM hook implementation that allocs and transfers sec_ctx spec to 218 * LSM hook implementation that allocs and transfers sec_ctx spec to
205 * xfrm_state. 219 * xfrm_state.
206 */ 220 */
@@ -292,6 +306,23 @@ u32 selinux_socket_getpeer_dgram(struct sk_buff *skb)
292 return SECSID_NULL; 306 return SECSID_NULL;
293} 307}
294 308
309 /*
310 * LSM hook implementation that authorizes deletion of labeled SAs.
311 */
312int selinux_xfrm_state_delete(struct xfrm_state *x)
313{
314 struct task_security_struct *tsec = current->security;
315 struct xfrm_sec_ctx *ctx = x->security;
316 int rc = 0;
317
318 if (ctx)
319 rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
320 SECCLASS_ASSOCIATION,
321 ASSOCIATION__SETCONTEXT, NULL);
322
323 return rc;
324}
325
295/* 326/*
296 * LSM hook that controls access to unlabelled packets. If 327 * LSM hook that controls access to unlabelled packets. If
297 * a xfrm_state is authorizable (defined by macro) then it was 328 * a xfrm_state is authorizable (defined by macro) then it was
@@ -356,18 +387,12 @@ int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb)
356 struct xfrm_state *x = dst_test->xfrm; 387 struct xfrm_state *x = dst_test->xfrm;
357 388
358 if (x && selinux_authorizable_xfrm(x)) 389 if (x && selinux_authorizable_xfrm(x))
359 goto accept; 390 goto out;
360 } 391 }
361 } 392 }
362 393
363 rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION, 394 rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION,
364 ASSOCIATION__SENDTO, NULL); 395 ASSOCIATION__SENDTO, NULL);
365 if (rc) 396out:
366 goto drop; 397 return rc;
367
368accept:
369 return NF_ACCEPT;
370
371drop:
372 return NF_DROP;
373} 398}