diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2018-04-19 10:17:14 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2018-04-19 10:19:28 -0400 |
commit | 5a786232eb69a1f870ddc0cfd69d5bdef241a2ea (patch) | |
tree | 4ef4e5a66e071e87539c0ca5e2321abbd95945cf | |
parent | d71efb599ad42ef1e564c652d8084252bdc85edf (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.c | 38 |
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"); | |||
36 | MODULE_ALIAS("ip6t_connmark"); | 36 | MODULE_ALIAS("ip6t_connmark"); |
37 | 37 | ||
38 | static unsigned int | 38 | static unsigned int |
39 | connmark_tg_shift(struct sk_buff *skb, | 39 | connmark_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 | |||
92 | connmark_tg(struct sk_buff *skb, const struct xt_action_param *par) | 93 | connmark_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 | ||
99 | static unsigned int | 106 | static 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 | ||
108 | static int connmark_tg_check(const struct xt_tgchk_param *par) | 114 | static int connmark_tg_check(const struct xt_tgchk_param *par) |