@@ -21,5 +21,8 @@ struct netns_nf {
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
struct nf_hook_ops *ipv6_defrag_ops;
#endif
+#ifdef CONFIG_SECURITY
+ struct nf_hook_ops *selinux_ops;
+#endif
};
#endif
@@ -6147,6 +6147,40 @@ static struct nf_hook_ops selinux_nf_ops[] = {
#endif /* IPV6 */
};
+static int selinux_net_init(struct net *net)
+{
+ int err;
+
+ net->nf.selinux_ops =
+ kmemdup(selinux_nf_ops, sizeof(selinux_nf_ops), GFP_KERNEL);
+ if (net->nf.selinux_ops == NULL) {
+ err = -ENOMEM;
+ goto err1;
+ }
+
+ err = nf_register_hooks(net, net->nf.selinux_ops,
+ ARRAY_SIZE(selinux_nf_ops));
+ if (err < 0)
+ goto err2;
+
+ return 0;
+err2:
+ kfree(net->nf.selinux_ops);
+err1:
+ return err;
+}
+
+static void selinux_net_exit(struct net *net)
+{
+ nf_unregister_hooks(net->nf.selinux_ops, ARRAY_SIZE(selinux_nf_ops));
+ kfree(net->nf.selinux_ops);
+}
+
+static struct pernet_operations selinux_net_ops = {
+ .init = selinux_net_init,
+ .exit = selinux_net_exit,
+};
+
static int __init selinux_nf_ip_init(void)
{
int err;
@@ -6156,9 +6190,8 @@ static int __init selinux_nf_ip_init(void)
printk(KERN_DEBUG "SELinux: Registering netfilter hooks\n");
- err = nf_register_hooks(&init_net, selinux_nf_ops,
- ARRAY_SIZE(selinux_nf_ops));
- if (err)
+ err = register_pernet_subsys(&selinux_net_ops);
+ if (err < 0)
panic("SELinux: nf_register_hooks: error %d\n", err);
return 0;
@@ -6170,9 +6203,7 @@ __initcall(selinux_nf_ip_init);
static void selinux_nf_ip_exit(void)
{
printk(KERN_DEBUG "SELinux: Unregistering netfilter hooks\n");
-
- nf_unregister_hooks(&init_net, selinux_nf_ops,
- ARRAY_SIZE(selinux_nf_ops));
+ unregister_pernet_subsys(&selinux_net_ops);
}
#endif
Since pernet hooks, we need to register the hook for each netnamespace space. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- include/net/netns/netfilter.h | 3 +++ security/selinux/hooks.c | 43 +++++++++++++++++++++++++++++++++++------ 2 files changed, 40 insertions(+), 6 deletions(-)