/[linux-patches]/genpatches-2.6/tags/2.6.18-9/1004_linux-2.6.18.5.patch
Gentoo

Contents of /genpatches-2.6/tags/2.6.18-9/1004_linux-2.6.18.5.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 802 - (show annotations) (download)
Wed Jan 10 14:47:23 2007 UTC (11 years, 9 months ago) by dsd
File size: 32884 byte(s)
2.6.18-9 release
1 diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
2 index 213c785..2b36afd 100644
3 --- a/arch/alpha/Kconfig
4 +++ b/arch/alpha/Kconfig
5 @@ -381,7 +381,7 @@ config ALPHA_EV56
6
7 config ALPHA_EV56
8 prompt "EV56 CPU (speed >= 333MHz)?"
9 - depends on ALPHA_NORITAKE && ALPHA_PRIMO
10 + depends on ALPHA_NORITAKE || ALPHA_PRIMO
11
12 config ALPHA_EV56
13 prompt "EV56 CPU (speed >= 400MHz)?"
14 diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c
15 index 40b44cc..e5520eb 100644
16 --- a/arch/i386/kernel/microcode.c
17 +++ b/arch/i386/kernel/microcode.c
18 @@ -250,14 +250,14 @@ static int find_matching_ucodes (void)
19 }
20
21 total_size = get_totalsize(&mc_header);
22 - if ((cursor + total_size > user_buffer_size) || (total_size < DEFAULT_UCODE_TOTALSIZE)) {
23 + if (cursor + total_size > user_buffer_size) {
24 printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");
25 error = -EINVAL;
26 goto out;
27 }
28
29 data_size = get_datasize(&mc_header);
30 - if ((data_size + MC_HEADER_SIZE > total_size) || (data_size < DEFAULT_UCODE_DATASIZE)) {
31 + if (data_size + MC_HEADER_SIZE > total_size) {
32 printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");
33 error = -EINVAL;
34 goto out;
35 @@ -460,11 +460,6 @@ static ssize_t microcode_write (struct f
36 {
37 ssize_t ret;
38
39 - if (len < DEFAULT_UCODE_TOTALSIZE) {
40 - printk(KERN_ERR "microcode: not enough data\n");
41 - return -EINVAL;
42 - }
43 -
44 if ((len >> PAGE_SHIFT) > num_physpages) {
45 printk(KERN_ERR "microcode: too much data (max %ld pages)\n", num_physpages);
46 return -EINVAL;
47 diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c
48 index 27dee45..c55f487 100644
49 --- a/arch/ia64/sn/kernel/bte.c
50 +++ b/arch/ia64/sn/kernel/bte.c
51 @@ -382,14 +382,13 @@ bte_result_t bte_unaligned_copy(u64 src,
52 * bcopy to the destination.
53 */
54
55 - /* Add the leader from source */
56 - headBteLen = len + (src & L1_CACHE_MASK);
57 - /* Add the trailing bytes from footer. */
58 - headBteLen += L1_CACHE_BYTES - (headBteLen & L1_CACHE_MASK);
59 - headBteSource = src & ~L1_CACHE_MASK;
60 headBcopySrcOffset = src & L1_CACHE_MASK;
61 headBcopyDest = dest;
62 headBcopyLen = len;
63 +
64 + headBteSource = src - headBcopySrcOffset;
65 + /* Add the leading and trailing bytes from source */
66 + headBteLen = L1_CACHE_ALIGN(len + headBcopySrcOffset);
67 }
68
69 if (headBcopyLen > 0) {
70 diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
71 index ed3d3ae..848ac42 100644
72 --- a/block/scsi_ioctl.c
73 +++ b/block/scsi_ioctl.c
74 @@ -286,9 +286,8 @@ static int sg_io(struct file *file, requ
75 * fill in request structure
76 */
77 rq->cmd_len = hdr->cmd_len;
78 + memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
79 memcpy(rq->cmd, cmd, hdr->cmd_len);
80 - if (sizeof(rq->cmd) != hdr->cmd_len)
81 - memset(rq->cmd + hdr->cmd_len, 0, sizeof(rq->cmd) - hdr->cmd_len);
82
83 memset(sense, 0, sizeof(sense));
84 rq->sense = sense;
85 diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
86 index cc5ea34..d218575 100644
87 --- a/drivers/char/agp/generic.c
88 +++ b/drivers/char/agp/generic.c
89 @@ -1042,7 +1042,7 @@ void *agp_generic_alloc_page(struct agp_
90 {
91 struct page * page;
92
93 - page = alloc_page(GFP_KERNEL);
94 + page = alloc_page(GFP_KERNEL | GFP_DMA32);
95 if (page == NULL)
96 return NULL;
97
98 diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
99 index 61ac380..64bb579 100644
100 --- a/drivers/char/agp/intel-agp.c
101 +++ b/drivers/char/agp/intel-agp.c
102 @@ -160,7 +160,7 @@ static void *i8xx_alloc_pages(void)
103 {
104 struct page * page;
105
106 - page = alloc_pages(GFP_KERNEL, 2);
107 + page = alloc_pages(GFP_KERNEL | GFP_DMA32, 2);
108 if (page == NULL)
109 return NULL;
110
111 diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
112 index ed4aa4e..9f7e1fe 100644
113 --- a/drivers/media/Kconfig
114 +++ b/drivers/media/Kconfig
115 @@ -54,6 +54,7 @@ config VIDEO_V4L1_COMPAT
116
117 config VIDEO_V4L2
118 bool
119 + depends on VIDEO_DEV
120 default y
121
122 source "drivers/media/video/Kconfig"
123 diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
124 index eafabb2..fa620ae 100644
125 --- a/drivers/net/tg3.c
126 +++ b/drivers/net/tg3.c
127 @@ -6889,8 +6889,10 @@ static int tg3_open(struct net_device *d
128 tg3_full_lock(tp, 0);
129
130 err = tg3_set_power_state(tp, PCI_D0);
131 - if (err)
132 + if (err) {
133 + tg3_full_unlock(tp);
134 return err;
135 + }
136
137 tg3_disable_ints(tp);
138 tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
139 diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
140 index f24ba4d..42eecf2 100644
141 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
142 +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
143 @@ -1463,6 +1463,23 @@ static void handle_irq_transmit_status(s
144 }
145 }
146
147 +static void drain_txstatus_queue(struct bcm43xx_private *bcm)
148 +{
149 + u32 dummy;
150 +
151 + if (bcm->current_core->rev < 5)
152 + return;
153 + /* Read all entries from the microcode TXstatus FIFO
154 + * and throw them away.
155 + */
156 + while (1) {
157 + dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0);
158 + if (!dummy)
159 + break;
160 + dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1);
161 + }
162 +}
163 +
164 static void bcm43xx_generate_noise_sample(struct bcm43xx_private *bcm)
165 {
166 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x408, 0x7F7F);
167 @@ -3517,6 +3534,7 @@ int bcm43xx_select_wireless_core(struct
168 bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
169 bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr));
170 bcm43xx_security_init(bcm);
171 + drain_txstatus_queue(bcm);
172 ieee80211softmac_start(bcm->net_dev);
173
174 /* Let's go! Be careful after enabling the IRQs.
175 diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
176 index 74b3124..95d5e88 100644
177 --- a/drivers/pcmcia/ds.c
178 +++ b/drivers/pcmcia/ds.c
179 @@ -1264,6 +1264,11 @@ static void pcmcia_bus_remove_socket(str
180 socket->pcmcia_state.dead = 1;
181 pccard_register_pcmcia(socket, NULL);
182
183 + /* unregister any unbound devices */
184 + mutex_lock(&socket->skt_mutex);
185 + pcmcia_card_remove(socket, NULL);
186 + mutex_unlock(&socket->skt_mutex);
187 +
188 pcmcia_put_socket(socket);
189
190 return;
191 diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
192 index 077c1c6..3031078 100644
193 --- a/drivers/scsi/scsi_lib.c
194 +++ b/drivers/scsi/scsi_lib.c
195 @@ -408,6 +408,7 @@ int scsi_execute_async(struct scsi_devic
196 goto free_req;
197
198 req->cmd_len = cmd_len;
199 + memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
200 memcpy(req->cmd, cmd, req->cmd_len);
201 req->sense = sioc->sense;
202 req->sense_len = 0;
203 diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
204 index 5d7c726..f75deeb 100644
205 --- a/fs/fuse/dir.c
206 +++ b/fs/fuse/dir.c
207 @@ -138,6 +138,7 @@ static int fuse_dentry_revalidate(struct
208 struct fuse_entry_out outarg;
209 struct fuse_conn *fc;
210 struct fuse_req *req;
211 + struct fuse_req *forget_req;
212
213 /* Doesn't hurt to "reset" the validity timeout */
214 fuse_invalidate_entry_cache(entry);
215 @@ -151,21 +152,29 @@ static int fuse_dentry_revalidate(struct
216 if (IS_ERR(req))
217 return 0;
218
219 + forget_req = fuse_get_req(fc);
220 + if (IS_ERR(forget_req)) {
221 + fuse_put_request(fc, req);
222 + return 0;
223 + }
224 +
225 fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg);
226 request_send(fc, req);
227 err = req->out.h.error;
228 + fuse_put_request(fc, req);
229 /* Zero nodeid is same as -ENOENT */
230 if (!err && !outarg.nodeid)
231 err = -ENOENT;
232 if (!err) {
233 struct fuse_inode *fi = get_fuse_inode(inode);
234 if (outarg.nodeid != get_node_id(inode)) {
235 - fuse_send_forget(fc, req, outarg.nodeid, 1);
236 + fuse_send_forget(fc, forget_req,
237 + outarg.nodeid, 1);
238 return 0;
239 }
240 fi->nlookup ++;
241 }
242 - fuse_put_request(fc, req);
243 + fuse_put_request(fc, forget_req);
244 if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
245 return 0;
246
247 @@ -214,6 +223,7 @@ static struct dentry *fuse_lookup(struct
248 struct inode *inode = NULL;
249 struct fuse_conn *fc = get_fuse_conn(dir);
250 struct fuse_req *req;
251 + struct fuse_req *forget_req;
252
253 if (entry->d_name.len > FUSE_NAME_MAX)
254 return ERR_PTR(-ENAMETOOLONG);
255 @@ -222,9 +232,16 @@ static struct dentry *fuse_lookup(struct
256 if (IS_ERR(req))
257 return ERR_PTR(PTR_ERR(req));
258
259 + forget_req = fuse_get_req(fc);
260 + if (IS_ERR(forget_req)) {
261 + fuse_put_request(fc, req);
262 + return ERR_PTR(PTR_ERR(forget_req));
263 + }
264 +
265 fuse_lookup_init(req, dir, entry, &outarg);
266 request_send(fc, req);
267 err = req->out.h.error;
268 + fuse_put_request(fc, req);
269 /* Zero nodeid is same as -ENOENT, but with valid timeout */
270 if (!err && outarg.nodeid &&
271 (invalid_nodeid(outarg.nodeid) || !valid_mode(outarg.attr.mode)))
272 @@ -233,11 +250,11 @@ static struct dentry *fuse_lookup(struct
273 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
274 &outarg.attr);
275 if (!inode) {
276 - fuse_send_forget(fc, req, outarg.nodeid, 1);
277 + fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
278 return ERR_PTR(-ENOMEM);
279 }
280 }
281 - fuse_put_request(fc, req);
282 + fuse_put_request(fc, forget_req);
283 if (err && err != -ENOENT)
284 return ERR_PTR(err);
285
286 @@ -375,6 +392,13 @@ static int create_new_entry(struct fuse_
287 struct fuse_entry_out outarg;
288 struct inode *inode;
289 int err;
290 + struct fuse_req *forget_req;
291 +
292 + forget_req = fuse_get_req(fc);
293 + if (IS_ERR(forget_req)) {
294 + fuse_put_request(fc, req);
295 + return PTR_ERR(forget_req);
296 + }
297
298 req->in.h.nodeid = get_node_id(dir);
299 req->out.numargs = 1;
300 @@ -382,24 +406,24 @@ static int create_new_entry(struct fuse_
301 req->out.args[0].value = &outarg;
302 request_send(fc, req);
303 err = req->out.h.error;
304 - if (err) {
305 - fuse_put_request(fc, req);
306 - return err;
307 - }
308 + fuse_put_request(fc, req);
309 + if (err)
310 + goto out_put_forget_req;
311 +
312 err = -EIO;
313 if (invalid_nodeid(outarg.nodeid))
314 - goto out_put_request;
315 + goto out_put_forget_req;
316
317 if ((outarg.attr.mode ^ mode) & S_IFMT)
318 - goto out_put_request;
319 + goto out_put_forget_req;
320
321 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
322 &outarg.attr);
323 if (!inode) {
324 - fuse_send_forget(fc, req, outarg.nodeid, 1);
325 + fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
326 return -ENOMEM;
327 }
328 - fuse_put_request(fc, req);
329 + fuse_put_request(fc, forget_req);
330
331 if (dir_alias(inode)) {
332 iput(inode);
333 @@ -411,8 +435,8 @@ static int create_new_entry(struct fuse_
334 fuse_invalidate_attr(dir);
335 return 0;
336
337 - out_put_request:
338 - fuse_put_request(fc, req);
339 + out_put_forget_req:
340 + fuse_put_request(fc, forget_req);
341 return err;
342 }
343
344 diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h
345 index ce02c98..5b63a23 100644
346 --- a/include/linux/netfilter_ipv4.h
347 +++ b/include/linux/netfilter_ipv4.h
348 @@ -77,7 +77,7 @@ enum nf_ip_hook_priorities {
349 #define SO_ORIGINAL_DST 80
350
351 #ifdef __KERNEL__
352 -extern int ip_route_me_harder(struct sk_buff **pskb);
353 +extern int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type);
354 extern int ip_xfrm_me_harder(struct sk_buff **pskb);
355 extern unsigned int nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
356 unsigned int dataoff, u_int8_t protocol);
357 diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
358 index 1a35d34..316fa7a 100644
359 --- a/net/bluetooth/hci_sock.c
360 +++ b/net/bluetooth/hci_sock.c
361 @@ -120,10 +120,13 @@ void hci_send_to_sock(struct hci_dev *hd
362 if (!hci_test_bit(evt, &flt->event_mask))
363 continue;
364
365 - if (flt->opcode && ((evt == HCI_EV_CMD_COMPLETE &&
366 - flt->opcode != *(__u16 *)(skb->data + 3)) ||
367 - (evt == HCI_EV_CMD_STATUS &&
368 - flt->opcode != *(__u16 *)(skb->data + 4))))
369 + if (flt->opcode &&
370 + ((evt == HCI_EV_CMD_COMPLETE &&
371 + flt->opcode !=
372 + get_unaligned((__u16 *)(skb->data + 3))) ||
373 + (evt == HCI_EV_CMD_STATUS &&
374 + flt->opcode !=
375 + get_unaligned((__u16 *)(skb->data + 4)))))
376 continue;
377 }
378
379 diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
380 index 610c722..3744c24 100644
381 --- a/net/dccp/ipv6.c
382 +++ b/net/dccp/ipv6.c
383 @@ -276,7 +276,7 @@ static void dccp_v6_err(struct sk_buff *
384 __u64 seq;
385
386 sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport,
387 - &hdr->saddr, dh->dccph_sport, skb->dev->ifindex);
388 + &hdr->saddr, dh->dccph_sport, inet6_iif(skb));
389
390 if (sk == NULL) {
391 ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
392 diff --git a/net/ieee80211/softmac/ieee80211softmac_io.c b/net/ieee80211/softmac/ieee80211softmac_io.c
393 index 6ae5a1d..3b67d19 100644
394 --- a/net/ieee80211/softmac/ieee80211softmac_io.c
395 +++ b/net/ieee80211/softmac/ieee80211softmac_io.c
396 @@ -304,7 +304,7 @@ ieee80211softmac_auth(struct ieee80211_a
397 2 + /* Auth Transaction Seq */
398 2 + /* Status Code */
399 /* Challenge Text IE */
400 - is_shared_response ? 0 : 1 + 1 + net->challenge_len
401 + (is_shared_response ? 1 + 1 + net->challenge_len : 0)
402 );
403 if (unlikely((*pkt) == NULL))
404 return 0;
405 diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
406 index 3f47ad8..f594635 100644
407 --- a/net/ipv4/ipvs/ip_vs_core.c
408 +++ b/net/ipv4/ipvs/ip_vs_core.c
409 @@ -813,6 +813,16 @@ ip_vs_out(unsigned int hooknum, struct s
410 skb->nh.iph->saddr = cp->vaddr;
411 ip_send_check(skb->nh.iph);
412
413 + /* For policy routing, packets originating from this
414 + * machine itself may be routed differently to packets
415 + * passing through. We want this packet to be routed as
416 + * if it came from this machine itself. So re-compute
417 + * the routing information.
418 + */
419 + if (ip_route_me_harder(pskb, RTN_LOCAL) != 0)
420 + goto drop;
421 + skb = *pskb;
422 +
423 IP_VS_DBG_PKT(10, pp, skb, 0, "After SNAT");
424
425 ip_vs_out_stats(cp, skb);
426 diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
427 index 6a9e34b..327ba37 100644
428 --- a/net/ipv4/netfilter.c
429 +++ b/net/ipv4/netfilter.c
430 @@ -8,7 +8,7 @@ #include <net/xfrm.h>
431 #include <net/ip.h>
432
433 /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
434 -int ip_route_me_harder(struct sk_buff **pskb)
435 +int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)
436 {
437 struct iphdr *iph = (*pskb)->nh.iph;
438 struct rtable *rt;
439 @@ -16,10 +16,13 @@ int ip_route_me_harder(struct sk_buff **
440 struct dst_entry *odst;
441 unsigned int hh_len;
442
443 + if (addr_type == RTN_UNSPEC)
444 + addr_type = inet_addr_type(iph->saddr);
445 +
446 /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
447 * packets with foreign saddr to appear on the NF_IP_LOCAL_OUT hook.
448 */
449 - if (inet_addr_type(iph->saddr) == RTN_LOCAL) {
450 + if (addr_type == RTN_LOCAL) {
451 fl.nl_u.ip4_u.daddr = iph->daddr;
452 fl.nl_u.ip4_u.saddr = iph->saddr;
453 fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
454 @@ -156,7 +159,7 @@ static int nf_ip_reroute(struct sk_buff
455 if (!(iph->tos == rt_info->tos
456 && iph->daddr == rt_info->daddr
457 && iph->saddr == rt_info->saddr))
458 - return ip_route_me_harder(pskb);
459 + return ip_route_me_harder(pskb, RTN_UNSPEC);
460 }
461 return 0;
462 }
463 diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
464 index 8d1d7a6..8ba83e8 100644
465 --- a/net/ipv4/netfilter/arp_tables.c
466 +++ b/net/ipv4/netfilter/arp_tables.c
467 @@ -380,6 +380,13 @@ static int mark_source_chains(struct xt_
468 && unconditional(&e->arp)) {
469 unsigned int oldpos, size;
470
471 + if (t->verdict < -NF_MAX_VERDICT - 1) {
472 + duprintf("mark_source_chains: bad "
473 + "negative verdict (%i)\n",
474 + t->verdict);
475 + return 0;
476 + }
477 +
478 /* Return: backtrack through the last
479 * big jump.
480 */
481 @@ -409,6 +416,14 @@ static int mark_source_chains(struct xt_
482 if (strcmp(t->target.u.user.name,
483 ARPT_STANDARD_TARGET) == 0
484 && newpos >= 0) {
485 + if (newpos > newinfo->size -
486 + sizeof(struct arpt_entry)) {
487 + duprintf("mark_source_chains: "
488 + "bad verdict (%i)\n",
489 + newpos);
490 + return 0;
491 + }
492 +
493 /* This a jump; chase it. */
494 duprintf("Jump rule %u -> %u\n",
495 pos, newpos);
496 @@ -431,8 +446,6 @@ static int mark_source_chains(struct xt_
497 static inline int standard_check(const struct arpt_entry_target *t,
498 unsigned int max_offset)
499 {
500 - struct arpt_standard_target *targ = (void *)t;
501 -
502 /* Check standard info. */
503 if (t->u.target_size
504 != ARPT_ALIGN(sizeof(struct arpt_standard_target))) {
505 @@ -442,18 +455,6 @@ static inline int standard_check(const s
506 return 0;
507 }
508
509 - if (targ->verdict >= 0
510 - && targ->verdict > max_offset - sizeof(struct arpt_entry)) {
511 - duprintf("arpt_standard_check: bad verdict (%i)\n",
512 - targ->verdict);
513 - return 0;
514 - }
515 -
516 - if (targ->verdict < -NF_MAX_VERDICT - 1) {
517 - duprintf("arpt_standard_check: bad negative verdict (%i)\n",
518 - targ->verdict);
519 - return 0;
520 - }
521 return 1;
522 }
523
524 @@ -471,7 +472,13 @@ static inline int check_entry(struct arp
525 return -EINVAL;
526 }
527
528 + if (e->target_offset + sizeof(struct arpt_entry_target) > e->next_offset)
529 + return -EINVAL;
530 +
531 t = arpt_get_target(e);
532 + if (e->target_offset + t->u.target_size > e->next_offset)
533 + return -EINVAL;
534 +
535 target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name,
536 t->u.user.revision),
537 "arpt_%s", t->u.user.name);
538 @@ -641,7 +648,7 @@ static int translate_table(const char *n
539
540 if (ret != 0) {
541 ARPT_ENTRY_ITERATE(entry0, newinfo->size,
542 - cleanup_entry, &i);
543 + cleanup_entry, &i);
544 return ret;
545 }
546
547 @@ -1204,6 +1211,8 @@ err1:
548 static void __exit arp_tables_fini(void)
549 {
550 nf_unregister_sockopt(&arpt_sockopts);
551 + xt_unregister_target(&arpt_error_target);
552 + xt_unregister_target(&arpt_standard_target);
553 xt_proto_fini(NF_ARP);
554 }
555
556 diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c
557 index 9a39e29..afe7039 100644
558 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323.c
559 +++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c
560 @@ -1417,7 +1417,7 @@ static int process_rcf(struct sk_buff **
561 DEBUGP
562 ("ip_ct_ras: set RAS connection timeout to %u seconds\n",
563 info->timeout);
564 - ip_ct_refresh_acct(ct, ctinfo, NULL, info->timeout * HZ);
565 + ip_ct_refresh(ct, *pskb, info->timeout * HZ);
566
567 /* Set expect timeout */
568 read_lock_bh(&ip_conntrack_lock);
569 @@ -1465,7 +1465,7 @@ static int process_urq(struct sk_buff **
570 info->sig_port[!dir] = 0;
571
572 /* Give it 30 seconds for UCF or URJ */
573 - ip_ct_refresh_acct(ct, ctinfo, NULL, 30 * HZ);
574 + ip_ct_refresh(ct, *pskb, 30 * HZ);
575
576 return 0;
577 }
578 diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
579 index 6db485f..c508544 100644
580 --- a/net/ipv4/netfilter/ip_nat_standalone.c
581 +++ b/net/ipv4/netfilter/ip_nat_standalone.c
582 @@ -275,7 +275,8 @@ #ifdef CONFIG_XFRM
583 ct->tuplehash[!dir].tuple.src.u.all
584 #endif
585 )
586 - return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
587 + if (ip_route_me_harder(pskb, RTN_UNSPEC))
588 + ret = NF_DROP;
589 }
590 return ret;
591 }
592 diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
593 index 048514f..e964436 100644
594 --- a/net/ipv4/netfilter/ip_tables.c
595 +++ b/net/ipv4/netfilter/ip_tables.c
596 @@ -404,6 +404,13 @@ mark_source_chains(struct xt_table_info
597 && unconditional(&e->ip)) {
598 unsigned int oldpos, size;
599
600 + if (t->verdict < -NF_MAX_VERDICT - 1) {
601 + duprintf("mark_source_chains: bad "
602 + "negative verdict (%i)\n",
603 + t->verdict);
604 + return 0;
605 + }
606 +
607 /* Return: backtrack through the last
608 big jump. */
609 do {
610 @@ -441,6 +448,13 @@ #endif
611 if (strcmp(t->target.u.user.name,
612 IPT_STANDARD_TARGET) == 0
613 && newpos >= 0) {
614 + if (newpos > newinfo->size -
615 + sizeof(struct ipt_entry)) {
616 + duprintf("mark_source_chains: "
617 + "bad verdict (%i)\n",
618 + newpos);
619 + return 0;
620 + }
621 /* This a jump; chase it. */
622 duprintf("Jump rule %u -> %u\n",
623 pos, newpos);
624 @@ -474,27 +488,6 @@ cleanup_match(struct ipt_entry_match *m,
625 }
626
627 static inline int
628 -standard_check(const struct ipt_entry_target *t,
629 - unsigned int max_offset)
630 -{
631 - struct ipt_standard_target *targ = (void *)t;
632 -
633 - /* Check standard info. */
634 - if (targ->verdict >= 0
635 - && targ->verdict > max_offset - sizeof(struct ipt_entry)) {
636 - duprintf("ipt_standard_check: bad verdict (%i)\n",
637 - targ->verdict);
638 - return 0;
639 - }
640 - if (targ->verdict < -NF_MAX_VERDICT - 1) {
641 - duprintf("ipt_standard_check: bad negative verdict (%i)\n",
642 - targ->verdict);
643 - return 0;
644 - }
645 - return 1;
646 -}
647 -
648 -static inline int
649 check_match(struct ipt_entry_match *m,
650 const char *name,
651 const struct ipt_ip *ip,
652 @@ -552,12 +545,18 @@ check_entry(struct ipt_entry *e, const c
653 return -EINVAL;
654 }
655
656 + if (e->target_offset + sizeof(struct ipt_entry_target) > e->next_offset)
657 + return -EINVAL;
658 +
659 j = 0;
660 ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j);
661 if (ret != 0)
662 goto cleanup_matches;
663
664 t = ipt_get_target(e);
665 + ret = -EINVAL;
666 + if (e->target_offset + t->u.target_size > e->next_offset)
667 + goto cleanup_matches;
668 target = try_then_request_module(xt_find_target(AF_INET,
669 t->u.user.name,
670 t->u.user.revision),
671 @@ -575,12 +574,7 @@ check_entry(struct ipt_entry *e, const c
672 if (ret)
673 goto err;
674
675 - if (t->u.kernel.target == &ipt_standard_target) {
676 - if (!standard_check(t, size)) {
677 - ret = -EINVAL;
678 - goto cleanup_matches;
679 - }
680 - } else if (t->u.kernel.target->checkentry
681 + if (t->u.kernel.target->checkentry
682 && !t->u.kernel.target->checkentry(name, e, target, t->data,
683 t->u.target_size
684 - sizeof(*t),
685 @@ -730,7 +724,7 @@ translate_table(const char *name,
686
687 if (ret != 0) {
688 IPT_ENTRY_ITERATE(entry0, newinfo->size,
689 - cleanup_entry, &i);
690 + cleanup_entry, &i);
691 return ret;
692 }
693
694 @@ -1531,15 +1525,22 @@ check_compat_entry_size_and_hooks(struct
695 return -EINVAL;
696 }
697
698 + if (e->target_offset + sizeof(struct compat_xt_entry_target) >
699 + e->next_offset)
700 + return -EINVAL;
701 +
702 off = 0;
703 entry_offset = (void *)e - (void *)base;
704 j = 0;
705 ret = IPT_MATCH_ITERATE(e, compat_check_calc_match, name, &e->ip,
706 e->comefrom, &off, &j);
707 if (ret != 0)
708 - goto out;
709 + goto cleanup_matches;
710
711 t = ipt_get_target(e);
712 + ret = -EINVAL;
713 + if (e->target_offset + t->u.target_size > e->next_offset)
714 + goto cleanup_matches;
715 target = try_then_request_module(xt_find_target(AF_INET,
716 t->u.user.name,
717 t->u.user.revision),
718 @@ -1547,7 +1548,7 @@ check_compat_entry_size_and_hooks(struct
719 if (IS_ERR(target) || !target) {
720 duprintf("check_entry: `%s' not found\n", t->u.user.name);
721 ret = target ? PTR_ERR(target) : -ENOENT;
722 - goto out;
723 + goto cleanup_matches;
724 }
725 t->u.kernel.target = target;
726
727 @@ -1574,7 +1575,10 @@ check_compat_entry_size_and_hooks(struct
728
729 (*i)++;
730 return 0;
731 +
732 out:
733 + module_put(t->u.kernel.target->me);
734 +cleanup_matches:
735 IPT_MATCH_ITERATE(e, cleanup_match, &j);
736 return ret;
737 }
738 @@ -1597,18 +1601,16 @@ static inline int compat_copy_match_from
739 ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm),
740 name, hookmask, ip->proto,
741 ip->invflags & IPT_INV_PROTO);
742 - if (ret)
743 - return ret;
744
745 - if (m->u.kernel.match->checkentry
746 + if (!ret && m->u.kernel.match->checkentry
747 && !m->u.kernel.match->checkentry(name, ip, match, dm->data,
748 dm->u.match_size - sizeof(*dm),
749 hookmask)) {
750 duprintf("ip_tables: check failed for `%s'.\n",
751 m->u.kernel.match->name);
752 - return -EINVAL;
753 + ret = -EINVAL;
754 }
755 - return 0;
756 + return ret;
757 }
758
759 static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
760 @@ -1630,7 +1632,7 @@ static int compat_copy_entry_from_user(s
761 ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size,
762 name, &de->ip, de->comefrom);
763 if (ret)
764 - goto out;
765 + goto err;
766 de->target_offset = e->target_offset - (origsize - *size);
767 t = ipt_get_target(e);
768 target = t->u.kernel.target;
769 @@ -1653,22 +1655,18 @@ static int compat_copy_entry_from_user(s
770 name, e->comefrom, e->ip.proto,
771 e->ip.invflags & IPT_INV_PROTO);
772 if (ret)
773 - goto out;
774 + goto err;
775
776 - ret = -EINVAL;
777 - if (t->u.kernel.target == &ipt_standard_target) {
778 - if (!standard_check(t, *size))
779 - goto out;
780 - } else if (t->u.kernel.target->checkentry
781 + if (t->u.kernel.target->checkentry
782 && !t->u.kernel.target->checkentry(name, de, target,
783 t->data, t->u.target_size - sizeof(*t),
784 de->comefrom)) {
785 duprintf("ip_tables: compat: check failed for `%s'.\n",
786 t->u.kernel.target->name);
787 - goto out;
788 + ret = -EINVAL;
789 + goto err;
790 }
791 - ret = 0;
792 -out:
793 + err:
794 return ret;
795 }
796
797 @@ -1682,7 +1680,7 @@ translate_compat_table(const char *name,
798 unsigned int *hook_entries,
799 unsigned int *underflows)
800 {
801 - unsigned int i;
802 + unsigned int i, j;
803 struct xt_table_info *newinfo, *info;
804 void *pos, *entry0, *entry1;
805 unsigned int size;
806 @@ -1700,21 +1698,21 @@ translate_compat_table(const char *name,
807 }
808
809 duprintf("translate_compat_table: size %u\n", info->size);
810 - i = 0;
811 + j = 0;
812 xt_compat_lock(AF_INET);
813 /* Walk through entries, checking offsets. */
814 ret = IPT_ENTRY_ITERATE(entry0, total_size,
815 check_compat_entry_size_and_hooks,
816 info, &size, entry0,
817 entry0 + total_size,
818 - hook_entries, underflows, &i, name);
819 + hook_entries, underflows, &j, name);
820 if (ret != 0)
821 goto out_unlock;
822
823 ret = -EINVAL;
824 - if (i != number) {
825 + if (j != number) {
826 duprintf("translate_compat_table: %u not %u entries\n",
827 - i, number);
828 + j, number);
829 goto out_unlock;
830 }
831
832 @@ -1773,8 +1771,10 @@ translate_compat_table(const char *name,
833 free_newinfo:
834 xt_free_table_info(newinfo);
835 out:
836 + IPT_ENTRY_ITERATE(entry0, total_size, cleanup_entry, &j);
837 return ret;
838 out_unlock:
839 + compat_flush_offsets();
840 xt_compat_unlock(AF_INET);
841 goto out;
842 }
843 @@ -1994,6 +1994,9 @@ compat_do_ipt_get_ctl(struct sock *sk, i
844 {
845 int ret;
846
847 + if (!capable(CAP_NET_ADMIN))
848 + return -EPERM;
849 +
850 switch (cmd) {
851 case IPT_SO_GET_INFO:
852 ret = get_info(user, len, 1);
853 diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
854 index 4e7998b..f7b8906 100644
855 --- a/net/ipv4/netfilter/iptable_mangle.c
856 +++ b/net/ipv4/netfilter/iptable_mangle.c
857 @@ -157,7 +157,8 @@ #ifdef CONFIG_IP_ROUTE_FWMARK
858 || (*pskb)->nfmark != nfmark
859 #endif
860 || (*pskb)->nh.iph->tos != tos))
861 - return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
862 + if (ip_route_me_harder(pskb, RTN_UNSPEC))
863 + ret = NF_DROP;
864
865 return ret;
866 }
867 diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
868 index f136cec..87b7fe5 100644
869 --- a/net/ipv4/udp.c
870 +++ b/net/ipv4/udp.c
871 @@ -892,23 +892,32 @@ #ifndef CONFIG_XFRM
872 return 1;
873 #else
874 struct udp_sock *up = udp_sk(sk);
875 - struct udphdr *uh = skb->h.uh;
876 + struct udphdr *uh;
877 struct iphdr *iph;
878 int iphlen, len;
879
880 - __u8 *udpdata = (__u8 *)uh + sizeof(struct udphdr);
881 - __u32 *udpdata32 = (__u32 *)udpdata;
882 + __u8 *udpdata;
883 + __u32 *udpdata32;
884 __u16 encap_type = up->encap_type;
885
886 /* if we're overly short, let UDP handle it */
887 - if (udpdata > skb->tail)
888 + len = skb->len - sizeof(struct udphdr);
889 + if (len <= 0)
890 return 1;
891
892 /* if this is not encapsulated socket, then just return now */
893 if (!encap_type)
894 return 1;
895
896 - len = skb->tail - udpdata;
897 + /* If this is a paged skb, make sure we pull up
898 + * whatever data we need to look at. */
899 + if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8)))
900 + return 1;
901 +
902 + /* Now we can get the pointers */
903 + uh = skb->h.uh;
904 + udpdata = (__u8 *)uh + sizeof(struct udphdr);
905 + udpdata32 = (__u32 *)udpdata;
906
907 switch (encap_type) {
908 default:
909 diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
910 index c9d6b23..751548a 100644
911 --- a/net/ipv6/netfilter/ip6_tables.c
912 +++ b/net/ipv6/netfilter/ip6_tables.c
913 @@ -444,6 +444,13 @@ mark_source_chains(struct xt_table_info
914 && unconditional(&e->ipv6)) {
915 unsigned int oldpos, size;
916
917 + if (t->verdict < -NF_MAX_VERDICT - 1) {
918 + duprintf("mark_source_chains: bad "
919 + "negative verdict (%i)\n",
920 + t->verdict);
921 + return 0;
922 + }
923 +
924 /* Return: backtrack through the last
925 big jump. */
926 do {
927 @@ -481,6 +488,13 @@ #endif
928 if (strcmp(t->target.u.user.name,
929 IP6T_STANDARD_TARGET) == 0
930 && newpos >= 0) {
931 + if (newpos > newinfo->size -
932 + sizeof(struct ip6t_entry)) {
933 + duprintf("mark_source_chains: "
934 + "bad verdict (%i)\n",
935 + newpos);
936 + return 0;
937 + }
938 /* This a jump; chase it. */
939 duprintf("Jump rule %u -> %u\n",
940 pos, newpos);
941 @@ -514,27 +528,6 @@ cleanup_match(struct ip6t_entry_match *m
942 }
943
944 static inline int
945 -standard_check(const struct ip6t_entry_target *t,
946 - unsigned int max_offset)
947 -{
948 - struct ip6t_standard_target *targ = (void *)t;
949 -
950 - /* Check standard info. */
951 - if (targ->verdict >= 0
952 - && targ->verdict > max_offset - sizeof(struct ip6t_entry)) {
953 - duprintf("ip6t_standard_check: bad verdict (%i)\n",
954 - targ->verdict);
955 - return 0;
956 - }
957 - if (targ->verdict < -NF_MAX_VERDICT - 1) {
958 - duprintf("ip6t_standard_check: bad negative verdict (%i)\n",
959 - targ->verdict);
960 - return 0;
961 - }
962 - return 1;
963 -}
964 -
965 -static inline int
966 check_match(struct ip6t_entry_match *m,
967 const char *name,
968 const struct ip6t_ip6 *ipv6,
969 @@ -592,12 +585,19 @@ check_entry(struct ip6t_entry *e, const
970 return -EINVAL;
971 }
972
973 + if (e->target_offset + sizeof(struct ip6t_entry_target) >
974 + e->next_offset)
975 + return -EINVAL;
976 +
977 j = 0;
978 ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, e->comefrom, &j);
979 if (ret != 0)
980 goto cleanup_matches;
981
982 t = ip6t_get_target(e);
983 + ret = -EINVAL;
984 + if (e->target_offset + t->u.target_size > e->next_offset)
985 + goto cleanup_matches;
986 target = try_then_request_module(xt_find_target(AF_INET6,
987 t->u.user.name,
988 t->u.user.revision),
989 @@ -615,12 +615,7 @@ check_entry(struct ip6t_entry *e, const
990 if (ret)
991 goto err;
992
993 - if (t->u.kernel.target == &ip6t_standard_target) {
994 - if (!standard_check(t, size)) {
995 - ret = -EINVAL;
996 - goto cleanup_matches;
997 - }
998 - } else if (t->u.kernel.target->checkentry
999 + if (t->u.kernel.target->checkentry
1000 && !t->u.kernel.target->checkentry(name, e, target, t->data,
1001 t->u.target_size
1002 - sizeof(*t),
1003 @@ -770,7 +765,7 @@ translate_table(const char *name,
1004
1005 if (ret != 0) {
1006 IP6T_ENTRY_ITERATE(entry0, newinfo->size,
1007 - cleanup_entry, &i);
1008 + cleanup_entry, &i);
1009 return ret;
1010 }
1011
1012 @@ -780,7 +775,7 @@ translate_table(const char *name,
1013 memcpy(newinfo->entries[i], entry0, newinfo->size);
1014 }
1015
1016 - return ret;
1017 + return 0;
1018 }
1019
1020 /* Gets counters. */
1021 diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
1022 index 3d54f24..7ecfe82 100644
1023 --- a/net/ipv6/udp.c
1024 +++ b/net/ipv6/udp.c
1025 @@ -314,14 +314,13 @@ static void udpv6_err(struct sk_buff *sk
1026 {
1027 struct ipv6_pinfo *np;
1028 struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
1029 - struct net_device *dev = skb->dev;
1030 struct in6_addr *saddr = &hdr->saddr;
1031 struct in6_addr *daddr = &hdr->daddr;
1032 struct udphdr *uh = (struct udphdr*)(skb->data+offset);
1033 struct sock *sk;
1034 int err;
1035
1036 - sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, dev->ifindex);
1037 + sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, inet6_iif(skb));
1038
1039 if (sk == NULL)
1040 return;
1041 @@ -415,7 +414,7 @@ static void udpv6_mcast_deliver(struct u
1042
1043 read_lock(&udp_hash_lock);
1044 sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]);
1045 - dif = skb->dev->ifindex;
1046 + dif = inet6_iif(skb);
1047 sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
1048 if (!sk) {
1049 kfree_skb(skb);
1050 @@ -496,7 +495,7 @@ static int udpv6_rcv(struct sk_buff **ps
1051 * check socket cache ... must talk to Alan about his plans
1052 * for sock caches... i'll skip this for now.
1053 */
1054 - sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, dev->ifindex);
1055 + sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, inet6_iif(skb));
1056
1057 if (sk == NULL) {
1058 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
1059 diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
1060 index a9894dd..e1c27b7 100644
1061 --- a/net/netfilter/Kconfig
1062 +++ b/net/netfilter/Kconfig
1063 @@ -197,7 +197,9 @@ config NETFILTER_XT_TARGET_SECMARK
1064
1065 config NETFILTER_XT_TARGET_CONNSECMARK
1066 tristate '"CONNSECMARK" target support'
1067 - depends on NETFILTER_XTABLES && (NF_CONNTRACK_SECMARK || IP_NF_CONNTRACK_SECMARK)
1068 + depends on NETFILTER_XTABLES && \
1069 + ((NF_CONNTRACK && NF_CONNTRACK_SECMARK) || \
1070 + (IP_NF_CONNTRACK && IP_NF_CONNTRACK_SECMARK))
1071 help
1072 The CONNSECMARK target copies security markings from packets
1073 to connections, and restores security markings from connections
1074 @@ -342,7 +344,7 @@ config NETFILTER_XT_MATCH_MULTIPORT
1075
1076 config NETFILTER_XT_MATCH_PHYSDEV
1077 tristate '"physdev" match support'
1078 - depends on NETFILTER_XTABLES && BRIDGE_NETFILTER
1079 + depends on NETFILTER_XTABLES && BRIDGE && BRIDGE_NETFILTER
1080 help
1081 Physdev packet matching matches against the physical bridge ports
1082 the IP packet arrived on or will leave by.
1083 -
1084 To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
1085 the body of a message to majordomo@vger.kernel.org
1086 More majordomo info at http://vger.kernel.org/majordomo-info.html
1087 Please read the FAQ at http://www.tux.org/lkml/
1088

  ViewVC Help
Powered by ViewVC 1.1.20