NFS: Fix infinite loop in gss_create_upcall()
authorBryan Schumaker <bjschuma@netapp.com>
Wed, 13 Apr 2011 18:31:28 +0000 (14:31 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 13 Apr 2011 19:12:22 +0000 (15:12 -0400)
There can be an infinite loop if gss_create_upcall() is called without
the userspace program running.  To prevent this, we return -EACCES if
we notice that pipe_version hasn't changed (indicating that the pipe
has not been opened).

Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/nfs4proc.c
net/sunrpc/auth_gss/auth_gss.c

index 9bf41eab3e4646eb1256c1192c4482fc89c4c61d..8a03ee0689f38e04f50bc2478d1ef6587c8db1ee 100644 (file)
@@ -2224,8 +2224,9 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
 
        for (i = 0; i < len; i++) {
                status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]);
-               if (status != -EPERM)
-                       break;
+               if (status == -EPERM || status == -EACCES)
+                       continue;
+               break;
        }
        if (status == 0)
                status = nfs4_server_capabilities(server, fhandle);
index f3914d0c5079596d04af62417ca909693675a64f..339ba64cce1e2ee7134a2c9d09cd64f5fb9cb85e 100644 (file)
@@ -520,7 +520,7 @@ gss_refresh_upcall(struct rpc_task *task)
                warn_gssd();
                task->tk_timeout = 15*HZ;
                rpc_sleep_on(&pipe_version_rpc_waitqueue, task, NULL);
-               return 0;
+               return -EAGAIN;
        }
        if (IS_ERR(gss_msg)) {
                err = PTR_ERR(gss_msg);
@@ -563,10 +563,12 @@ retry:
        if (PTR_ERR(gss_msg) == -EAGAIN) {
                err = wait_event_interruptible_timeout(pipe_version_waitqueue,
                                pipe_version >= 0, 15*HZ);
+               if (pipe_version < 0) {
+                       warn_gssd();
+                       err = -EACCES;
+               }
                if (err)
                        goto out;
-               if (pipe_version < 0)
-                       warn_gssd();
                goto retry;
        }
        if (IS_ERR(gss_msg)) {