diff options
author | <jgarzik@pretzel.yyz.us> | 2005-05-26 01:47:10 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-05-26 01:47:10 -0400 |
commit | 949d33e70f2c3e93bfe5265a50e40175b1ab1ec1 (patch) | |
tree | ca88fd8f8f81b167dc4685ed34e9636f267db60d /net | |
parent | b095518ef51c37658c58367bd19240b8a113f25c (diff) | |
parent | bef9c558841604116704e10b3d9ff3dbf4939423 (diff) |
Automatic merge of rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git branch HEAD
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/ip_output.c | 8 | ||||
-rw-r--r-- | net/ipv4/ipvs/ip_vs_xmit.c | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_core.c | 28 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 11 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 14 | ||||
-rw-r--r-- | net/ipv6/xfrm6_output.c | 1 | ||||
-rw-r--r-- | net/netlink/af_netlink.c | 13 | ||||
-rw-r--r-- | net/unix/af_unix.c | 28 | ||||
-rw-r--r-- | net/xfrm/xfrm_algo.c | 2 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 15 |
10 files changed, 51 insertions, 70 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index daebd93fd8a0..760dc8238d65 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -490,6 +490,14 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) | |||
490 | /* Partially cloned skb? */ | 490 | /* Partially cloned skb? */ |
491 | if (skb_shared(frag)) | 491 | if (skb_shared(frag)) |
492 | goto slow_path; | 492 | goto slow_path; |
493 | |||
494 | BUG_ON(frag->sk); | ||
495 | if (skb->sk) { | ||
496 | sock_hold(skb->sk); | ||
497 | frag->sk = skb->sk; | ||
498 | frag->destructor = sock_wfree; | ||
499 | skb->truesize -= frag->truesize; | ||
500 | } | ||
493 | } | 501 | } |
494 | 502 | ||
495 | /* Everything is OK. Generate! */ | 503 | /* Everything is OK. Generate! */ |
diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c index faa6176bbeb1..de21da00057f 100644 --- a/net/ipv4/ipvs/ip_vs_xmit.c +++ b/net/ipv4/ipvs/ip_vs_xmit.c | |||
@@ -508,7 +508,6 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
508 | rc = NF_ACCEPT; | 508 | rc = NF_ACCEPT; |
509 | /* do not touch skb anymore */ | 509 | /* do not touch skb anymore */ |
510 | atomic_inc(&cp->in_pkts); | 510 | atomic_inc(&cp->in_pkts); |
511 | __ip_vs_conn_put(cp); | ||
512 | goto out; | 511 | goto out; |
513 | } | 512 | } |
514 | 513 | ||
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 28d9425d5c39..09e824622977 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c | |||
@@ -940,37 +940,25 @@ void ip_ct_refresh_acct(struct ip_conntrack *ct, | |||
940 | struct sk_buff * | 940 | struct sk_buff * |
941 | ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user) | 941 | ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user) |
942 | { | 942 | { |
943 | struct sock *sk = skb->sk; | ||
944 | #ifdef CONFIG_NETFILTER_DEBUG | 943 | #ifdef CONFIG_NETFILTER_DEBUG |
945 | unsigned int olddebug = skb->nf_debug; | 944 | unsigned int olddebug = skb->nf_debug; |
946 | #endif | 945 | #endif |
947 | 946 | ||
948 | if (sk) { | 947 | skb_orphan(skb); |
949 | sock_hold(sk); | ||
950 | skb_orphan(skb); | ||
951 | } | ||
952 | 948 | ||
953 | local_bh_disable(); | 949 | local_bh_disable(); |
954 | skb = ip_defrag(skb, user); | 950 | skb = ip_defrag(skb, user); |
955 | local_bh_enable(); | 951 | local_bh_enable(); |
956 | 952 | ||
957 | if (!skb) { | 953 | if (skb) { |
958 | if (sk) | 954 | ip_send_check(skb->nh.iph); |
959 | sock_put(sk); | 955 | skb->nfcache |= NFC_ALTERED; |
960 | return skb; | ||
961 | } | ||
962 | |||
963 | if (sk) { | ||
964 | skb_set_owner_w(skb, sk); | ||
965 | sock_put(sk); | ||
966 | } | ||
967 | |||
968 | ip_send_check(skb->nh.iph); | ||
969 | skb->nfcache |= NFC_ALTERED; | ||
970 | #ifdef CONFIG_NETFILTER_DEBUG | 956 | #ifdef CONFIG_NETFILTER_DEBUG |
971 | /* Packet path as if nothing had happened. */ | 957 | /* Packet path as if nothing had happened. */ |
972 | skb->nf_debug = olddebug; | 958 | skb->nf_debug = olddebug; |
973 | #endif | 959 | #endif |
960 | } | ||
961 | |||
974 | return skb; | 962 | return skb; |
975 | } | 963 | } |
976 | 964 | ||
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 79835a67a274..5bad504630a3 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -4355,16 +4355,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
4355 | goto no_ack; | 4355 | goto no_ack; |
4356 | } | 4356 | } |
4357 | 4357 | ||
4358 | if (eaten) { | 4358 | __tcp_ack_snd_check(sk, 0); |
4359 | if (tcp_in_quickack_mode(tp)) { | ||
4360 | tcp_send_ack(sk); | ||
4361 | } else { | ||
4362 | tcp_send_delayed_ack(sk); | ||
4363 | } | ||
4364 | } else { | ||
4365 | __tcp_ack_snd_check(sk, 0); | ||
4366 | } | ||
4367 | |||
4368 | no_ack: | 4359 | no_ack: |
4369 | if (eaten) | 4360 | if (eaten) |
4370 | __kfree_skb(skb); | 4361 | __kfree_skb(skb); |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 0f0711417c9d..b78a53586804 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -552,13 +552,17 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
552 | skb_headroom(frag) < hlen) | 552 | skb_headroom(frag) < hlen) |
553 | goto slow_path; | 553 | goto slow_path; |
554 | 554 | ||
555 | /* Correct socket ownership. */ | ||
556 | if (frag->sk == NULL) | ||
557 | goto slow_path; | ||
558 | |||
559 | /* Partially cloned skb? */ | 555 | /* Partially cloned skb? */ |
560 | if (skb_shared(frag)) | 556 | if (skb_shared(frag)) |
561 | goto slow_path; | 557 | goto slow_path; |
558 | |||
559 | BUG_ON(frag->sk); | ||
560 | if (skb->sk) { | ||
561 | sock_hold(skb->sk); | ||
562 | frag->sk = skb->sk; | ||
563 | frag->destructor = sock_wfree; | ||
564 | skb->truesize -= frag->truesize; | ||
565 | } | ||
562 | } | 566 | } |
563 | 567 | ||
564 | err = 0; | 568 | err = 0; |
@@ -1116,12 +1120,10 @@ int ip6_push_pending_frames(struct sock *sk) | |||
1116 | tail_skb = &(tmp_skb->next); | 1120 | tail_skb = &(tmp_skb->next); |
1117 | skb->len += tmp_skb->len; | 1121 | skb->len += tmp_skb->len; |
1118 | skb->data_len += tmp_skb->len; | 1122 | skb->data_len += tmp_skb->len; |
1119 | #if 0 /* Logically correct, but useless work, ip_fragment() will have to undo */ | ||
1120 | skb->truesize += tmp_skb->truesize; | 1123 | skb->truesize += tmp_skb->truesize; |
1121 | __sock_put(tmp_skb->sk); | 1124 | __sock_put(tmp_skb->sk); |
1122 | tmp_skb->destructor = NULL; | 1125 | tmp_skb->destructor = NULL; |
1123 | tmp_skb->sk = NULL; | 1126 | tmp_skb->sk = NULL; |
1124 | #endif | ||
1125 | } | 1127 | } |
1126 | 1128 | ||
1127 | ipv6_addr_copy(final_dst, &fl->fl6_dst); | 1129 | ipv6_addr_copy(final_dst, &fl->fl6_dst); |
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index 601a148f60f3..6b9867717d11 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c | |||
@@ -84,6 +84,7 @@ static int xfrm6_tunnel_check_size(struct sk_buff *skb) | |||
84 | mtu = IPV6_MIN_MTU; | 84 | mtu = IPV6_MIN_MTU; |
85 | 85 | ||
86 | if (skb->len > mtu) { | 86 | if (skb->len > mtu) { |
87 | skb->dev = dst->dev; | ||
87 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); | 88 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); |
88 | ret = -EMSGSIZE; | 89 | ret = -EMSGSIZE; |
89 | } | 90 | } |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 733bf52cef3e..e41ce458c2a9 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -735,11 +735,15 @@ static inline int do_one_broadcast(struct sock *sk, | |||
735 | 735 | ||
736 | sock_hold(sk); | 736 | sock_hold(sk); |
737 | if (p->skb2 == NULL) { | 737 | if (p->skb2 == NULL) { |
738 | if (atomic_read(&p->skb->users) != 1) { | 738 | if (skb_shared(p->skb)) { |
739 | p->skb2 = skb_clone(p->skb, p->allocation); | 739 | p->skb2 = skb_clone(p->skb, p->allocation); |
740 | } else { | 740 | } else { |
741 | p->skb2 = p->skb; | 741 | p->skb2 = skb_get(p->skb); |
742 | atomic_inc(&p->skb->users); | 742 | /* |
743 | * skb ownership may have been set when | ||
744 | * delivered to a previous socket. | ||
745 | */ | ||
746 | skb_orphan(p->skb2); | ||
743 | } | 747 | } |
744 | } | 748 | } |
745 | if (p->skb2 == NULL) { | 749 | if (p->skb2 == NULL) { |
@@ -785,11 +789,12 @@ int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, | |||
785 | sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list) | 789 | sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list) |
786 | do_one_broadcast(sk, &info); | 790 | do_one_broadcast(sk, &info); |
787 | 791 | ||
792 | kfree_skb(skb); | ||
793 | |||
788 | netlink_unlock_table(); | 794 | netlink_unlock_table(); |
789 | 795 | ||
790 | if (info.skb2) | 796 | if (info.skb2) |
791 | kfree_skb(info.skb2); | 797 | kfree_skb(info.skb2); |
792 | kfree_skb(skb); | ||
793 | 798 | ||
794 | if (info.delivered) { | 799 | if (info.delivered) { |
795 | if (info.congested && (allocation & __GFP_WAIT)) | 800 | if (info.congested && (allocation & __GFP_WAIT)) |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index c478fc8db776..c420eba4876b 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -770,33 +770,12 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
770 | err = path_lookup(sunaddr->sun_path, LOOKUP_PARENT, &nd); | 770 | err = path_lookup(sunaddr->sun_path, LOOKUP_PARENT, &nd); |
771 | if (err) | 771 | if (err) |
772 | goto out_mknod_parent; | 772 | goto out_mknod_parent; |
773 | /* | 773 | |
774 | * Yucky last component or no last component at all? | 774 | dentry = lookup_create(&nd, 0); |
775 | * (foo/., foo/.., /////) | ||
776 | */ | ||
777 | err = -EEXIST; | ||
778 | if (nd.last_type != LAST_NORM) | ||
779 | goto out_mknod; | ||
780 | /* | ||
781 | * Lock the directory. | ||
782 | */ | ||
783 | down(&nd.dentry->d_inode->i_sem); | ||
784 | /* | ||
785 | * Do the final lookup. | ||
786 | */ | ||
787 | dentry = lookup_hash(&nd.last, nd.dentry); | ||
788 | err = PTR_ERR(dentry); | 775 | err = PTR_ERR(dentry); |
789 | if (IS_ERR(dentry)) | 776 | if (IS_ERR(dentry)) |
790 | goto out_mknod_unlock; | 777 | goto out_mknod_unlock; |
791 | err = -ENOENT; | 778 | |
792 | /* | ||
793 | * Special case - lookup gave negative, but... we had foo/bar/ | ||
794 | * From the vfs_mknod() POV we just have a negative dentry - | ||
795 | * all is fine. Let's be bastards - you had / on the end, you've | ||
796 | * been asking for (non-existent) directory. -ENOENT for you. | ||
797 | */ | ||
798 | if (nd.last.name[nd.last.len] && !dentry->d_inode) | ||
799 | goto out_mknod_dput; | ||
800 | /* | 779 | /* |
801 | * All right, let's create it. | 780 | * All right, let's create it. |
802 | */ | 781 | */ |
@@ -845,7 +824,6 @@ out_mknod_dput: | |||
845 | dput(dentry); | 824 | dput(dentry); |
846 | out_mknod_unlock: | 825 | out_mknod_unlock: |
847 | up(&nd.dentry->d_inode->i_sem); | 826 | up(&nd.dentry->d_inode->i_sem); |
848 | out_mknod: | ||
849 | path_release(&nd); | 827 | path_release(&nd); |
850 | out_mknod_parent: | 828 | out_mknod_parent: |
851 | if (err==-EEXIST) | 829 | if (err==-EEXIST) |
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index 080aae243ce0..2f4531fcaca2 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c | |||
@@ -698,7 +698,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) | |||
698 | return -ENOMEM; | 698 | return -ENOMEM; |
699 | 699 | ||
700 | if (skb1->sk) | 700 | if (skb1->sk) |
701 | skb_set_owner_w(skb, skb1->sk); | 701 | skb_set_owner_w(skb2, skb1->sk); |
702 | 702 | ||
703 | /* Looking around. Are we still alive? | 703 | /* Looking around. Are we still alive? |
704 | * OK, link new skb, drop old one */ | 704 | * OK, link new skb, drop old one */ |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 5ddda2c98af9..97509011c274 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -34,14 +34,21 @@ static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type) | |||
34 | { | 34 | { |
35 | struct rtattr *rt = xfrma[type - 1]; | 35 | struct rtattr *rt = xfrma[type - 1]; |
36 | struct xfrm_algo *algp; | 36 | struct xfrm_algo *algp; |
37 | int len; | ||
37 | 38 | ||
38 | if (!rt) | 39 | if (!rt) |
39 | return 0; | 40 | return 0; |
40 | 41 | ||
41 | if ((rt->rta_len - sizeof(*rt)) < sizeof(*algp)) | 42 | len = (rt->rta_len - sizeof(*rt)) - sizeof(*algp); |
43 | if (len < 0) | ||
42 | return -EINVAL; | 44 | return -EINVAL; |
43 | 45 | ||
44 | algp = RTA_DATA(rt); | 46 | algp = RTA_DATA(rt); |
47 | |||
48 | len -= (algp->alg_key_len + 7U) / 8; | ||
49 | if (len < 0) | ||
50 | return -EINVAL; | ||
51 | |||
45 | switch (type) { | 52 | switch (type) { |
46 | case XFRMA_ALG_AUTH: | 53 | case XFRMA_ALG_AUTH: |
47 | if (!algp->alg_key_len && | 54 | if (!algp->alg_key_len && |
@@ -162,6 +169,7 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props, | |||
162 | struct rtattr *rta = u_arg; | 169 | struct rtattr *rta = u_arg; |
163 | struct xfrm_algo *p, *ualg; | 170 | struct xfrm_algo *p, *ualg; |
164 | struct xfrm_algo_desc *algo; | 171 | struct xfrm_algo_desc *algo; |
172 | int len; | ||
165 | 173 | ||
166 | if (!rta) | 174 | if (!rta) |
167 | return 0; | 175 | return 0; |
@@ -173,11 +181,12 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props, | |||
173 | return -ENOSYS; | 181 | return -ENOSYS; |
174 | *props = algo->desc.sadb_alg_id; | 182 | *props = algo->desc.sadb_alg_id; |
175 | 183 | ||
176 | p = kmalloc(sizeof(*ualg) + ualg->alg_key_len, GFP_KERNEL); | 184 | len = sizeof(*ualg) + (ualg->alg_key_len + 7U) / 8; |
185 | p = kmalloc(len, GFP_KERNEL); | ||
177 | if (!p) | 186 | if (!p) |
178 | return -ENOMEM; | 187 | return -ENOMEM; |
179 | 188 | ||
180 | memcpy(p, ualg, sizeof(*ualg) + ualg->alg_key_len); | 189 | memcpy(p, ualg, len); |
181 | *algpp = p; | 190 | *algpp = p; |
182 | return 0; | 191 | return 0; |
183 | } | 192 | } |