From f5895943d91b41b0368830cdb6eaffb8eda0f4c8 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 14 Mar 2014 17:44:49 +0000 Subject: KEYS: Move the flags representing required permission to linux/key.h Move the flags representing required permission to linux/key.h as the perm parameter of security_key_permission() is in terms of them - and not the permissions mask flags used in key->perm. Whilst we're at it: (1) Rename them to be KEY_NEED_xxx rather than KEY_xxx to avoid collisions with symbols in uapi/linux/input.h. (2) Don't use key_perm_t for a mask of required permissions, but rather limit it to the permissions mask attached to the key and arguments related directly to that. Signed-off-by: David Howells Tested-by: Dmitry Kasatkin --- security/selinux/hooks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'security/selinux') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 4b34847208cc..eb5c307fcc9a 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -5704,7 +5704,7 @@ static void selinux_key_free(struct key *k) static int selinux_key_permission(key_ref_t key_ref, const struct cred *cred, - key_perm_t perm) + unsigned perm) { struct key *key; struct key_security_struct *ksec; -- cgit v1.2.3-59-g8ed1b From ca7786a2f916540931d7114d441efa141c99c898 Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Tue, 29 Apr 2014 11:29:04 -0700 Subject: selinux: Report permissive mode in avc: denied messages. We cannot presently tell from an avc: denied message whether access was in fact denied or was allowed due to global or per-domain permissive mode. Add a permissive= field to the avc message to reflect this information. Signed-off-by: Stephen Smalley Acked-by: Eric Paris Signed-off-by: Paul Moore --- security/selinux/avc.c | 7 ++++++- security/selinux/hooks.c | 5 +++-- security/selinux/include/avc.h | 4 ++-- 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'security/selinux') diff --git a/security/selinux/avc.c b/security/selinux/avc.c index fc3e6628a864..a18f1fa6440b 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -444,11 +444,15 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) avc_dump_query(ab, ad->selinux_audit_data->ssid, ad->selinux_audit_data->tsid, ad->selinux_audit_data->tclass); + if (ad->selinux_audit_data->denied) { + audit_log_format(ab, " permissive=%u", + ad->selinux_audit_data->result ? 0 : 1); + } } /* This is the slow part of avc audit with big stack footprint */ noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, - u32 requested, u32 audited, u32 denied, + u32 requested, u32 audited, u32 denied, int result, struct common_audit_data *a, unsigned flags) { @@ -477,6 +481,7 @@ noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, sad.tsid = tsid; sad.audited = audited; sad.denied = denied; + sad.result = result; a->selinux_audit_data = &sad; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6ab22720c277..d3a2c2e80fec 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2770,6 +2770,7 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na static noinline int audit_inode_permission(struct inode *inode, u32 perms, u32 audited, u32 denied, + int result, unsigned flags) { struct common_audit_data ad; @@ -2780,7 +2781,7 @@ static noinline int audit_inode_permission(struct inode *inode, ad.u.inode = inode; rc = slow_avc_audit(current_sid(), isec->sid, isec->sclass, perms, - audited, denied, &ad, flags); + audited, denied, result, &ad, flags); if (rc) return rc; return 0; @@ -2822,7 +2823,7 @@ static int selinux_inode_permission(struct inode *inode, int mask) if (likely(!audited)) return rc; - rc2 = audit_inode_permission(inode, perms, audited, denied, flags); + rc2 = audit_inode_permission(inode, perms, audited, denied, rc, flags); if (rc2) return rc2; return rc; diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index f53ee3c58d0f..ddf8eec03f21 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -102,7 +102,7 @@ static inline u32 avc_audit_required(u32 requested, } int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, - u32 requested, u32 audited, u32 denied, + u32 requested, u32 audited, u32 denied, int result, struct common_audit_data *a, unsigned flags); @@ -137,7 +137,7 @@ static inline int avc_audit(u32 ssid, u32 tsid, if (likely(!audited)) return 0; return slow_avc_audit(ssid, tsid, tclass, - requested, audited, denied, + requested, audited, denied, result, a, 0); } -- cgit v1.2.3-59-g8ed1b From 5b589d44fad18228f18749360d008d5c8ff3aaf8 Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Thu, 15 May 2014 11:16:06 -0400 Subject: selinux: reject setexeccon() on MNT_NOSUID applications with -EACCES We presently prevent processes from using setexecon() to set the security label of exec()'d processes when NO_NEW_PRIVS is enabled by returning an error; however, we silently ignore setexeccon() when exec()'ing from a nosuid mounted filesystem. This patch makes things a bit more consistent by returning an error in the setexeccon()/nosuid case. Signed-off-by: Paul Moore Acked-by: Andy Lutomirski Acked-by: Stephen Smalley --- security/selinux/hooks.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'security/selinux') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index d3a2c2e80fec..d4cbf7d16f07 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2123,11 +2123,13 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) new_tsec->exec_sid = 0; /* - * Minimize confusion: if no_new_privs and a transition is - * explicitly requested, then fail the exec. + * Minimize confusion: if no_new_privs or nosuid and a + * transition is explicitly requested, then fail the exec. */ if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) return -EPERM; + if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) + return -EACCES; } else { /* Check for a default transition on this program. */ rc = security_transition_sid(old_tsec->sid, isec->sid, -- cgit v1.2.3-59-g8ed1b From 9a591f39a9d11df435652738e7f6e62a09c87909 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 15 May 2014 15:02:53 -0400 Subject: selinux: conditionally reschedule in mls_convert_context while loading selinux policy On a slow machine (with debugging enabled), upgrading selinux policy may take a considerable amount of time. Long enough that the softlockup detector gets triggered. The backtrace looks like this.. > BUG: soft lockup - CPU#2 stuck for 23s! [load_policy:19045] > Call Trace: > [] symcmp+0xf/0x20 > [] hashtab_search+0x47/0x80 > [] mls_convert_context+0xdc/0x1c0 > [] convert_context+0x378/0x460 > [] ? security_context_to_sid_core+0x240/0x240 > [] sidtab_map+0x45/0x80 > [] security_load_policy+0x3ff/0x580 > [] ? sched_clock_cpu+0xa8/0x100 > [] ? sched_clock_local+0x1d/0x80 > [] ? sched_clock_cpu+0xa8/0x100 > [] ? __change_page_attr_set_clr+0x82a/0xa50 > [] ? sched_clock_local+0x1d/0x80 > [] ? sched_clock_cpu+0xa8/0x100 > [] ? __change_page_attr_set_clr+0x82a/0xa50 > [] ? sched_clock_cpu+0xa8/0x100 > [] ? retint_restore_args+0xe/0xe > [] ? trace_hardirqs_on_caller+0xfd/0x1c0 > [] ? trace_hardirqs_on_thunk+0x3a/0x3f > [] ? rcu_irq_exit+0x68/0xb0 > [] ? retint_restore_args+0xe/0xe > [] sel_write_load+0xa7/0x770 > [] ? vfs_write+0x1c3/0x200 > [] ? security_file_permission+0x1e/0xa0 > [] vfs_write+0xbb/0x200 > [] ? fget_light+0x397/0x4b0 > [] SyS_write+0x47/0xa0 > [] tracesys+0xdd/0xe2 Stephen Smalley suggested: > Maybe put a cond_resched() within the ebitmap_for_each_positive_bit() > loop in mls_convert_context()? That seems to do the trick. Tested by downgrading and re-upgrading selinux-policy-targeted. Signed-off-by: Dave Jones Acked-by: Stephen Smalley Signed-off-by: Paul Moore --- security/selinux/ss/mls.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'security/selinux') diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index c85bc1ec040c..d307b37ddc2b 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c @@ -492,6 +492,8 @@ int mls_convert_context(struct policydb *oldp, rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1); if (rc) return rc; + + cond_resched(); } ebitmap_destroy(&c->range.level[l].cat); c->range.level[l].cat = bitmap; -- cgit v1.2.3-59-g8ed1b From ed1c96429a6aa6ffd8c4ee3e80bcde28aad270bc Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 15 May 2014 15:03:53 -0400 Subject: selinux: conditionally reschedule in hashtab_insert while loading selinux policy After silencing the sleeping warning in mls_convert_context() I started seeing similar traces from hashtab_insert. Do a cond_resched there too. Signed-off-by: Dave Jones Acked-by: Stephen Smalley Signed-off-by: Paul Moore --- security/selinux/ss/hashtab.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'security/selinux') diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c index 933e735bb185..2cc496149842 100644 --- a/security/selinux/ss/hashtab.c +++ b/security/selinux/ss/hashtab.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "hashtab.h" struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *key), @@ -40,6 +41,8 @@ int hashtab_insert(struct hashtab *h, void *key, void *datum) u32 hvalue; struct hashtab_node *prev, *cur, *newnode; + cond_resched(); + if (!h || h->nel == HASHTAB_MAX_NODES) return -EINVAL; -- cgit v1.2.3-59-g8ed1b