Commit 5c4b274981950049af3330f14ed9e9aa25afb2fb

Authored by David S. Miller

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

... ... @@ -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
... ... @@ -30,7 +30,8 @@
30 30 } u;
31 31 };
32 32  
33   -typedef void nf_logfn(u_int8_t pf,
  33 +typedef void nf_logfn(struct net *net,
  34 + u_int8_t pf,
34 35 unsigned int hooknum,
35 36 const struct sk_buff *skb,
36 37 const struct net_device *in,
include/net/netfilter/nfnetlink_log.h
... ... @@ -2,7 +2,8 @@
2 2 #define _KER_NFNETLINK_LOG_H
3 3  
4 4 void
5   -nfulnl_log_packet(u_int8_t pf,
  5 +nfulnl_log_packet(struct net *net,
  6 + u_int8_t pf,
6 7 unsigned int hooknum,
7 8 const struct sk_buff *skb,
8 9 const struct net_device *in,
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