aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2018-04-19 10:17:14 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2018-04-19 10:19:28 -0400
commit5a786232eb69a1f870ddc0cfd69d5bdef241a2ea (patch)
tree4ef4e5a66e071e87539c0ca5e2321abbd95945cf
parentd71efb599ad42ef1e564c652d8084252bdc85edf (diff)
netfilter: xt_connmark: do not cast xt_connmark_tginfo1 to xt_connmark_tginfo2
These structures have different layout, fill xt_connmark_tginfo2 with old fields in xt_connmark_tginfo1. Based on patch from Jack Ma. Fixes: 472a73e00757 ("netfilter: xt_conntrack: Support bit-shifting for CONNMARK & MARK targets.") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--net/netfilter/xt_connmark.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
index 4b424e6caf3e..94df000abb92 100644
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -36,9 +36,7 @@ MODULE_ALIAS("ipt_connmark");
36MODULE_ALIAS("ip6t_connmark"); 36MODULE_ALIAS("ip6t_connmark");
37 37
38static unsigned int 38static unsigned int
39connmark_tg_shift(struct sk_buff *skb, 39connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
40 const struct xt_connmark_tginfo1 *info,
41 u8 shift_bits, u8 shift_dir)
42{ 40{
43 enum ip_conntrack_info ctinfo; 41 enum ip_conntrack_info ctinfo;
44 u_int32_t new_targetmark; 42 u_int32_t new_targetmark;
@@ -52,10 +50,11 @@ connmark_tg_shift(struct sk_buff *skb,
52 switch (info->mode) { 50 switch (info->mode) {
53 case XT_CONNMARK_SET: 51 case XT_CONNMARK_SET:
54 newmark = (ct->mark & ~info->ctmask) ^ info->ctmark; 52 newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
55 if (shift_dir == D_SHIFT_RIGHT) 53 if (info->shift_dir == D_SHIFT_RIGHT)
56 newmark >>= shift_bits; 54 newmark >>= info->shift_bits;
57 else 55 else
58 newmark <<= shift_bits; 56 newmark <<= info->shift_bits;
57
59 if (ct->mark != newmark) { 58 if (ct->mark != newmark) {
60 ct->mark = newmark; 59 ct->mark = newmark;
61 nf_conntrack_event_cache(IPCT_MARK, ct); 60 nf_conntrack_event_cache(IPCT_MARK, ct);
@@ -63,10 +62,11 @@ connmark_tg_shift(struct sk_buff *skb,
63 break; 62 break;
64 case XT_CONNMARK_SAVE: 63 case XT_CONNMARK_SAVE:
65 new_targetmark = (skb->mark & info->nfmask); 64 new_targetmark = (skb->mark & info->nfmask);
66 if (shift_dir == D_SHIFT_RIGHT) 65 if (info->shift_dir == D_SHIFT_RIGHT)
67 new_targetmark >>= shift_bits; 66 new_targetmark >>= info->shift_bits;
68 else 67 else
69 new_targetmark <<= shift_bits; 68 new_targetmark <<= info->shift_bits;
69
70 newmark = (ct->mark & ~info->ctmask) ^ 70 newmark = (ct->mark & ~info->ctmask) ^
71 new_targetmark; 71 new_targetmark;
72 if (ct->mark != newmark) { 72 if (ct->mark != newmark) {
@@ -76,10 +76,11 @@ connmark_tg_shift(struct sk_buff *skb,
76 break; 76 break;
77 case XT_CONNMARK_RESTORE: 77 case XT_CONNMARK_RESTORE:
78 new_targetmark = (ct->mark & info->ctmask); 78 new_targetmark = (ct->mark & info->ctmask);
79 if (shift_dir == D_SHIFT_RIGHT) 79 if (info->shift_dir == D_SHIFT_RIGHT)
80 new_targetmark >>= shift_bits; 80 new_targetmark >>= info->shift_bits;
81 else 81 else
82 new_targetmark <<= shift_bits; 82 new_targetmark <<= info->shift_bits;
83
83 newmark = (skb->mark & ~info->nfmask) ^ 84 newmark = (skb->mark & ~info->nfmask) ^
84 new_targetmark; 85 new_targetmark;
85 skb->mark = newmark; 86 skb->mark = newmark;
@@ -92,8 +93,14 @@ static unsigned int
92connmark_tg(struct sk_buff *skb, const struct xt_action_param *par) 93connmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
93{ 94{
94 const struct xt_connmark_tginfo1 *info = par->targinfo; 95 const struct xt_connmark_tginfo1 *info = par->targinfo;
95 96 const struct xt_connmark_tginfo2 info2 = {
96 return connmark_tg_shift(skb, info, 0, 0); 97 .ctmark = info->ctmark,
98 .ctmask = info->ctmask,
99 .nfmask = info->nfmask,
100 .mode = info->mode,
101 };
102
103 return connmark_tg_shift(skb, &info2);
97} 104}
98 105
99static unsigned int 106static unsigned int
@@ -101,8 +108,7 @@ connmark_tg_v2(struct sk_buff *skb, const struct xt_action_param *par)
101{ 108{
102 const struct xt_connmark_tginfo2 *info = par->targinfo; 109 const struct xt_connmark_tginfo2 *info = par->targinfo;
103 110
104 return connmark_tg_shift(skb, (const struct xt_connmark_tginfo1 *)info, 111 return connmark_tg_shift(skb, info);
105 info->shift_bits, info->shift_dir);
106} 112}
107 113
108static int connmark_tg_check(const struct xt_tgchk_param *par) 114static int connmark_tg_check(const struct xt_tgchk_param *par)