From: Richard Guy Briggs <rgb@redhat.com>
To: Paul Moore <paul@paul-moore.com>
Cc: selinux@vger.kernel.org, linux-security-module@vger.kernel.org,
linux-audit@redhat.com,
John Johansen <john.johansen@canonical.com>
Subject: Re: [PATCH v2 2/3] selinux: clarify task subjective and objective credentials
Date: Fri, 19 Mar 2021 09:36:25 -0400 [thread overview]
Message-ID: <20210319133625.GD2781019@madcap2.tricolour.ca> (raw)
In-Reply-To: <161610014979.55424.673449459081578214.stgit@olly>
On 2021-03-18 16:42, Paul Moore wrote:
> SELinux has a function, task_sid(), which returns the task's
> objective credentials, but unfortunately is used in a few places
> where the subjective task credentials should be used. Most notably
> in the new security_task_getsecid_subj() LSM hook.
>
> This patch fixes this and attempts to make things more obvious by
> introducing a new function, task_sid_subj(), and renaming the
> existing task_sid() function to task_sid_obj().
>
> This patch also adds an interesting function in task_sid_binder().
> The task_sid_binder() function has a comment which hopefully
> describes it's reason for being, but it basically boils down to the
> simple fact that we can't safely access another task's subjective
> credentials so in the case of binder we need to stick with the
> objective credentials regardless.
>
> Signed-off-by: Paul Moore <paul@paul-moore.com>
Reviewed-by: Richard Guy Briggs <rgb@redhat.com>
> ---
> security/selinux/hooks.c | 112 ++++++++++++++++++++++++++++++----------------
> 1 file changed, 73 insertions(+), 39 deletions(-)
>
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 24ca545c6e1b..901a3ce453f1 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -229,10 +229,23 @@ static inline u32 cred_sid(const struct cred *cred)
> return tsec->sid;
> }
>
> +/*
> + * get the subjective security ID of a task
> + */
> +static inline u32 task_sid_subj(const struct task_struct *task)
> +{
> + u32 sid;
> +
> + rcu_read_lock();
> + sid = cred_sid(rcu_dereference(task->cred));
> + rcu_read_unlock();
> + return sid;
> +}
> +
> /*
> * get the objective security ID of a task
> */
> -static inline u32 task_sid(const struct task_struct *task)
> +static inline u32 task_sid_obj(const struct task_struct *task)
> {
> u32 sid;
>
> @@ -242,6 +255,29 @@ static inline u32 task_sid(const struct task_struct *task)
> return sid;
> }
>
> +/*
> + * get the security ID of a task for use with binder
> + */
> +static inline u32 task_sid_binder(const struct task_struct *task)
> +{
> + /*
> + * In many case where this function is used we should be using the
> + * task's subjective SID, but we can't reliably access the subjective
> + * creds of a task other than our own so we must use the objective
> + * creds/SID, which are safe to access. The downside is that if a task
> + * is temporarily overriding it's creds it will not be reflected here;
> + * however, it isn't clear that binder would handle that case well
> + * anyway.
> + *
> + * If this ever changes and we can safely reference the subjective
> + * creds/SID of another task, this function will make it easier to
> + * identify the various places where we make use of the task SIDs in
> + * the binder code. It is also likely that we will need to adjust
> + * the main drivers/android binder code as well.
> + */
> + return task_sid_obj(task);
> +}
> +
> static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
>
> /*
> @@ -2035,11 +2071,8 @@ static inline u32 open_file_to_av(struct file *file)
>
> static int selinux_binder_set_context_mgr(struct task_struct *mgr)
> {
> - u32 mysid = current_sid();
> - u32 mgrsid = task_sid(mgr);
> -
> return avc_has_perm(&selinux_state,
> - mysid, mgrsid, SECCLASS_BINDER,
> + current_sid(), task_sid_binder(mgr), SECCLASS_BINDER,
> BINDER__SET_CONTEXT_MGR, NULL);
> }
>
> @@ -2047,8 +2080,7 @@ static int selinux_binder_transaction(struct task_struct *from,
> struct task_struct *to)
> {
> u32 mysid = current_sid();
> - u32 fromsid = task_sid(from);
> - u32 tosid = task_sid(to);
> + u32 fromsid = task_sid_binder(from);
> int rc;
>
> if (mysid != fromsid) {
> @@ -2059,19 +2091,16 @@ static int selinux_binder_transaction(struct task_struct *from,
> return rc;
> }
>
> - return avc_has_perm(&selinux_state,
> - fromsid, tosid, SECCLASS_BINDER, BINDER__CALL,
> - NULL);
> + return avc_has_perm(&selinux_state, fromsid, task_sid_binder(to),
> + SECCLASS_BINDER, BINDER__CALL, NULL);
> }
>
> static int selinux_binder_transfer_binder(struct task_struct *from,
> struct task_struct *to)
> {
> - u32 fromsid = task_sid(from);
> - u32 tosid = task_sid(to);
> -
> return avc_has_perm(&selinux_state,
> - fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER,
> + task_sid_binder(from), task_sid_binder(to),
> + SECCLASS_BINDER, BINDER__TRANSFER,
> NULL);
> }
>
> @@ -2079,7 +2108,7 @@ static int selinux_binder_transfer_file(struct task_struct *from,
> struct task_struct *to,
> struct file *file)
> {
> - u32 sid = task_sid(to);
> + u32 sid = task_sid_binder(to);
> struct file_security_struct *fsec = selinux_file(file);
> struct dentry *dentry = file->f_path.dentry;
> struct inode_security_struct *isec;
> @@ -2115,10 +2144,10 @@ static int selinux_binder_transfer_file(struct task_struct *from,
> }
>
> static int selinux_ptrace_access_check(struct task_struct *child,
> - unsigned int mode)
> + unsigned int mode)
> {
> u32 sid = current_sid();
> - u32 csid = task_sid(child);
> + u32 csid = task_sid_obj(child);
>
> if (mode & PTRACE_MODE_READ)
> return avc_has_perm(&selinux_state,
> @@ -2131,15 +2160,15 @@ static int selinux_ptrace_access_check(struct task_struct *child,
> static int selinux_ptrace_traceme(struct task_struct *parent)
> {
> return avc_has_perm(&selinux_state,
> - task_sid(parent), current_sid(), SECCLASS_PROCESS,
> - PROCESS__PTRACE, NULL);
> + task_sid_subj(parent), task_sid_obj(current),
> + SECCLASS_PROCESS, PROCESS__PTRACE, NULL);
> }
>
> static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
> kernel_cap_t *inheritable, kernel_cap_t *permitted)
> {
> return avc_has_perm(&selinux_state,
> - current_sid(), task_sid(target), SECCLASS_PROCESS,
> + current_sid(), task_sid_obj(target), SECCLASS_PROCESS,
> PROCESS__GETCAP, NULL);
> }
>
> @@ -2264,7 +2293,7 @@ static u32 ptrace_parent_sid(void)
> rcu_read_lock();
> tracer = ptrace_parent(current);
> if (tracer)
> - sid = task_sid(tracer);
> + sid = task_sid_obj(tracer);
> rcu_read_unlock();
>
> return sid;
> @@ -3921,7 +3950,7 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk,
> struct fown_struct *fown, int signum)
> {
> struct file *file;
> - u32 sid = task_sid(tsk);
> + u32 sid = task_sid_obj(tsk);
> u32 perm;
> struct file_security_struct *fsec;
>
> @@ -4140,47 +4169,52 @@ static int selinux_kernel_load_data(enum kernel_load_data_id id, bool contents)
> static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
> {
> return avc_has_perm(&selinux_state,
> - current_sid(), task_sid(p), SECCLASS_PROCESS,
> + current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
> PROCESS__SETPGID, NULL);
> }
>
> static int selinux_task_getpgid(struct task_struct *p)
> {
> return avc_has_perm(&selinux_state,
> - current_sid(), task_sid(p), SECCLASS_PROCESS,
> + current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
> PROCESS__GETPGID, NULL);
> }
>
> static int selinux_task_getsid(struct task_struct *p)
> {
> return avc_has_perm(&selinux_state,
> - current_sid(), task_sid(p), SECCLASS_PROCESS,
> + current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
> PROCESS__GETSESSION, NULL);
> }
>
> -static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
> +static void selinux_task_getsecid_subj(struct task_struct *p, u32 *secid)
> +{
> + *secid = task_sid_subj(p);
> +}
> +
> +static void selinux_task_getsecid_obj(struct task_struct *p, u32 *secid)
> {
> - *secid = task_sid(p);
> + *secid = task_sid_obj(p);
> }
>
> static int selinux_task_setnice(struct task_struct *p, int nice)
> {
> return avc_has_perm(&selinux_state,
> - current_sid(), task_sid(p), SECCLASS_PROCESS,
> + current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
> PROCESS__SETSCHED, NULL);
> }
>
> static int selinux_task_setioprio(struct task_struct *p, int ioprio)
> {
> return avc_has_perm(&selinux_state,
> - current_sid(), task_sid(p), SECCLASS_PROCESS,
> + current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
> PROCESS__SETSCHED, NULL);
> }
>
> static int selinux_task_getioprio(struct task_struct *p)
> {
> return avc_has_perm(&selinux_state,
> - current_sid(), task_sid(p), SECCLASS_PROCESS,
> + current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
> PROCESS__GETSCHED, NULL);
> }
>
> @@ -4211,7 +4245,7 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
> upon context transitions. See selinux_bprm_committing_creds. */
> if (old_rlim->rlim_max != new_rlim->rlim_max)
> return avc_has_perm(&selinux_state,
> - current_sid(), task_sid(p),
> + current_sid(), task_sid_obj(p),
> SECCLASS_PROCESS, PROCESS__SETRLIMIT, NULL);
>
> return 0;
> @@ -4220,21 +4254,21 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
> static int selinux_task_setscheduler(struct task_struct *p)
> {
> return avc_has_perm(&selinux_state,
> - current_sid(), task_sid(p), SECCLASS_PROCESS,
> + current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
> PROCESS__SETSCHED, NULL);
> }
>
> static int selinux_task_getscheduler(struct task_struct *p)
> {
> return avc_has_perm(&selinux_state,
> - current_sid(), task_sid(p), SECCLASS_PROCESS,
> + current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
> PROCESS__GETSCHED, NULL);
> }
>
> static int selinux_task_movememory(struct task_struct *p)
> {
> return avc_has_perm(&selinux_state,
> - current_sid(), task_sid(p), SECCLASS_PROCESS,
> + current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
> PROCESS__SETSCHED, NULL);
> }
>
> @@ -4253,14 +4287,14 @@ static int selinux_task_kill(struct task_struct *p, struct kernel_siginfo *info,
> else
> secid = cred_sid(cred);
> return avc_has_perm(&selinux_state,
> - secid, task_sid(p), SECCLASS_PROCESS, perm, NULL);
> + secid, task_sid_obj(p), SECCLASS_PROCESS, perm, NULL);
> }
>
> static void selinux_task_to_inode(struct task_struct *p,
> struct inode *inode)
> {
> struct inode_security_struct *isec = selinux_inode(inode);
> - u32 sid = task_sid(p);
> + u32 sid = task_sid_obj(p);
>
> spin_lock(&isec->lock);
> isec->sclass = inode_mode_to_security_class(inode->i_mode);
> @@ -6153,7 +6187,7 @@ static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *m
> struct ipc_security_struct *isec;
> struct msg_security_struct *msec;
> struct common_audit_data ad;
> - u32 sid = task_sid(target);
> + u32 sid = task_sid_subj(target);
> int rc;
>
> isec = selinux_ipc(msq);
> @@ -7149,8 +7183,8 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
> LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid),
> LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid),
> LSM_HOOK_INIT(task_getsid, selinux_task_getsid),
> - LSM_HOOK_INIT(task_getsecid_subj, selinux_task_getsecid),
> - LSM_HOOK_INIT(task_getsecid_obj, selinux_task_getsecid),
> + LSM_HOOK_INIT(task_getsecid_subj, selinux_task_getsecid_subj),
> + LSM_HOOK_INIT(task_getsecid_obj, selinux_task_getsecid_obj),
> LSM_HOOK_INIT(task_setnice, selinux_task_setnice),
> LSM_HOOK_INIT(task_setioprio, selinux_task_setioprio),
> LSM_HOOK_INIT(task_getioprio, selinux_task_getioprio),
>
> --
> Linux-audit mailing list
> Linux-audit@redhat.com
> https://listman.redhat.com/mailman/listinfo/linux-audit
- RGB
--
Richard Guy Briggs <rgb@redhat.com>
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635
--
Linux-audit mailing list
Linux-audit@redhat.com
https://listman.redhat.com/mailman/listinfo/linux-audit
next prev parent reply other threads:[~2021-03-19 13:36 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-18 20:42 [PATCH v2 0/3] Split security_task_getsecid() into subj and obj variants Paul Moore
2021-03-18 20:42 ` [PATCH v2 1/3] lsm: separate security_task_getsecid() into subjective and objective variants Paul Moore
2021-03-18 20:57 ` Casey Schaufler
2021-03-19 3:44 ` Paul Moore
2021-03-19 13:35 ` Richard Guy Briggs
2021-03-18 20:42 ` [PATCH v2 2/3] selinux: clarify task subjective and objective credentials Paul Moore
2021-03-19 13:36 ` Richard Guy Briggs [this message]
2021-03-18 20:42 ` [PATCH v2 3/3] smack: differentiate between subjective and objective task credentials Paul Moore
2021-03-22 19:29 ` [PATCH v2 0/3] Split security_task_getsecid() into subj and obj variants Paul Moore
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210319133625.GD2781019@madcap2.tricolour.ca \
--to=rgb@redhat.com \
--cc=john.johansen@canonical.com \
--cc=linux-audit@redhat.com \
--cc=linux-security-module@vger.kernel.org \
--cc=paul@paul-moore.com \
--cc=selinux@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).