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