diff options
Diffstat (limited to 'security/selinux')
-rw-r--r-- | security/selinux/hooks.c | 22 | ||||
-rw-r--r-- | security/selinux/include/classmap.h | 2 | ||||
-rw-r--r-- | security/selinux/selinuxfs.c | 16 |
3 files changed, 22 insertions, 18 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index cda18fd8ca0f..e276eb468536 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -3924,18 +3924,18 @@ static int selinux_socket_shutdown(struct socket *sock, int how) | |||
3924 | return sock_has_perm(current, sock->sk, SOCKET__SHUTDOWN); | 3924 | return sock_has_perm(current, sock->sk, SOCKET__SHUTDOWN); |
3925 | } | 3925 | } |
3926 | 3926 | ||
3927 | static int selinux_socket_unix_stream_connect(struct socket *sock, | 3927 | static int selinux_socket_unix_stream_connect(struct sock *sock, |
3928 | struct socket *other, | 3928 | struct sock *other, |
3929 | struct sock *newsk) | 3929 | struct sock *newsk) |
3930 | { | 3930 | { |
3931 | struct sk_security_struct *sksec_sock = sock->sk->sk_security; | 3931 | struct sk_security_struct *sksec_sock = sock->sk_security; |
3932 | struct sk_security_struct *sksec_other = other->sk->sk_security; | 3932 | struct sk_security_struct *sksec_other = other->sk_security; |
3933 | struct sk_security_struct *sksec_new = newsk->sk_security; | 3933 | struct sk_security_struct *sksec_new = newsk->sk_security; |
3934 | struct common_audit_data ad; | 3934 | struct common_audit_data ad; |
3935 | int err; | 3935 | int err; |
3936 | 3936 | ||
3937 | COMMON_AUDIT_DATA_INIT(&ad, NET); | 3937 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
3938 | ad.u.net.sk = other->sk; | 3938 | ad.u.net.sk = other; |
3939 | 3939 | ||
3940 | err = avc_has_perm(sksec_sock->sid, sksec_other->sid, | 3940 | err = avc_has_perm(sksec_sock->sid, sksec_other->sid, |
3941 | sksec_other->sclass, | 3941 | sksec_other->sclass, |
@@ -4523,11 +4523,11 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, | |||
4523 | if (selinux_secmark_enabled()) | 4523 | if (selinux_secmark_enabled()) |
4524 | if (avc_has_perm(sksec->sid, skb->secmark, | 4524 | if (avc_has_perm(sksec->sid, skb->secmark, |
4525 | SECCLASS_PACKET, PACKET__SEND, &ad)) | 4525 | SECCLASS_PACKET, PACKET__SEND, &ad)) |
4526 | return NF_DROP; | 4526 | return NF_DROP_ERR(-ECONNREFUSED); |
4527 | 4527 | ||
4528 | if (selinux_policycap_netpeer) | 4528 | if (selinux_policycap_netpeer) |
4529 | if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto)) | 4529 | if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto)) |
4530 | return NF_DROP; | 4530 | return NF_DROP_ERR(-ECONNREFUSED); |
4531 | 4531 | ||
4532 | return NF_ACCEPT; | 4532 | return NF_ACCEPT; |
4533 | } | 4533 | } |
@@ -4584,7 +4584,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, | |||
4584 | secmark_perm = PACKET__SEND; | 4584 | secmark_perm = PACKET__SEND; |
4585 | break; | 4585 | break; |
4586 | default: | 4586 | default: |
4587 | return NF_DROP; | 4587 | return NF_DROP_ERR(-ECONNREFUSED); |
4588 | } | 4588 | } |
4589 | if (secmark_perm == PACKET__FORWARD_OUT) { | 4589 | if (secmark_perm == PACKET__FORWARD_OUT) { |
4590 | if (selinux_skb_peerlbl_sid(skb, family, &peer_sid)) | 4590 | if (selinux_skb_peerlbl_sid(skb, family, &peer_sid)) |
@@ -4606,7 +4606,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, | |||
4606 | if (secmark_active) | 4606 | if (secmark_active) |
4607 | if (avc_has_perm(peer_sid, skb->secmark, | 4607 | if (avc_has_perm(peer_sid, skb->secmark, |
4608 | SECCLASS_PACKET, secmark_perm, &ad)) | 4608 | SECCLASS_PACKET, secmark_perm, &ad)) |
4609 | return NF_DROP; | 4609 | return NF_DROP_ERR(-ECONNREFUSED); |
4610 | 4610 | ||
4611 | if (peerlbl_active) { | 4611 | if (peerlbl_active) { |
4612 | u32 if_sid; | 4612 | u32 if_sid; |
@@ -4616,13 +4616,13 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, | |||
4616 | return NF_DROP; | 4616 | return NF_DROP; |
4617 | if (avc_has_perm(peer_sid, if_sid, | 4617 | if (avc_has_perm(peer_sid, if_sid, |
4618 | SECCLASS_NETIF, NETIF__EGRESS, &ad)) | 4618 | SECCLASS_NETIF, NETIF__EGRESS, &ad)) |
4619 | return NF_DROP; | 4619 | return NF_DROP_ERR(-ECONNREFUSED); |
4620 | 4620 | ||
4621 | if (sel_netnode_sid(addrp, family, &node_sid)) | 4621 | if (sel_netnode_sid(addrp, family, &node_sid)) |
4622 | return NF_DROP; | 4622 | return NF_DROP; |
4623 | if (avc_has_perm(peer_sid, node_sid, | 4623 | if (avc_has_perm(peer_sid, node_sid, |
4624 | SECCLASS_NODE, NODE__SENDTO, &ad)) | 4624 | SECCLASS_NODE, NODE__SENDTO, &ad)) |
4625 | return NF_DROP; | 4625 | return NF_DROP_ERR(-ECONNREFUSED); |
4626 | } | 4626 | } |
4627 | 4627 | ||
4628 | return NF_ACCEPT; | 4628 | return NF_ACCEPT; |
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index 8858d2b2d4b6..7ed3663332ec 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h | |||
@@ -142,7 +142,7 @@ struct security_class_mapping secclass_map[] = { | |||
142 | "node_bind", "name_connect", NULL } }, | 142 | "node_bind", "name_connect", NULL } }, |
143 | { "memprotect", { "mmap_zero", NULL } }, | 143 | { "memprotect", { "mmap_zero", NULL } }, |
144 | { "peer", { "recv", NULL } }, | 144 | { "peer", { "recv", NULL } }, |
145 | { "capability2", { "mac_override", "mac_admin", NULL } }, | 145 | { "capability2", { "mac_override", "mac_admin", "syslog", NULL } }, |
146 | { "kernel_service", { "use_as_override", "create_files_as", NULL } }, | 146 | { "kernel_service", { "use_as_override", "create_files_as", NULL } }, |
147 | { "tun_socket", | 147 | { "tun_socket", |
148 | { COMMON_SOCK_PERMS, NULL } }, | 148 | { COMMON_SOCK_PERMS, NULL } }, |
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 45d35e629fc6..ea39cb742ae5 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
@@ -1149,24 +1149,28 @@ static void sel_remove_entries(struct dentry *de) | |||
1149 | { | 1149 | { |
1150 | struct list_head *node; | 1150 | struct list_head *node; |
1151 | 1151 | ||
1152 | spin_lock(&dcache_lock); | 1152 | spin_lock(&de->d_lock); |
1153 | node = de->d_subdirs.next; | 1153 | node = de->d_subdirs.next; |
1154 | while (node != &de->d_subdirs) { | 1154 | while (node != &de->d_subdirs) { |
1155 | struct dentry *d = list_entry(node, struct dentry, d_u.d_child); | 1155 | struct dentry *d = list_entry(node, struct dentry, d_u.d_child); |
1156 | |||
1157 | spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED); | ||
1156 | list_del_init(node); | 1158 | list_del_init(node); |
1157 | 1159 | ||
1158 | if (d->d_inode) { | 1160 | if (d->d_inode) { |
1159 | d = dget_locked(d); | 1161 | dget_dlock(d); |
1160 | spin_unlock(&dcache_lock); | 1162 | spin_unlock(&de->d_lock); |
1163 | spin_unlock(&d->d_lock); | ||
1161 | d_delete(d); | 1164 | d_delete(d); |
1162 | simple_unlink(de->d_inode, d); | 1165 | simple_unlink(de->d_inode, d); |
1163 | dput(d); | 1166 | dput(d); |
1164 | spin_lock(&dcache_lock); | 1167 | spin_lock(&de->d_lock); |
1165 | } | 1168 | } else |
1169 | spin_unlock(&d->d_lock); | ||
1166 | node = de->d_subdirs.next; | 1170 | node = de->d_subdirs.next; |
1167 | } | 1171 | } |
1168 | 1172 | ||
1169 | spin_unlock(&dcache_lock); | 1173 | spin_unlock(&de->d_lock); |
1170 | } | 1174 | } |
1171 | 1175 | ||
1172 | #define BOOL_DIR_NAME "booleans" | 1176 | #define BOOL_DIR_NAME "booleans" |