smack_netfilter.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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. #include <linux/netfilter_ipv4.h>
  17. #include <linux/netfilter_ipv6.h>
  18. #include <linux/netdevice.h>
  19. #include <net/inet_sock.h>
  20. #include <net/net_namespace.h>
  21. #include "smack.h"
  22. #if IS_ENABLED(CONFIG_IPV6)
  23. static unsigned int smack_ipv6_output(void *priv,
  24. struct sk_buff *skb,
  25. const struct nf_hook_state *state)
  26. {
  27. struct sock *sk = skb_to_full_sk(skb);
  28. struct socket_smack *ssp;
  29. struct smack_known *skp;
  30. if (sk && sk->sk_security) {
  31. ssp = sk->sk_security;
  32. skp = ssp->smk_out;
  33. skb->secmark = skp->smk_secid;
  34. }
  35. return NF_ACCEPT;
  36. }
  37. #endif /* IPV6 */
  38. static unsigned int smack_ipv4_output(void *priv,
  39. struct sk_buff *skb,
  40. const struct nf_hook_state *state)
  41. {
  42. struct sock *sk = skb_to_full_sk(skb);
  43. struct socket_smack *ssp;
  44. struct smack_known *skp;
  45. if (sk && sk->sk_security) {
  46. ssp = sk->sk_security;
  47. skp = ssp->smk_out;
  48. skb->secmark = skp->smk_secid;
  49. }
  50. return NF_ACCEPT;
  51. }
  52. static const struct nf_hook_ops smack_nf_ops[] = {
  53. {
  54. .hook = smack_ipv4_output,
  55. .pf = NFPROTO_IPV4,
  56. .hooknum = NF_INET_LOCAL_OUT,
  57. .priority = NF_IP_PRI_SELINUX_FIRST,
  58. },
  59. #if IS_ENABLED(CONFIG_IPV6)
  60. {
  61. .hook = smack_ipv6_output,
  62. .pf = NFPROTO_IPV6,
  63. .hooknum = NF_INET_LOCAL_OUT,
  64. .priority = NF_IP6_PRI_SELINUX_FIRST,
  65. },
  66. #endif /* IPV6 */
  67. };
  68. static int __net_init smack_nf_register(struct net *net)
  69. {
  70. return nf_register_net_hooks(net, smack_nf_ops,
  71. ARRAY_SIZE(smack_nf_ops));
  72. }
  73. static void __net_exit smack_nf_unregister(struct net *net)
  74. {
  75. nf_unregister_net_hooks(net, smack_nf_ops, ARRAY_SIZE(smack_nf_ops));
  76. }
  77. static struct pernet_operations smack_net_ops = {
  78. .init = smack_nf_register,
  79. .exit = smack_nf_unregister,
  80. };
  81. static int __init smack_nf_ip_init(void)
  82. {
  83. if (smack_enabled == 0)
  84. return 0;
  85. printk(KERN_DEBUG "Smack: Registering netfilter hooks\n");
  86. return register_pernet_subsys(&smack_net_ops);
  87. }
  88. __initcall(smack_nf_ip_init);