aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/compat.c13
-rw-r--r--net/sched/sch_api.c11
-rw-r--r--net/socket.c72
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c62
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c8
-rw-r--r--net/sunrpc/netns.h4
-rw-r--r--net/sunrpc/rpc_pipe.c5
-rw-r--r--net/sunrpc/sched.c8
-rw-r--r--net/sunrpc/svcauth_unix.c12
9 files changed, 119 insertions, 76 deletions
diff --git a/net/compat.c b/net/compat.c
index 79ae88485001..f0a1ba6c8086 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -734,19 +734,25 @@ static unsigned char nas[21] = {
734 734
735asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags) 735asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags)
736{ 736{
737 return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); 737 if (flags & MSG_CMSG_COMPAT)
738 return -EINVAL;
739 return __sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
738} 740}
739 741
740asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg, 742asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg,
741 unsigned int vlen, unsigned int flags) 743 unsigned int vlen, unsigned int flags)
742{ 744{
745 if (flags & MSG_CMSG_COMPAT)
746 return -EINVAL;
743 return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, 747 return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
744 flags | MSG_CMSG_COMPAT); 748 flags | MSG_CMSG_COMPAT);
745} 749}
746 750
747asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags) 751asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags)
748{ 752{
749 return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); 753 if (flags & MSG_CMSG_COMPAT)
754 return -EINVAL;
755 return __sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
750} 756}
751 757
752asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned int flags) 758asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned int flags)
@@ -768,6 +774,9 @@ asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg,
768 int datagrams; 774 int datagrams;
769 struct timespec ktspec; 775 struct timespec ktspec;
770 776
777 if (flags & MSG_CMSG_COMPAT)
778 return -EINVAL;
779
771 if (COMPAT_USE_64BIT_TIME) 780 if (COMPAT_USE_64BIT_TIME)
772 return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, 781 return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen,
773 flags | MSG_CMSG_COMPAT, 782 flags | MSG_CMSG_COMPAT,
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 2b935e7cfe7b..281c1bded1f6 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -291,17 +291,18 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct nlattr *ta
291{ 291{
292 struct qdisc_rate_table *rtab; 292 struct qdisc_rate_table *rtab;
293 293
294 if (tab == NULL || r->rate == 0 || r->cell_log == 0 ||
295 nla_len(tab) != TC_RTAB_SIZE)
296 return NULL;
297
294 for (rtab = qdisc_rtab_list; rtab; rtab = rtab->next) { 298 for (rtab = qdisc_rtab_list; rtab; rtab = rtab->next) {
295 if (memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) == 0) { 299 if (!memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) &&
300 !memcmp(&rtab->data, nla_data(tab), 1024)) {
296 rtab->refcnt++; 301 rtab->refcnt++;
297 return rtab; 302 return rtab;
298 } 303 }
299 } 304 }
300 305
301 if (tab == NULL || r->rate == 0 || r->cell_log == 0 ||
302 nla_len(tab) != TC_RTAB_SIZE)
303 return NULL;
304
305 rtab = kmalloc(sizeof(*rtab), GFP_KERNEL); 306 rtab = kmalloc(sizeof(*rtab), GFP_KERNEL);
306 if (rtab) { 307 if (rtab) {
307 rtab->rate = *r; 308 rtab->rate = *r;
diff --git a/net/socket.c b/net/socket.c
index 9ff6366fee13..4ca1526db756 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1956,7 +1956,7 @@ struct used_address {
1956 unsigned int name_len; 1956 unsigned int name_len;
1957}; 1957};
1958 1958
1959static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, 1959static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
1960 struct msghdr *msg_sys, unsigned int flags, 1960 struct msghdr *msg_sys, unsigned int flags,
1961 struct used_address *used_address) 1961 struct used_address *used_address)
1962{ 1962{
@@ -2071,26 +2071,30 @@ out:
2071 * BSD sendmsg interface 2071 * BSD sendmsg interface
2072 */ 2072 */
2073 2073
2074SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags) 2074long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
2075{ 2075{
2076 int fput_needed, err; 2076 int fput_needed, err;
2077 struct msghdr msg_sys; 2077 struct msghdr msg_sys;
2078 struct socket *sock; 2078 struct socket *sock;
2079 2079
2080 if (flags & MSG_CMSG_COMPAT)
2081 return -EINVAL;
2082
2083 sock = sockfd_lookup_light(fd, &err, &fput_needed); 2080 sock = sockfd_lookup_light(fd, &err, &fput_needed);
2084 if (!sock) 2081 if (!sock)
2085 goto out; 2082 goto out;
2086 2083
2087 err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL); 2084 err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL);
2088 2085
2089 fput_light(sock->file, fput_needed); 2086 fput_light(sock->file, fput_needed);
2090out: 2087out:
2091 return err; 2088 return err;
2092} 2089}
2093 2090
2091SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags)
2092{
2093 if (flags & MSG_CMSG_COMPAT)
2094 return -EINVAL;
2095 return __sys_sendmsg(fd, msg, flags);
2096}
2097
2094/* 2098/*
2095 * Linux sendmmsg interface 2099 * Linux sendmmsg interface
2096 */ 2100 */
@@ -2121,15 +2125,16 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
2121 2125
2122 while (datagrams < vlen) { 2126 while (datagrams < vlen) {
2123 if (MSG_CMSG_COMPAT & flags) { 2127 if (MSG_CMSG_COMPAT & flags) {
2124 err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, 2128 err = ___sys_sendmsg(sock, (struct msghdr __user *)compat_entry,
2125 &msg_sys, flags, &used_address); 2129 &msg_sys, flags, &used_address);
2126 if (err < 0) 2130 if (err < 0)
2127 break; 2131 break;
2128 err = __put_user(err, &compat_entry->msg_len); 2132 err = __put_user(err, &compat_entry->msg_len);
2129 ++compat_entry; 2133 ++compat_entry;
2130 } else { 2134 } else {
2131 err = __sys_sendmsg(sock, (struct msghdr __user *)entry, 2135 err = ___sys_sendmsg(sock,
2132 &msg_sys, flags, &used_address); 2136 (struct msghdr __user *)entry,
2137 &msg_sys, flags, &used_address);
2133 if (err < 0) 2138 if (err < 0)
2134 break; 2139 break;
2135 err = put_user(err, &entry->msg_len); 2140 err = put_user(err, &entry->msg_len);
@@ -2158,7 +2163,7 @@ SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
2158 return __sys_sendmmsg(fd, mmsg, vlen, flags); 2163 return __sys_sendmmsg(fd, mmsg, vlen, flags);
2159} 2164}
2160 2165
2161static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg, 2166static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
2162 struct msghdr *msg_sys, unsigned int flags, int nosec) 2167 struct msghdr *msg_sys, unsigned int flags, int nosec)
2163{ 2168{
2164 struct compat_msghdr __user *msg_compat = 2169 struct compat_msghdr __user *msg_compat =
@@ -2250,27 +2255,31 @@ out:
2250 * BSD recvmsg interface 2255 * BSD recvmsg interface
2251 */ 2256 */
2252 2257
2253SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, 2258long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags)
2254 unsigned int, flags)
2255{ 2259{
2256 int fput_needed, err; 2260 int fput_needed, err;
2257 struct msghdr msg_sys; 2261 struct msghdr msg_sys;
2258 struct socket *sock; 2262 struct socket *sock;
2259 2263
2260 if (flags & MSG_CMSG_COMPAT)
2261 return -EINVAL;
2262
2263 sock = sockfd_lookup_light(fd, &err, &fput_needed); 2264 sock = sockfd_lookup_light(fd, &err, &fput_needed);
2264 if (!sock) 2265 if (!sock)
2265 goto out; 2266 goto out;
2266 2267
2267 err = __sys_recvmsg(sock, msg, &msg_sys, flags, 0); 2268 err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0);
2268 2269
2269 fput_light(sock->file, fput_needed); 2270 fput_light(sock->file, fput_needed);
2270out: 2271out:
2271 return err; 2272 return err;
2272} 2273}
2273 2274
2275SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
2276 unsigned int, flags)
2277{
2278 if (flags & MSG_CMSG_COMPAT)
2279 return -EINVAL;
2280 return __sys_recvmsg(fd, msg, flags);
2281}
2282
2274/* 2283/*
2275 * Linux recvmmsg interface 2284 * Linux recvmmsg interface
2276 */ 2285 */
@@ -2308,17 +2317,18 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
2308 * No need to ask LSM for more than the first datagram. 2317 * No need to ask LSM for more than the first datagram.
2309 */ 2318 */
2310 if (MSG_CMSG_COMPAT & flags) { 2319 if (MSG_CMSG_COMPAT & flags) {
2311 err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry, 2320 err = ___sys_recvmsg(sock, (struct msghdr __user *)compat_entry,
2312 &msg_sys, flags & ~MSG_WAITFORONE, 2321 &msg_sys, flags & ~MSG_WAITFORONE,
2313 datagrams); 2322 datagrams);
2314 if (err < 0) 2323 if (err < 0)
2315 break; 2324 break;
2316 err = __put_user(err, &compat_entry->msg_len); 2325 err = __put_user(err, &compat_entry->msg_len);
2317 ++compat_entry; 2326 ++compat_entry;
2318 } else { 2327 } else {
2319 err = __sys_recvmsg(sock, (struct msghdr __user *)entry, 2328 err = ___sys_recvmsg(sock,
2320 &msg_sys, flags & ~MSG_WAITFORONE, 2329 (struct msghdr __user *)entry,
2321 datagrams); 2330 &msg_sys, flags & ~MSG_WAITFORONE,
2331 datagrams);
2322 if (err < 0) 2332 if (err < 0)
2323 break; 2333 break;
2324 err = put_user(err, &entry->msg_len); 2334 err = put_user(err, &entry->msg_len);
@@ -2505,31 +2515,15 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
2505 (int __user *)a[4]); 2515 (int __user *)a[4]);
2506 break; 2516 break;
2507 case SYS_SENDMSG: 2517 case SYS_SENDMSG:
2508 if (a[2] & MSG_CMSG_COMPAT) {
2509 err = -EINVAL;
2510 break;
2511 }
2512 err = sys_sendmsg(a0, (struct msghdr __user *)a1, a[2]); 2518 err = sys_sendmsg(a0, (struct msghdr __user *)a1, a[2]);
2513 break; 2519 break;
2514 case SYS_SENDMMSG: 2520 case SYS_SENDMMSG:
2515 if (a[3] & MSG_CMSG_COMPAT) {
2516 err = -EINVAL;
2517 break;
2518 }
2519 err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]); 2521 err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]);
2520 break; 2522 break;
2521 case SYS_RECVMSG: 2523 case SYS_RECVMSG:
2522 if (a[2] & MSG_CMSG_COMPAT) {
2523 err = -EINVAL;
2524 break;
2525 }
2526 err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]); 2524 err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]);
2527 break; 2525 break;
2528 case SYS_RECVMMSG: 2526 case SYS_RECVMMSG:
2529 if (a[3] & MSG_CMSG_COMPAT) {
2530 err = -EINVAL;
2531 break;
2532 }
2533 err = sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3], 2527 err = sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3],
2534 (struct timespec __user *)a[4]); 2528 (struct timespec __user *)a[4]);
2535 break; 2529 break;
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 7da6b457f66a..fc2f78d6a9b4 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -52,6 +52,8 @@
52#include <linux/sunrpc/gss_api.h> 52#include <linux/sunrpc/gss_api.h>
53#include <asm/uaccess.h> 53#include <asm/uaccess.h>
54 54
55#include "../netns.h"
56
55static const struct rpc_authops authgss_ops; 57static const struct rpc_authops authgss_ops;
56 58
57static const struct rpc_credops gss_credops; 59static const struct rpc_credops gss_credops;
@@ -85,8 +87,6 @@ struct gss_auth {
85}; 87};
86 88
87/* pipe_version >= 0 if and only if someone has a pipe open. */ 89/* pipe_version >= 0 if and only if someone has a pipe open. */
88static int pipe_version = -1;
89static atomic_t pipe_users = ATOMIC_INIT(0);
90static DEFINE_SPINLOCK(pipe_version_lock); 90static DEFINE_SPINLOCK(pipe_version_lock);
91static struct rpc_wait_queue pipe_version_rpc_waitqueue; 91static struct rpc_wait_queue pipe_version_rpc_waitqueue;
92static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue); 92static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue);
@@ -266,24 +266,27 @@ struct gss_upcall_msg {
266 char databuf[UPCALL_BUF_LEN]; 266 char databuf[UPCALL_BUF_LEN];
267}; 267};
268 268
269static int get_pipe_version(void) 269static int get_pipe_version(struct net *net)
270{ 270{
271 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
271 int ret; 272 int ret;
272 273
273 spin_lock(&pipe_version_lock); 274 spin_lock(&pipe_version_lock);
274 if (pipe_version >= 0) { 275 if (sn->pipe_version >= 0) {
275 atomic_inc(&pipe_users); 276 atomic_inc(&sn->pipe_users);
276 ret = pipe_version; 277 ret = sn->pipe_version;
277 } else 278 } else
278 ret = -EAGAIN; 279 ret = -EAGAIN;
279 spin_unlock(&pipe_version_lock); 280 spin_unlock(&pipe_version_lock);
280 return ret; 281 return ret;
281} 282}
282 283
283static void put_pipe_version(void) 284static void put_pipe_version(struct net *net)
284{ 285{
285 if (atomic_dec_and_lock(&pipe_users, &pipe_version_lock)) { 286 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
286 pipe_version = -1; 287
288 if (atomic_dec_and_lock(&sn->pipe_users, &pipe_version_lock)) {
289 sn->pipe_version = -1;
287 spin_unlock(&pipe_version_lock); 290 spin_unlock(&pipe_version_lock);
288 } 291 }
289} 292}
@@ -291,9 +294,10 @@ static void put_pipe_version(void)
291static void 294static void
292gss_release_msg(struct gss_upcall_msg *gss_msg) 295gss_release_msg(struct gss_upcall_msg *gss_msg)
293{ 296{
297 struct net *net = rpc_net_ns(gss_msg->auth->client);
294 if (!atomic_dec_and_test(&gss_msg->count)) 298 if (!atomic_dec_and_test(&gss_msg->count))
295 return; 299 return;
296 put_pipe_version(); 300 put_pipe_version(net);
297 BUG_ON(!list_empty(&gss_msg->list)); 301 BUG_ON(!list_empty(&gss_msg->list));
298 if (gss_msg->ctx != NULL) 302 if (gss_msg->ctx != NULL)
299 gss_put_ctx(gss_msg->ctx); 303 gss_put_ctx(gss_msg->ctx);
@@ -439,7 +443,10 @@ static void gss_encode_msg(struct gss_upcall_msg *gss_msg,
439 struct rpc_clnt *clnt, 443 struct rpc_clnt *clnt,
440 const char *service_name) 444 const char *service_name)
441{ 445{
442 if (pipe_version == 0) 446 struct net *net = rpc_net_ns(clnt);
447 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
448
449 if (sn->pipe_version == 0)
443 gss_encode_v0_msg(gss_msg); 450 gss_encode_v0_msg(gss_msg);
444 else /* pipe_version == 1 */ 451 else /* pipe_version == 1 */
445 gss_encode_v1_msg(gss_msg, clnt, service_name); 452 gss_encode_v1_msg(gss_msg, clnt, service_name);
@@ -455,7 +462,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt,
455 gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS); 462 gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS);
456 if (gss_msg == NULL) 463 if (gss_msg == NULL)
457 return ERR_PTR(-ENOMEM); 464 return ERR_PTR(-ENOMEM);
458 vers = get_pipe_version(); 465 vers = get_pipe_version(rpc_net_ns(clnt));
459 if (vers < 0) { 466 if (vers < 0) {
460 kfree(gss_msg); 467 kfree(gss_msg);
461 return ERR_PTR(vers); 468 return ERR_PTR(vers);
@@ -559,24 +566,34 @@ out:
559static inline int 566static inline int
560gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) 567gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
561{ 568{
569 struct net *net = rpc_net_ns(gss_auth->client);
570 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
562 struct rpc_pipe *pipe; 571 struct rpc_pipe *pipe;
563 struct rpc_cred *cred = &gss_cred->gc_base; 572 struct rpc_cred *cred = &gss_cred->gc_base;
564 struct gss_upcall_msg *gss_msg; 573 struct gss_upcall_msg *gss_msg;
574 unsigned long timeout;
565 DEFINE_WAIT(wait); 575 DEFINE_WAIT(wait);
566 int err = 0; 576 int err;
567 577
568 dprintk("RPC: %s for uid %u\n", 578 dprintk("RPC: %s for uid %u\n",
569 __func__, from_kuid(&init_user_ns, cred->cr_uid)); 579 __func__, from_kuid(&init_user_ns, cred->cr_uid));
570retry: 580retry:
581 err = 0;
582 /* Default timeout is 15s unless we know that gssd is not running */
583 timeout = 15 * HZ;
584 if (!sn->gssd_running)
585 timeout = HZ >> 2;
571 gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred); 586 gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred);
572 if (PTR_ERR(gss_msg) == -EAGAIN) { 587 if (PTR_ERR(gss_msg) == -EAGAIN) {
573 err = wait_event_interruptible_timeout(pipe_version_waitqueue, 588 err = wait_event_interruptible_timeout(pipe_version_waitqueue,
574 pipe_version >= 0, 15*HZ); 589 sn->pipe_version >= 0, timeout);
575 if (pipe_version < 0) { 590 if (sn->pipe_version < 0) {
591 if (err == 0)
592 sn->gssd_running = 0;
576 warn_gssd(); 593 warn_gssd();
577 err = -EACCES; 594 err = -EACCES;
578 } 595 }
579 if (err) 596 if (err < 0)
580 goto out; 597 goto out;
581 goto retry; 598 goto retry;
582 } 599 }
@@ -707,20 +724,22 @@ out:
707 724
708static int gss_pipe_open(struct inode *inode, int new_version) 725static int gss_pipe_open(struct inode *inode, int new_version)
709{ 726{
727 struct net *net = inode->i_sb->s_fs_info;
728 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
710 int ret = 0; 729 int ret = 0;
711 730
712 spin_lock(&pipe_version_lock); 731 spin_lock(&pipe_version_lock);
713 if (pipe_version < 0) { 732 if (sn->pipe_version < 0) {
714 /* First open of any gss pipe determines the version: */ 733 /* First open of any gss pipe determines the version: */
715 pipe_version = new_version; 734 sn->pipe_version = new_version;
716 rpc_wake_up(&pipe_version_rpc_waitqueue); 735 rpc_wake_up(&pipe_version_rpc_waitqueue);
717 wake_up(&pipe_version_waitqueue); 736 wake_up(&pipe_version_waitqueue);
718 } else if (pipe_version != new_version) { 737 } else if (sn->pipe_version != new_version) {
719 /* Trying to open a pipe of a different version */ 738 /* Trying to open a pipe of a different version */
720 ret = -EBUSY; 739 ret = -EBUSY;
721 goto out; 740 goto out;
722 } 741 }
723 atomic_inc(&pipe_users); 742 atomic_inc(&sn->pipe_users);
724out: 743out:
725 spin_unlock(&pipe_version_lock); 744 spin_unlock(&pipe_version_lock);
726 return ret; 745 return ret;
@@ -740,6 +759,7 @@ static int gss_pipe_open_v1(struct inode *inode)
740static void 759static void
741gss_pipe_release(struct inode *inode) 760gss_pipe_release(struct inode *inode)
742{ 761{
762 struct net *net = inode->i_sb->s_fs_info;
743 struct rpc_pipe *pipe = RPC_I(inode)->pipe; 763 struct rpc_pipe *pipe = RPC_I(inode)->pipe;
744 struct gss_upcall_msg *gss_msg; 764 struct gss_upcall_msg *gss_msg;
745 765
@@ -758,7 +778,7 @@ restart:
758 } 778 }
759 spin_unlock(&pipe->lock); 779 spin_unlock(&pipe->lock);
760 780
761 put_pipe_version(); 781 put_pipe_version(net);
762} 782}
763 783
764static void 784static void
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 871c73c92165..29b4ba93ab3c 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -1287,7 +1287,7 @@ static bool use_gss_proxy(struct net *net)
1287 1287
1288#ifdef CONFIG_PROC_FS 1288#ifdef CONFIG_PROC_FS
1289 1289
1290static bool set_gss_proxy(struct net *net, int type) 1290static int set_gss_proxy(struct net *net, int type)
1291{ 1291{
1292 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 1292 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1293 int ret = 0; 1293 int ret = 0;
@@ -1317,10 +1317,12 @@ static inline bool gssp_ready(struct sunrpc_net *sn)
1317 return false; 1317 return false;
1318} 1318}
1319 1319
1320static int wait_for_gss_proxy(struct net *net) 1320static int wait_for_gss_proxy(struct net *net, struct file *file)
1321{ 1321{
1322 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 1322 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1323 1323
1324 if (file->f_flags & O_NONBLOCK && !gssp_ready(sn))
1325 return -EAGAIN;
1324 return wait_event_interruptible(sn->gssp_wq, gssp_ready(sn)); 1326 return wait_event_interruptible(sn->gssp_wq, gssp_ready(sn));
1325} 1327}
1326 1328
@@ -1362,7 +1364,7 @@ static ssize_t read_gssp(struct file *file, char __user *buf,
1362 size_t len; 1364 size_t len;
1363 int ret; 1365 int ret;
1364 1366
1365 ret = wait_for_gss_proxy(net); 1367 ret = wait_for_gss_proxy(net, file);
1366 if (ret) 1368 if (ret)
1367 return ret; 1369 return ret;
1368 1370
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index 7111a4c9113b..74d948f5d5a1 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -28,7 +28,11 @@ struct sunrpc_net {
28 wait_queue_head_t gssp_wq; 28 wait_queue_head_t gssp_wq;
29 struct rpc_clnt *gssp_clnt; 29 struct rpc_clnt *gssp_clnt;
30 int use_gss_proxy; 30 int use_gss_proxy;
31 int pipe_version;
32 atomic_t pipe_users;
31 struct proc_dir_entry *use_gssp_proc; 33 struct proc_dir_entry *use_gssp_proc;
34
35 unsigned int gssd_running;
32}; 36};
33 37
34extern int sunrpc_net_id; 38extern int sunrpc_net_id;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index a9129f8d7070..e7ce4b3eb0bd 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -216,11 +216,14 @@ rpc_destroy_inode(struct inode *inode)
216static int 216static int
217rpc_pipe_open(struct inode *inode, struct file *filp) 217rpc_pipe_open(struct inode *inode, struct file *filp)
218{ 218{
219 struct net *net = inode->i_sb->s_fs_info;
220 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
219 struct rpc_pipe *pipe; 221 struct rpc_pipe *pipe;
220 int first_open; 222 int first_open;
221 int res = -ENXIO; 223 int res = -ENXIO;
222 224
223 mutex_lock(&inode->i_mutex); 225 mutex_lock(&inode->i_mutex);
226 sn->gssd_running = 1;
224 pipe = RPC_I(inode)->pipe; 227 pipe = RPC_I(inode)->pipe;
225 if (pipe == NULL) 228 if (pipe == NULL)
226 goto out; 229 goto out;
@@ -1069,6 +1072,8 @@ void rpc_pipefs_init_net(struct net *net)
1069 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 1072 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1070 1073
1071 mutex_init(&sn->pipefs_sb_lock); 1074 mutex_init(&sn->pipefs_sb_lock);
1075 sn->gssd_running = 1;
1076 sn->pipe_version = -1;
1072} 1077}
1073 1078
1074/* 1079/*
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index f8529fc8e542..5356b120dbf8 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -324,11 +324,17 @@ EXPORT_SYMBOL_GPL(__rpc_wait_for_completion_task);
324 * Note: If the task is ASYNC, and is being made runnable after sitting on an 324 * Note: If the task is ASYNC, and is being made runnable after sitting on an
325 * rpc_wait_queue, this must be called with the queue spinlock held to protect 325 * rpc_wait_queue, this must be called with the queue spinlock held to protect
326 * the wait queue operation. 326 * the wait queue operation.
327 * Note the ordering of rpc_test_and_set_running() and rpc_clear_queued(),
328 * which is needed to ensure that __rpc_execute() doesn't loop (due to the
329 * lockless RPC_IS_QUEUED() test) before we've had a chance to test
330 * the RPC_TASK_RUNNING flag.
327 */ 331 */
328static void rpc_make_runnable(struct rpc_task *task) 332static void rpc_make_runnable(struct rpc_task *task)
329{ 333{
334 bool need_wakeup = !rpc_test_and_set_running(task);
335
330 rpc_clear_queued(task); 336 rpc_clear_queued(task);
331 if (rpc_test_and_set_running(task)) 337 if (!need_wakeup)
332 return; 338 return;
333 if (RPC_IS_ASYNC(task)) { 339 if (RPC_IS_ASYNC(task)) {
334 INIT_WORK(&task->u.tk_work, rpc_async_schedule); 340 INIT_WORK(&task->u.tk_work, rpc_async_schedule);
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index c3f9e1ef7f53..06bdf5a1082c 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -810,11 +810,15 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
810 goto badcred; 810 goto badcred;
811 argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */ 811 argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */
812 argv->iov_len -= slen*4; 812 argv->iov_len -= slen*4;
813 813 /*
814 * Note: we skip uid_valid()/gid_valid() checks here for
815 * backwards compatibility with clients that use -1 id's.
816 * Instead, -1 uid or gid is later mapped to the
817 * (export-specific) anonymous id by nfsd_setuser.
818 * Supplementary gid's will be left alone.
819 */
814 cred->cr_uid = make_kuid(&init_user_ns, svc_getnl(argv)); /* uid */ 820 cred->cr_uid = make_kuid(&init_user_ns, svc_getnl(argv)); /* uid */
815 cred->cr_gid = make_kgid(&init_user_ns, svc_getnl(argv)); /* gid */ 821 cred->cr_gid = make_kgid(&init_user_ns, svc_getnl(argv)); /* gid */
816 if (!uid_valid(cred->cr_uid) || !gid_valid(cred->cr_gid))
817 goto badcred;
818 slen = svc_getnl(argv); /* gids length */ 822 slen = svc_getnl(argv); /* gids length */
819 if (slen > 16 || (len -= (slen + 2)*4) < 0) 823 if (slen > 16 || (len -= (slen + 2)*4) < 0)
820 goto badcred; 824 goto badcred;
@@ -823,8 +827,6 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
823 return SVC_CLOSE; 827 return SVC_CLOSE;
824 for (i = 0; i < slen; i++) { 828 for (i = 0; i < slen; i++) {
825 kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv)); 829 kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv));
826 if (!gid_valid(kgid))
827 goto badcred;
828 GROUP_AT(cred->cr_group_info, i) = kgid; 830 GROUP_AT(cred->cr_group_info, i) = kgid;
829 } 831 }
830 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { 832 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {