Skip to content

Commit d6d3f08

Browse files
Jan Engelhardtkaber
authored andcommitted
netfilter: xtables: conntrack match revision 2
As reported by Philip, the UNTRACKED state bit does not fit within the 8-bit state_mask member. Enlarge state_mask and give status_mask a few more bits too. Reported-by: Philip Craig <philipc@snapgear.com> References: http://markmail.org/thread/b7eg6aovfh4agyz7 Signed-off-by: Jan Engelhardt <jengelh@medozas.de> Signed-off-by: Patrick McHardy <kaber@trash.net>
1 parent 8a3af79 commit d6d3f08

File tree

2 files changed

+73
-6
lines changed

2 files changed

+73
-6
lines changed

include/linux/netfilter/xt_conntrack.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,17 @@ struct xt_conntrack_mtinfo1 {
8181
__u8 state_mask, status_mask;
8282
};
8383

84+
struct xt_conntrack_mtinfo2 {
85+
union nf_inet_addr origsrc_addr, origsrc_mask;
86+
union nf_inet_addr origdst_addr, origdst_mask;
87+
union nf_inet_addr replsrc_addr, replsrc_mask;
88+
union nf_inet_addr repldst_addr, repldst_mask;
89+
__u32 expires_min, expires_max;
90+
__u16 l4proto;
91+
__be16 origsrc_port, origdst_port;
92+
__be16 replsrc_port, repldst_port;
93+
__u16 match_flags, invert_flags;
94+
__u16 state_mask, status_mask;
95+
};
96+
8497
#endif /*_XT_CONNTRACK_H*/

net/netfilter/xt_conntrack.c

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ conntrack_addrcmp(const union nf_inet_addr *kaddr,
129129

130130
static inline bool
131131
conntrack_mt_origsrc(const struct nf_conn *ct,
132-
const struct xt_conntrack_mtinfo1 *info,
132+
const struct xt_conntrack_mtinfo2 *info,
133133
u_int8_t family)
134134
{
135135
return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3,
@@ -138,7 +138,7 @@ conntrack_mt_origsrc(const struct nf_conn *ct,
138138

139139
static inline bool
140140
conntrack_mt_origdst(const struct nf_conn *ct,
141-
const struct xt_conntrack_mtinfo1 *info,
141+
const struct xt_conntrack_mtinfo2 *info,
142142
u_int8_t family)
143143
{
144144
return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3,
@@ -147,7 +147,7 @@ conntrack_mt_origdst(const struct nf_conn *ct,
147147

148148
static inline bool
149149
conntrack_mt_replsrc(const struct nf_conn *ct,
150-
const struct xt_conntrack_mtinfo1 *info,
150+
const struct xt_conntrack_mtinfo2 *info,
151151
u_int8_t family)
152152
{
153153
return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3,
@@ -156,15 +156,15 @@ conntrack_mt_replsrc(const struct nf_conn *ct,
156156

157157
static inline bool
158158
conntrack_mt_repldst(const struct nf_conn *ct,
159-
const struct xt_conntrack_mtinfo1 *info,
159+
const struct xt_conntrack_mtinfo2 *info,
160160
u_int8_t family)
161161
{
162162
return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3,
163163
&info->repldst_addr, &info->repldst_mask, family);
164164
}
165165

166166
static inline bool
167-
ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info,
167+
ct_proto_port_check(const struct xt_conntrack_mtinfo2 *info,
168168
const struct nf_conn *ct)
169169
{
170170
const struct nf_conntrack_tuple *tuple;
@@ -204,7 +204,7 @@ ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info,
204204
static bool
205205
conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
206206
{
207-
const struct xt_conntrack_mtinfo1 *info = par->matchinfo;
207+
const struct xt_conntrack_mtinfo2 *info = par->matchinfo;
208208
enum ip_conntrack_info ctinfo;
209209
const struct nf_conn *ct;
210210
unsigned int statebit;
@@ -278,6 +278,16 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
278278
return true;
279279
}
280280

281+
static bool
282+
conntrack_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
283+
{
284+
const struct xt_conntrack_mtinfo2 *const *info = par->matchinfo;
285+
struct xt_match_param newpar = *par;
286+
287+
newpar.matchinfo = *info;
288+
return conntrack_mt(skb, &newpar);
289+
}
290+
281291
static bool conntrack_mt_check(const struct xt_mtchk_param *par)
282292
{
283293
if (nf_ct_l3proto_try_module_get(par->family) < 0) {
@@ -288,11 +298,45 @@ static bool conntrack_mt_check(const struct xt_mtchk_param *par)
288298
return true;
289299
}
290300

301+
static bool conntrack_mt_check_v1(const struct xt_mtchk_param *par)
302+
{
303+
struct xt_conntrack_mtinfo1 *info = par->matchinfo;
304+
struct xt_conntrack_mtinfo2 *up;
305+
int ret = conntrack_mt_check(par);
306+
307+
if (ret < 0)
308+
return ret;
309+
310+
up = kmalloc(sizeof(*up), GFP_KERNEL);
311+
if (up == NULL) {
312+
nf_ct_l3proto_module_put(par->family);
313+
return -ENOMEM;
314+
}
315+
316+
/*
317+
* The strategy here is to minimize the overhead of v1 matching,
318+
* by prebuilding a v2 struct and putting the pointer into the
319+
* v1 dataspace.
320+
*/
321+
memcpy(up, info, offsetof(typeof(*info), state_mask));
322+
up->state_mask = info->state_mask;
323+
up->status_mask = info->status_mask;
324+
*(void **)info = up;
325+
return true;
326+
}
327+
291328
static void conntrack_mt_destroy(const struct xt_mtdtor_param *par)
292329
{
293330
nf_ct_l3proto_module_put(par->family);
294331
}
295332

333+
static void conntrack_mt_destroy_v1(const struct xt_mtdtor_param *par)
334+
{
335+
struct xt_conntrack_mtinfo2 **info = par->matchinfo;
336+
kfree(*info);
337+
conntrack_mt_destroy(par);
338+
}
339+
296340
#ifdef CONFIG_COMPAT
297341
struct compat_xt_conntrack_info
298342
{
@@ -363,6 +407,16 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = {
363407
.revision = 1,
364408
.family = NFPROTO_UNSPEC,
365409
.matchsize = sizeof(struct xt_conntrack_mtinfo1),
410+
.match = conntrack_mt_v1,
411+
.checkentry = conntrack_mt_check_v1,
412+
.destroy = conntrack_mt_destroy_v1,
413+
.me = THIS_MODULE,
414+
},
415+
{
416+
.name = "conntrack",
417+
.revision = 2,
418+
.family = NFPROTO_UNSPEC,
419+
.matchsize = sizeof(struct xt_conntrack_mtinfo2),
366420
.match = conntrack_mt,
367421
.checkentry = conntrack_mt_check,
368422
.destroy = conntrack_mt_destroy,

0 commit comments

Comments
 (0)