From e661a58279132da0127c67705e59d12f6027858d Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 21 Apr 2017 11:49:08 +0200 Subject: [PATCH 1/3] smack: use pernet operations for hook registration It will allow us to remove the old netfilter hook api in the near future. Signed-off-by: Florian Westphal Signed-off-by: Casey Schaufler --- security/smack/smack_netfilter.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c index 205b785fb400..cdeb0f3243dd 100644 --- a/security/smack/smack_netfilter.c +++ b/security/smack/smack_netfilter.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "smack.h" #if IS_ENABLED(CONFIG_IPV6) @@ -74,20 +75,29 @@ static struct nf_hook_ops smack_nf_ops[] = { #endif /* IPV6 */ }; +static int __net_init smack_nf_register(struct net *net) +{ + return nf_register_net_hooks(net, smack_nf_ops, + ARRAY_SIZE(smack_nf_ops)); +} + +static void __net_exit smack_nf_unregister(struct net *net) +{ + nf_unregister_net_hooks(net, smack_nf_ops, ARRAY_SIZE(smack_nf_ops)); +} + +static struct pernet_operations smack_net_ops = { + .init = smack_nf_register, + .exit = smack_nf_unregister, +}; + static int __init smack_nf_ip_init(void) { - int err; - if (smack_enabled == 0) return 0; printk(KERN_DEBUG "Smack: Registering netfilter hooks\n"); - - err = nf_register_hooks(smack_nf_ops, ARRAY_SIZE(smack_nf_ops)); - if (err) - pr_info("Smack: nf_register_hooks: error %d\n", err); - - return 0; + return register_pernet_subsys(&smack_net_ops); } __initcall(smack_nf_ip_init); From 51d59af26fe81967e0d7ec92bd9381d3b26434f3 Mon Sep 17 00:00:00 2001 From: Casey Schaufler Date: Wed, 31 May 2017 08:53:42 -0700 Subject: [PATCH 2/3] Smack: Safer check for a socket in file_receive The check of S_ISSOCK() in smack_file_receive() is not appropriate if the passed descriptor is a socket. Reported-by: Stephen Smalley Signed-off-by: Casey Schaufler --- security/smack/smack_lsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 658f5d8c7e76..463af86812c7 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -1915,7 +1915,7 @@ static int smack_file_receive(struct file *file) smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); - if (S_ISSOCK(inode->i_mode)) { + if (inode->i_sb->s_magic == SOCKFS_MAGIC) { sock = SOCKET_I(inode); ssp = sock->sk->sk_security; tsp = current_security(); From f28e783ff668cf5757182f6b00d488be37226bff Mon Sep 17 00:00:00 2001 From: Casey Schaufler Date: Wed, 31 May 2017 13:23:41 -0700 Subject: [PATCH 3/3] Smack: Use cap_capable in privilege check Use cap_capable() rather than capable() in the Smack privilege check as the former does not invoke other security module privilege check, while the later does. This becomes important when stacking. It may be a problem even with minor modules. Signed-off-by: Casey Schaufler --- security/smack/smack.h | 2 +- security/smack/smack_access.c | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/security/smack/smack.h b/security/smack/smack.h index 612b810fbbc6..6a71fc7831ab 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -320,7 +320,7 @@ int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int); 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 *); -int smack_privileged(int cap); +bool smack_privileged(int cap); void smk_destroy_label_list(struct list_head *list); /* diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index a4b2e6b94abd..1a3004189447 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c @@ -627,35 +627,38 @@ DEFINE_MUTEX(smack_onlycap_lock); * Is the task privileged and allowed to be privileged * by the onlycap rule. * - * Returns 1 if the task is allowed to be privileged, 0 if it's not. + * Returns true if the task is allowed to be privileged, false if it's not. */ -int smack_privileged(int cap) +bool smack_privileged(int cap) { struct smack_known *skp = smk_of_current(); struct smack_known_list_elem *sklep; + int rc; /* * All kernel tasks are privileged */ if (unlikely(current->flags & PF_KTHREAD)) - return 1; + return true; - if (!capable(cap)) - return 0; + rc = cap_capable(current_cred(), &init_user_ns, cap, + SECURITY_CAP_AUDIT); + if (rc) + return false; rcu_read_lock(); if (list_empty(&smack_onlycap_list)) { rcu_read_unlock(); - return 1; + return true; } list_for_each_entry_rcu(sklep, &smack_onlycap_list, list) { if (sklep->smk_label == skp) { rcu_read_unlock(); - return 1; + return true; } } rcu_read_unlock(); - return 0; + return false; }