aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c64
1 files changed, 43 insertions, 21 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 28832e689800..24caaeec8894 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -18,7 +18,6 @@
18 * as published by the Free Software Foundation. 18 * as published by the Free Software Foundation.
19 */ 19 */
20 20
21#include <linux/config.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <linux/kernel.h> 23#include <linux/kernel.h>
@@ -69,6 +68,7 @@
69#include <linux/sysctl.h> 68#include <linux/sysctl.h>
70#include <linux/audit.h> 69#include <linux/audit.h>
71#include <linux/string.h> 70#include <linux/string.h>
71#include <linux/selinux.h>
72 72
73#include "avc.h" 73#include "avc.h"
74#include "objsec.h" 74#include "objsec.h"
@@ -2643,6 +2643,11 @@ static int selinux_task_getsid(struct task_struct *p)
2643 return task_has_perm(current, p, PROCESS__GETSESSION); 2643 return task_has_perm(current, p, PROCESS__GETSESSION);
2644} 2644}
2645 2645
2646static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
2647{
2648 selinux_get_task_sid(p, secid);
2649}
2650
2646static int selinux_task_setgroups(struct group_info *group_info) 2651static int selinux_task_setgroups(struct group_info *group_info)
2647{ 2652{
2648 /* See the comment for setuid above. */ 2653 /* See the comment for setuid above. */
@@ -2665,6 +2670,11 @@ static int selinux_task_setioprio(struct task_struct *p, int ioprio)
2665 return task_has_perm(current, p, PROCESS__SETSCHED); 2670 return task_has_perm(current, p, PROCESS__SETSCHED);
2666} 2671}
2667 2672
2673static int selinux_task_getioprio(struct task_struct *p)
2674{
2675 return task_has_perm(current, p, PROCESS__GETSCHED);
2676}
2677
2668static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) 2678static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim)
2669{ 2679{
2670 struct rlimit *old_rlim = current->signal->rlim + resource; 2680 struct rlimit *old_rlim = current->signal->rlim + resource;
@@ -2699,12 +2709,14 @@ static int selinux_task_movememory(struct task_struct *p)
2699 return task_has_perm(current, p, PROCESS__SETSCHED); 2709 return task_has_perm(current, p, PROCESS__SETSCHED);
2700} 2710}
2701 2711
2702static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int sig) 2712static int selinux_task_kill(struct task_struct *p, struct siginfo *info,
2713 int sig, u32 secid)
2703{ 2714{
2704 u32 perm; 2715 u32 perm;
2705 int rc; 2716 int rc;
2717 struct task_security_struct *tsec;
2706 2718
2707 rc = secondary_ops->task_kill(p, info, sig); 2719 rc = secondary_ops->task_kill(p, info, sig, secid);
2708 if (rc) 2720 if (rc)
2709 return rc; 2721 return rc;
2710 2722
@@ -2715,8 +2727,12 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info, int si
2715 perm = PROCESS__SIGNULL; /* null signal; existence test */ 2727 perm = PROCESS__SIGNULL; /* null signal; existence test */
2716 else 2728 else
2717 perm = signal_to_av(sig); 2729 perm = signal_to_av(sig);
2718 2730 tsec = p->security;
2719 return task_has_perm(current, p, perm); 2731 if (secid)
2732 rc = avc_has_perm(secid, tsec->sid, SECCLASS_PROCESS, perm, NULL);
2733 else
2734 rc = task_has_perm(current, p, perm);
2735 return rc;
2720} 2736}
2721 2737
2722static int selinux_task_prctl(int option, 2738static int selinux_task_prctl(int option,
@@ -3420,7 +3436,13 @@ out:
3420static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, u32 *seclen) 3436static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, u32 *seclen)
3421{ 3437{
3422 int err = 0; 3438 int err = 0;
3423 u32 peer_sid = selinux_socket_getpeer_dgram(skb); 3439 u32 peer_sid;
3440
3441 if (skb->sk->sk_family == PF_UNIX)
3442 selinux_get_inode_sid(SOCK_INODE(skb->sk->sk_socket),
3443 &peer_sid);
3444 else
3445 peer_sid = selinux_socket_getpeer_dgram(skb);
3424 3446
3425 if (peer_sid == SECSID_NULL) 3447 if (peer_sid == SECSID_NULL)
3426 return -EINVAL; 3448 return -EINVAL;
@@ -3432,8 +3454,6 @@ static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata,
3432 return 0; 3454 return 0;
3433} 3455}
3434 3456
3435
3436
3437static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority) 3457static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
3438{ 3458{
3439 return sk_alloc_security(sk, family, priority); 3459 return sk_alloc_security(sk, family, priority);
@@ -3641,32 +3661,32 @@ static unsigned int selinux_ipv6_postroute_last(unsigned int hooknum,
3641 3661
3642static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) 3662static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
3643{ 3663{
3644 struct task_security_struct *tsec;
3645 struct av_decision avd;
3646 int err; 3664 int err;
3647 3665
3648 err = secondary_ops->netlink_send(sk, skb); 3666 err = secondary_ops->netlink_send(sk, skb);
3649 if (err) 3667 if (err)
3650 return err; 3668 return err;
3651 3669
3652 tsec = current->security;
3653
3654 avd.allowed = 0;
3655 avc_has_perm_noaudit(tsec->sid, tsec->sid,
3656 SECCLASS_CAPABILITY, ~0, &avd);
3657 cap_mask(NETLINK_CB(skb).eff_cap, avd.allowed);
3658
3659 if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS) 3670 if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS)
3660 err = selinux_nlmsg_perm(sk, skb); 3671 err = selinux_nlmsg_perm(sk, skb);
3661 3672
3662 return err; 3673 return err;
3663} 3674}
3664 3675
3665static int selinux_netlink_recv(struct sk_buff *skb) 3676static int selinux_netlink_recv(struct sk_buff *skb, int capability)
3666{ 3677{
3667 if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) 3678 int err;
3668 return -EPERM; 3679 struct avc_audit_data ad;
3669 return 0; 3680
3681 err = secondary_ops->netlink_recv(skb, capability);
3682 if (err)
3683 return err;
3684
3685 AVC_AUDIT_DATA_INIT(&ad, CAP);
3686 ad.u.cap = capability;
3687
3688 return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid,
3689 SECCLASS_CAPABILITY, CAP_TO_MASK(capability), &ad);
3670} 3690}
3671 3691
3672static int ipc_alloc_security(struct task_struct *task, 3692static int ipc_alloc_security(struct task_struct *task,
@@ -4429,9 +4449,11 @@ static struct security_operations selinux_ops = {
4429 .task_setpgid = selinux_task_setpgid, 4449 .task_setpgid = selinux_task_setpgid,
4430 .task_getpgid = selinux_task_getpgid, 4450 .task_getpgid = selinux_task_getpgid,
4431 .task_getsid = selinux_task_getsid, 4451 .task_getsid = selinux_task_getsid,
4452 .task_getsecid = selinux_task_getsecid,
4432 .task_setgroups = selinux_task_setgroups, 4453 .task_setgroups = selinux_task_setgroups,
4433 .task_setnice = selinux_task_setnice, 4454 .task_setnice = selinux_task_setnice,
4434 .task_setioprio = selinux_task_setioprio, 4455 .task_setioprio = selinux_task_setioprio,
4456 .task_getioprio = selinux_task_getioprio,
4435 .task_setrlimit = selinux_task_setrlimit, 4457 .task_setrlimit = selinux_task_setrlimit,
4436 .task_setscheduler = selinux_task_setscheduler, 4458 .task_setscheduler = selinux_task_setscheduler,
4437 .task_getscheduler = selinux_task_getscheduler, 4459 .task_getscheduler = selinux_task_getscheduler,