aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/802/psnap.c2
-rw-r--r--net/Kconfig7
-rw-r--r--net/bridge/netfilter/ebt_ulog.c10
-rw-r--r--net/bridge/netfilter/ebtables.c7
-rw-r--r--net/core/dev.c2
-rw-r--r--net/core/utils.c4
-rw-r--r--net/ipv4/icmp.c5
-rw-r--r--net/ipv4/multipath_wrandom.c8
-rw-r--r--net/ipv4/netfilter/arp_tables.c7
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c3
-rw-r--r--net/ipv4/netfilter/ip_conntrack_tftp.c1
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c4
-rw-r--r--net/ipv4/netfilter/ip_tables.c7
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c26
-rw-r--r--net/ipv4/netfilter/ipt_policy.c11
-rw-r--r--net/ipv4/proc.c2
-rw-r--r--net/ipv6/addrconf.c6
-rw-r--r--net/ipv6/af_inet6.c6
-rw-r--r--net/ipv6/netfilter/ip6_tables.c7
-rw-r--r--net/ipv6/netfilter/ip6t_policy.c7
-rw-r--r--net/ipv6/proc.c2
-rw-r--r--net/netfilter/nf_conntrack_core.c2
-rw-r--r--net/netfilter/nf_conntrack_ftp.c2
-rw-r--r--net/netfilter/nf_conntrack_netlink.c3
-rw-r--r--net/netfilter/nfnetlink_log.c20
-rw-r--r--net/netfilter/nfnetlink_queue.c3
-rw-r--r--net/sctp/output.c2
-rw-r--r--net/sctp/outqueue.c12
-rw-r--r--net/socket.c2
-rw-r--r--net/sunrpc/auth.c25
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c40
-rw-r--r--net/sunrpc/auth_unix.c6
-rw-r--r--net/sunrpc/rpc_pipe.c102
33 files changed, 225 insertions, 128 deletions
diff --git a/net/802/psnap.c b/net/802/psnap.c
index 4d638944d933..34e42968b477 100644
--- a/net/802/psnap.c
+++ b/net/802/psnap.c
@@ -59,8 +59,10 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev,
59 proto = find_snap_client(skb->h.raw); 59 proto = find_snap_client(skb->h.raw);
60 if (proto) { 60 if (proto) {
61 /* Pass the frame on. */ 61 /* Pass the frame on. */
62 u8 *hdr = skb->data;
62 skb->h.raw += 5; 63 skb->h.raw += 5;
63 skb_pull(skb, 5); 64 skb_pull(skb, 5);
65 skb_postpull_rcsum(skb, hdr, 5);
64 rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev); 66 rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev);
65 } else { 67 } else {
66 skb->sk = NULL; 68 skb->sk = NULL;
diff --git a/net/Kconfig b/net/Kconfig
index bc603d9aea56..5126f58d9c44 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -27,6 +27,13 @@ if NET
27 27
28menu "Networking options" 28menu "Networking options"
29 29
30config NETDEBUG
31 bool "Network packet debugging"
32 help
33 You can say Y here if you want to get additional messages useful in
34 debugging bad packets, but can overwhelm logs under denial of service
35 attacks.
36
30source "net/packet/Kconfig" 37source "net/packet/Kconfig"
31source "net/unix/Kconfig" 38source "net/unix/Kconfig"
32source "net/xfrm/Kconfig" 39source "net/xfrm/Kconfig"
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index ce617b3dbbb8..802baf755ef4 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -46,7 +46,7 @@
46#define PRINTR(format, args...) do { if (net_ratelimit()) \ 46#define PRINTR(format, args...) do { if (net_ratelimit()) \
47 printk(format , ## args); } while (0) 47 printk(format , ## args); } while (0)
48 48
49static unsigned int nlbufsiz = 4096; 49static unsigned int nlbufsiz = NLMSG_GOODSIZE;
50module_param(nlbufsiz, uint, 0600); 50module_param(nlbufsiz, uint, 0600);
51MODULE_PARM_DESC(nlbufsiz, "netlink buffer size (number of bytes) " 51MODULE_PARM_DESC(nlbufsiz, "netlink buffer size (number of bytes) "
52 "(defaults to 4096)"); 52 "(defaults to 4096)");
@@ -98,12 +98,14 @@ static void ulog_timer(unsigned long data)
98static struct sk_buff *ulog_alloc_skb(unsigned int size) 98static struct sk_buff *ulog_alloc_skb(unsigned int size)
99{ 99{
100 struct sk_buff *skb; 100 struct sk_buff *skb;
101 unsigned int n;
101 102
102 skb = alloc_skb(nlbufsiz, GFP_ATOMIC); 103 n = max(size, nlbufsiz);
104 skb = alloc_skb(n, GFP_ATOMIC);
103 if (!skb) { 105 if (!skb) {
104 PRINTR(KERN_ERR "ebt_ulog: can't alloc whole buffer " 106 PRINTR(KERN_ERR "ebt_ulog: can't alloc whole buffer "
105 "of size %ub!\n", nlbufsiz); 107 "of size %ub!\n", n);
106 if (size < nlbufsiz) { 108 if (n > size) {
107 /* try to allocate only as much as we need for 109 /* try to allocate only as much as we need for
108 * current packet */ 110 * current packet */
109 skb = alloc_skb(size, GFP_ATOMIC); 111 skb = alloc_skb(size, GFP_ATOMIC);
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 00729b3604f8..cbd4020cc84d 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -934,6 +934,13 @@ static int do_replace(void __user *user, unsigned int len)
934 BUGPRINT("Entries_size never zero\n"); 934 BUGPRINT("Entries_size never zero\n");
935 return -EINVAL; 935 return -EINVAL;
936 } 936 }
937 /* overflow check */
938 if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) / NR_CPUS -
939 SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
940 return -ENOMEM;
941 if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
942 return -ENOMEM;
943
937 countersize = COUNTER_OFFSET(tmp.nentries) * 944 countersize = COUNTER_OFFSET(tmp.nentries) *
938 (highest_possible_processor_id()+1); 945 (highest_possible_processor_id()+1);
939 newinfo = (struct ebt_table_info *) 946 newinfo = (struct ebt_table_info *)
diff --git a/net/core/dev.c b/net/core/dev.c
index ffb82073056e..2afb0de95329 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3237,7 +3237,7 @@ static int __init net_dev_init(void)
3237 * Initialise the packet receive queues. 3237 * Initialise the packet receive queues.
3238 */ 3238 */
3239 3239
3240 for (i = 0; i < NR_CPUS; i++) { 3240 for_each_cpu(i) {
3241 struct softnet_data *queue; 3241 struct softnet_data *queue;
3242 3242
3243 queue = &per_cpu(softnet_data, i); 3243 queue = &per_cpu(softnet_data, i);
diff --git a/net/core/utils.c b/net/core/utils.c
index ac1d1fcf8673..fdc4f38bc46c 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -121,7 +121,7 @@ void __init net_random_init(void)
121{ 121{
122 int i; 122 int i;
123 123
124 for (i = 0; i < NR_CPUS; i++) { 124 for_each_cpu(i) {
125 struct nrnd_state *state = &per_cpu(net_rand_state,i); 125 struct nrnd_state *state = &per_cpu(net_rand_state,i);
126 __net_srandom(state, i+jiffies); 126 __net_srandom(state, i+jiffies);
127 } 127 }
@@ -133,7 +133,7 @@ static int net_random_reseed(void)
133 unsigned long seed[NR_CPUS]; 133 unsigned long seed[NR_CPUS];
134 134
135 get_random_bytes(seed, sizeof(seed)); 135 get_random_bytes(seed, sizeof(seed));
136 for (i = 0; i < NR_CPUS; i++) { 136 for_each_cpu(i) {
137 struct nrnd_state *state = &per_cpu(net_rand_state,i); 137 struct nrnd_state *state = &per_cpu(net_rand_state,i);
138 __net_srandom(state, seed[i]); 138 __net_srandom(state, seed[i]);
139 } 139 }
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 105039eb7629..4d1c40972a4b 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -385,7 +385,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
385 u32 daddr; 385 u32 daddr;
386 386
387 if (ip_options_echo(&icmp_param->replyopts, skb)) 387 if (ip_options_echo(&icmp_param->replyopts, skb))
388 goto out; 388 return;
389 389
390 if (icmp_xmit_lock()) 390 if (icmp_xmit_lock())
391 return; 391 return;
@@ -416,7 +416,6 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
416 ip_rt_put(rt); 416 ip_rt_put(rt);
417out_unlock: 417out_unlock:
418 icmp_xmit_unlock(); 418 icmp_xmit_unlock();
419out:;
420} 419}
421 420
422 421
@@ -525,7 +524,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info)
525 iph->tos; 524 iph->tos;
526 525
527 if (ip_options_echo(&icmp_param.replyopts, skb_in)) 526 if (ip_options_echo(&icmp_param.replyopts, skb_in))
528 goto ende; 527 goto out_unlock;
529 528
530 529
531 /* 530 /*
diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c
index d34a9fa608e0..342d0b9098f5 100644
--- a/net/ipv4/multipath_wrandom.c
+++ b/net/ipv4/multipath_wrandom.c
@@ -228,7 +228,7 @@ static void wrandom_set_nhinfo(__u32 network,
228 struct multipath_dest *d, *target_dest = NULL; 228 struct multipath_dest *d, *target_dest = NULL;
229 229
230 /* store the weight information for a certain route */ 230 /* store the weight information for a certain route */
231 spin_lock(&state[state_idx].lock); 231 spin_lock_bh(&state[state_idx].lock);
232 232
233 /* find state entry for gateway or add one if necessary */ 233 /* find state entry for gateway or add one if necessary */
234 list_for_each_entry_rcu(r, &state[state_idx].head, list) { 234 list_for_each_entry_rcu(r, &state[state_idx].head, list) {
@@ -276,7 +276,7 @@ static void wrandom_set_nhinfo(__u32 network,
276 * we are finished 276 * we are finished
277 */ 277 */
278 278
279 spin_unlock(&state[state_idx].lock); 279 spin_unlock_bh(&state[state_idx].lock);
280} 280}
281 281
282static void __multipath_free(struct rcu_head *head) 282static void __multipath_free(struct rcu_head *head)
@@ -302,7 +302,7 @@ static void wrandom_flush(void)
302 for (i = 0; i < MULTIPATH_STATE_SIZE; ++i) { 302 for (i = 0; i < MULTIPATH_STATE_SIZE; ++i) {
303 struct multipath_route *r; 303 struct multipath_route *r;
304 304
305 spin_lock(&state[i].lock); 305 spin_lock_bh(&state[i].lock);
306 list_for_each_entry_rcu(r, &state[i].head, list) { 306 list_for_each_entry_rcu(r, &state[i].head, list) {
307 struct multipath_dest *d; 307 struct multipath_dest *d;
308 list_for_each_entry_rcu(d, &r->dests, list) { 308 list_for_each_entry_rcu(d, &r->dests, list) {
@@ -315,7 +315,7 @@ static void wrandom_flush(void)
315 __multipath_free); 315 __multipath_free);
316 } 316 }
317 317
318 spin_unlock(&state[i].lock); 318 spin_unlock_bh(&state[i].lock);
319 } 319 }
320} 320}
321 321
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index afe3d8f8177d..dd1048be8a01 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -807,6 +807,13 @@ static int do_replace(void __user *user, unsigned int len)
807 if (len != sizeof(tmp) + tmp.size) 807 if (len != sizeof(tmp) + tmp.size)
808 return -ENOPROTOOPT; 808 return -ENOPROTOOPT;
809 809
810 /* overflow check */
811 if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
812 SMP_CACHE_BYTES)
813 return -ENOMEM;
814 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
815 return -ENOMEM;
816
810 newinfo = xt_alloc_table_info(tmp.size); 817 newinfo = xt_alloc_table_info(tmp.size);
811 if (!newinfo) 818 if (!newinfo)
812 return -ENOMEM; 819 return -ENOMEM;
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index c9ebbe0d2d9c..e0b5926c76f9 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -1216,7 +1216,7 @@ static int ctnetlink_expect_event(struct notifier_block *this,
1216 1216
1217 b = skb->tail; 1217 b = skb->tail;
1218 1218
1219 type |= NFNL_SUBSYS_CTNETLINK << 8; 1219 type |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
1220 nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg)); 1220 nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
1221 nfmsg = NLMSG_DATA(nlh); 1221 nfmsg = NLMSG_DATA(nlh);
1222 1222
@@ -1567,6 +1567,7 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = {
1567}; 1567};
1568 1568
1569MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK); 1569MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
1570MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP);
1570 1571
1571static int __init ctnetlink_init(void) 1572static int __init ctnetlink_init(void)
1572{ 1573{
diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c
index d3c5a371f993..4ba4463cec28 100644
--- a/net/ipv4/netfilter/ip_conntrack_tftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_tftp.c
@@ -71,6 +71,7 @@ static int tftp_help(struct sk_buff **pskb,
71 71
72 exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; 72 exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
73 exp->mask.src.ip = 0xffffffff; 73 exp->mask.src.ip = 0xffffffff;
74 exp->mask.src.u.udp.port = 0;
74 exp->mask.dst.ip = 0xffffffff; 75 exp->mask.dst.ip = 0xffffffff;
75 exp->mask.dst.u.udp.port = 0xffff; 76 exp->mask.dst.u.udp.port = 0xffff;
76 exp->mask.dst.protonum = 0xff; 77 exp->mask.dst.protonum = 0xff;
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index ad438fb185b8..92c54999a19d 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -209,8 +209,8 @@ ip_nat_in(unsigned int hooknum,
209 && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) { 209 && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
210 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 210 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
211 211
212 if (ct->tuplehash[dir].tuple.src.ip != 212 if (ct->tuplehash[dir].tuple.dst.ip !=
213 ct->tuplehash[!dir].tuple.dst.ip) { 213 ct->tuplehash[!dir].tuple.src.ip) {
214 dst_release((*pskb)->dst); 214 dst_release((*pskb)->dst);
215 (*pskb)->dst = NULL; 215 (*pskb)->dst = NULL;
216 } 216 }
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 2371b2062c2d..16f47c675fef 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -921,6 +921,13 @@ do_replace(void __user *user, unsigned int len)
921 if (len != sizeof(tmp) + tmp.size) 921 if (len != sizeof(tmp) + tmp.size)
922 return -ENOPROTOOPT; 922 return -ENOPROTOOPT;
923 923
924 /* overflow check */
925 if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
926 SMP_CACHE_BYTES)
927 return -ENOMEM;
928 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
929 return -ENOMEM;
930
924 newinfo = xt_alloc_table_info(tmp.size); 931 newinfo = xt_alloc_table_info(tmp.size);
925 if (!newinfo) 932 if (!newinfo)
926 return -ENOMEM; 933 return -ENOMEM;
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index 641dbc477650..180a9ea57b69 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -35,6 +35,10 @@
35 * each nlgroup you are using, so the total kernel memory usage increases 35 * each nlgroup you are using, so the total kernel memory usage increases
36 * by that factor. 36 * by that factor.
37 * 37 *
38 * Actually you should use nlbufsiz a bit smaller than PAGE_SIZE, since
39 * nlbufsiz is used with alloc_skb, which adds another
40 * sizeof(struct skb_shared_info). Use NLMSG_GOODSIZE instead.
41 *
38 * flushtimeout: 42 * flushtimeout:
39 * Specify, after how many hundredths of a second the queue should be 43 * Specify, after how many hundredths of a second the queue should be
40 * flushed even if it is not full yet. 44 * flushed even if it is not full yet.
@@ -76,7 +80,7 @@ MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NFLOG);
76 80
77#define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0) 81#define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0)
78 82
79static unsigned int nlbufsiz = 4096; 83static unsigned int nlbufsiz = NLMSG_GOODSIZE;
80module_param(nlbufsiz, uint, 0400); 84module_param(nlbufsiz, uint, 0400);
81MODULE_PARM_DESC(nlbufsiz, "netlink buffer size"); 85MODULE_PARM_DESC(nlbufsiz, "netlink buffer size");
82 86
@@ -143,22 +147,26 @@ static void ulog_timer(unsigned long data)
143static struct sk_buff *ulog_alloc_skb(unsigned int size) 147static struct sk_buff *ulog_alloc_skb(unsigned int size)
144{ 148{
145 struct sk_buff *skb; 149 struct sk_buff *skb;
150 unsigned int n;
146 151
147 /* alloc skb which should be big enough for a whole 152 /* alloc skb which should be big enough for a whole
148 * multipart message. WARNING: has to be <= 131000 153 * multipart message. WARNING: has to be <= 131000
149 * due to slab allocator restrictions */ 154 * due to slab allocator restrictions */
150 155
151 skb = alloc_skb(nlbufsiz, GFP_ATOMIC); 156 n = max(size, nlbufsiz);
157 skb = alloc_skb(n, GFP_ATOMIC);
152 if (!skb) { 158 if (!skb) {
153 PRINTR("ipt_ULOG: can't alloc whole buffer %ub!\n", 159 PRINTR("ipt_ULOG: can't alloc whole buffer %ub!\n", n);
154 nlbufsiz);
155 160
156 /* try to allocate only as much as we need for 161 if (n > size) {
157 * current packet */ 162 /* try to allocate only as much as we need for
163 * current packet */
158 164
159 skb = alloc_skb(size, GFP_ATOMIC); 165 skb = alloc_skb(size, GFP_ATOMIC);
160 if (!skb) 166 if (!skb)
161 PRINTR("ipt_ULOG: can't even allocate %ub\n", size); 167 PRINTR("ipt_ULOG: can't even allocate %ub\n",
168 size);
169 }
162 } 170 }
163 171
164 return skb; 172 return skb;
diff --git a/net/ipv4/netfilter/ipt_policy.c b/net/ipv4/netfilter/ipt_policy.c
index 18ca8258a1c5..5a7a265280f9 100644
--- a/net/ipv4/netfilter/ipt_policy.c
+++ b/net/ipv4/netfilter/ipt_policy.c
@@ -26,10 +26,13 @@ MODULE_LICENSE("GPL");
26static inline int 26static inline int
27match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e) 27match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e)
28{ 28{
29#define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x)) 29#define MATCH_ADDR(x,y,z) (!e->match.x || \
30 ((e->x.a4.s_addr == (e->y.a4.s_addr & (z))) \
31 ^ e->invert.x))
32#define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x))
30 33
31 return MATCH(saddr, x->props.saddr.a4 & e->smask) && 34 return MATCH_ADDR(saddr, smask, x->props.saddr.a4) &&
32 MATCH(daddr, x->id.daddr.a4 & e->dmask) && 35 MATCH_ADDR(daddr, dmask, x->id.daddr.a4) &&
33 MATCH(proto, x->id.proto) && 36 MATCH(proto, x->id.proto) &&
34 MATCH(mode, x->props.mode) && 37 MATCH(mode, x->props.mode) &&
35 MATCH(spi, x->id.spi) && 38 MATCH(spi, x->id.spi) &&
@@ -89,7 +92,7 @@ match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info)
89 return 0; 92 return 0;
90 } 93 }
91 94
92 return strict ? 1 : 0; 95 return strict ? i == info->len : 0;
93} 96}
94 97
95static int match(const struct sk_buff *skb, 98static int match(const struct sk_buff *skb,
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 39d49dc333a7..1b167c4bb3be 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -49,7 +49,7 @@ static int fold_prot_inuse(struct proto *proto)
49 int res = 0; 49 int res = 0;
50 int cpu; 50 int cpu;
51 51
52 for (cpu = 0; cpu < NR_CPUS; cpu++) 52 for_each_cpu(cpu)
53 res += proto->stats[cpu].inuse; 53 res += proto->stats[cpu].inuse;
54 54
55 return res; 55 return res;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index d328d5986143..1db50487916b 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3321,9 +3321,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
3321 3321
3322 switch (event) { 3322 switch (event) {
3323 case RTM_NEWADDR: 3323 case RTM_NEWADDR:
3324 dst_hold(&ifp->rt->u.dst); 3324 ip6_ins_rt(ifp->rt, NULL, NULL, NULL);
3325 if (ip6_ins_rt(ifp->rt, NULL, NULL, NULL))
3326 dst_release(&ifp->rt->u.dst);
3327 if (ifp->idev->cnf.forwarding) 3325 if (ifp->idev->cnf.forwarding)
3328 addrconf_join_anycast(ifp); 3326 addrconf_join_anycast(ifp);
3329 break; 3327 break;
@@ -3334,8 +3332,6 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
3334 dst_hold(&ifp->rt->u.dst); 3332 dst_hold(&ifp->rt->u.dst);
3335 if (ip6_del_rt(ifp->rt, NULL, NULL, NULL)) 3333 if (ip6_del_rt(ifp->rt, NULL, NULL, NULL))
3336 dst_free(&ifp->rt->u.dst); 3334 dst_free(&ifp->rt->u.dst);
3337 else
3338 dst_release(&ifp->rt->u.dst);
3339 break; 3335 break;
3340 } 3336 }
3341} 3337}
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 064ffab82a9f..6c9711ac1c03 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -369,12 +369,6 @@ int inet6_destroy_sock(struct sock *sk)
369 struct sk_buff *skb; 369 struct sk_buff *skb;
370 struct ipv6_txoptions *opt; 370 struct ipv6_txoptions *opt;
371 371
372 /*
373 * Release destination entry
374 */
375
376 sk_dst_reset(sk);
377
378 /* Release rx options */ 372 /* Release rx options */
379 373
380 if ((skb = xchg(&np->pktoptions, NULL)) != NULL) 374 if ((skb = xchg(&np->pktoptions, NULL)) != NULL)
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 847068fd3367..74ff56c322f4 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -978,6 +978,13 @@ do_replace(void __user *user, unsigned int len)
978 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 978 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
979 return -EFAULT; 979 return -EFAULT;
980 980
981 /* overflow check */
982 if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
983 SMP_CACHE_BYTES)
984 return -ENOMEM;
985 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
986 return -ENOMEM;
987
981 newinfo = xt_alloc_table_info(tmp.size); 988 newinfo = xt_alloc_table_info(tmp.size);
982 if (!newinfo) 989 if (!newinfo)
983 return -ENOMEM; 990 return -ENOMEM;
diff --git a/net/ipv6/netfilter/ip6t_policy.c b/net/ipv6/netfilter/ip6t_policy.c
index afe1cc4c18a5..3d39ec924041 100644
--- a/net/ipv6/netfilter/ip6t_policy.c
+++ b/net/ipv6/netfilter/ip6t_policy.c
@@ -26,8 +26,9 @@ MODULE_LICENSE("GPL");
26static inline int 26static inline int
27match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e) 27match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e)
28{ 28{
29#define MATCH_ADDR(x,y,z) (!e->match.x || \ 29#define MATCH_ADDR(x,y,z) (!e->match.x || \
30 ((ip6_masked_addrcmp((z), &e->x, &e->y)) == 0) ^ e->invert.x) 30 ((!ip6_masked_addrcmp(&e->x.a6, &e->y.a6, z)) \
31 ^ e->invert.x))
31#define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x)) 32#define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x))
32 33
33 return MATCH_ADDR(saddr, smask, (struct in6_addr *)&x->props.saddr.a6) && 34 return MATCH_ADDR(saddr, smask, (struct in6_addr *)&x->props.saddr.a6) &&
@@ -91,7 +92,7 @@ match_policy_out(const struct sk_buff *skb, const struct ip6t_policy_info *info)
91 return 0; 92 return 0;
92 } 93 }
93 94
94 return strict ? 1 : 0; 95 return strict ? i == info->len : 0;
95} 96}
96 97
97static int match(const struct sk_buff *skb, 98static int match(const struct sk_buff *skb,
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 50a13e75d70e..4238b1ed8860 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -38,7 +38,7 @@ static int fold_prot_inuse(struct proto *proto)
38 int res = 0; 38 int res = 0;
39 int cpu; 39 int cpu;
40 40
41 for (cpu=0; cpu<NR_CPUS; cpu++) 41 for_each_cpu(cpu)
42 res += proto->stats[cpu].inuse; 42 res += proto->stats[cpu].inuse;
43 43
44 return res; 44 return res;
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 62bb509f05d4..0ce337a1d974 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -188,7 +188,7 @@ extern struct nf_conntrack_protocol nf_conntrack_generic_protocol;
188struct nf_conntrack_protocol * 188struct nf_conntrack_protocol *
189__nf_ct_proto_find(u_int16_t l3proto, u_int8_t protocol) 189__nf_ct_proto_find(u_int16_t l3proto, u_int8_t protocol)
190{ 190{
191 if (unlikely(nf_ct_protos[l3proto] == NULL)) 191 if (unlikely(l3proto >= AF_MAX || nf_ct_protos[l3proto] == NULL))
192 return &nf_conntrack_generic_protocol; 192 return &nf_conntrack_generic_protocol;
193 193
194 return nf_ct_protos[l3proto][protocol]; 194 return nf_ct_protos[l3proto][protocol];
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index ab0c920f0d30..6f210f399762 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -657,8 +657,6 @@ static int __init init(void)
657 /* FIXME should be configurable whether IPv4 and IPv6 FTP connections 657 /* FIXME should be configurable whether IPv4 and IPv6 FTP connections
658 are tracked or not - YK */ 658 are tracked or not - YK */
659 for (i = 0; i < ports_c; i++) { 659 for (i = 0; i < ports_c; i++) {
660 memset(&ftp[i], 0, sizeof(struct nf_conntrack_helper));
661
662 ftp[i][0].tuple.src.l3num = PF_INET; 660 ftp[i][0].tuple.src.l3num = PF_INET;
663 ftp[i][1].tuple.src.l3num = PF_INET6; 661 ftp[i][1].tuple.src.l3num = PF_INET6;
664 for (j = 0; j < 2; j++) { 662 for (j = 0; j < 2; j++) {
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 73ab16bc7d40..9ff3463037e1 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1232,7 +1232,7 @@ static int ctnetlink_expect_event(struct notifier_block *this,
1232 1232
1233 b = skb->tail; 1233 b = skb->tail;
1234 1234
1235 type |= NFNL_SUBSYS_CTNETLINK << 8; 1235 type |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
1236 nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg)); 1236 nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
1237 nfmsg = NLMSG_DATA(nlh); 1237 nfmsg = NLMSG_DATA(nlh);
1238 1238
@@ -1589,6 +1589,7 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = {
1589}; 1589};
1590 1590
1591MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK); 1591MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
1592MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP);
1592 1593
1593static int __init ctnetlink_init(void) 1594static int __init ctnetlink_init(void)
1594{ 1595{
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index e10512e229b6..3b3c781b40c0 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -37,7 +37,7 @@
37#include "../bridge/br_private.h" 37#include "../bridge/br_private.h"
38#endif 38#endif
39 39
40#define NFULNL_NLBUFSIZ_DEFAULT 4096 40#define NFULNL_NLBUFSIZ_DEFAULT NLMSG_GOODSIZE
41#define NFULNL_TIMEOUT_DEFAULT 100 /* every second */ 41#define NFULNL_TIMEOUT_DEFAULT 100 /* every second */
42#define NFULNL_QTHRESH_DEFAULT 100 /* 100 packets */ 42#define NFULNL_QTHRESH_DEFAULT 100 /* 100 packets */
43 43
@@ -314,24 +314,28 @@ static struct sk_buff *nfulnl_alloc_skb(unsigned int inst_size,
314 unsigned int pkt_size) 314 unsigned int pkt_size)
315{ 315{
316 struct sk_buff *skb; 316 struct sk_buff *skb;
317 unsigned int n;
317 318
318 UDEBUG("entered (%u, %u)\n", inst_size, pkt_size); 319 UDEBUG("entered (%u, %u)\n", inst_size, pkt_size);
319 320
320 /* alloc skb which should be big enough for a whole multipart 321 /* alloc skb which should be big enough for a whole multipart
321 * message. WARNING: has to be <= 128k due to slab restrictions */ 322 * message. WARNING: has to be <= 128k due to slab restrictions */
322 323
323 skb = alloc_skb(inst_size, GFP_ATOMIC); 324 n = max(inst_size, pkt_size);
325 skb = alloc_skb(n, GFP_ATOMIC);
324 if (!skb) { 326 if (!skb) {
325 PRINTR("nfnetlink_log: can't alloc whole buffer (%u bytes)\n", 327 PRINTR("nfnetlink_log: can't alloc whole buffer (%u bytes)\n",
326 inst_size); 328 inst_size);
327 329
328 /* try to allocate only as much as we need for current 330 if (n > pkt_size) {
329 * packet */ 331 /* try to allocate only as much as we need for current
332 * packet */
330 333
331 skb = alloc_skb(pkt_size, GFP_ATOMIC); 334 skb = alloc_skb(pkt_size, GFP_ATOMIC);
332 if (!skb) 335 if (!skb)
333 PRINTR("nfnetlink_log: can't even alloc %u bytes\n", 336 PRINTR("nfnetlink_log: can't even alloc %u "
334 pkt_size); 337 "bytes\n", pkt_size);
338 }
335 } 339 }
336 340
337 return skb; 341 return skb;
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 18ed9c5d209c..cac38b2e147a 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -825,7 +825,8 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
825 } 825 }
826 826
827 if (nfqa[NFQA_MARK-1]) 827 if (nfqa[NFQA_MARK-1])
828 skb->nfmark = ntohl(*(u_int32_t *)NFA_DATA(nfqa[NFQA_MARK-1])); 828 entry->skb->nfmark = ntohl(*(u_int32_t *)
829 NFA_DATA(nfqa[NFQA_MARK-1]));
829 830
830 issue_verdict(entry, verdict); 831 issue_verdict(entry, verdict);
831 instance_put(queue); 832 instance_put(queue);
diff --git a/net/sctp/output.c b/net/sctp/output.c
index a40991ef72c9..437cba7260a4 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -608,7 +608,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
608 * When a Fast Retransmit is being performed the sender SHOULD 608 * When a Fast Retransmit is being performed the sender SHOULD
609 * ignore the value of cwnd and SHOULD NOT delay retransmission. 609 * ignore the value of cwnd and SHOULD NOT delay retransmission.
610 */ 610 */
611 if (!chunk->fast_retransmit) 611 if (chunk->fast_retransmit <= 0)
612 if (transport->flight_size >= transport->cwnd) { 612 if (transport->flight_size >= transport->cwnd) {
613 retval = SCTP_XMIT_RWND_FULL; 613 retval = SCTP_XMIT_RWND_FULL;
614 goto finish; 614 goto finish;
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index efb72faba20c..f148f9576dd2 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -406,7 +406,7 @@ void sctp_retransmit_mark(struct sctp_outq *q,
406 * chunks that are not yet acked should be added to the 406 * chunks that are not yet acked should be added to the
407 * retransmit queue. 407 * retransmit queue.
408 */ 408 */
409 if ((fast_retransmit && chunk->fast_retransmit) || 409 if ((fast_retransmit && (chunk->fast_retransmit > 0)) ||
410 (!fast_retransmit && !chunk->tsn_gap_acked)) { 410 (!fast_retransmit && !chunk->tsn_gap_acked)) {
411 /* RFC 2960 6.2.1 Processing a Received SACK 411 /* RFC 2960 6.2.1 Processing a Received SACK
412 * 412 *
@@ -603,7 +603,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
603 /* Mark the chunk as ineligible for fast retransmit 603 /* Mark the chunk as ineligible for fast retransmit
604 * after it is retransmitted. 604 * after it is retransmitted.
605 */ 605 */
606 chunk->fast_retransmit = 0; 606 if (chunk->fast_retransmit > 0)
607 chunk->fast_retransmit = -1;
607 608
608 *start_timer = 1; 609 *start_timer = 1;
609 q->empty = 0; 610 q->empty = 0;
@@ -621,7 +622,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
621 list_for_each(lchunk1, lqueue) { 622 list_for_each(lchunk1, lqueue) {
622 chunk1 = list_entry(lchunk1, struct sctp_chunk, 623 chunk1 = list_entry(lchunk1, struct sctp_chunk,
623 transmitted_list); 624 transmitted_list);
624 chunk1->fast_retransmit = 0; 625 if (chunk1->fast_retransmit > 0)
626 chunk1->fast_retransmit = -1;
625 } 627 }
626 } 628 }
627 } 629 }
@@ -1562,11 +1564,11 @@ static void sctp_mark_missing(struct sctp_outq *q,
1562 /* 1564 /*
1563 * M4) If any DATA chunk is found to have a 1565 * M4) If any DATA chunk is found to have a
1564 * 'TSN.Missing.Report' 1566 * 'TSN.Missing.Report'
1565 * value larger than or equal to 4, mark that chunk for 1567 * value larger than or equal to 3, mark that chunk for
1566 * retransmission and start the fast retransmit procedure. 1568 * retransmission and start the fast retransmit procedure.
1567 */ 1569 */
1568 1570
1569 if (chunk->tsn_missing_report >= 4) { 1571 if (chunk->tsn_missing_report >= 3) {
1570 chunk->fast_retransmit = 1; 1572 chunk->fast_retransmit = 1;
1571 do_fast_retransmit = 1; 1573 do_fast_retransmit = 1;
1572 } 1574 }
diff --git a/net/socket.c b/net/socket.c
index b38a263853c3..a00851f981db 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2078,7 +2078,7 @@ void socket_seq_show(struct seq_file *seq)
2078 int cpu; 2078 int cpu;
2079 int counter = 0; 2079 int counter = 0;
2080 2080
2081 for (cpu = 0; cpu < NR_CPUS; cpu++) 2081 for_each_cpu(cpu)
2082 counter += per_cpu(sockets_in_use, cpu); 2082 counter += per_cpu(sockets_in_use, cpu);
2083 2083
2084 /* It can be negative, by the way. 8) */ 2084 /* It can be negative, by the way. 8) */
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 9ac1b8c26c01..8d6f1a176b15 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -184,7 +184,7 @@ rpcauth_gc_credcache(struct rpc_auth *auth, struct hlist_head *free)
184 */ 184 */
185struct rpc_cred * 185struct rpc_cred *
186rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, 186rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
187 int taskflags) 187 int flags)
188{ 188{
189 struct rpc_cred_cache *cache = auth->au_credcache; 189 struct rpc_cred_cache *cache = auth->au_credcache;
190 HLIST_HEAD(free); 190 HLIST_HEAD(free);
@@ -193,7 +193,7 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
193 *cred = NULL; 193 *cred = NULL;
194 int nr = 0; 194 int nr = 0;
195 195
196 if (!(taskflags & RPC_TASK_ROOTCREDS)) 196 if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS))
197 nr = acred->uid & RPC_CREDCACHE_MASK; 197 nr = acred->uid & RPC_CREDCACHE_MASK;
198retry: 198retry:
199 spin_lock(&rpc_credcache_lock); 199 spin_lock(&rpc_credcache_lock);
@@ -202,7 +202,7 @@ retry:
202 hlist_for_each_safe(pos, next, &cache->hashtable[nr]) { 202 hlist_for_each_safe(pos, next, &cache->hashtable[nr]) {
203 struct rpc_cred *entry; 203 struct rpc_cred *entry;
204 entry = hlist_entry(pos, struct rpc_cred, cr_hash); 204 entry = hlist_entry(pos, struct rpc_cred, cr_hash);
205 if (entry->cr_ops->crmatch(acred, entry, taskflags)) { 205 if (entry->cr_ops->crmatch(acred, entry, flags)) {
206 hlist_del(&entry->cr_hash); 206 hlist_del(&entry->cr_hash);
207 cred = entry; 207 cred = entry;
208 break; 208 break;
@@ -224,7 +224,7 @@ retry:
224 rpcauth_destroy_credlist(&free); 224 rpcauth_destroy_credlist(&free);
225 225
226 if (!cred) { 226 if (!cred) {
227 new = auth->au_ops->crcreate(auth, acred, taskflags); 227 new = auth->au_ops->crcreate(auth, acred, flags);
228 if (!IS_ERR(new)) { 228 if (!IS_ERR(new)) {
229#ifdef RPC_DEBUG 229#ifdef RPC_DEBUG
230 new->cr_magic = RPCAUTH_CRED_MAGIC; 230 new->cr_magic = RPCAUTH_CRED_MAGIC;
@@ -232,13 +232,21 @@ retry:
232 goto retry; 232 goto retry;
233 } else 233 } else
234 cred = new; 234 cred = new;
235 } else if ((cred->cr_flags & RPCAUTH_CRED_NEW)
236 && cred->cr_ops->cr_init != NULL
237 && !(flags & RPCAUTH_LOOKUP_NEW)) {
238 int res = cred->cr_ops->cr_init(auth, cred);
239 if (res < 0) {
240 put_rpccred(cred);
241 cred = ERR_PTR(res);
242 }
235 } 243 }
236 244
237 return (struct rpc_cred *) cred; 245 return (struct rpc_cred *) cred;
238} 246}
239 247
240struct rpc_cred * 248struct rpc_cred *
241rpcauth_lookupcred(struct rpc_auth *auth, int taskflags) 249rpcauth_lookupcred(struct rpc_auth *auth, int flags)
242{ 250{
243 struct auth_cred acred = { 251 struct auth_cred acred = {
244 .uid = current->fsuid, 252 .uid = current->fsuid,
@@ -250,7 +258,7 @@ rpcauth_lookupcred(struct rpc_auth *auth, int taskflags)
250 dprintk("RPC: looking up %s cred\n", 258 dprintk("RPC: looking up %s cred\n",
251 auth->au_ops->au_name); 259 auth->au_ops->au_name);
252 get_group_info(acred.group_info); 260 get_group_info(acred.group_info);
253 ret = auth->au_ops->lookup_cred(auth, &acred, taskflags); 261 ret = auth->au_ops->lookup_cred(auth, &acred, flags);
254 put_group_info(acred.group_info); 262 put_group_info(acred.group_info);
255 return ret; 263 return ret;
256} 264}
@@ -265,11 +273,14 @@ rpcauth_bindcred(struct rpc_task *task)
265 .group_info = current->group_info, 273 .group_info = current->group_info,
266 }; 274 };
267 struct rpc_cred *ret; 275 struct rpc_cred *ret;
276 int flags = 0;
268 277
269 dprintk("RPC: %4d looking up %s cred\n", 278 dprintk("RPC: %4d looking up %s cred\n",
270 task->tk_pid, task->tk_auth->au_ops->au_name); 279 task->tk_pid, task->tk_auth->au_ops->au_name);
271 get_group_info(acred.group_info); 280 get_group_info(acred.group_info);
272 ret = auth->au_ops->lookup_cred(auth, &acred, task->tk_flags); 281 if (task->tk_flags & RPC_TASK_ROOTCREDS)
282 flags |= RPCAUTH_LOOKUP_ROOTCREDS;
283 ret = auth->au_ops->lookup_cred(auth, &acred, flags);
273 if (!IS_ERR(ret)) 284 if (!IS_ERR(ret))
274 task->tk_msg.rpc_cred = ret; 285 task->tk_msg.rpc_cred = ret;
275 else 286 else
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 8d782282ec19..bb46efd92e57 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -158,6 +158,7 @@ gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx)
158 old = gss_cred->gc_ctx; 158 old = gss_cred->gc_ctx;
159 gss_cred->gc_ctx = ctx; 159 gss_cred->gc_ctx = ctx;
160 cred->cr_flags |= RPCAUTH_CRED_UPTODATE; 160 cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
161 cred->cr_flags &= ~RPCAUTH_CRED_NEW;
161 write_unlock(&gss_ctx_lock); 162 write_unlock(&gss_ctx_lock);
162 if (old) 163 if (old)
163 gss_put_ctx(old); 164 gss_put_ctx(old);
@@ -580,7 +581,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
580 } else { 581 } else {
581 struct auth_cred acred = { .uid = uid }; 582 struct auth_cred acred = { .uid = uid };
582 spin_unlock(&gss_auth->lock); 583 spin_unlock(&gss_auth->lock);
583 cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, 0); 584 cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, RPCAUTH_LOOKUP_NEW);
584 if (IS_ERR(cred)) { 585 if (IS_ERR(cred)) {
585 err = PTR_ERR(cred); 586 err = PTR_ERR(cred);
586 goto err_put_ctx; 587 goto err_put_ctx;
@@ -758,13 +759,13 @@ gss_destroy_cred(struct rpc_cred *rc)
758 * Lookup RPCSEC_GSS cred for the current process 759 * Lookup RPCSEC_GSS cred for the current process
759 */ 760 */
760static struct rpc_cred * 761static struct rpc_cred *
761gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags) 762gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
762{ 763{
763 return rpcauth_lookup_credcache(auth, acred, taskflags); 764 return rpcauth_lookup_credcache(auth, acred, flags);
764} 765}
765 766
766static struct rpc_cred * 767static struct rpc_cred *
767gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags) 768gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
768{ 769{
769 struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth); 770 struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth);
770 struct gss_cred *cred = NULL; 771 struct gss_cred *cred = NULL;
@@ -785,13 +786,8 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags)
785 */ 786 */
786 cred->gc_flags = 0; 787 cred->gc_flags = 0;
787 cred->gc_base.cr_ops = &gss_credops; 788 cred->gc_base.cr_ops = &gss_credops;
789 cred->gc_base.cr_flags = RPCAUTH_CRED_NEW;
788 cred->gc_service = gss_auth->service; 790 cred->gc_service = gss_auth->service;
789 do {
790 err = gss_create_upcall(gss_auth, cred);
791 } while (err == -EAGAIN);
792 if (err < 0)
793 goto out_err;
794
795 return &cred->gc_base; 791 return &cred->gc_base;
796 792
797out_err: 793out_err:
@@ -801,13 +797,34 @@ out_err:
801} 797}
802 798
803static int 799static int
804gss_match(struct auth_cred *acred, struct rpc_cred *rc, int taskflags) 800gss_cred_init(struct rpc_auth *auth, struct rpc_cred *cred)
801{
802 struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth);
803 struct gss_cred *gss_cred = container_of(cred,struct gss_cred, gc_base);
804 int err;
805
806 do {
807 err = gss_create_upcall(gss_auth, gss_cred);
808 } while (err == -EAGAIN);
809 return err;
810}
811
812static int
813gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags)
805{ 814{
806 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base); 815 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base);
807 816
817 /*
818 * If the searchflags have set RPCAUTH_LOOKUP_NEW, then
819 * we don't really care if the credential has expired or not,
820 * since the caller should be prepared to reinitialise it.
821 */
822 if ((flags & RPCAUTH_LOOKUP_NEW) && (rc->cr_flags & RPCAUTH_CRED_NEW))
823 goto out;
808 /* Don't match with creds that have expired. */ 824 /* Don't match with creds that have expired. */
809 if (gss_cred->gc_ctx && time_after(jiffies, gss_cred->gc_ctx->gc_expiry)) 825 if (gss_cred->gc_ctx && time_after(jiffies, gss_cred->gc_ctx->gc_expiry))
810 return 0; 826 return 0;
827out:
811 return (rc->cr_uid == acred->uid); 828 return (rc->cr_uid == acred->uid);
812} 829}
813 830
@@ -1241,6 +1258,7 @@ static struct rpc_authops authgss_ops = {
1241static struct rpc_credops gss_credops = { 1258static struct rpc_credops gss_credops = {
1242 .cr_name = "AUTH_GSS", 1259 .cr_name = "AUTH_GSS",
1243 .crdestroy = gss_destroy_cred, 1260 .crdestroy = gss_destroy_cred,
1261 .cr_init = gss_cred_init,
1244 .crmatch = gss_match, 1262 .crmatch = gss_match,
1245 .crmarshal = gss_marshal, 1263 .crmarshal = gss_marshal,
1246 .crrefresh = gss_refresh, 1264 .crrefresh = gss_refresh,
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 1b3ed4fd1987..df14b6bfbf10 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -75,7 +75,7 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
75 75
76 atomic_set(&cred->uc_count, 1); 76 atomic_set(&cred->uc_count, 1);
77 cred->uc_flags = RPCAUTH_CRED_UPTODATE; 77 cred->uc_flags = RPCAUTH_CRED_UPTODATE;
78 if (flags & RPC_TASK_ROOTCREDS) { 78 if (flags & RPCAUTH_LOOKUP_ROOTCREDS) {
79 cred->uc_uid = 0; 79 cred->uc_uid = 0;
80 cred->uc_gid = 0; 80 cred->uc_gid = 0;
81 cred->uc_gids[0] = NOGROUP; 81 cred->uc_gids[0] = NOGROUP;
@@ -108,12 +108,12 @@ unx_destroy_cred(struct rpc_cred *cred)
108 * request root creds (e.g. for NFS swapping). 108 * request root creds (e.g. for NFS swapping).
109 */ 109 */
110static int 110static int
111unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int taskflags) 111unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
112{ 112{
113 struct unx_cred *cred = (struct unx_cred *) rcred; 113 struct unx_cred *cred = (struct unx_cred *) rcred;
114 int i; 114 int i;
115 115
116 if (!(taskflags & RPC_TASK_ROOTCREDS)) { 116 if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) {
117 int groups; 117 int groups;
118 118
119 if (cred->uc_uid != acred->uid 119 if (cred->uc_uid != acred->uid
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 9764c80ab0b2..a5c0c7b6e151 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -38,44 +38,42 @@ static kmem_cache_t *rpc_inode_cachep __read_mostly;
38 38
39#define RPC_UPCALL_TIMEOUT (30*HZ) 39#define RPC_UPCALL_TIMEOUT (30*HZ)
40 40
41static void 41static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head,
42__rpc_purge_list(struct rpc_inode *rpci, struct list_head *head, int err) 42 void (*destroy_msg)(struct rpc_pipe_msg *), int err)
43{ 43{
44 struct rpc_pipe_msg *msg; 44 struct rpc_pipe_msg *msg;
45 void (*destroy_msg)(struct rpc_pipe_msg *);
46 45
47 destroy_msg = rpci->ops->destroy_msg; 46 if (list_empty(head))
48 while (!list_empty(head)) { 47 return;
48 do {
49 msg = list_entry(head->next, struct rpc_pipe_msg, list); 49 msg = list_entry(head->next, struct rpc_pipe_msg, list);
50 list_del_init(&msg->list); 50 list_del(&msg->list);
51 msg->errno = err; 51 msg->errno = err;
52 destroy_msg(msg); 52 destroy_msg(msg);
53 } 53 } while (!list_empty(head));
54}
55
56static void
57__rpc_purge_upcall(struct inode *inode, int err)
58{
59 struct rpc_inode *rpci = RPC_I(inode);
60
61 __rpc_purge_list(rpci, &rpci->pipe, err);
62 rpci->pipelen = 0;
63 wake_up(&rpci->waitq); 54 wake_up(&rpci->waitq);
64} 55}
65 56
66static void 57static void
67rpc_timeout_upcall_queue(void *data) 58rpc_timeout_upcall_queue(void *data)
68{ 59{
60 LIST_HEAD(free_list);
69 struct rpc_inode *rpci = (struct rpc_inode *)data; 61 struct rpc_inode *rpci = (struct rpc_inode *)data;
70 struct inode *inode = &rpci->vfs_inode; 62 struct inode *inode = &rpci->vfs_inode;
63 void (*destroy_msg)(struct rpc_pipe_msg *);
71 64
72 mutex_lock(&inode->i_mutex); 65 spin_lock(&inode->i_lock);
73 if (rpci->ops == NULL) 66 if (rpci->ops == NULL) {
74 goto out; 67 spin_unlock(&inode->i_lock);
75 if (rpci->nreaders == 0 && !list_empty(&rpci->pipe)) 68 return;
76 __rpc_purge_upcall(inode, -ETIMEDOUT); 69 }
77out: 70 destroy_msg = rpci->ops->destroy_msg;
78 mutex_unlock(&inode->i_mutex); 71 if (rpci->nreaders == 0) {
72 list_splice_init(&rpci->pipe, &free_list);
73 rpci->pipelen = 0;
74 }
75 spin_unlock(&inode->i_lock);
76 rpc_purge_list(rpci, &free_list, destroy_msg, -ETIMEDOUT);
79} 77}
80 78
81int 79int
@@ -84,7 +82,7 @@ rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg)
84 struct rpc_inode *rpci = RPC_I(inode); 82 struct rpc_inode *rpci = RPC_I(inode);
85 int res = -EPIPE; 83 int res = -EPIPE;
86 84
87 mutex_lock(&inode->i_mutex); 85 spin_lock(&inode->i_lock);
88 if (rpci->ops == NULL) 86 if (rpci->ops == NULL)
89 goto out; 87 goto out;
90 if (rpci->nreaders) { 88 if (rpci->nreaders) {
@@ -100,7 +98,7 @@ rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg)
100 res = 0; 98 res = 0;
101 } 99 }
102out: 100out:
103 mutex_unlock(&inode->i_mutex); 101 spin_unlock(&inode->i_lock);
104 wake_up(&rpci->waitq); 102 wake_up(&rpci->waitq);
105 return res; 103 return res;
106} 104}
@@ -115,21 +113,29 @@ static void
115rpc_close_pipes(struct inode *inode) 113rpc_close_pipes(struct inode *inode)
116{ 114{
117 struct rpc_inode *rpci = RPC_I(inode); 115 struct rpc_inode *rpci = RPC_I(inode);
116 struct rpc_pipe_ops *ops;
118 117
119 mutex_lock(&inode->i_mutex); 118 mutex_lock(&inode->i_mutex);
120 if (rpci->ops != NULL) { 119 ops = rpci->ops;
120 if (ops != NULL) {
121 LIST_HEAD(free_list);
122
123 spin_lock(&inode->i_lock);
121 rpci->nreaders = 0; 124 rpci->nreaders = 0;
122 __rpc_purge_list(rpci, &rpci->in_upcall, -EPIPE); 125 list_splice_init(&rpci->in_upcall, &free_list);
123 __rpc_purge_upcall(inode, -EPIPE); 126 list_splice_init(&rpci->pipe, &free_list);
124 rpci->nwriters = 0; 127 rpci->pipelen = 0;
125 if (rpci->ops->release_pipe)
126 rpci->ops->release_pipe(inode);
127 rpci->ops = NULL; 128 rpci->ops = NULL;
129 spin_unlock(&inode->i_lock);
130 rpc_purge_list(rpci, &free_list, ops->destroy_msg, -EPIPE);
131 rpci->nwriters = 0;
132 if (ops->release_pipe)
133 ops->release_pipe(inode);
134 cancel_delayed_work(&rpci->queue_timeout);
135 flush_scheduled_work();
128 } 136 }
129 rpc_inode_setowner(inode, NULL); 137 rpc_inode_setowner(inode, NULL);
130 mutex_unlock(&inode->i_mutex); 138 mutex_unlock(&inode->i_mutex);
131 cancel_delayed_work(&rpci->queue_timeout);
132 flush_scheduled_work();
133} 139}
134 140
135static struct inode * 141static struct inode *
@@ -177,16 +183,26 @@ rpc_pipe_release(struct inode *inode, struct file *filp)
177 goto out; 183 goto out;
178 msg = (struct rpc_pipe_msg *)filp->private_data; 184 msg = (struct rpc_pipe_msg *)filp->private_data;
179 if (msg != NULL) { 185 if (msg != NULL) {
186 spin_lock(&inode->i_lock);
180 msg->errno = -EAGAIN; 187 msg->errno = -EAGAIN;
181 list_del_init(&msg->list); 188 list_del(&msg->list);
189 spin_unlock(&inode->i_lock);
182 rpci->ops->destroy_msg(msg); 190 rpci->ops->destroy_msg(msg);
183 } 191 }
184 if (filp->f_mode & FMODE_WRITE) 192 if (filp->f_mode & FMODE_WRITE)
185 rpci->nwriters --; 193 rpci->nwriters --;
186 if (filp->f_mode & FMODE_READ) 194 if (filp->f_mode & FMODE_READ) {
187 rpci->nreaders --; 195 rpci->nreaders --;
188 if (!rpci->nreaders) 196 if (rpci->nreaders == 0) {
189 __rpc_purge_upcall(inode, -EAGAIN); 197 LIST_HEAD(free_list);
198 spin_lock(&inode->i_lock);
199 list_splice_init(&rpci->pipe, &free_list);
200 rpci->pipelen = 0;
201 spin_unlock(&inode->i_lock);
202 rpc_purge_list(rpci, &free_list,
203 rpci->ops->destroy_msg, -EAGAIN);
204 }
205 }
190 if (rpci->ops->release_pipe) 206 if (rpci->ops->release_pipe)
191 rpci->ops->release_pipe(inode); 207 rpci->ops->release_pipe(inode);
192out: 208out:
@@ -209,6 +225,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
209 } 225 }
210 msg = filp->private_data; 226 msg = filp->private_data;
211 if (msg == NULL) { 227 if (msg == NULL) {
228 spin_lock(&inode->i_lock);
212 if (!list_empty(&rpci->pipe)) { 229 if (!list_empty(&rpci->pipe)) {
213 msg = list_entry(rpci->pipe.next, 230 msg = list_entry(rpci->pipe.next,
214 struct rpc_pipe_msg, 231 struct rpc_pipe_msg,
@@ -218,6 +235,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
218 filp->private_data = msg; 235 filp->private_data = msg;
219 msg->copied = 0; 236 msg->copied = 0;
220 } 237 }
238 spin_unlock(&inode->i_lock);
221 if (msg == NULL) 239 if (msg == NULL)
222 goto out_unlock; 240 goto out_unlock;
223 } 241 }
@@ -225,7 +243,9 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
225 res = rpci->ops->upcall(filp, msg, buf, len); 243 res = rpci->ops->upcall(filp, msg, buf, len);
226 if (res < 0 || msg->len == msg->copied) { 244 if (res < 0 || msg->len == msg->copied) {
227 filp->private_data = NULL; 245 filp->private_data = NULL;
228 list_del_init(&msg->list); 246 spin_lock(&inode->i_lock);
247 list_del(&msg->list);
248 spin_unlock(&inode->i_lock);
229 rpci->ops->destroy_msg(msg); 249 rpci->ops->destroy_msg(msg);
230 } 250 }
231out_unlock: 251out_unlock:
@@ -610,7 +630,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd)
610 return ERR_PTR(error); 630 return ERR_PTR(error);
611 dir = nd->dentry->d_inode; 631 dir = nd->dentry->d_inode;
612 mutex_lock(&dir->i_mutex); 632 mutex_lock(&dir->i_mutex);
613 dentry = lookup_hash(nd); 633 dentry = lookup_one_len(nd->last.name, nd->dentry, nd->last.len);
614 if (IS_ERR(dentry)) 634 if (IS_ERR(dentry))
615 goto out_err; 635 goto out_err;
616 if (dentry->d_inode) { 636 if (dentry->d_inode) {
@@ -672,7 +692,7 @@ rpc_rmdir(char *path)
672 return error; 692 return error;
673 dir = nd.dentry->d_inode; 693 dir = nd.dentry->d_inode;
674 mutex_lock(&dir->i_mutex); 694 mutex_lock(&dir->i_mutex);
675 dentry = lookup_hash(&nd); 695 dentry = lookup_one_len(nd.last.name, nd.dentry, nd.last.len);
676 if (IS_ERR(dentry)) { 696 if (IS_ERR(dentry)) {
677 error = PTR_ERR(dentry); 697 error = PTR_ERR(dentry);
678 goto out_release; 698 goto out_release;
@@ -733,7 +753,7 @@ rpc_unlink(char *path)
733 return error; 753 return error;
734 dir = nd.dentry->d_inode; 754 dir = nd.dentry->d_inode;
735 mutex_lock(&dir->i_mutex); 755 mutex_lock(&dir->i_mutex);
736 dentry = lookup_hash(&nd); 756 dentry = lookup_one_len(nd.last.name, nd.dentry, nd.last.len);
737 if (IS_ERR(dentry)) { 757 if (IS_ERR(dentry)) {
738 error = PTR_ERR(dentry); 758 error = PTR_ERR(dentry);
739 goto out_release; 759 goto out_release;