diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-31 13:10:22 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-31 13:10:22 -0800 |
commit | 2a7149031457c5dd05f670737a9dd5d32524f145 (patch) | |
tree | c41f725c2440cfc5d2f12e36c71c1af1e4649324 /security | |
parent | 3c29548f87f9545f2f3c1cd1a784fae8ad2d53ba (diff) | |
parent | d19dfe58b7ecbef3bd0c403c650200c57913ba1b (diff) |
Merge branch 'next-smack' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull smack updates from James Morris:
"Two minor fixes"
* 'next-smack' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
Smack: Privilege check on key operations
Smack: fix dereferenced before check
Diffstat (limited to 'security')
-rw-r--r-- | security/smack/smack.h | 1 | ||||
-rw-r--r-- | security/smack/smack_access.c | 40 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 10 |
3 files changed, 39 insertions, 12 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h index 6a71fc7831ab..f7db791fb566 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -321,6 +321,7 @@ struct smack_known *smk_import_entry(const char *, int); void smk_insert_entry(struct smack_known *skp); struct smack_known *smk_find_entry(const char *); bool smack_privileged(int cap); +bool smack_privileged_cred(int cap, const struct cred *cred); void smk_destroy_label_list(struct list_head *list); /* diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index 1a3004189447..9a4c0ad46518 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c @@ -623,26 +623,24 @@ struct smack_known *smack_from_secid(const u32 secid) LIST_HEAD(smack_onlycap_list); DEFINE_MUTEX(smack_onlycap_lock); -/* +/** + * smack_privileged_cred - are all privilege requirements met by cred + * @cap: The requested capability + * @cred: the credential to use + * * Is the task privileged and allowed to be privileged * by the onlycap rule. * * Returns true if the task is allowed to be privileged, false if it's not. */ -bool smack_privileged(int cap) +bool smack_privileged_cred(int cap, const struct cred *cred) { - struct smack_known *skp = smk_of_current(); + struct task_smack *tsp = cred->security; + struct smack_known *skp = tsp->smk_task; struct smack_known_list_elem *sklep; int rc; - /* - * All kernel tasks are privileged - */ - if (unlikely(current->flags & PF_KTHREAD)) - return true; - - rc = cap_capable(current_cred(), &init_user_ns, cap, - SECURITY_CAP_AUDIT); + rc = cap_capable(cred, &init_user_ns, cap, SECURITY_CAP_AUDIT); if (rc) return false; @@ -662,3 +660,23 @@ bool smack_privileged(int cap) return false; } + +/** + * smack_privileged - are all privilege requirements met + * @cap: The requested capability + * + * Is the task privileged and allowed to be privileged + * by the onlycap rule. + * + * Returns true if the task is allowed to be privileged, false if it's not. + */ +bool smack_privileged(int cap) +{ + /* + * All kernel tasks are privileged + */ + if (unlikely(current->flags & PF_KTHREAD)) + return true; + + return smack_privileged_cred(cap, current_cred()); +} diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 14cc7940b36d..03fdecba93bb 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -2866,12 +2866,16 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, #endif #ifdef SMACK_IPV6_SECMARK_LABELING struct smack_known *rsp; - struct socket_smack *ssp = sock->sk->sk_security; + struct socket_smack *ssp; #endif if (sock->sk == NULL) return 0; +#ifdef SMACK_IPV6_SECMARK_LABELING + ssp = sock->sk->sk_security; +#endif + switch (sock->sk->sk_family) { case PF_INET: if (addrlen < sizeof(struct sockaddr_in)) @@ -4365,6 +4369,10 @@ static int smack_key_permission(key_ref_t key_ref, */ if (tkp == NULL) return -EACCES; + + if (smack_privileged_cred(CAP_MAC_OVERRIDE, cred)) + return 0; + #ifdef CONFIG_AUDIT smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY); ad.a.u.key_struct.key = keyp->serial; |