Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
[IPV6]: fix flowlabel seqfile handling
[IPV6]: return EINVAL for invalid address with flowlabel lease request
[SCTP]: Remove temporary associations from backlog and hash.
[SCTP]: Correctly set IP id for SCTP traffic
[NetLabel]: protect the CIPSOv4 socket option from setsockopt()
[NETFILTER]: ip_tables: compat code module refcounting fix
[NETFILTER]: nf_conntrack: add missing unlock in get_next_corpse()
[NETFILTER]: ip_tables: compat error way cleanup
[NETFILTER]: Missed and reordered checks in {arp,ip,ip6}_tables
[NETFILTER]: remove masq/NAT from ip6tables Kconfig help
[IPV6]: fix lockup via /proc/net/ip6_flowlabel
[NET]: fix uaccess handling
[SCTP]: Always linearise packet on input
[ETH1394]: Fix unaligned accesses.
[DCCP]: fix printk format warnings
[NET]: Fix segmentation of linear packets
[XFRM] xfrm_user: Fix unaligned accesses.
[APPLETALK]: Fix potential OOPS in atalk_sendmsg().
[NET] sealevel: uses arp_broken_ops

+229 -116
+12 -8
drivers/ieee1394/eth1394.c
··· 64 64 #include <linux/ethtool.h> 65 65 #include <asm/uaccess.h> 66 66 #include <asm/delay.h> 67 + #include <asm/unaligned.h> 67 68 #include <net/arp.h> 68 69 69 70 #include "config_roms.h" ··· 492 491 int i; 493 492 struct eth1394_priv *priv = netdev_priv(dev); 494 493 struct hpsb_host *host = priv->host; 495 - u64 guid = *((u64*)&(host->csr.rom->bus_info_data[3])); 494 + u64 guid = get_unaligned((u64*)&(host->csr.rom->bus_info_data[3])); 496 495 u16 maxpayload = 1 << (host->csr.max_rec + 1); 497 496 int max_speed = IEEE1394_SPEED_MAX; 498 497 ··· 515 514 ETHER1394_GASP_OVERHEAD))); 516 515 517 516 /* Set our hardware address while we're at it */ 518 - *(u64*)dev->dev_addr = guid; 519 - *(u64*)dev->broadcast = ~0x0ULL; 517 + memcpy(dev->dev_addr, &guid, sizeof(u64)); 518 + memset(dev->broadcast, 0xff, sizeof(u64)); 520 519 } 521 520 522 521 spin_unlock_irqrestore (&priv->lock, flags); ··· 895 894 u16 maxpayload; 896 895 struct eth1394_node_ref *node; 897 896 struct eth1394_node_info *node_info; 897 + __be64 guid; 898 898 899 899 /* Sanity check. MacOSX seems to be sending us 131 in this 900 900 * field (atleast on my Panther G5). Not sure why. */ ··· 904 902 905 903 maxpayload = min(eth1394_speedto_maxpayload[sspd], (u16)(1 << (max_rec + 1))); 906 904 905 + guid = get_unaligned(&arp1394->s_uniq_id); 907 906 node = eth1394_find_node_guid(&priv->ip_node_list, 908 - be64_to_cpu(arp1394->s_uniq_id)); 907 + be64_to_cpu(guid)); 909 908 if (!node) { 910 909 return 0; 911 910 } ··· 934 931 arp_ptr += arp->ar_pln; /* skip over sender IP addr */ 935 932 936 933 if (arp->ar_op == htons(ARPOP_REQUEST)) 937 - /* just set ARP req target unique ID to 0 */ 938 - *((u64*)arp_ptr) = 0; 934 + memset(arp_ptr, 0, sizeof(u64)); 939 935 else 940 - *((u64*)arp_ptr) = *((u64*)dev->dev_addr); 936 + memcpy(arp_ptr, dev->dev_addr, sizeof(u64)); 941 937 } 942 938 943 939 /* Now add the ethernet header. */ ··· 1677 1675 if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF]) 1678 1676 priv->bc_dgl++; 1679 1677 } else { 1678 + __be64 guid = get_unaligned((u64 *)eth->h_dest); 1679 + 1680 1680 node = eth1394_find_node_guid(&priv->ip_node_list, 1681 - be64_to_cpu(*(u64*)eth->h_dest)); 1681 + be64_to_cpu(guid)); 1682 1682 if (!node) { 1683 1683 ret = -EAGAIN; 1684 1684 goto fail;
+1 -1
drivers/net/wan/Kconfig
··· 127 127 # There is no way to detect a Sealevel board. Force it modular 128 128 config SEALEVEL_4021 129 129 tristate "Sealevel Systems 4021 support" 130 - depends on WAN && ISA && m && ISA_DMA_API 130 + depends on WAN && ISA && m && ISA_DMA_API && INET 131 131 help 132 132 This is a driver for the Sealevel Systems ACB 56 serial I/O adapter. 133 133
-2
net/appletalk/ddp.c
··· 1584 1584 1585 1585 if (usat->sat_addr.s_net || usat->sat_addr.s_node == ATADDR_ANYNODE) { 1586 1586 rt = atrtr_find(&usat->sat_addr); 1587 - dev = rt->dev; 1588 1587 } else { 1589 1588 struct atalk_addr at_hint; 1590 1589 ··· 1591 1592 at_hint.s_net = at->src_net; 1592 1593 1593 1594 rt = atrtr_find(&at_hint); 1594 - dev = rt->dev; 1595 1595 } 1596 1596 if (!rt) 1597 1597 return -ENETUNREACH;
+4 -5
net/core/skbuff.c
··· 1946 1946 do { 1947 1947 struct sk_buff *nskb; 1948 1948 skb_frag_t *frag; 1949 - int hsize, nsize; 1949 + int hsize; 1950 1950 int k; 1951 1951 int size; 1952 1952 ··· 1957 1957 hsize = skb_headlen(skb) - offset; 1958 1958 if (hsize < 0) 1959 1959 hsize = 0; 1960 - nsize = hsize + doffset; 1961 - if (nsize > len + doffset || !sg) 1962 - nsize = len + doffset; 1960 + if (hsize > len || !sg) 1961 + hsize = len; 1963 1962 1964 - nskb = alloc_skb(nsize + headroom, GFP_ATOMIC); 1963 + nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC); 1965 1964 if (unlikely(!nskb)) 1966 1965 goto err; 1967 1966
+10 -8
net/dccp/ccids/ccid2.c
··· 352 352 353 353 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG 354 354 ccid2_pr_debug("pipe=%d\n", hctx->ccid2hctx_pipe); 355 - ccid2_pr_debug("Sent: seq=%llu\n", seq); 355 + ccid2_pr_debug("Sent: seq=%llu\n", (unsigned long long)seq); 356 356 do { 357 357 struct ccid2_seq *seqp = hctx->ccid2hctx_seqt; 358 358 359 359 while (seqp != hctx->ccid2hctx_seqh) { 360 360 ccid2_pr_debug("out seq=%llu acked=%d time=%lu\n", 361 - seqp->ccid2s_seq, seqp->ccid2s_acked, 362 - seqp->ccid2s_sent); 361 + (unsigned long long)seqp->ccid2s_seq, 362 + seqp->ccid2s_acked, seqp->ccid2s_sent); 363 363 seqp = seqp->ccid2s_next; 364 364 } 365 365 } while (0); ··· 480 480 /* first measurement */ 481 481 if (hctx->ccid2hctx_srtt == -1) { 482 482 ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n", 483 - r, jiffies, seqp->ccid2s_seq); 483 + r, jiffies, 484 + (unsigned long long)seqp->ccid2s_seq); 484 485 ccid2_change_srtt(hctx, r); 485 486 hctx->ccid2hctx_rttvar = r >> 1; 486 487 } else { ··· 637 636 u64 ackno_end_rl; 638 637 639 638 dccp_set_seqno(&ackno_end_rl, ackno - rl); 640 - ccid2_pr_debug("ackvec start:%llu end:%llu\n", ackno, 641 - ackno_end_rl); 639 + ccid2_pr_debug("ackvec start:%llu end:%llu\n", 640 + (unsigned long long)ackno, 641 + (unsigned long long)ackno_end_rl); 642 642 /* if the seqno we are analyzing is larger than the 643 643 * current ackno, then move towards the tail of our 644 644 * seqnos. ··· 674 672 675 673 seqp->ccid2s_acked = 1; 676 674 ccid2_pr_debug("Got ack for %llu\n", 677 - seqp->ccid2s_seq); 675 + (unsigned long long)seqp->ccid2s_seq); 678 676 ccid2_hc_tx_dec_pipe(sk); 679 677 } 680 678 if (seqp == hctx->ccid2hctx_seqt) { ··· 720 718 while (1) { 721 719 if (!seqp->ccid2s_acked) { 722 720 ccid2_pr_debug("Packet lost: %llu\n", 723 - seqp->ccid2s_seq); 721 + (unsigned long long)seqp->ccid2s_seq); 724 722 /* XXX need to traverse from tail -> head in 725 723 * order to detect multiple congestion events in 726 724 * one ack vector.
+3 -4
net/ipv4/cipso_ipv4.c
··· 1307 1307 1308 1308 /* We can't use ip_options_get() directly because it makes a call to 1309 1309 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and 1310 - * we can't block here. */ 1310 + * we won't always have CAP_NET_RAW even though we _always_ want to 1311 + * set the IPOPT_CIPSO option. */ 1311 1312 opt_len = (buf_len + 3) & ~3; 1312 1313 opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC); 1313 1314 if (opt == NULL) { ··· 1318 1317 memcpy(opt->__data, buf, buf_len); 1319 1318 opt->optlen = opt_len; 1320 1319 opt->is_data = 1; 1320 + opt->cipso = sizeof(struct iphdr); 1321 1321 kfree(buf); 1322 1322 buf = NULL; 1323 - ret_val = ip_options_compile(opt, NULL); 1324 - if (ret_val != 0) 1325 - goto socket_setattr_failure; 1326 1323 1327 1324 sk_inet = inet_sk(sk); 1328 1325 if (sk_inet->is_icsk) {
+1 -1
net/ipv4/ip_options.c
··· 443 443 opt->router_alert = optptr - iph; 444 444 break; 445 445 case IPOPT_CIPSO: 446 - if (opt->cipso) { 446 + if ((!skb && !capable(CAP_NET_RAW)) || opt->cipso) { 447 447 pp_ptr = optptr; 448 448 goto error; 449 449 }
+16 -9
net/ipv4/netfilter/arp_tables.c
··· 466 466 return -EINVAL; 467 467 } 468 468 469 + if (e->target_offset + sizeof(struct arpt_entry_target) > e->next_offset) 470 + return -EINVAL; 471 + 469 472 t = arpt_get_target(e); 473 + if (e->target_offset + t->u.target_size > e->next_offset) 474 + return -EINVAL; 475 + 470 476 target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, 471 477 t->u.user.revision), 472 478 "arpt_%s", t->u.user.name); ··· 627 621 } 628 622 } 629 623 630 - if (!mark_source_chains(newinfo, valid_hooks, entry0)) { 631 - duprintf("Looping hook\n"); 632 - return -ELOOP; 633 - } 634 - 635 624 /* Finally, each sanity check must pass */ 636 625 i = 0; 637 626 ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, 638 627 check_entry, name, size, &i); 639 628 640 - if (ret != 0) { 641 - ARPT_ENTRY_ITERATE(entry0, newinfo->size, 642 - cleanup_entry, &i); 643 - return ret; 629 + if (ret != 0) 630 + goto cleanup; 631 + 632 + ret = -ELOOP; 633 + if (!mark_source_chains(newinfo, valid_hooks, entry0)) { 634 + duprintf("Looping hook\n"); 635 + goto cleanup; 644 636 } 645 637 646 638 /* And one copy for every other CPU */ ··· 647 643 memcpy(newinfo->entries[i], entry0, newinfo->size); 648 644 } 649 645 646 + return 0; 647 + cleanup: 648 + ARPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); 650 649 return ret; 651 650 } 652 651
+34 -33
net/ipv4/netfilter/ip_tables.c
··· 547 547 return -EINVAL; 548 548 } 549 549 550 + if (e->target_offset + sizeof(struct ipt_entry_target) > e->next_offset) 551 + return -EINVAL; 552 + 550 553 j = 0; 551 554 ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j); 552 555 if (ret != 0) 553 556 goto cleanup_matches; 554 557 555 558 t = ipt_get_target(e); 559 + ret = -EINVAL; 560 + if (e->target_offset + t->u.target_size > e->next_offset) 561 + goto cleanup_matches; 556 562 target = try_then_request_module(xt_find_target(AF_INET, 557 563 t->u.user.name, 558 564 t->u.user.revision), ··· 718 712 } 719 713 } 720 714 721 - if (!mark_source_chains(newinfo, valid_hooks, entry0)) 722 - return -ELOOP; 723 - 724 715 /* Finally, each sanity check must pass */ 725 716 i = 0; 726 717 ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, 727 718 check_entry, name, size, &i); 728 719 729 - if (ret != 0) { 730 - IPT_ENTRY_ITERATE(entry0, newinfo->size, 731 - cleanup_entry, &i); 732 - return ret; 733 - } 720 + if (ret != 0) 721 + goto cleanup; 722 + 723 + ret = -ELOOP; 724 + if (!mark_source_chains(newinfo, valid_hooks, entry0)) 725 + goto cleanup; 734 726 735 727 /* And one copy for every other CPU */ 736 728 for_each_possible_cpu(i) { ··· 736 732 memcpy(newinfo->entries[i], entry0, newinfo->size); 737 733 } 738 734 735 + return 0; 736 + cleanup: 737 + IPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); 739 738 return ret; 740 739 } 741 740 ··· 1470 1463 return -EINVAL; 1471 1464 } 1472 1465 1466 + if (e->target_offset + sizeof(struct compat_xt_entry_target) > 1467 + e->next_offset) 1468 + return -EINVAL; 1469 + 1473 1470 off = 0; 1474 1471 entry_offset = (void *)e - (void *)base; 1475 1472 j = 0; ··· 1483 1472 goto cleanup_matches; 1484 1473 1485 1474 t = ipt_get_target(e); 1475 + ret = -EINVAL; 1476 + if (e->target_offset + t->u.target_size > e->next_offset) 1477 + goto cleanup_matches; 1486 1478 target = try_then_request_module(xt_find_target(AF_INET, 1487 1479 t->u.user.name, 1488 1480 t->u.user.revision), ··· 1527 1513 1528 1514 static inline int compat_copy_match_from_user(struct ipt_entry_match *m, 1529 1515 void **dstptr, compat_uint_t *size, const char *name, 1530 - const struct ipt_ip *ip, unsigned int hookmask, int *i) 1516 + const struct ipt_ip *ip, unsigned int hookmask) 1531 1517 { 1532 1518 struct ipt_entry_match *dm; 1533 1519 struct ipt_match *match; ··· 1540 1526 ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm), 1541 1527 name, hookmask, ip->proto, 1542 1528 ip->invflags & IPT_INV_PROTO); 1543 - if (ret) 1544 - goto err; 1545 - 1546 - if (m->u.kernel.match->checkentry 1529 + if (!ret && m->u.kernel.match->checkentry 1547 1530 && !m->u.kernel.match->checkentry(name, ip, match, dm->data, 1548 1531 hookmask)) { 1549 1532 duprintf("ip_tables: check failed for `%s'.\n", 1550 1533 m->u.kernel.match->name); 1551 1534 ret = -EINVAL; 1552 - goto err; 1553 1535 } 1554 - (*i)++; 1555 - return 0; 1556 - 1557 - err: 1558 - module_put(m->u.kernel.match->me); 1559 1536 return ret; 1560 1537 } 1561 1538 ··· 1558 1553 struct ipt_target *target; 1559 1554 struct ipt_entry *de; 1560 1555 unsigned int origsize; 1561 - int ret, h, j; 1556 + int ret, h; 1562 1557 1563 1558 ret = 0; 1564 1559 origsize = *size; 1565 1560 de = (struct ipt_entry *)*dstptr; 1566 1561 memcpy(de, e, sizeof(struct ipt_entry)); 1567 1562 1568 - j = 0; 1569 1563 *dstptr += sizeof(struct compat_ipt_entry); 1570 1564 ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size, 1571 - name, &de->ip, de->comefrom, &j); 1565 + name, &de->ip, de->comefrom); 1572 1566 if (ret) 1573 - goto cleanup_matches; 1567 + goto err; 1574 1568 de->target_offset = e->target_offset - (origsize - *size); 1575 1569 t = ipt_get_target(e); 1576 1570 target = t->u.kernel.target; ··· 1603 1599 goto err; 1604 1600 } 1605 1601 ret = 0; 1606 - return ret; 1607 - 1608 1602 err: 1609 - module_put(t->u.kernel.target->me); 1610 - cleanup_matches: 1611 - IPT_MATCH_ITERATE(e, cleanup_match, &j); 1612 1603 return ret; 1613 1604 } 1614 1605 ··· 1617 1618 unsigned int *hook_entries, 1618 1619 unsigned int *underflows) 1619 1620 { 1620 - unsigned int i; 1621 + unsigned int i, j; 1621 1622 struct xt_table_info *newinfo, *info; 1622 1623 void *pos, *entry0, *entry1; 1623 1624 unsigned int size; ··· 1635 1636 } 1636 1637 1637 1638 duprintf("translate_compat_table: size %u\n", info->size); 1638 - i = 0; 1639 + j = 0; 1639 1640 xt_compat_lock(AF_INET); 1640 1641 /* Walk through entries, checking offsets. */ 1641 1642 ret = IPT_ENTRY_ITERATE(entry0, total_size, 1642 1643 check_compat_entry_size_and_hooks, 1643 1644 info, &size, entry0, 1644 1645 entry0 + total_size, 1645 - hook_entries, underflows, &i, name); 1646 + hook_entries, underflows, &j, name); 1646 1647 if (ret != 0) 1647 1648 goto out_unlock; 1648 1649 1649 1650 ret = -EINVAL; 1650 - if (i != number) { 1651 + if (j != number) { 1651 1652 duprintf("translate_compat_table: %u not %u entries\n", 1652 - i, number); 1653 + j, number); 1653 1654 goto out_unlock; 1654 1655 } 1655 1656 ··· 1708 1709 free_newinfo: 1709 1710 xt_free_table_info(newinfo); 1710 1711 out: 1712 + IPT_ENTRY_ITERATE(entry0, total_size, cleanup_entry, &j); 1711 1713 return ret; 1712 1714 out_unlock: 1715 + compat_flush_offsets(); 1713 1716 xt_compat_unlock(AF_INET); 1714 1717 goto out; 1715 1718 }
+11 -6
net/ipv4/raw.c
··· 329 329 return err; 330 330 } 331 331 332 - static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) 332 + static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) 333 333 { 334 334 struct iovec *iov; 335 335 u8 __user *type = NULL; ··· 338 338 unsigned int i; 339 339 340 340 if (!msg->msg_iov) 341 - return; 341 + return 0; 342 342 343 343 for (i = 0; i < msg->msg_iovlen; i++) { 344 344 iov = &msg->msg_iov[i]; ··· 360 360 code = iov->iov_base; 361 361 362 362 if (type && code) { 363 - get_user(fl->fl_icmp_type, type); 364 - get_user(fl->fl_icmp_code, code); 363 + if (get_user(fl->fl_icmp_type, type) || 364 + get_user(fl->fl_icmp_code, code)) 365 + return -EFAULT; 365 366 probed = 1; 366 367 } 367 368 break; ··· 373 372 if (probed) 374 373 break; 375 374 } 375 + return 0; 376 376 } 377 377 378 378 static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, ··· 482 480 .proto = inet->hdrincl ? IPPROTO_RAW : 483 481 sk->sk_protocol, 484 482 }; 485 - if (!inet->hdrincl) 486 - raw_probe_proto_opt(&fl, msg); 483 + if (!inet->hdrincl) { 484 + err = raw_probe_proto_opt(&fl, msg); 485 + if (err) 486 + goto done; 487 + } 487 488 488 489 security_sk_classify_flow(sk, &fl); 489 490 err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
+11 -13
net/ipv6/ip6_flowlabel.c
··· 330 330 fl->share = freq->flr_share; 331 331 addr_type = ipv6_addr_type(&freq->flr_dst); 332 332 if ((addr_type&IPV6_ADDR_MAPPED) 333 - || addr_type == IPV6_ADDR_ANY) 333 + || addr_type == IPV6_ADDR_ANY) { 334 + err = -EINVAL; 334 335 goto done; 336 + } 335 337 ipv6_addr_copy(&fl->dst, &freq->flr_dst); 336 338 atomic_set(&fl->users, 1); 337 339 switch (fl->share) { ··· 589 587 while (!fl) { 590 588 if (++state->bucket <= FL_HASH_MASK) 591 589 fl = fl_ht[state->bucket]; 590 + else 591 + break; 592 592 } 593 593 return fl; 594 594 } ··· 627 623 read_unlock_bh(&ip6_fl_lock); 628 624 } 629 625 630 - static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl) 626 + static int ip6fl_seq_show(struct seq_file *seq, void *v) 631 627 { 632 - while(fl) { 628 + if (v == SEQ_START_TOKEN) 629 + seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", 630 + "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); 631 + else { 632 + struct ip6_flowlabel *fl = v; 633 633 seq_printf(seq, 634 634 "%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_SEQFMT " %-4d\n", 635 635 (unsigned)ntohl(fl->label), ··· 644 636 (long)(fl->expires - jiffies)/HZ, 645 637 NIP6(fl->dst), 646 638 fl->opt ? fl->opt->opt_nflen : 0); 647 - fl = fl->next; 648 639 } 649 - } 650 - 651 - static int ip6fl_seq_show(struct seq_file *seq, void *v) 652 - { 653 - if (v == SEQ_START_TOKEN) 654 - seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", 655 - "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); 656 - else 657 - ip6fl_fl_seq_show(seq, v); 658 640 return 0; 659 641 } 660 642
+1 -1
net/ipv6/netfilter/Kconfig
··· 40 40 To compile it as a module, choose M here. If unsure, say N. 41 41 42 42 config IP6_NF_IPTABLES 43 - tristate "IP6 tables support (required for filtering/masq/NAT)" 43 + tristate "IP6 tables support (required for filtering)" 44 44 depends on NETFILTER_XTABLES 45 45 help 46 46 ip6tables is a general, extensible packet identification framework.
+16 -8
net/ipv6/netfilter/ip6_tables.c
··· 586 586 return -EINVAL; 587 587 } 588 588 589 + if (e->target_offset + sizeof(struct ip6t_entry_target) > 590 + e->next_offset) 591 + return -EINVAL; 592 + 589 593 j = 0; 590 594 ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, e->comefrom, &j); 591 595 if (ret != 0) 592 596 goto cleanup_matches; 593 597 594 598 t = ip6t_get_target(e); 599 + ret = -EINVAL; 600 + if (e->target_offset + t->u.target_size > e->next_offset) 601 + goto cleanup_matches; 595 602 target = try_then_request_module(xt_find_target(AF_INET6, 596 603 t->u.user.name, 597 604 t->u.user.revision), ··· 758 751 } 759 752 } 760 753 761 - if (!mark_source_chains(newinfo, valid_hooks, entry0)) 762 - return -ELOOP; 763 - 764 754 /* Finally, each sanity check must pass */ 765 755 i = 0; 766 756 ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, 767 757 check_entry, name, size, &i); 768 758 769 - if (ret != 0) { 770 - IP6T_ENTRY_ITERATE(entry0, newinfo->size, 771 - cleanup_entry, &i); 772 - return ret; 773 - } 759 + if (ret != 0) 760 + goto cleanup; 761 + 762 + ret = -ELOOP; 763 + if (!mark_source_chains(newinfo, valid_hooks, entry0)) 764 + goto cleanup; 774 765 775 766 /* And one copy for every other CPU */ 776 767 for_each_possible_cpu(i) { ··· 776 771 memcpy(newinfo->entries[i], entry0, newinfo->size); 777 772 } 778 773 774 + return 0; 775 + cleanup: 776 + IP6T_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); 779 777 return ret; 780 778 } 781 779
+11 -6
net/ipv6/raw.c
··· 604 604 return err; 605 605 } 606 606 607 - static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) 607 + static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) 608 608 { 609 609 struct iovec *iov; 610 610 u8 __user *type = NULL; ··· 616 616 int i; 617 617 618 618 if (!msg->msg_iov) 619 - return; 619 + return 0; 620 620 621 621 for (i = 0; i < msg->msg_iovlen; i++) { 622 622 iov = &msg->msg_iov[i]; ··· 638 638 code = iov->iov_base; 639 639 640 640 if (type && code) { 641 - get_user(fl->fl_icmp_type, type); 642 - get_user(fl->fl_icmp_code, code); 641 + if (get_user(fl->fl_icmp_type, type) || 642 + get_user(fl->fl_icmp_code, code)) 643 + return -EFAULT; 643 644 probed = 1; 644 645 } 645 646 break; ··· 651 650 /* check if type field is readable or not. */ 652 651 if (iov->iov_len > 2 - len) { 653 652 u8 __user *p = iov->iov_base; 654 - get_user(fl->fl_mh_type, &p[2 - len]); 653 + if (get_user(fl->fl_mh_type, &p[2 - len])) 654 + return -EFAULT; 655 655 probed = 1; 656 656 } else 657 657 len += iov->iov_len; ··· 666 664 if (probed) 667 665 break; 668 666 } 667 + return 0; 669 668 } 670 669 671 670 static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, ··· 790 787 opt = ipv6_fixup_options(&opt_space, opt); 791 788 792 789 fl.proto = proto; 793 - rawv6_probe_proto_opt(&fl, msg); 790 + err = rawv6_probe_proto_opt(&fl, msg); 791 + if (err) 792 + goto out; 794 793 795 794 ipv6_addr_copy(&fl.fl6_dst, daddr); 796 795 if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
+2 -1
net/netfilter/nf_conntrack_core.c
··· 1520 1520 if (iter(ct, data)) 1521 1521 goto found; 1522 1522 } 1523 + write_unlock_bh(&nf_conntrack_lock); 1523 1524 return NULL; 1524 1525 found: 1525 - atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use); 1526 + atomic_inc(&ct->ct_general.use); 1526 1527 write_unlock_bh(&nf_conntrack_lock); 1527 1528 return ct; 1528 1529 }
+3 -2
net/netlink/af_netlink.c
··· 1075 1075 return -EINVAL; 1076 1076 len = sizeof(int); 1077 1077 val = nlk->flags & NETLINK_RECV_PKTINFO ? 1 : 0; 1078 - put_user(len, optlen); 1079 - put_user(val, optval); 1078 + if (put_user(len, optlen) || 1079 + put_user(val, optval)) 1080 + return -EFAULT; 1080 1081 err = 0; 1081 1082 break; 1082 1083 default:
+11 -4
net/sctp/associola.c
··· 346 346 struct list_head *pos, *temp; 347 347 int i; 348 348 349 - list_del(&asoc->asocs); 349 + /* Only real associations count against the endpoint, so 350 + * don't bother for if this is a temporary association. 351 + */ 352 + if (!asoc->temp) { 353 + list_del(&asoc->asocs); 350 354 351 - /* Decrement the backlog value for a TCP-style listening socket. */ 352 - if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) 353 - sk->sk_ack_backlog--; 355 + /* Decrement the backlog value for a TCP-style listening 356 + * socket. 357 + */ 358 + if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) 359 + sk->sk_ack_backlog--; 360 + } 354 361 355 362 /* Mark as dead, so other users can know this structure is 356 363 * going away.
+7
net/sctp/endpointola.c
··· 144 144 { 145 145 struct sock *sk = ep->base.sk; 146 146 147 + /* If this is a temporary association, don't bother 148 + * since we'll be removing it shortly and don't 149 + * want anyone to find it anyway. 150 + */ 151 + if (asoc->temp) 152 + return; 153 + 147 154 /* Now just add it to our list of asocs */ 148 155 list_add_tail(&asoc->asocs, &ep->asocs); 149 156
+9
net/sctp/input.c
··· 135 135 136 136 SCTP_INC_STATS_BH(SCTP_MIB_INSCTPPACKS); 137 137 138 + if (skb_linearize(skb)) 139 + goto discard_it; 140 + 138 141 sh = (struct sctphdr *) skb->h.raw; 139 142 140 143 /* Pull up the IP and SCTP headers. */ ··· 771 768 /* Add an association to the hash. Local BH-safe. */ 772 769 void sctp_hash_established(struct sctp_association *asoc) 773 770 { 771 + if (asoc->temp) 772 + return; 773 + 774 774 sctp_local_bh_disable(); 775 775 __sctp_hash_established(asoc); 776 776 sctp_local_bh_enable(); ··· 807 801 /* Remove association from the hash table. Local BH-safe. */ 808 802 void sctp_unhash_established(struct sctp_association *asoc) 809 803 { 804 + if (asoc->temp) 805 + return; 806 + 810 807 sctp_local_bh_disable(); 811 808 __sctp_unhash_established(asoc); 812 809 sctp_local_bh_enable();
+1 -1
net/sctp/protocol.c
··· 591 591 newinet->dport = htons(asoc->peer.port); 592 592 newinet->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr; 593 593 newinet->pmtudisc = inet->pmtudisc; 594 - newinet->id = 0; 594 + newinet->id = asoc->next_tsn ^ jiffies; 595 595 596 596 newinet->uc_ttl = -1; 597 597 newinet->mc_loop = 1;
+9
net/sctp/socket.c
··· 3372 3372 { 3373 3373 struct sock *sk = asoc->base.sk; 3374 3374 struct socket *sock; 3375 + struct inet_sock *inetsk; 3375 3376 int err = 0; 3376 3377 3377 3378 /* An association cannot be branched off from an already peeled-off ··· 3390 3389 * asoc to the newsk. 3391 3390 */ 3392 3391 sctp_sock_migrate(sk, sock->sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH); 3392 + 3393 + /* Make peeled-off sockets more like 1-1 accepted sockets. 3394 + * Set the daddr and initialize id to something more random 3395 + */ 3396 + inetsk = inet_sk(sock->sk); 3397 + inetsk->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr; 3398 + inetsk->id = asoc->next_tsn ^ jiffies; 3399 + 3393 3400 *sockp = sock; 3394 3401 3395 3402 return err;
+2 -2
net/xfrm/xfrm_user.c
··· 323 323 x->props.replay_window = p->replay_window; 324 324 x->props.reqid = p->reqid; 325 325 x->props.family = p->family; 326 - x->props.saddr = p->saddr; 326 + memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr)); 327 327 x->props.flags = p->flags; 328 328 } 329 329 ··· 545 545 memcpy(&p->lft, &x->lft, sizeof(p->lft)); 546 546 memcpy(&p->curlft, &x->curlft, sizeof(p->curlft)); 547 547 memcpy(&p->stats, &x->stats, sizeof(p->stats)); 548 - p->saddr = x->props.saddr; 548 + memcpy(&p->saddr, &x->props.saddr, sizeof(p->saddr)); 549 549 p->mode = x->props.mode; 550 550 p->replay_window = x->props.replay_window; 551 551 p->reqid = x->props.reqid;
+7 -1
security/selinux/hooks.c
··· 3313 3313 3314 3314 static int selinux_socket_setsockopt(struct socket *sock,int level,int optname) 3315 3315 { 3316 - return socket_has_perm(current, sock, SOCKET__SETOPT); 3316 + int err; 3317 + 3318 + err = socket_has_perm(current, sock, SOCKET__SETOPT); 3319 + if (err) 3320 + return err; 3321 + 3322 + return selinux_netlbl_socket_setsockopt(sock, level, optname); 3317 3323 } 3318 3324 3319 3325 static int selinux_socket_getsockopt(struct socket *sock, int level,
+10
security/selinux/include/selinux_netlabel.h
··· 53 53 void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec, 54 54 struct sk_security_struct *newssec); 55 55 int selinux_netlbl_inode_permission(struct inode *inode, int mask); 56 + int selinux_netlbl_socket_setsockopt(struct socket *sock, 57 + int level, 58 + int optname); 56 59 #else 57 60 static inline void selinux_netlbl_cache_invalidate(void) 58 61 { ··· 114 111 115 112 static inline int selinux_netlbl_inode_permission(struct inode *inode, 116 113 int mask) 114 + { 115 + return 0; 116 + } 117 + 118 + static inline int selinux_netlbl_socket_setsockopt(struct socket *sock, 119 + int level, 120 + int optname) 117 121 { 118 122 return 0; 119 123 }
+37
security/selinux/ss/services.c
··· 2682 2682 2683 2683 return peer_sid; 2684 2684 } 2685 + 2686 + /** 2687 + * selinux_netlbl_socket_setsockopt - Do not allow users to remove a NetLabel 2688 + * @sock: the socket 2689 + * @level: the socket level or protocol 2690 + * @optname: the socket option name 2691 + * 2692 + * Description: 2693 + * Check the setsockopt() call and if the user is trying to replace the IP 2694 + * options on a socket and a NetLabel is in place for the socket deny the 2695 + * access; otherwise allow the access. Returns zero when the access is 2696 + * allowed, -EACCES when denied, and other negative values on error. 2697 + * 2698 + */ 2699 + int selinux_netlbl_socket_setsockopt(struct socket *sock, 2700 + int level, 2701 + int optname) 2702 + { 2703 + int rc = 0; 2704 + struct inode *inode = SOCK_INODE(sock); 2705 + struct sk_security_struct *sksec = sock->sk->sk_security; 2706 + struct inode_security_struct *isec = inode->i_security; 2707 + struct netlbl_lsm_secattr secattr; 2708 + 2709 + mutex_lock(&isec->lock); 2710 + if (level == IPPROTO_IP && optname == IP_OPTIONS && 2711 + sksec->nlbl_state == NLBL_LABELED) { 2712 + netlbl_secattr_init(&secattr); 2713 + rc = netlbl_socket_getattr(sock, &secattr); 2714 + if (rc == 0 && (secattr.cache || secattr.mls_lvl_vld)) 2715 + rc = -EACCES; 2716 + netlbl_secattr_destroy(&secattr); 2717 + } 2718 + mutex_unlock(&isec->lock); 2719 + 2720 + return rc; 2721 + } 2685 2722 #endif /* CONFIG_NETLABEL */