From: Casey Schaufler <casey@schaufler-ca.com>
To: Paolo Abeni <pabeni@redhat.com>, linux-security-module@vger.kernel.org
Cc: "David S. Miller" <davem@davemloft.net>,
James Morris <james.l.morris@oracle.com>,
Paul Moore <paul@paul-moore.com>,
Andreas Gruenbacher <agruenba@redhat.com>,
Stephen Smalley <sds@tycho.nsa.gov>,
Florian Westphal <fw@strlen.de>,
netdev@vger.kernel.org
Subject: Re: [RFC PATCH 2/2] selinux: implement support for dynamic net hook [de-]registration
Date: Wed, 6 Apr 2016 15:32:07 -0700 [thread overview]
Message-ID: <57058E67.5020502@schaufler-ca.com> (raw)
In-Reply-To: <b7f1a4578e0617c7361dd392282e03556aa37b46.1459934322.git.pabeni@redhat.com>
On 4/6/2016 2:51 AM, Paolo Abeni wrote:
> This patch leverage the netlbl_changed() hook to perform on demand
> registration and deregistration of the netfilter hooks and the
> socket_sock_rcv_skb hook.
>
> With default policy and empty netfilter/netlabel configuration, the
> above hooks are not registered and this allows avoiding nf_hook_slow
> in the xmit path and socket_sock_rcv_skb() in the rx path.
There is no reason to assume that there is a relationship between
a netlabel configuration and a netfilter configuration. Smack always
has a netlabel configuration. Security modules (e.g. AppArmor) may
well use netfilter without netlabel.
Please stop assuming that security == SELinux.
>
> This gives measurable network performance improvement in both
> directions.
In the case where SELinux is enabled and netfilter is not.
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> ---
> security/selinux/hooks.c | 72 +++++++++++++++++++++++++++++++------
> security/selinux/include/security.h | 1 +
> security/selinux/ss/services.c | 1 +
> security/selinux/xfrm.c | 4 +++
> 4 files changed, 68 insertions(+), 10 deletions(-)
>
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 912deee..a3baa69 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -4745,11 +4745,13 @@ static int selinux_secmark_relabel_packet(u32 sid)
> static void selinux_secmark_refcount_inc(void)
> {
> atomic_inc(&selinux_secmark_refcount);
> + selinux_net_update();
> }
>
> static void selinux_secmark_refcount_dec(void)
> {
> atomic_dec(&selinux_secmark_refcount);
> + selinux_net_update();
> }
>
> static void selinux_req_classify_flow(const struct request_sock *req,
> @@ -4836,6 +4838,11 @@ static int selinux_tun_dev_open(void *security)
> return 0;
> }
>
> +static void selinux_netlbl_changed(void)
> +{
> + selinux_net_update();
> +}
> +
> static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
> {
> int err = 0;
> @@ -6091,7 +6098,6 @@ static struct security_hook_list selinux_hooks[] = {
> LSM_HOOK_INIT(socket_getsockopt, selinux_socket_getsockopt),
> LSM_HOOK_INIT(socket_setsockopt, selinux_socket_setsockopt),
> LSM_HOOK_INIT(socket_shutdown, selinux_socket_shutdown),
> - LSM_HOOK_INIT(socket_sock_rcv_skb, selinux_socket_sock_rcv_skb),
> LSM_HOOK_INIT(socket_getpeersec_stream,
> selinux_socket_getpeersec_stream),
> LSM_HOOK_INIT(socket_getpeersec_dgram, selinux_socket_getpeersec_dgram),
> @@ -6113,6 +6119,7 @@ static struct security_hook_list selinux_hooks[] = {
> LSM_HOOK_INIT(tun_dev_attach_queue, selinux_tun_dev_attach_queue),
> LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach),
> LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open),
> + LSM_HOOK_INIT(netlbl_changed, selinux_netlbl_changed),
>
> #ifdef CONFIG_SECURITY_NETWORK_XFRM
> LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc),
> @@ -6145,6 +6152,11 @@ static struct security_hook_list selinux_hooks[] = {
> #endif
> };
>
> +/* dynamically registered/unregisterd */
> +static struct security_hook_list selinux_sock_hooks[] = {
> + LSM_HOOK_INIT(socket_sock_rcv_skb, selinux_socket_sock_rcv_skb),
> +};
> +
> static __init int selinux_init(void)
> {
> if (!security_module_enable("selinux")) {
> @@ -6240,7 +6252,9 @@ static struct nf_hook_ops selinux_nf_ops[] = {
> #endif /* IPV6 */
> };
>
> -static int __init selinux_nf_ip_init(void)
> +static bool nf_hooks_registered;
> +
> +static int selinux_nf_ip_init(void)
> {
> int err;
>
> @@ -6253,25 +6267,21 @@ static int __init selinux_nf_ip_init(void)
> if (err)
> panic("SELinux: nf_register_hooks: error %d\n", err);
>
> + nf_hooks_registered = true;
> return 0;
> }
>
> -__initcall(selinux_nf_ip_init);
> -
> -#ifdef CONFIG_SECURITY_SELINUX_DISABLE
> static void selinux_nf_ip_exit(void)
> {
> printk(KERN_DEBUG "SELinux: Unregistering netfilter hooks\n");
>
> nf_unregister_hooks(selinux_nf_ops, ARRAY_SIZE(selinux_nf_ops));
> + nf_hooks_registered = false;
> }
> -#endif
>
> #else /* CONFIG_NETFILTER */
>
> -#ifdef CONFIG_SECURITY_SELINUX_DISABLE
> #define selinux_nf_ip_exit()
> -#endif
>
> #endif /* CONFIG_NETFILTER */
>
> @@ -6300,8 +6310,8 @@ int selinux_disable(void)
> /* Try to destroy the avc node cache */
> avc_disable();
>
> - /* Unregister netfilter hooks. */
> - selinux_nf_ip_exit();
> + /* Unregister net hooks. */
> + selinux_net_update();
>
> /* Unregister selinuxfs. */
> exit_sel_fs();
> @@ -6309,3 +6319,45 @@ int selinux_disable(void)
> return 0;
> }
> #endif
> +
> +DEFINE_MUTEX(selinux_net_mutex);
> +
> +static bool nf_hooks_required(void)
> +{
> + return (selinux_secmark_enabled() || selinux_peerlbl_enabled() ||
> + !selinux_policycap_netpeer) && selinux_enabled;
> +}
> +
> +static bool sock_hooks_required(void)
> +{
> + return (!selinux_policycap_netpeer || selinux_secmark_enabled() ||
> + selinux_peerlbl_enabled()) && selinux_enabled;
> +}
> +
> +static bool sock_hooks_registered;
> +
> +void selinux_net_update(void)
> +{
> + if ((nf_hooks_required() == nf_hooks_registered) &&
> + (sock_hooks_required() == sock_hooks_registered))
> + return;
> +
> + mutex_lock(&selinux_net_mutex);
> + if (nf_hooks_required() != nf_hooks_registered) {
> + if (!nf_hooks_registered)
> + selinux_nf_ip_init();
> + else
> + selinux_nf_ip_exit();
> + }
> +
> + if (sock_hooks_required() != sock_hooks_registered) {
> + if (!sock_hooks_registered)
> + security_add_hooks(selinux_sock_hooks,
> + ARRAY_SIZE(selinux_sock_hooks));
> + else
> + security_delete_hooks(selinux_sock_hooks,
> + ARRAY_SIZE(selinux_sock_hooks));
> + sock_hooks_registered = !sock_hooks_registered;
> + }
> + mutex_unlock(&selinux_net_mutex);
> +}
> diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
> index 38feb55..0428ab4 100644
> --- a/security/selinux/include/security.h
> +++ b/security/selinux/include/security.h
> @@ -261,6 +261,7 @@ extern void selinux_status_update_setenforce(int enforcing);
> extern void selinux_status_update_policyload(int seqno);
> extern void selinux_complete_init(void);
> extern int selinux_disable(void);
> +extern void selinux_net_update(void);
> extern void exit_sel_fs(void);
> extern struct path selinux_null;
> extern struct vfsmount *selinuxfs_mount;
> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index ebda973..c509018 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -2016,6 +2016,7 @@ static void security_load_policycaps(void)
> POLICYDB_CAPABILITY_OPENPERM);
> selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps,
> POLICYDB_CAPABILITY_ALWAYSNETWORK);
> + selinux_net_update();
> }
>
> static int security_preserve_bools(struct policydb *p);
> diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
> index 56e354f..cc2b0d4 100644
> --- a/security/selinux/xfrm.c
> +++ b/security/selinux/xfrm.c
> @@ -112,6 +112,7 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
>
> *ctxp = ctx;
> atomic_inc(&selinux_xfrm_refcount);
> + selinux_net_update();
> return 0;
>
> err:
> @@ -128,6 +129,7 @@ static void selinux_xfrm_free(struct xfrm_sec_ctx *ctx)
> return;
>
> atomic_dec(&selinux_xfrm_refcount);
> + selinux_net_update();
> kfree(ctx);
> }
>
> @@ -303,6 +305,7 @@ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
> if (!new_ctx)
> return -ENOMEM;
> atomic_inc(&selinux_xfrm_refcount);
> + selinux_net_update();
> *new_ctxp = new_ctx;
>
> return 0;
> @@ -370,6 +373,7 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
>
> x->security = ctx;
> atomic_inc(&selinux_xfrm_refcount);
> + selinux_net_update();
> out:
> kfree(ctx_str);
> return rc;
next prev parent reply other threads:[~2016-04-06 22:38 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-06 9:51 [RFC PATCH 0/2] selinux: avoid nf hooks overhead when not needed Paolo Abeni
2016-04-06 9:51 ` [RFC PATCH 1/2] security: add hook for netlabel status change notification Paolo Abeni
2016-04-06 9:51 ` [RFC PATCH 2/2] selinux: implement support for dynamic net hook [de-]registration Paolo Abeni
2016-04-06 22:32 ` Casey Schaufler [this message]
2016-04-06 12:33 ` [RFC PATCH 0/2] selinux: avoid nf hooks overhead when not needed Paul Moore
2016-04-06 14:03 ` Paolo Abeni
2016-04-06 14:07 ` Paul Moore
2016-04-06 18:23 ` David Miller
2016-04-06 18:36 ` Paul Moore
2016-04-06 19:39 ` David Miller
2016-04-06 20:07 ` Paul Moore
2016-04-06 22:14 ` Florian Westphal
2016-04-06 23:15 ` Paul Moore
2016-04-06 23:45 ` Florian Westphal
2016-04-07 18:55 ` Paul Moore
2016-04-12 8:52 ` Paolo Abeni
2016-04-12 13:57 ` Casey Schaufler
2016-04-13 11:57 ` Paolo Abeni
2016-04-13 15:06 ` Casey Schaufler
2016-04-14 22:53 ` Paul Moore
2016-04-15 9:38 ` Paolo Abeni
2016-04-15 15:54 ` Casey Schaufler
2016-04-06 21:37 ` Casey Schaufler
2016-04-06 21:43 ` Paul Moore
2016-04-06 21:43 ` Casey Schaufler
2016-04-07 7:59 ` Paolo Abeni
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=57058E67.5020502@schaufler-ca.com \
--to=casey@schaufler-ca.com \
--cc=agruenba@redhat.com \
--cc=davem@davemloft.net \
--cc=fw@strlen.de \
--cc=james.l.morris@oracle.com \
--cc=linux-security-module@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=paul@paul-moore.com \
--cc=sds@tycho.nsa.gov \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.