Alter security_task_getsecid(), selinux_get_task_sid() and associated functions
to return both the objective/victim and subjective/action task SIDs.  Both
results are optional by submitting NULL result pointers.

Interestingly, AF_NETLINK calls directly into SELinux.  I suspect this to be
incorrect.  It should probably use security_task_getsecid() instead.

Signed-off-by: David Howells <[EMAIL PROTECTED]>
---

 drivers/usb/core/devio.c          |    4 ++--
 include/linux/security.h          |   18 +++++++++++++-----
 include/linux/selinux.h           |   15 ++++++++++-----
 kernel/auditsc.c                  |   14 +++++++-------
 net/netlabel/netlabel_unlabeled.c |    2 +-
 net/netlink/af_netlink.c          |    2 +-
 security/dummy.c                  |    3 ++-
 security/selinux/exports.c        |   22 ++++++++++++++++++----
 security/selinux/hooks.c          |    5 +++--
 security/selinux/xfrm.c           |   12 ++++++------
 10 files changed, 63 insertions(+), 34 deletions(-)

diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 927a181..1e651d8 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -579,7 +579,7 @@ static int usbdev_open(struct inode *inode, struct file 
*file)
        ps->disc_euid = current->euid;
        ps->disccontext = NULL;
        ps->ifclaimed = 0;
-       security_task_getsecid(current, &ps->secid);
+       security_task_getsecid(current, NULL, &ps->secid);
        smp_wmb();
        list_add_tail(&ps->list, &dev->filelist);
        file->private_data = ps;
@@ -1069,7 +1069,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct 
usbdevfs_urb *uurb,
        as->pid = get_pid(task_pid(current));
        as->uid = current->uid;
        as->euid = current->euid;
-       security_task_getsecid(current, &as->secid);
+       security_task_getsecid(current, NULL, &as->secid);
        if (!(uurb->endpoint & USB_DIR_IN)) {
                if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, 
as->urb->transfer_buffer_length)) {
                        free_async(as);
diff --git a/include/linux/security.h b/include/linux/security.h
index 74cc204..0933333 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -584,7 +584,12 @@ struct request_sock;
  *     Return 0 if permission is granted.
  * @task_getsecid:
  *     Retrieve the security identifier of the process @p.
- *     @p contains the task_struct for the process and place is into @secid.
+ *     @p contains the task_struct for the process to be interrogated.  The
+ *     security ID of the task itself is placed in [EMAIL PROTECTED], and the
+ *     security ID as which the task is currently acting is placed in
+ *     [EMAIL PROTECTED]  Either result pointer may be NULL if that particular
+ *     ID is not required.
+ *
  * @task_setgroups:
  *     Check permission before setting the supplementary group set of the
  *     current process.
@@ -1281,7 +1286,8 @@ struct security_operations {
        int (*task_setpgid) (struct task_struct * p, pid_t pgid);
        int (*task_getpgid) (struct task_struct * p);
        int (*task_getsid) (struct task_struct * p);
-       void (*task_getsecid) (struct task_struct * p, u32 * secid);
+       void (*task_getsecid) (struct task_struct * p,
+                              u32 * object_secid, u32 * subject_secid);
        int (*task_setgroups) (struct group_info *group_info);
        int (*task_setnice) (struct task_struct * p, int nice);
        int (*task_setioprio) (struct task_struct * p, int ioprio);
@@ -1936,9 +1942,10 @@ static inline int security_task_getsid (struct 
task_struct *p)
        return security_ops->task_getsid (p);
 }
 
-static inline void security_task_getsecid (struct task_struct *p, u32 *secid)
+static inline void security_task_getsecid (struct task_struct *p,
+                                          u32 *object_secid, u32 *action_secid)
 {
-       security_ops->task_getsecid (p, secid);
+       security_ops->task_getsecid (p, object_secid, action_secid);
 }
 
 static inline int security_task_setgroups (struct group_info *group_info)
@@ -2625,7 +2632,8 @@ static inline int security_task_getsid (struct 
task_struct *p)
        return 0;
 }
 
-static inline void security_task_getsecid (struct task_struct *p, u32 *secid)
+static inline void security_task_getsecid (struct task_struct *p,
+                                          u32 *object_secid, u32 *action_secid)
 { }
 
 static inline int security_task_setgroups (struct group_info *group_info)
diff --git a/include/linux/selinux.h b/include/linux/selinux.h
index d1b7ca6..26cdec3 100644
--- a/include/linux/selinux.h
+++ b/include/linux/selinux.h
@@ -101,12 +101,16 @@ void selinux_get_ipc_sid(const struct kern_ipc_perm 
*ipcp, u32 *sid);
 
 /**
  *     selinux_get_task_sid - return the SID of task
- *     @tsk: the task whose SID will be returned
- *     @sid: pointer to security context ID to be filled in.
+ *     @tsk: the task to be queried.
+ *     @object_sid: optional pointer to where the objective security context ID
+ *     of the task is to be placed.
+ *     @action_sid: optional pointer to where the subjective security context 
ID
+ *     of the task is to be placed.
  *
  *     Returns nothing
  */
-void selinux_get_task_sid(struct task_struct *tsk, u32 *sid);
+void selinux_get_task_sid(struct task_struct *tsk,
+                         u32 *object_sid, u32 *action_sid);
 
 /**
  *     selinux_string_to_sid - map a security context string to a security ID
@@ -173,9 +177,10 @@ static inline void selinux_get_ipc_sid(const struct 
kern_ipc_perm *ipcp, u32 *si
        *sid = 0;
 }
 
-static inline void selinux_get_task_sid(struct task_struct *tsk, u32 *sid)
+lstatic inline void selinux_get_task_sid(struct task_struct *tsk,
+                                        u32 *object_sid, u32 *action_sid)
 {
-       *sid = 0;
+       *object_sid = *action_sid = 0;
 }
 
 static inline int selinux_string_to_sid(const char *str, u32 *sid)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 282e041..d87f7ac 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -399,7 +399,7 @@ static int audit_filter_rules(struct task_struct *tsk,
                           logged upon error */
                        if (f->se_rule) {
                                if (need_sid) {
-                                       selinux_get_task_sid(tsk, &sid);
+                                       selinux_get_task_sid(tsk, NULL, &sid);
                                        need_sid = 0;
                                }
                                result = selinux_audit_rule_match(sid, f->type,
@@ -746,7 +746,7 @@ void audit_log_task_context(struct audit_buffer *ab)
        int error;
        u32 sid;
 
-       selinux_get_task_sid(current, &sid);
+       selinux_get_task_sid(current, NULL, &sid);
        if (!sid)
                return;
 
@@ -1977,7 +1977,7 @@ void __audit_ptrace(struct task_struct *t)
        struct audit_context *context = current->audit_context;
 
        context->target_pid = t->pid;
-       selinux_get_task_sid(t, &context->target_sid);
+       selinux_get_task_sid(t, &context->target_sid, NULL);
 }
 
 /**
@@ -2004,7 +2004,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
                                audit_sig_uid = ctx->loginuid;
                        else
                                audit_sig_uid = tsk->uid;
-                       selinux_get_task_sid(tsk, &audit_sig_sid);
+                       selinux_get_task_sid(tsk, NULL, &audit_sig_sid);
                }
                if (!audit_signals || audit_dummy_context())
                        return 0;
@@ -2014,7 +2014,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
         * in audit_context */
        if (!ctx->target_pid) {
                ctx->target_pid = t->tgid;
-               selinux_get_task_sid(t, &ctx->target_sid);
+               selinux_get_task_sid(t, &ctx->target_sid, NULL);
                return 0;
        }
 
@@ -2031,7 +2031,7 @@ int __audit_signal_info(int sig, struct task_struct *t)
        BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS);
 
        axp->target_pid[axp->pid_count] = t->tgid;
-       selinux_get_task_sid(t, &axp->target_sid[axp->pid_count]);
+       selinux_get_task_sid(t, &axp->target_sid[axp->pid_count], NULL);
        axp->pid_count++;
 
        return 0;
@@ -2059,7 +2059,7 @@ void audit_core_dumps(long signr)
        audit_log_format(ab, "auid=%u uid=%u gid=%u",
                        audit_get_loginuid(current->audit_context),
                        current->uid, current->gid);
-       selinux_get_task_sid(current, &sid);
+       selinux_get_task_sid(current, NULL, &sid);
        if (sid) {
                char *ctx = NULL;
                u32 len;
diff --git a/net/netlabel/netlabel_unlabeled.c 
b/net/netlabel/netlabel_unlabeled.c
index 5c303c6..474c03a 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -277,7 +277,7 @@ int netlbl_unlabel_defconf(void)
        /* Only the kernel is allowed to call this function and the only time
         * it is called is at bootup before the audit subsystem is reporting
         * messages so don't worry to much about these values. */
-       security_task_getsecid(current, &audit_info.secid);
+       security_task_getsecid(current, NULL, &audit_info.secid);
        audit_info.loginuid = 0;
 
        entry = kzalloc(sizeof(*entry), GFP_KERNEL);
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 5681ce3..8c37d5f 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1190,7 +1190,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct 
socket *sock,
        NETLINK_CB(skb).pid     = nlk->pid;
        NETLINK_CB(skb).dst_group = dst_group;
        NETLINK_CB(skb).loginuid = audit_get_loginuid(current->audit_context);
-       selinux_get_task_sid(current, &(NETLINK_CB(skb).sid));
+       selinux_get_task_sid(current, NULL, &(NETLINK_CB(skb).sid));
        memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
 
        /* What can I do? Netlink is asynchronous, so that
diff --git a/security/dummy.c b/security/dummy.c
index f535cc6..187fc4b 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -523,7 +523,8 @@ static int dummy_task_getsid (struct task_struct *p)
        return 0;
 }
 
-static void dummy_task_getsecid (struct task_struct *p, u32 *secid)
+static void dummy_task_getsecid (struct task_struct *p,
+                                u32 *object_secid, u32 *action_secid)
 { }
 
 static int dummy_task_setgroups (struct group_info *group_info)
diff --git a/security/selinux/exports.c b/security/selinux/exports.c
index 29cb87a..374a7b2 100644
--- a/security/selinux/exports.c
+++ b/security/selinux/exports.c
@@ -53,14 +53,28 @@ void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, 
u32 *sid)
        *sid = 0;
 }
 
-void selinux_get_task_sid(struct task_struct *tsk, u32 *sid)
+void selinux_get_task_sid(struct task_struct *tsk,
+                         u32 *object_sid, u32 *action_sid)
 {
        if (selinux_enabled) {
-               struct task_security_struct *tsec = tsk->security;
-               *sid = tsec->victim_sid;
+               struct task_security_struct *tsec;
+               struct cred_security_struct *csec;
+               if (object_sid) {
+                       tsec = tsk->security;
+                       *object_sid = tsec->victim_sid;
+               }
+               if (action_sid) {
+                       rcu_read_lock();
+                       csec = task_cred(tsk)->security;
+                       *action_sid = csec->action_sid;
+                       rcu_read_unlock();
+               }
                return;
        }
-       *sid = 0;
+       if (object_sid)
+               *object_sid = 0;
+       if (action_sid)
+               *action_sid = 0;
 }
 
 int selinux_string_to_sid(char *str, u32 *sid)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 4e72dbb..2ee1712 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2853,9 +2853,10 @@ static int selinux_task_getsid(struct task_struct *p)
        return task_has_perm(current, p, PROCESS__GETSESSION);
 }
 
-static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
+static void selinux_task_getsecid(struct task_struct *p,
+                                 u32 *object_secid, u32 *action_secid)
 {
-       selinux_get_task_sid(p, secid);
+       selinux_get_task_sid(p, object_secid, action_secid);
 }
 
 static int selinux_task_setgroups(struct group_info *group_info)
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index 902d302..9dfa8f3 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -199,7 +199,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx 
**ctxp,
        struct xfrm_user_sec_ctx *uctx, u32 sid)
 {
        int rc = 0;
-       struct task_security_struct *tsec = current->security;
+       struct cred_security_struct *csec = current->cred->security;
        struct xfrm_sec_ctx *ctx = NULL;
        char *ctx_str = NULL;
        u32 str_len;
@@ -240,7 +240,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx 
**ctxp,
        /*
         * Does the subject have permission to set security context?
         */
-       rc = avc_has_perm(tsec->action_sid, ctx->ctx_sid,
+       rc = avc_has_perm(csec->action_sid, ctx->ctx_sid,
                          SECCLASS_ASSOCIATION,
                          ASSOCIATION__SETCONTEXT, NULL);
        if (rc)
@@ -336,12 +336,12 @@ void selinux_xfrm_policy_free(struct xfrm_policy *xp)
  */
 int selinux_xfrm_policy_delete(struct xfrm_policy *xp)
 {
-       struct task_security_struct *tsec = current->security;
+       struct cred_security_struct *csec = current->cred->security;
        struct xfrm_sec_ctx *ctx = xp->security;
        int rc = 0;
 
        if (ctx)
-               rc = avc_has_perm(tsec->action_sid, ctx->ctx_sid,
+               rc = avc_has_perm(csec->action_sid, ctx->ctx_sid,
                                  SECCLASS_ASSOCIATION,
                                  ASSOCIATION__SETCONTEXT, NULL);
 
@@ -378,12 +378,12 @@ void selinux_xfrm_state_free(struct xfrm_state *x)
   */
 int selinux_xfrm_state_delete(struct xfrm_state *x)
 {
-       struct task_security_struct *tsec = current->security;
+       struct cred_security_struct *csec = current->cred->security;
        struct xfrm_sec_ctx *ctx = x->security;
        int rc = 0;
 
        if (ctx)
-               rc = avc_has_perm(tsec->action_sid, ctx->ctx_sid,
+               rc = avc_has_perm(csec->action_sid, ctx->ctx_sid,
                                  SECCLASS_ASSOCIATION,
                                  ASSOCIATION__SETCONTEXT, NULL);
 

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to