root/net/netfilter/xt_SECMARK.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. secmark_tg
  2. checkentry_lsm
  3. secmark_tg_check
  4. secmark_tg_destroy
  5. secmark_tg_init
  6. secmark_tg_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Module for modifying the secmark field of the skb, for use by
   4  * security subsystems.
   5  *
   6  * Based on the nfmark match by:
   7  * (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
   8  *
   9  * (C) 2006,2008 Red Hat, Inc., James Morris <jmorris@redhat.com>
  10  */
  11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  12 #include <linux/module.h>
  13 #include <linux/security.h>
  14 #include <linux/skbuff.h>
  15 #include <linux/netfilter/x_tables.h>
  16 #include <linux/netfilter/xt_SECMARK.h>
  17 
  18 MODULE_LICENSE("GPL");
  19 MODULE_AUTHOR("James Morris <jmorris@redhat.com>");
  20 MODULE_DESCRIPTION("Xtables: packet security mark modification");
  21 MODULE_ALIAS("ipt_SECMARK");
  22 MODULE_ALIAS("ip6t_SECMARK");
  23 
  24 #define PFX "SECMARK: "
  25 
  26 static u8 mode;
  27 
  28 static unsigned int
  29 secmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
  30 {
  31         u32 secmark = 0;
  32         const struct xt_secmark_target_info *info = par->targinfo;
  33 
  34         switch (mode) {
  35         case SECMARK_MODE_SEL:
  36                 secmark = info->secid;
  37                 break;
  38         default:
  39                 BUG();
  40         }
  41 
  42         skb->secmark = secmark;
  43         return XT_CONTINUE;
  44 }
  45 
  46 static int checkentry_lsm(struct xt_secmark_target_info *info)
  47 {
  48         int err;
  49 
  50         info->secctx[SECMARK_SECCTX_MAX - 1] = '\0';
  51         info->secid = 0;
  52 
  53         err = security_secctx_to_secid(info->secctx, strlen(info->secctx),
  54                                        &info->secid);
  55         if (err) {
  56                 if (err == -EINVAL)
  57                         pr_info_ratelimited("invalid security context \'%s\'\n",
  58                                             info->secctx);
  59                 return err;
  60         }
  61 
  62         if (!info->secid) {
  63                 pr_info_ratelimited("unable to map security context \'%s\'\n",
  64                                     info->secctx);
  65                 return -ENOENT;
  66         }
  67 
  68         err = security_secmark_relabel_packet(info->secid);
  69         if (err) {
  70                 pr_info_ratelimited("unable to obtain relabeling permission\n");
  71                 return err;
  72         }
  73 
  74         security_secmark_refcount_inc();
  75         return 0;
  76 }
  77 
  78 static int secmark_tg_check(const struct xt_tgchk_param *par)
  79 {
  80         struct xt_secmark_target_info *info = par->targinfo;
  81         int err;
  82 
  83         if (strcmp(par->table, "mangle") != 0 &&
  84             strcmp(par->table, "security") != 0) {
  85                 pr_info_ratelimited("only valid in \'mangle\' or \'security\' table, not \'%s\'\n",
  86                                     par->table);
  87                 return -EINVAL;
  88         }
  89 
  90         if (mode && mode != info->mode) {
  91                 pr_info_ratelimited("mode already set to %hu cannot mix with rules for mode %hu\n",
  92                                     mode, info->mode);
  93                 return -EINVAL;
  94         }
  95 
  96         switch (info->mode) {
  97         case SECMARK_MODE_SEL:
  98                 break;
  99         default:
 100                 pr_info_ratelimited("invalid mode: %hu\n", info->mode);
 101                 return -EINVAL;
 102         }
 103 
 104         err = checkentry_lsm(info);
 105         if (err)
 106                 return err;
 107 
 108         if (!mode)
 109                 mode = info->mode;
 110         return 0;
 111 }
 112 
 113 static void secmark_tg_destroy(const struct xt_tgdtor_param *par)
 114 {
 115         switch (mode) {
 116         case SECMARK_MODE_SEL:
 117                 security_secmark_refcount_dec();
 118         }
 119 }
 120 
 121 static struct xt_target secmark_tg_reg __read_mostly = {
 122         .name       = "SECMARK",
 123         .revision   = 0,
 124         .family     = NFPROTO_UNSPEC,
 125         .checkentry = secmark_tg_check,
 126         .destroy    = secmark_tg_destroy,
 127         .target     = secmark_tg,
 128         .targetsize = sizeof(struct xt_secmark_target_info),
 129         .me         = THIS_MODULE,
 130 };
 131 
 132 static int __init secmark_tg_init(void)
 133 {
 134         return xt_register_target(&secmark_tg_reg);
 135 }
 136 
 137 static void __exit secmark_tg_exit(void)
 138 {
 139         xt_unregister_target(&secmark_tg_reg);
 140 }
 141 
 142 module_init(secmark_tg_init);
 143 module_exit(secmark_tg_exit);

/* [<][>][^][v][top][bottom][index][help] */