1 /* 2 * Simplified MAC Kernel (smack) security module 3 * 4 * This file contains the Smack netfilter implementation 5 * 6 * Author: 7 * Casey Schaufler <casey@schaufler-ca.com> 8 * 9 * Copyright (C) 2014 Casey Schaufler <casey@schaufler-ca.com> 10 * Copyright (C) 2014 Intel Corporation. 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License version 2, 14 * as published by the Free Software Foundation. 15 */ 16 17 #include <linux/netfilter_ipv4.h> 18 #include <linux/netfilter_ipv6.h> 19 #include <linux/netdevice.h> 20 #include <net/inet_sock.h> 21 #include <net/net_namespace.h> 22 #include "smack.h" 23 24 #if IS_ENABLED(CONFIG_IPV6) 25 26 static unsigned int smack_ipv6_output(void *priv, 27 struct sk_buff *skb, 28 const struct nf_hook_state *state) 29 { 30 struct sock *sk = skb_to_full_sk(skb); 31 struct socket_smack *ssp; 32 struct smack_known *skp; 33 34 if (sk && sk->sk_security) { 35 ssp = sk->sk_security; 36 skp = ssp->smk_out; 37 skb->secmark = skp->smk_secid; 38 } 39 40 return NF_ACCEPT; 41 } 42 #endif /* IPV6 */ 43 44 static unsigned int smack_ipv4_output(void *priv, 45 struct sk_buff *skb, 46 const struct nf_hook_state *state) 47 { 48 struct sock *sk = skb_to_full_sk(skb); 49 struct socket_smack *ssp; 50 struct smack_known *skp; 51 52 if (sk && sk->sk_security) { 53 ssp = sk->sk_security; 54 skp = ssp->smk_out; 55 skb->secmark = skp->smk_secid; 56 } 57 58 return NF_ACCEPT; 59 } 60 61 static const struct nf_hook_ops smack_nf_ops[] = { 62 { 63 .hook = smack_ipv4_output, 64 .pf = NFPROTO_IPV4, 65 .hooknum = NF_INET_LOCAL_OUT, 66 .priority = NF_IP_PRI_SELINUX_FIRST, 67 }, 68 #if IS_ENABLED(CONFIG_IPV6) 69 { 70 .hook = smack_ipv6_output, 71 .pf = NFPROTO_IPV6, 72 .hooknum = NF_INET_LOCAL_OUT, 73 .priority = NF_IP6_PRI_SELINUX_FIRST, 74 }, 75 #endif /* IPV6 */ 76 }; 77 78 static int __net_init smack_nf_register(struct net *net) 79 { 80 return nf_register_net_hooks(net, smack_nf_ops, 81 ARRAY_SIZE(smack_nf_ops)); 82 } 83 84 static void __net_exit smack_nf_unregister(struct net *net) 85 { 86 nf_unregister_net_hooks(net, smack_nf_ops, ARRAY_SIZE(smack_nf_ops)); 87 } 88 89 static struct pernet_operations smack_net_ops = { 90 .init = smack_nf_register, 91 .exit = smack_nf_unregister, 92 }; 93 94 static int __init smack_nf_ip_init(void) 95 { 96 if (smack_enabled == 0) 97 return 0; 98 99 printk(KERN_DEBUG "Smack: Registering netfilter hooks\n"); 100 return register_pernet_subsys(&smack_net_ops); 101 } 102 103 __initcall(smack_nf_ip_init); 104