diff options
Diffstat (limited to 'net/ipv4')
| -rw-r--r-- | net/ipv4/cipso_ipv4.c | 7 | ||||
| -rw-r--r-- | net/ipv4/ip_options.c | 2 | ||||
| -rw-r--r-- | net/ipv4/ipconfig.c | 2 | ||||
| -rw-r--r-- | net/ipv4/ipvs/ip_vs_ftp.c | 2 | ||||
| -rw-r--r-- | net/ipv4/ipvs/ip_vs_proto_tcp.c | 2 | ||||
| -rw-r--r-- | net/ipv4/ipvs/ip_vs_proto_udp.c | 8 | ||||
| -rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 25 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_queue.c | 7 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_tables.c | 67 | ||||
| -rw-r--r-- | net/ipv4/raw.c | 17 | ||||
| -rw-r--r-- | net/ipv4/sysctl_net_ipv4.c | 7 | ||||
| -rw-r--r-- | net/ipv4/tcp.c | 11 | ||||
| -rw-r--r-- | net/ipv4/tcp_cong.c | 8 | ||||
| -rw-r--r-- | net/ipv4/tcp_cubic.c | 6 | ||||
| -rw-r--r-- | net/ipv4/tcp_htcp.c | 2 |
15 files changed, 94 insertions, 79 deletions
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index e2077a3aa8c0..6460233407c7 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c | |||
| @@ -1307,7 +1307,8 @@ int cipso_v4_socket_setattr(const struct socket *sock, | |||
| 1307 | 1307 | ||
| 1308 | /* We can't use ip_options_get() directly because it makes a call to | 1308 | /* We can't use ip_options_get() directly because it makes a call to |
| 1309 | * ip_options_get_alloc() which allocates memory with GFP_KERNEL and | 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 | opt_len = (buf_len + 3) & ~3; | 1312 | opt_len = (buf_len + 3) & ~3; |
| 1312 | opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC); | 1313 | opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC); |
| 1313 | if (opt == NULL) { | 1314 | if (opt == NULL) { |
| @@ -1317,11 +1318,9 @@ int cipso_v4_socket_setattr(const struct socket *sock, | |||
| 1317 | memcpy(opt->__data, buf, buf_len); | 1318 | memcpy(opt->__data, buf, buf_len); |
| 1318 | opt->optlen = opt_len; | 1319 | opt->optlen = opt_len; |
| 1319 | opt->is_data = 1; | 1320 | opt->is_data = 1; |
| 1321 | opt->cipso = sizeof(struct iphdr); | ||
| 1320 | kfree(buf); | 1322 | kfree(buf); |
| 1321 | buf = NULL; | 1323 | buf = NULL; |
| 1322 | ret_val = ip_options_compile(opt, NULL); | ||
| 1323 | if (ret_val != 0) | ||
| 1324 | goto socket_setattr_failure; | ||
| 1325 | 1324 | ||
| 1326 | sk_inet = inet_sk(sk); | 1325 | sk_inet = inet_sk(sk); |
| 1327 | if (sk_inet->is_icsk) { | 1326 | if (sk_inet->is_icsk) { |
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 8dabbfc31267..9f02917d6f45 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c | |||
| @@ -443,7 +443,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb) | |||
| 443 | opt->router_alert = optptr - iph; | 443 | opt->router_alert = optptr - iph; |
| 444 | break; | 444 | break; |
| 445 | case IPOPT_CIPSO: | 445 | case IPOPT_CIPSO: |
| 446 | if (opt->cipso) { | 446 | if ((!skb && !capable(CAP_NET_RAW)) || opt->cipso) { |
| 447 | pp_ptr = optptr; | 447 | pp_ptr = optptr; |
| 448 | goto error; | 448 | goto error; |
| 449 | } | 449 | } |
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index f8ce84759159..955a07abb91d 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
| @@ -420,7 +420,7 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt | |||
| 420 | { | 420 | { |
| 421 | struct arphdr *rarp; | 421 | struct arphdr *rarp; |
| 422 | unsigned char *rarp_ptr; | 422 | unsigned char *rarp_ptr; |
| 423 | unsigned long sip, tip; | 423 | u32 sip, tip; |
| 424 | unsigned char *sha, *tha; /* s for "source", t for "target" */ | 424 | unsigned char *sha, *tha; /* s for "source", t for "target" */ |
| 425 | struct ic_device *d; | 425 | struct ic_device *d; |
| 426 | 426 | ||
diff --git a/net/ipv4/ipvs/ip_vs_ftp.c b/net/ipv4/ipvs/ip_vs_ftp.c index 6d398f10aa91..687c1de1146f 100644 --- a/net/ipv4/ipvs/ip_vs_ftp.c +++ b/net/ipv4/ipvs/ip_vs_ftp.c | |||
| @@ -200,7 +200,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
| 200 | from = n_cp->vaddr; | 200 | from = n_cp->vaddr; |
| 201 | port = n_cp->vport; | 201 | port = n_cp->vport; |
| 202 | sprintf(buf,"%d,%d,%d,%d,%d,%d", NIPQUAD(from), | 202 | sprintf(buf,"%d,%d,%d,%d,%d,%d", NIPQUAD(from), |
| 203 | ntohs(port)&255, (ntohs(port)>>8)&255); | 203 | (ntohs(port)>>8)&255, ntohs(port)&255); |
| 204 | buf_len = strlen(buf); | 204 | buf_len = strlen(buf); |
| 205 | 205 | ||
| 206 | /* | 206 | /* |
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c index bfe779e74590..6ff05c3a32e6 100644 --- a/net/ipv4/ipvs/ip_vs_proto_tcp.c +++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c | |||
| @@ -117,7 +117,7 @@ tcp_fast_csum_update(struct tcphdr *tcph, __be32 oldip, __be32 newip, | |||
| 117 | { | 117 | { |
| 118 | tcph->check = | 118 | tcph->check = |
| 119 | ip_vs_check_diff(~oldip, newip, | 119 | ip_vs_check_diff(~oldip, newip, |
| 120 | ip_vs_check_diff(oldport ^ htonl(0xFFFF), | 120 | ip_vs_check_diff(oldport ^ htons(0xFFFF), |
| 121 | newport, tcph->check)); | 121 | newport, tcph->check)); |
| 122 | } | 122 | } |
| 123 | 123 | ||
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c index 54aa7603591f..691c8b637b29 100644 --- a/net/ipv4/ipvs/ip_vs_proto_udp.c +++ b/net/ipv4/ipvs/ip_vs_proto_udp.c | |||
| @@ -122,10 +122,10 @@ udp_fast_csum_update(struct udphdr *uhdr, __be32 oldip, __be32 newip, | |||
| 122 | { | 122 | { |
| 123 | uhdr->check = | 123 | uhdr->check = |
| 124 | ip_vs_check_diff(~oldip, newip, | 124 | ip_vs_check_diff(~oldip, newip, |
| 125 | ip_vs_check_diff(oldport ^ htonl(0xFFFF), | 125 | ip_vs_check_diff(oldport ^ htons(0xFFFF), |
| 126 | newport, uhdr->check)); | 126 | newport, uhdr->check)); |
| 127 | if (!uhdr->check) | 127 | if (!uhdr->check) |
| 128 | uhdr->check = htonl(0xFFFF); | 128 | uhdr->check = -1; |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | static int | 131 | static int |
| @@ -173,7 +173,7 @@ udp_snat_handler(struct sk_buff **pskb, | |||
| 173 | cp->protocol, | 173 | cp->protocol, |
| 174 | (*pskb)->csum); | 174 | (*pskb)->csum); |
| 175 | if (udph->check == 0) | 175 | if (udph->check == 0) |
| 176 | udph->check = htonl(0xFFFF); | 176 | udph->check = -1; |
| 177 | IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n", | 177 | IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n", |
| 178 | pp->name, udph->check, | 178 | pp->name, udph->check, |
| 179 | (char*)&(udph->check) - (char*)udph); | 179 | (char*)&(udph->check) - (char*)udph); |
| @@ -228,7 +228,7 @@ udp_dnat_handler(struct sk_buff **pskb, | |||
| 228 | cp->protocol, | 228 | cp->protocol, |
| 229 | (*pskb)->csum); | 229 | (*pskb)->csum); |
| 230 | if (udph->check == 0) | 230 | if (udph->check == 0) |
| 231 | udph->check = 0xFFFF; | 231 | udph->check = -1; |
| 232 | (*pskb)->ip_summed = CHECKSUM_UNNECESSARY; | 232 | (*pskb)->ip_summed = CHECKSUM_UNNECESSARY; |
| 233 | } | 233 | } |
| 234 | return 1; | 234 | return 1; |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 0849f1cced13..413c2d0a1f3d 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
| @@ -466,7 +466,13 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i | |||
| 466 | return -EINVAL; | 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 | t = arpt_get_target(e); | 472 | t = arpt_get_target(e); |
| 473 | if (e->target_offset + t->u.target_size > e->next_offset) | ||
| 474 | return -EINVAL; | ||
| 475 | |||
| 470 | target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, | 476 | target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, |
| 471 | t->u.user.revision), | 477 | t->u.user.revision), |
| 472 | "arpt_%s", t->u.user.name); | 478 | "arpt_%s", t->u.user.name); |
| @@ -621,20 +627,18 @@ static int translate_table(const char *name, | |||
| 621 | } | 627 | } |
| 622 | } | 628 | } |
| 623 | 629 | ||
| 624 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) { | ||
| 625 | duprintf("Looping hook\n"); | ||
| 626 | return -ELOOP; | ||
| 627 | } | ||
| 628 | |||
| 629 | /* Finally, each sanity check must pass */ | 630 | /* Finally, each sanity check must pass */ |
| 630 | i = 0; | 631 | i = 0; |
| 631 | ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, | 632 | ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, |
| 632 | check_entry, name, size, &i); | 633 | check_entry, name, size, &i); |
| 633 | 634 | ||
| 634 | if (ret != 0) { | 635 | if (ret != 0) |
| 635 | ARPT_ENTRY_ITERATE(entry0, newinfo->size, | 636 | goto cleanup; |
| 636 | cleanup_entry, &i); | 637 | |
| 637 | return ret; | 638 | ret = -ELOOP; |
| 639 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) { | ||
| 640 | duprintf("Looping hook\n"); | ||
| 641 | goto cleanup; | ||
| 638 | } | 642 | } |
| 639 | 643 | ||
| 640 | /* And one copy for every other CPU */ | 644 | /* And one copy for every other CPU */ |
| @@ -643,6 +647,9 @@ static int translate_table(const char *name, | |||
| 643 | memcpy(newinfo->entries[i], entry0, newinfo->size); | 647 | memcpy(newinfo->entries[i], entry0, newinfo->size); |
| 644 | } | 648 | } |
| 645 | 649 | ||
| 650 | return 0; | ||
| 651 | cleanup: | ||
| 652 | ARPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); | ||
| 646 | return ret; | 653 | return ret; |
| 647 | } | 654 | } |
| 648 | 655 | ||
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 7edad790478a..97556cc2e4e0 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
| @@ -351,9 +351,10 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) | |||
| 351 | if (v->data_len < sizeof(*user_iph)) | 351 | if (v->data_len < sizeof(*user_iph)) |
| 352 | return 0; | 352 | return 0; |
| 353 | diff = v->data_len - e->skb->len; | 353 | diff = v->data_len - e->skb->len; |
| 354 | if (diff < 0) | 354 | if (diff < 0) { |
| 355 | skb_trim(e->skb, v->data_len); | 355 | if (pskb_trim(e->skb, v->data_len)) |
| 356 | else if (diff > 0) { | 356 | return -ENOMEM; |
| 357 | } else if (diff > 0) { | ||
| 357 | if (v->data_len > 0xFFFF) | 358 | if (v->data_len > 0xFFFF) |
| 358 | return -EINVAL; | 359 | return -EINVAL; |
| 359 | if (diff > skb_tailroom(e->skb)) { | 360 | if (diff > skb_tailroom(e->skb)) { |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 4b90927619b8..8a455439b128 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
| @@ -547,12 +547,18 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size, | |||
| 547 | return -EINVAL; | 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 | j = 0; | 553 | j = 0; |
| 551 | ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j); | 554 | ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j); |
| 552 | if (ret != 0) | 555 | if (ret != 0) |
| 553 | goto cleanup_matches; | 556 | goto cleanup_matches; |
| 554 | 557 | ||
| 555 | t = ipt_get_target(e); | 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 | target = try_then_request_module(xt_find_target(AF_INET, | 562 | target = try_then_request_module(xt_find_target(AF_INET, |
| 557 | t->u.user.name, | 563 | t->u.user.name, |
| 558 | t->u.user.revision), | 564 | t->u.user.revision), |
| @@ -712,19 +718,17 @@ translate_table(const char *name, | |||
| 712 | } | 718 | } |
| 713 | } | 719 | } |
| 714 | 720 | ||
| 715 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) | ||
| 716 | return -ELOOP; | ||
| 717 | |||
| 718 | /* Finally, each sanity check must pass */ | 721 | /* Finally, each sanity check must pass */ |
| 719 | i = 0; | 722 | i = 0; |
| 720 | ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, | 723 | ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, |
| 721 | check_entry, name, size, &i); | 724 | check_entry, name, size, &i); |
| 722 | 725 | ||
| 723 | if (ret != 0) { | 726 | if (ret != 0) |
| 724 | IPT_ENTRY_ITERATE(entry0, newinfo->size, | 727 | goto cleanup; |
| 725 | cleanup_entry, &i); | 728 | |
| 726 | return ret; | 729 | ret = -ELOOP; |
| 727 | } | 730 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) |
| 731 | goto cleanup; | ||
| 728 | 732 | ||
| 729 | /* And one copy for every other CPU */ | 733 | /* And one copy for every other CPU */ |
| 730 | for_each_possible_cpu(i) { | 734 | for_each_possible_cpu(i) { |
| @@ -732,6 +736,9 @@ translate_table(const char *name, | |||
| 732 | memcpy(newinfo->entries[i], entry0, newinfo->size); | 736 | memcpy(newinfo->entries[i], entry0, newinfo->size); |
| 733 | } | 737 | } |
| 734 | 738 | ||
| 739 | return 0; | ||
| 740 | cleanup: | ||
| 741 | IPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); | ||
| 735 | return ret; | 742 | return ret; |
| 736 | } | 743 | } |
| 737 | 744 | ||
| @@ -1463,6 +1470,10 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, | |||
| 1463 | return -EINVAL; | 1470 | return -EINVAL; |
| 1464 | } | 1471 | } |
| 1465 | 1472 | ||
| 1473 | if (e->target_offset + sizeof(struct compat_xt_entry_target) > | ||
| 1474 | e->next_offset) | ||
| 1475 | return -EINVAL; | ||
| 1476 | |||
| 1466 | off = 0; | 1477 | off = 0; |
| 1467 | entry_offset = (void *)e - (void *)base; | 1478 | entry_offset = (void *)e - (void *)base; |
| 1468 | j = 0; | 1479 | j = 0; |
| @@ -1472,6 +1483,9 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, | |||
| 1472 | goto cleanup_matches; | 1483 | goto cleanup_matches; |
| 1473 | 1484 | ||
| 1474 | t = ipt_get_target(e); | 1485 | t = ipt_get_target(e); |
| 1486 | ret = -EINVAL; | ||
| 1487 | if (e->target_offset + t->u.target_size > e->next_offset) | ||
| 1488 | goto cleanup_matches; | ||
| 1475 | target = try_then_request_module(xt_find_target(AF_INET, | 1489 | target = try_then_request_module(xt_find_target(AF_INET, |
| 1476 | t->u.user.name, | 1490 | t->u.user.name, |
| 1477 | t->u.user.revision), | 1491 | t->u.user.revision), |
| @@ -1513,7 +1527,7 @@ cleanup_matches: | |||
| 1513 | 1527 | ||
| 1514 | static inline int compat_copy_match_from_user(struct ipt_entry_match *m, | 1528 | static inline int compat_copy_match_from_user(struct ipt_entry_match *m, |
| 1515 | void **dstptr, compat_uint_t *size, const char *name, | 1529 | void **dstptr, compat_uint_t *size, const char *name, |
| 1516 | const struct ipt_ip *ip, unsigned int hookmask, int *i) | 1530 | const struct ipt_ip *ip, unsigned int hookmask) |
| 1517 | { | 1531 | { |
| 1518 | struct ipt_entry_match *dm; | 1532 | struct ipt_entry_match *dm; |
| 1519 | struct ipt_match *match; | 1533 | struct ipt_match *match; |
| @@ -1526,22 +1540,13 @@ static inline int compat_copy_match_from_user(struct ipt_entry_match *m, | |||
| 1526 | ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm), | 1540 | ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm), |
| 1527 | name, hookmask, ip->proto, | 1541 | name, hookmask, ip->proto, |
| 1528 | ip->invflags & IPT_INV_PROTO); | 1542 | ip->invflags & IPT_INV_PROTO); |
| 1529 | if (ret) | 1543 | if (!ret && m->u.kernel.match->checkentry |
| 1530 | goto err; | ||
| 1531 | |||
| 1532 | if (m->u.kernel.match->checkentry | ||
| 1533 | && !m->u.kernel.match->checkentry(name, ip, match, dm->data, | 1544 | && !m->u.kernel.match->checkentry(name, ip, match, dm->data, |
| 1534 | hookmask)) { | 1545 | hookmask)) { |
| 1535 | duprintf("ip_tables: check failed for `%s'.\n", | 1546 | duprintf("ip_tables: check failed for `%s'.\n", |
| 1536 | m->u.kernel.match->name); | 1547 | m->u.kernel.match->name); |
| 1537 | ret = -EINVAL; | 1548 | ret = -EINVAL; |
| 1538 | goto err; | ||
| 1539 | } | 1549 | } |
| 1540 | (*i)++; | ||
| 1541 | return 0; | ||
| 1542 | |||
| 1543 | err: | ||
| 1544 | module_put(m->u.kernel.match->me); | ||
| 1545 | return ret; | 1550 | return ret; |
| 1546 | } | 1551 | } |
| 1547 | 1552 | ||
| @@ -1553,19 +1558,18 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, | |||
| 1553 | struct ipt_target *target; | 1558 | struct ipt_target *target; |
| 1554 | struct ipt_entry *de; | 1559 | struct ipt_entry *de; |
| 1555 | unsigned int origsize; | 1560 | unsigned int origsize; |
| 1556 | int ret, h, j; | 1561 | int ret, h; |
| 1557 | 1562 | ||
| 1558 | ret = 0; | 1563 | ret = 0; |
| 1559 | origsize = *size; | 1564 | origsize = *size; |
| 1560 | de = (struct ipt_entry *)*dstptr; | 1565 | de = (struct ipt_entry *)*dstptr; |
| 1561 | memcpy(de, e, sizeof(struct ipt_entry)); | 1566 | memcpy(de, e, sizeof(struct ipt_entry)); |
| 1562 | 1567 | ||
| 1563 | j = 0; | ||
| 1564 | *dstptr += sizeof(struct compat_ipt_entry); | 1568 | *dstptr += sizeof(struct compat_ipt_entry); |
| 1565 | ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size, | 1569 | ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size, |
| 1566 | name, &de->ip, de->comefrom, &j); | 1570 | name, &de->ip, de->comefrom); |
| 1567 | if (ret) | 1571 | if (ret) |
| 1568 | goto cleanup_matches; | 1572 | goto err; |
| 1569 | de->target_offset = e->target_offset - (origsize - *size); | 1573 | de->target_offset = e->target_offset - (origsize - *size); |
| 1570 | t = ipt_get_target(e); | 1574 | t = ipt_get_target(e); |
| 1571 | target = t->u.kernel.target; | 1575 | target = t->u.kernel.target; |
| @@ -1599,12 +1603,7 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, | |||
| 1599 | goto err; | 1603 | goto err; |
| 1600 | } | 1604 | } |
| 1601 | ret = 0; | 1605 | ret = 0; |
| 1602 | return ret; | ||
| 1603 | |||
| 1604 | err: | 1606 | err: |
| 1605 | module_put(t->u.kernel.target->me); | ||
| 1606 | cleanup_matches: | ||
| 1607 | IPT_MATCH_ITERATE(e, cleanup_match, &j); | ||
| 1608 | return ret; | 1607 | return ret; |
| 1609 | } | 1608 | } |
| 1610 | 1609 | ||
| @@ -1618,7 +1617,7 @@ translate_compat_table(const char *name, | |||
| 1618 | unsigned int *hook_entries, | 1617 | unsigned int *hook_entries, |
| 1619 | unsigned int *underflows) | 1618 | unsigned int *underflows) |
| 1620 | { | 1619 | { |
| 1621 | unsigned int i; | 1620 | unsigned int i, j; |
| 1622 | struct xt_table_info *newinfo, *info; | 1621 | struct xt_table_info *newinfo, *info; |
| 1623 | void *pos, *entry0, *entry1; | 1622 | void *pos, *entry0, *entry1; |
| 1624 | unsigned int size; | 1623 | unsigned int size; |
| @@ -1636,21 +1635,21 @@ translate_compat_table(const char *name, | |||
| 1636 | } | 1635 | } |
| 1637 | 1636 | ||
| 1638 | duprintf("translate_compat_table: size %u\n", info->size); | 1637 | duprintf("translate_compat_table: size %u\n", info->size); |
| 1639 | i = 0; | 1638 | j = 0; |
| 1640 | xt_compat_lock(AF_INET); | 1639 | xt_compat_lock(AF_INET); |
| 1641 | /* Walk through entries, checking offsets. */ | 1640 | /* Walk through entries, checking offsets. */ |
| 1642 | ret = IPT_ENTRY_ITERATE(entry0, total_size, | 1641 | ret = IPT_ENTRY_ITERATE(entry0, total_size, |
| 1643 | check_compat_entry_size_and_hooks, | 1642 | check_compat_entry_size_and_hooks, |
| 1644 | info, &size, entry0, | 1643 | info, &size, entry0, |
| 1645 | entry0 + total_size, | 1644 | entry0 + total_size, |
| 1646 | hook_entries, underflows, &i, name); | 1645 | hook_entries, underflows, &j, name); |
| 1647 | if (ret != 0) | 1646 | if (ret != 0) |
| 1648 | goto out_unlock; | 1647 | goto out_unlock; |
| 1649 | 1648 | ||
| 1650 | ret = -EINVAL; | 1649 | ret = -EINVAL; |
| 1651 | if (i != number) { | 1650 | if (j != number) { |
| 1652 | duprintf("translate_compat_table: %u not %u entries\n", | 1651 | duprintf("translate_compat_table: %u not %u entries\n", |
| 1653 | i, number); | 1652 | j, number); |
| 1654 | goto out_unlock; | 1653 | goto out_unlock; |
| 1655 | } | 1654 | } |
| 1656 | 1655 | ||
| @@ -1709,8 +1708,10 @@ translate_compat_table(const char *name, | |||
| 1709 | free_newinfo: | 1708 | free_newinfo: |
| 1710 | xt_free_table_info(newinfo); | 1709 | xt_free_table_info(newinfo); |
| 1711 | out: | 1710 | out: |
| 1711 | IPT_ENTRY_ITERATE(entry0, total_size, cleanup_entry, &j); | ||
| 1712 | return ret; | 1712 | return ret; |
| 1713 | out_unlock: | 1713 | out_unlock: |
| 1714 | compat_flush_offsets(); | ||
| 1714 | xt_compat_unlock(AF_INET); | 1715 | xt_compat_unlock(AF_INET); |
| 1715 | goto out; | 1716 | goto out; |
| 1716 | } | 1717 | } |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index b430cf2a4f66..5c31dead2bdc 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
| @@ -329,7 +329,7 @@ error: | |||
| 329 | return err; | 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 | struct iovec *iov; | 334 | struct iovec *iov; |
| 335 | u8 __user *type = NULL; | 335 | u8 __user *type = NULL; |
| @@ -338,7 +338,7 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
| 338 | unsigned int i; | 338 | unsigned int i; |
| 339 | 339 | ||
| 340 | if (!msg->msg_iov) | 340 | if (!msg->msg_iov) |
| 341 | return; | 341 | return 0; |
| 342 | 342 | ||
| 343 | for (i = 0; i < msg->msg_iovlen; i++) { | 343 | for (i = 0; i < msg->msg_iovlen; i++) { |
| 344 | iov = &msg->msg_iov[i]; | 344 | iov = &msg->msg_iov[i]; |
| @@ -360,8 +360,9 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
| 360 | code = iov->iov_base; | 360 | code = iov->iov_base; |
| 361 | 361 | ||
| 362 | if (type && code) { | 362 | if (type && code) { |
| 363 | get_user(fl->fl_icmp_type, type); | 363 | if (get_user(fl->fl_icmp_type, type) || |
| 364 | get_user(fl->fl_icmp_code, code); | 364 | get_user(fl->fl_icmp_code, code)) |
| 365 | return -EFAULT; | ||
| 365 | probed = 1; | 366 | probed = 1; |
| 366 | } | 367 | } |
| 367 | break; | 368 | break; |
| @@ -372,6 +373,7 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
| 372 | if (probed) | 373 | if (probed) |
| 373 | break; | 374 | break; |
| 374 | } | 375 | } |
| 376 | return 0; | ||
| 375 | } | 377 | } |
| 376 | 378 | ||
| 377 | static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | 379 | static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
| @@ -480,8 +482,11 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 480 | .proto = inet->hdrincl ? IPPROTO_RAW : | 482 | .proto = inet->hdrincl ? IPPROTO_RAW : |
| 481 | sk->sk_protocol, | 483 | sk->sk_protocol, |
| 482 | }; | 484 | }; |
| 483 | if (!inet->hdrincl) | 485 | if (!inet->hdrincl) { |
| 484 | raw_probe_proto_opt(&fl, msg); | 486 | err = raw_probe_proto_opt(&fl, msg); |
| 487 | if (err) | ||
| 488 | goto done; | ||
| 489 | } | ||
| 485 | 490 | ||
| 486 | security_sk_classify_flow(sk, &fl); | 491 | security_sk_classify_flow(sk, &fl); |
| 487 | err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); | 492 | err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT)); |
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index e82a5be894b5..15061b314411 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
| @@ -129,13 +129,6 @@ static int sysctl_tcp_congestion_control(ctl_table *table, int __user *name, | |||
| 129 | return ret; | 129 | return ret; |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | static int __init tcp_congestion_default(void) | ||
| 133 | { | ||
| 134 | return tcp_set_default_congestion_control(CONFIG_DEFAULT_TCP_CONG); | ||
| 135 | } | ||
| 136 | |||
| 137 | late_initcall(tcp_congestion_default); | ||
| 138 | |||
| 139 | ctl_table ipv4_table[] = { | 132 | ctl_table ipv4_table[] = { |
| 140 | { | 133 | { |
| 141 | .ctl_name = NET_IPV4_TCP_TIMESTAMPS, | 134 | .ctl_name = NET_IPV4_TCP_TIMESTAMPS, |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 66e9a729f6df..c05e8edaf544 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -2270,7 +2270,7 @@ void __init tcp_init(void) | |||
| 2270 | thash_entries, | 2270 | thash_entries, |
| 2271 | (num_physpages >= 128 * 1024) ? | 2271 | (num_physpages >= 128 * 1024) ? |
| 2272 | 13 : 15, | 2272 | 13 : 15, |
| 2273 | HASH_HIGHMEM, | 2273 | 0, |
| 2274 | &tcp_hashinfo.ehash_size, | 2274 | &tcp_hashinfo.ehash_size, |
| 2275 | NULL, | 2275 | NULL, |
| 2276 | 0); | 2276 | 0); |
| @@ -2286,7 +2286,7 @@ void __init tcp_init(void) | |||
| 2286 | tcp_hashinfo.ehash_size, | 2286 | tcp_hashinfo.ehash_size, |
| 2287 | (num_physpages >= 128 * 1024) ? | 2287 | (num_physpages >= 128 * 1024) ? |
| 2288 | 13 : 15, | 2288 | 13 : 15, |
| 2289 | HASH_HIGHMEM, | 2289 | 0, |
| 2290 | &tcp_hashinfo.bhash_size, | 2290 | &tcp_hashinfo.bhash_size, |
| 2291 | NULL, | 2291 | NULL, |
| 2292 | 64 * 1024); | 2292 | 64 * 1024); |
| @@ -2316,9 +2316,10 @@ void __init tcp_init(void) | |||
| 2316 | sysctl_max_syn_backlog = 128; | 2316 | sysctl_max_syn_backlog = 128; |
| 2317 | } | 2317 | } |
| 2318 | 2318 | ||
| 2319 | sysctl_tcp_mem[0] = 768 << order; | 2319 | /* Allow no more than 3/4 kernel memory (usually less) allocated to TCP */ |
| 2320 | sysctl_tcp_mem[1] = 1024 << order; | 2320 | sysctl_tcp_mem[0] = (1536 / sizeof (struct inet_bind_hashbucket)) << order; |
| 2321 | sysctl_tcp_mem[2] = 1536 << order; | 2321 | sysctl_tcp_mem[1] = sysctl_tcp_mem[0] * 4 / 3; |
| 2322 | sysctl_tcp_mem[2] = sysctl_tcp_mem[0] * 2; | ||
| 2322 | 2323 | ||
| 2323 | limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7); | 2324 | limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7); |
| 2324 | max_share = min(4UL*1024*1024, limit); | 2325 | max_share = min(4UL*1024*1024, limit); |
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index af0aca1e6be6..1e2982f4acd4 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
| @@ -131,6 +131,14 @@ int tcp_set_default_congestion_control(const char *name) | |||
| 131 | return ret; | 131 | return ret; |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | /* Set default value from kernel configuration at bootup */ | ||
| 135 | static int __init tcp_congestion_default(void) | ||
| 136 | { | ||
| 137 | return tcp_set_default_congestion_control(CONFIG_DEFAULT_TCP_CONG); | ||
| 138 | } | ||
| 139 | late_initcall(tcp_congestion_default); | ||
| 140 | |||
| 141 | |||
| 134 | /* Get current default congestion control */ | 142 | /* Get current default congestion control */ |
| 135 | void tcp_get_default_congestion_control(char *name) | 143 | void tcp_get_default_congestion_control(char *name) |
| 136 | { | 144 | { |
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c index a60ef38d75c6..6ad184802266 100644 --- a/net/ipv4/tcp_cubic.c +++ b/net/ipv4/tcp_cubic.c | |||
| @@ -190,7 +190,7 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd) | |||
| 190 | */ | 190 | */ |
| 191 | 191 | ||
| 192 | /* change the unit from HZ to bictcp_HZ */ | 192 | /* change the unit from HZ to bictcp_HZ */ |
| 193 | t = ((tcp_time_stamp + ca->delay_min - ca->epoch_start) | 193 | t = ((tcp_time_stamp + (ca->delay_min>>3) - ca->epoch_start) |
| 194 | << BICTCP_HZ) / HZ; | 194 | << BICTCP_HZ) / HZ; |
| 195 | 195 | ||
| 196 | if (t < ca->bic_K) /* t - K */ | 196 | if (t < ca->bic_K) /* t - K */ |
| @@ -259,7 +259,7 @@ static inline void measure_delay(struct sock *sk) | |||
| 259 | (s32)(tcp_time_stamp - ca->epoch_start) < HZ) | 259 | (s32)(tcp_time_stamp - ca->epoch_start) < HZ) |
| 260 | return; | 260 | return; |
| 261 | 261 | ||
| 262 | delay = tcp_time_stamp - tp->rx_opt.rcv_tsecr; | 262 | delay = (tcp_time_stamp - tp->rx_opt.rcv_tsecr)<<3; |
| 263 | if (delay == 0) | 263 | if (delay == 0) |
| 264 | delay = 1; | 264 | delay = 1; |
| 265 | 265 | ||
| @@ -366,7 +366,7 @@ static int __init cubictcp_register(void) | |||
| 366 | 366 | ||
| 367 | beta_scale = 8*(BICTCP_BETA_SCALE+beta)/ 3 / (BICTCP_BETA_SCALE - beta); | 367 | beta_scale = 8*(BICTCP_BETA_SCALE+beta)/ 3 / (BICTCP_BETA_SCALE - beta); |
| 368 | 368 | ||
| 369 | cube_rtt_scale = (bic_scale << 3) / 10; /* 1024*c/rtt */ | 369 | cube_rtt_scale = (bic_scale * 10); /* 1024*c/rtt */ |
| 370 | 370 | ||
| 371 | /* calculate the "K" for (wmax-cwnd) = c/rtt * K^3 | 371 | /* calculate the "K" for (wmax-cwnd) = c/rtt * K^3 |
| 372 | * so K = cubic_root( (wmax-cwnd)*rtt/c ) | 372 | * so K = cubic_root( (wmax-cwnd)*rtt/c ) |
diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c index 682e7d5b6f2f..283be3cb4667 100644 --- a/net/ipv4/tcp_htcp.c +++ b/net/ipv4/tcp_htcp.c | |||
| @@ -23,7 +23,7 @@ module_param(use_bandwidth_switch, int, 0644); | |||
| 23 | MODULE_PARM_DESC(use_bandwidth_switch, "turn on/off bandwidth switcher"); | 23 | MODULE_PARM_DESC(use_bandwidth_switch, "turn on/off bandwidth switcher"); |
| 24 | 24 | ||
| 25 | struct htcp { | 25 | struct htcp { |
| 26 | u16 alpha; /* Fixed point arith, << 7 */ | 26 | u32 alpha; /* Fixed point arith, << 7 */ |
| 27 | u8 beta; /* Fixed point arith, << 7 */ | 27 | u8 beta; /* Fixed point arith, << 7 */ |
| 28 | u8 modeswitch; /* Delay modeswitch until we had at least one congestion event */ | 28 | u8 modeswitch; /* Delay modeswitch until we had at least one congestion event */ |
| 29 | u32 last_cong; /* Time since last congestion event end */ | 29 | u32 last_cong; /* Time since last congestion event end */ |
