diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index dbeaa783b2a9..00815973d412 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1433,12 +1433,13 @@ static int current_has_perm(const struct task_struct *tsk, | |||
1433 | 1433 | ||
1434 | /* Check whether a task is allowed to use a capability. */ | 1434 | /* Check whether a task is allowed to use a capability. */ |
1435 | static int task_has_capability(struct task_struct *tsk, | 1435 | static int task_has_capability(struct task_struct *tsk, |
1436 | const struct cred *cred, | ||
1436 | int cap, int audit) | 1437 | int cap, int audit) |
1437 | { | 1438 | { |
1438 | struct avc_audit_data ad; | 1439 | struct avc_audit_data ad; |
1439 | struct av_decision avd; | 1440 | struct av_decision avd; |
1440 | u16 sclass; | 1441 | u16 sclass; |
1441 | u32 sid = task_sid(tsk); | 1442 | u32 sid = cred_sid(cred); |
1442 | u32 av = CAP_TO_MASK(cap); | 1443 | u32 av = CAP_TO_MASK(cap); |
1443 | int rc; | 1444 | int rc; |
1444 | 1445 | ||
@@ -1865,15 +1866,16 @@ static int selinux_capset(struct cred *new, const struct cred *old, | |||
1865 | return cred_has_perm(old, new, PROCESS__SETCAP); | 1866 | return cred_has_perm(old, new, PROCESS__SETCAP); |
1866 | } | 1867 | } |
1867 | 1868 | ||
1868 | static int selinux_capable(struct task_struct *tsk, int cap, int audit) | 1869 | static int selinux_capable(struct task_struct *tsk, const struct cred *cred, |
1870 | int cap, int audit) | ||
1869 | { | 1871 | { |
1870 | int rc; | 1872 | int rc; |
1871 | 1873 | ||
1872 | rc = secondary_ops->capable(tsk, cap, audit); | 1874 | rc = secondary_ops->capable(tsk, cred, cap, audit); |
1873 | if (rc) | 1875 | if (rc) |
1874 | return rc; | 1876 | return rc; |
1875 | 1877 | ||
1876 | return task_has_capability(tsk, cap, audit); | 1878 | return task_has_capability(tsk, cred, cap, audit); |
1877 | } | 1879 | } |
1878 | 1880 | ||
1879 | static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid) | 1881 | static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid) |
@@ -2037,7 +2039,8 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) | |||
2037 | { | 2039 | { |
2038 | int rc, cap_sys_admin = 0; | 2040 | int rc, cap_sys_admin = 0; |
2039 | 2041 | ||
2040 | rc = selinux_capable(current, CAP_SYS_ADMIN, SECURITY_CAP_NOAUDIT); | 2042 | rc = selinux_capable(current, current_cred(), CAP_SYS_ADMIN, |
2043 | SECURITY_CAP_NOAUDIT); | ||
2041 | if (rc == 0) | 2044 | if (rc == 0) |
2042 | cap_sys_admin = 1; | 2045 | cap_sys_admin = 1; |
2043 | 2046 | ||
@@ -2880,7 +2883,8 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name | |||
2880 | * and lack of permission just means that we fall back to the | 2883 | * and lack of permission just means that we fall back to the |
2881 | * in-core context value, not a denial. | 2884 | * in-core context value, not a denial. |
2882 | */ | 2885 | */ |
2883 | error = selinux_capable(current, CAP_MAC_ADMIN, SECURITY_CAP_NOAUDIT); | 2886 | error = selinux_capable(current, current_cred(), CAP_MAC_ADMIN, |
2887 | SECURITY_CAP_NOAUDIT); | ||
2884 | if (!error) | 2888 | if (!error) |
2885 | error = security_sid_to_context_force(isec->sid, &context, | 2889 | error = security_sid_to_context_force(isec->sid, &context, |
2886 | &size); | 2890 | &size); |
@@ -4185,7 +4189,7 @@ static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk, | |||
4185 | static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, | 4189 | static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, |
4186 | u16 family) | 4190 | u16 family) |
4187 | { | 4191 | { |
4188 | int err; | 4192 | int err = 0; |
4189 | struct sk_security_struct *sksec = sk->sk_security; | 4193 | struct sk_security_struct *sksec = sk->sk_security; |
4190 | u32 peer_sid; | 4194 | u32 peer_sid; |
4191 | u32 sk_sid = sksec->sid; | 4195 | u32 sk_sid = sksec->sid; |
@@ -4202,7 +4206,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, | |||
4202 | if (selinux_compat_net) | 4206 | if (selinux_compat_net) |
4203 | err = selinux_sock_rcv_skb_iptables_compat(sk, skb, &ad, | 4207 | err = selinux_sock_rcv_skb_iptables_compat(sk, skb, &ad, |
4204 | family, addrp); | 4208 | family, addrp); |
4205 | else | 4209 | else if (selinux_secmark_enabled()) |
4206 | err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET, | 4210 | err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET, |
4207 | PACKET__RECV, &ad); | 4211 | PACKET__RECV, &ad); |
4208 | if (err) | 4212 | if (err) |
@@ -4705,7 +4709,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, | |||
4705 | if (selinux_ip_postroute_iptables_compat(skb->sk, ifindex, | 4709 | if (selinux_ip_postroute_iptables_compat(skb->sk, ifindex, |
4706 | &ad, family, addrp)) | 4710 | &ad, family, addrp)) |
4707 | return NF_DROP; | 4711 | return NF_DROP; |
4708 | } else { | 4712 | } else if (selinux_secmark_enabled()) { |
4709 | if (avc_has_perm(sksec->sid, skb->secmark, | 4713 | if (avc_has_perm(sksec->sid, skb->secmark, |
4710 | SECCLASS_PACKET, PACKET__SEND, &ad)) | 4714 | SECCLASS_PACKET, PACKET__SEND, &ad)) |
4711 | return NF_DROP; | 4715 | return NF_DROP; |