smack_netfilter.c 2.2 KB

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