Commit 5c4b274981950049af3330f14ed9e9aa25afb2fb
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: ==================== The following patchset contains three Netfilter fixes and update for the MAINTAINER file for your net tree, they are: * Fix crash if nf_log_packet is called from conntrack, in that case both interfaces are NULL, from Hans Schillstrom. This bug introduced with the logging netns support in the previous merge window. * Fix compilation of nf_log and nf_queue without CONFIG_PROC_FS, from myself. This bug was introduced in the previous merge window with the new netns support for the netfilter logging infrastructure. * Fix possible crash in xt_TCPOPTSTRIP due to missing sanity checkings to validate that the TCP header is well-formed, from myself. I can find this bug in 2.6.25, probably it's been there since the beginning. I'll pass this to -stable. * Update MAINTAINER file to point to new nf trees at git.kernel.org, remove Harald and use M: instead of P: (now obsolete tag) to keep Jozsef in the list of people. Please, consider pulling this. Thanks! ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 12 changed files Side-by-side Diff
- MAINTAINERS
- include/net/netfilter/nf_log.h
- include/net/netfilter/nfnetlink_log.h
- net/bridge/netfilter/ebt_log.c
- net/bridge/netfilter/ebt_ulog.c
- net/ipv4/netfilter/ipt_ULOG.c
- net/netfilter/nf_log.c
- net/netfilter/nfnetlink_log.c
- net/netfilter/nfnetlink_queue_core.c
- net/netfilter/xt_LOG.c
- net/netfilter/xt_NFLOG.c
- net/netfilter/xt_TCPOPTSTRIP.c
MAINTAINERS
... | ... | @@ -5509,18 +5509,18 @@ |
5509 | 5509 | F: Documentation/networking/vxge.txt |
5510 | 5510 | F: drivers/net/ethernet/neterion/ |
5511 | 5511 | |
5512 | -NETFILTER/IPTABLES/IPCHAINS | |
5513 | -P: Harald Welte | |
5514 | -P: Jozsef Kadlecsik | |
5512 | +NETFILTER/IPTABLES | |
5515 | 5513 | M: Pablo Neira Ayuso <pablo@netfilter.org> |
5516 | 5514 | M: Patrick McHardy <kaber@trash.net> |
5515 | +M: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | |
5517 | 5516 | L: netfilter-devel@vger.kernel.org |
5518 | 5517 | L: netfilter@vger.kernel.org |
5519 | 5518 | L: coreteam@netfilter.org |
5520 | 5519 | W: http://www.netfilter.org/ |
5521 | 5520 | W: http://www.iptables.org/ |
5522 | -T: git git://1984.lsi.us.es/nf | |
5523 | -T: git git://1984.lsi.us.es/nf-next | |
5521 | +Q: http://patchwork.ozlabs.org/project/netfilter-devel/list/ | |
5522 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git | |
5523 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git | |
5524 | 5524 | S: Supported |
5525 | 5525 | F: include/linux/netfilter* |
5526 | 5526 | F: include/linux/netfilter/ |
include/net/netfilter/nf_log.h
include/net/netfilter/nfnetlink_log.h
net/bridge/netfilter/ebt_log.c
... | ... | @@ -72,13 +72,12 @@ |
72 | 72 | } |
73 | 73 | |
74 | 74 | static void |
75 | -ebt_log_packet(u_int8_t pf, unsigned int hooknum, | |
76 | - const struct sk_buff *skb, const struct net_device *in, | |
77 | - const struct net_device *out, const struct nf_loginfo *loginfo, | |
78 | - const char *prefix) | |
75 | +ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum, | |
76 | + const struct sk_buff *skb, const struct net_device *in, | |
77 | + const struct net_device *out, const struct nf_loginfo *loginfo, | |
78 | + const char *prefix) | |
79 | 79 | { |
80 | 80 | unsigned int bitmask; |
81 | - struct net *net = dev_net(in ? in : out); | |
82 | 81 | |
83 | 82 | /* FIXME: Disabled from containers until syslog ns is supported */ |
84 | 83 | if (!net_eq(net, &init_net)) |
... | ... | @@ -191,7 +190,7 @@ |
191 | 190 | nf_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb, |
192 | 191 | par->in, par->out, &li, "%s", info->prefix); |
193 | 192 | else |
194 | - ebt_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in, | |
193 | + ebt_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb, par->in, | |
195 | 194 | par->out, &li, info->prefix); |
196 | 195 | return EBT_CONTINUE; |
197 | 196 | } |
net/bridge/netfilter/ebt_ulog.c
... | ... | @@ -131,14 +131,16 @@ |
131 | 131 | return skb; |
132 | 132 | } |
133 | 133 | |
134 | -static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb, | |
135 | - const struct net_device *in, const struct net_device *out, | |
136 | - const struct ebt_ulog_info *uloginfo, const char *prefix) | |
134 | +static void ebt_ulog_packet(struct net *net, unsigned int hooknr, | |
135 | + const struct sk_buff *skb, | |
136 | + const struct net_device *in, | |
137 | + const struct net_device *out, | |
138 | + const struct ebt_ulog_info *uloginfo, | |
139 | + const char *prefix) | |
137 | 140 | { |
138 | 141 | ebt_ulog_packet_msg_t *pm; |
139 | 142 | size_t size, copy_len; |
140 | 143 | struct nlmsghdr *nlh; |
141 | - struct net *net = dev_net(in ? in : out); | |
142 | 144 | struct ebt_ulog_net *ebt = ebt_ulog_pernet(net); |
143 | 145 | unsigned int group = uloginfo->nlgroup; |
144 | 146 | ebt_ulog_buff_t *ub = &ebt->ulog_buffers[group]; |
... | ... | @@ -233,7 +235,7 @@ |
233 | 235 | } |
234 | 236 | |
235 | 237 | /* this function is registered with the netfilter core */ |
236 | -static void ebt_log_packet(u_int8_t pf, unsigned int hooknum, | |
238 | +static void ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum, | |
237 | 239 | const struct sk_buff *skb, const struct net_device *in, |
238 | 240 | const struct net_device *out, const struct nf_loginfo *li, |
239 | 241 | const char *prefix) |
240 | 242 | |
... | ... | @@ -252,13 +254,15 @@ |
252 | 254 | strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix)); |
253 | 255 | } |
254 | 256 | |
255 | - ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); | |
257 | + ebt_ulog_packet(net, hooknum, skb, in, out, &loginfo, prefix); | |
256 | 258 | } |
257 | 259 | |
258 | 260 | static unsigned int |
259 | 261 | ebt_ulog_tg(struct sk_buff *skb, const struct xt_action_param *par) |
260 | 262 | { |
261 | - ebt_ulog_packet(par->hooknum, skb, par->in, par->out, | |
263 | + struct net *net = dev_net(par->in ? par->in : par->out); | |
264 | + | |
265 | + ebt_ulog_packet(net, par->hooknum, skb, par->in, par->out, | |
262 | 266 | par->targinfo, NULL); |
263 | 267 | return EBT_CONTINUE; |
264 | 268 | } |
net/ipv4/netfilter/ipt_ULOG.c
... | ... | @@ -162,7 +162,8 @@ |
162 | 162 | return skb; |
163 | 163 | } |
164 | 164 | |
165 | -static void ipt_ulog_packet(unsigned int hooknum, | |
165 | +static void ipt_ulog_packet(struct net *net, | |
166 | + unsigned int hooknum, | |
166 | 167 | const struct sk_buff *skb, |
167 | 168 | const struct net_device *in, |
168 | 169 | const struct net_device *out, |
... | ... | @@ -174,7 +175,6 @@ |
174 | 175 | size_t size, copy_len; |
175 | 176 | struct nlmsghdr *nlh; |
176 | 177 | struct timeval tv; |
177 | - struct net *net = dev_net(in ? in : out); | |
178 | 178 | struct ulog_net *ulog = ulog_pernet(net); |
179 | 179 | |
180 | 180 | /* ffs == find first bit set, necessary because userspace |
181 | 181 | |
... | ... | @@ -291,12 +291,15 @@ |
291 | 291 | static unsigned int |
292 | 292 | ulog_tg(struct sk_buff *skb, const struct xt_action_param *par) |
293 | 293 | { |
294 | - ipt_ulog_packet(par->hooknum, skb, par->in, par->out, | |
294 | + struct net *net = dev_net(par->in ? par->in : par->out); | |
295 | + | |
296 | + ipt_ulog_packet(net, par->hooknum, skb, par->in, par->out, | |
295 | 297 | par->targinfo, NULL); |
296 | 298 | return XT_CONTINUE; |
297 | 299 | } |
298 | 300 | |
299 | -static void ipt_logfn(u_int8_t pf, | |
301 | +static void ipt_logfn(struct net *net, | |
302 | + u_int8_t pf, | |
300 | 303 | unsigned int hooknum, |
301 | 304 | const struct sk_buff *skb, |
302 | 305 | const struct net_device *in, |
... | ... | @@ -318,7 +321,7 @@ |
318 | 321 | strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix)); |
319 | 322 | } |
320 | 323 | |
321 | - ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); | |
324 | + ipt_ulog_packet(net, hooknum, skb, in, out, &loginfo, prefix); | |
322 | 325 | } |
323 | 326 | |
324 | 327 | static int ulog_tg_check(const struct xt_tgchk_param *par) |
net/netfilter/nf_log.c
... | ... | @@ -148,7 +148,7 @@ |
148 | 148 | va_start(args, fmt); |
149 | 149 | vsnprintf(prefix, sizeof(prefix), fmt, args); |
150 | 150 | va_end(args); |
151 | - logger->logfn(pf, hooknum, skb, in, out, loginfo, prefix); | |
151 | + logger->logfn(net, pf, hooknum, skb, in, out, loginfo, prefix); | |
152 | 152 | } |
153 | 153 | rcu_read_unlock(); |
154 | 154 | } |
155 | 155 | |
156 | 156 | |
157 | 157 | |
... | ... | @@ -368,17 +368,20 @@ |
368 | 368 | return 0; |
369 | 369 | |
370 | 370 | out_sysctl: |
371 | +#ifdef CONFIG_PROC_FS | |
371 | 372 | /* For init_net: errors will trigger panic, don't unroll on error. */ |
372 | 373 | if (!net_eq(net, &init_net)) |
373 | 374 | remove_proc_entry("nf_log", net->nf.proc_netfilter); |
374 | - | |
375 | +#endif | |
375 | 376 | return ret; |
376 | 377 | } |
377 | 378 | |
378 | 379 | static void __net_exit nf_log_net_exit(struct net *net) |
379 | 380 | { |
380 | 381 | netfilter_log_sysctl_exit(net); |
382 | +#ifdef CONFIG_PROC_FS | |
381 | 383 | remove_proc_entry("nf_log", net->nf.proc_netfilter); |
384 | +#endif | |
382 | 385 | } |
383 | 386 | |
384 | 387 | static struct pernet_operations nf_log_net_ops = { |
net/netfilter/nfnetlink_log.c
... | ... | @@ -602,7 +602,8 @@ |
602 | 602 | |
603 | 603 | /* log handler for internal netfilter logging api */ |
604 | 604 | void |
605 | -nfulnl_log_packet(u_int8_t pf, | |
605 | +nfulnl_log_packet(struct net *net, | |
606 | + u_int8_t pf, | |
606 | 607 | unsigned int hooknum, |
607 | 608 | const struct sk_buff *skb, |
608 | 609 | const struct net_device *in, |
... | ... | @@ -615,7 +616,6 @@ |
615 | 616 | const struct nf_loginfo *li; |
616 | 617 | unsigned int qthreshold; |
617 | 618 | unsigned int plen; |
618 | - struct net *net = dev_net(in ? in : out); | |
619 | 619 | struct nfnl_log_net *log = nfnl_log_pernet(net); |
620 | 620 | |
621 | 621 | if (li_user && li_user->type == NF_LOG_TYPE_ULOG) |
622 | 622 | |
... | ... | @@ -1045,7 +1045,9 @@ |
1045 | 1045 | |
1046 | 1046 | static void __net_exit nfnl_log_net_exit(struct net *net) |
1047 | 1047 | { |
1048 | +#ifdef CONFIG_PROC_FS | |
1048 | 1049 | remove_proc_entry("nfnetlink_log", net->nf.proc_netfilter); |
1050 | +#endif | |
1049 | 1051 | } |
1050 | 1052 | |
1051 | 1053 | static struct pernet_operations nfnl_log_net_ops = { |
net/netfilter/nfnetlink_queue_core.c
... | ... | @@ -1285,7 +1285,9 @@ |
1285 | 1285 | |
1286 | 1286 | static void __net_exit nfnl_queue_net_exit(struct net *net) |
1287 | 1287 | { |
1288 | +#ifdef CONFIG_PROC_FS | |
1288 | 1289 | remove_proc_entry("nfnetlink_queue", net->nf.proc_netfilter); |
1290 | +#endif | |
1289 | 1291 | } |
1290 | 1292 | |
1291 | 1293 | static struct pernet_operations nfnl_queue_net_ops = { |
net/netfilter/xt_LOG.c
... | ... | @@ -466,7 +466,8 @@ |
466 | 466 | |
467 | 467 | |
468 | 468 | static void |
469 | -ipt_log_packet(u_int8_t pf, | |
469 | +ipt_log_packet(struct net *net, | |
470 | + u_int8_t pf, | |
470 | 471 | unsigned int hooknum, |
471 | 472 | const struct sk_buff *skb, |
472 | 473 | const struct net_device *in, |
... | ... | @@ -475,7 +476,6 @@ |
475 | 476 | const char *prefix) |
476 | 477 | { |
477 | 478 | struct sbuff *m; |
478 | - struct net *net = dev_net(in ? in : out); | |
479 | 479 | |
480 | 480 | /* FIXME: Disabled from containers until syslog ns is supported */ |
481 | 481 | if (!net_eq(net, &init_net)) |
... | ... | @@ -797,7 +797,8 @@ |
797 | 797 | } |
798 | 798 | |
799 | 799 | static void |
800 | -ip6t_log_packet(u_int8_t pf, | |
800 | +ip6t_log_packet(struct net *net, | |
801 | + u_int8_t pf, | |
801 | 802 | unsigned int hooknum, |
802 | 803 | const struct sk_buff *skb, |
803 | 804 | const struct net_device *in, |
... | ... | @@ -806,7 +807,6 @@ |
806 | 807 | const char *prefix) |
807 | 808 | { |
808 | 809 | struct sbuff *m; |
809 | - struct net *net = dev_net(in ? in : out); | |
810 | 810 | |
811 | 811 | /* FIXME: Disabled from containers until syslog ns is supported */ |
812 | 812 | if (!net_eq(net, &init_net)) |
813 | 813 | |
814 | 814 | |
... | ... | @@ -833,17 +833,18 @@ |
833 | 833 | { |
834 | 834 | const struct xt_log_info *loginfo = par->targinfo; |
835 | 835 | struct nf_loginfo li; |
836 | + struct net *net = dev_net(par->in ? par->in : par->out); | |
836 | 837 | |
837 | 838 | li.type = NF_LOG_TYPE_LOG; |
838 | 839 | li.u.log.level = loginfo->level; |
839 | 840 | li.u.log.logflags = loginfo->logflags; |
840 | 841 | |
841 | 842 | if (par->family == NFPROTO_IPV4) |
842 | - ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in, | |
843 | + ipt_log_packet(net, NFPROTO_IPV4, par->hooknum, skb, par->in, | |
843 | 844 | par->out, &li, loginfo->prefix); |
844 | 845 | #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) |
845 | 846 | else if (par->family == NFPROTO_IPV6) |
846 | - ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in, | |
847 | + ip6t_log_packet(net, NFPROTO_IPV6, par->hooknum, skb, par->in, | |
847 | 848 | par->out, &li, loginfo->prefix); |
848 | 849 | #endif |
849 | 850 | else |
net/netfilter/xt_NFLOG.c
... | ... | @@ -26,13 +26,14 @@ |
26 | 26 | { |
27 | 27 | const struct xt_nflog_info *info = par->targinfo; |
28 | 28 | struct nf_loginfo li; |
29 | + struct net *net = dev_net(par->in ? par->in : par->out); | |
29 | 30 | |
30 | 31 | li.type = NF_LOG_TYPE_ULOG; |
31 | 32 | li.u.ulog.copy_len = info->len; |
32 | 33 | li.u.ulog.group = info->group; |
33 | 34 | li.u.ulog.qthreshold = info->threshold; |
34 | 35 | |
35 | - nfulnl_log_packet(par->family, par->hooknum, skb, par->in, | |
36 | + nfulnl_log_packet(net, par->family, par->hooknum, skb, par->in, | |
36 | 37 | par->out, &li, info->prefix); |
37 | 38 | return XT_CONTINUE; |
38 | 39 | } |
net/netfilter/xt_TCPOPTSTRIP.c
... | ... | @@ -30,17 +30,28 @@ |
30 | 30 | |
31 | 31 | static unsigned int |
32 | 32 | tcpoptstrip_mangle_packet(struct sk_buff *skb, |
33 | - const struct xt_tcpoptstrip_target_info *info, | |
33 | + const struct xt_action_param *par, | |
34 | 34 | unsigned int tcphoff, unsigned int minlen) |
35 | 35 | { |
36 | + const struct xt_tcpoptstrip_target_info *info = par->targinfo; | |
36 | 37 | unsigned int optl, i, j; |
37 | 38 | struct tcphdr *tcph; |
38 | 39 | u_int16_t n, o; |
39 | 40 | u_int8_t *opt; |
41 | + int len; | |
40 | 42 | |
43 | + /* This is a fragment, no TCP header is available */ | |
44 | + if (par->fragoff != 0) | |
45 | + return XT_CONTINUE; | |
46 | + | |
41 | 47 | if (!skb_make_writable(skb, skb->len)) |
42 | 48 | return NF_DROP; |
43 | 49 | |
50 | + len = skb->len - tcphoff; | |
51 | + if (len < (int)sizeof(struct tcphdr) || | |
52 | + tcp_hdr(skb)->doff * 4 > len) | |
53 | + return NF_DROP; | |
54 | + | |
44 | 55 | tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff); |
45 | 56 | opt = (u_int8_t *)tcph; |
46 | 57 | |
... | ... | @@ -76,7 +87,7 @@ |
76 | 87 | static unsigned int |
77 | 88 | tcpoptstrip_tg4(struct sk_buff *skb, const struct xt_action_param *par) |
78 | 89 | { |
79 | - return tcpoptstrip_mangle_packet(skb, par->targinfo, ip_hdrlen(skb), | |
90 | + return tcpoptstrip_mangle_packet(skb, par, ip_hdrlen(skb), | |
80 | 91 | sizeof(struct iphdr) + sizeof(struct tcphdr)); |
81 | 92 | } |
82 | 93 | |
... | ... | @@ -94,7 +105,7 @@ |
94 | 105 | if (tcphoff < 0) |
95 | 106 | return NF_DROP; |
96 | 107 | |
97 | - return tcpoptstrip_mangle_packet(skb, par->targinfo, tcphoff, | |
108 | + return tcpoptstrip_mangle_packet(skb, par, tcphoff, | |
98 | 109 | sizeof(*ipv6h) + sizeof(struct tcphdr)); |
99 | 110 | } |
100 | 111 | #endif |