SUNRPC refactor rpcauth_checkverf error returns
authorAndy Adamson <andros@netapp.com>
Wed, 14 Aug 2013 15:59:17 +0000 (11:59 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 3 Sep 2013 19:25:09 +0000 (15:25 -0400)
Most of the time an error from the credops crvalidate function means the
server has sent us a garbage verifier. The gss_validate function is the
exception where there is an -EACCES case if the user GSS_context on the client
has expired.

Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/auth_null.c
net/sunrpc/auth_unix.c
net/sunrpc/clnt.c

index a9b1edca917c8d8931bf4ebb9069a9c8538f59d3..30eb502135bb93f4d43b9789936d48bd50459a77 100644 (file)
@@ -1501,6 +1501,7 @@ gss_validate(struct rpc_task *task, __be32 *p)
        struct xdr_netobj mic;
        u32             flav,len;
        u32             maj_stat;
+       __be32          *ret = ERR_PTR(-EIO);
 
        dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
 
@@ -1516,6 +1517,7 @@ gss_validate(struct rpc_task *task, __be32 *p)
        mic.data = (u8 *)p;
        mic.len = len;
 
+       ret = ERR_PTR(-EACCES);
        maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
        if (maj_stat == GSS_S_CONTEXT_EXPIRED)
                clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
@@ -1533,8 +1535,9 @@ gss_validate(struct rpc_task *task, __be32 *p)
        return p + XDR_QUADLEN(len);
 out_bad:
        gss_put_ctx(ctx);
-       dprintk("RPC: %5u %s failed.\n", task->tk_pid, __func__);
-       return NULL;
+       dprintk("RPC: %5u %s failed ret %ld.\n", task->tk_pid, __func__,
+               PTR_ERR(ret));
+       return ret;
 }
 
 static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp,
index 4664eb46baa08c29c1b2320cb5b0c6bbcecc8a91..f0ebe07978a236e66744bc2dfe332a92bfb85d05 100644 (file)
@@ -88,13 +88,13 @@ nul_validate(struct rpc_task *task, __be32 *p)
        flavor = ntohl(*p++);
        if (flavor != RPC_AUTH_NULL) {
                printk("RPC: bad verf flavor: %u\n", flavor);
-               return NULL;
+               return ERR_PTR(-EIO);
        }
 
        size = ntohl(*p++);
        if (size != 0) {
                printk("RPC: bad verf size: %u\n", size);
-               return NULL;
+               return ERR_PTR(-EIO);
        }
 
        return p;
index e52d832f9a2a1c6c27c9bd007ec98c2109a4e87f..d5d692366294bacf976ed53fbb83fb1ecbb5ef61 100644 (file)
@@ -192,13 +192,13 @@ unx_validate(struct rpc_task *task, __be32 *p)
            flavor != RPC_AUTH_UNIX &&
            flavor != RPC_AUTH_SHORT) {
                printk("RPC: bad verf flavor: %u\n", flavor);
-               return NULL;
+               return ERR_PTR(-EIO);
        }
 
        size = ntohl(*p++);
        if (size > RPC_MAX_AUTH_SIZE) {
                printk("RPC: giant verf size: %u\n", size);
-               return NULL;
+               return ERR_PTR(-EIO);
        }
        task->tk_rqstp->rq_cred->cr_auth->au_rslack = (size >> 2) + 2;
        p += (size >> 2);
index 631085ff0ad98e2a702c8baa3e4bf66527b9883e..0cd5b6d5c75e3c5bd76b6b722fbd5d65dcd89950 100644 (file)
@@ -2072,7 +2072,8 @@ rpc_verify_header(struct rpc_task *task)
                dprintk("RPC: %5u %s: XDR representation not a multiple of"
                       " 4 bytes: 0x%x\n", task->tk_pid, __func__,
                       task->tk_rqstp->rq_rcv_buf.len);
-               goto out_eio;
+               error = -EIO;
+               goto out_err;
        }
        if ((len -= 3) < 0)
                goto out_overflow;
@@ -2081,6 +2082,7 @@ rpc_verify_header(struct rpc_task *task)
        if ((n = ntohl(*p++)) != RPC_REPLY) {
                dprintk("RPC: %5u %s: not an RPC reply: %x\n",
                        task->tk_pid, __func__, n);
+               error = -EIO;
                goto out_garbage;
        }
 
@@ -2099,7 +2101,8 @@ rpc_verify_header(struct rpc_task *task)
                        dprintk("RPC: %5u %s: RPC call rejected, "
                                "unknown error: %x\n",
                                task->tk_pid, __func__, n);
-                       goto out_eio;
+                       error = -EIO;
+                       goto out_err;
                }
                if (--len < 0)
                        goto out_overflow;
@@ -2144,9 +2147,11 @@ rpc_verify_header(struct rpc_task *task)
                                task->tk_pid, __func__, n);
                goto out_err;
        }
-       if (!(p = rpcauth_checkverf(task, p))) {
-               dprintk("RPC: %5u %s: auth check failed\n",
-                               task->tk_pid, __func__);
+       p = rpcauth_checkverf(task, p);
+       if (IS_ERR(p)) {
+               error = PTR_ERR(p);
+               dprintk("RPC: %5u %s: auth check failed with %d\n",
+                               task->tk_pid, __func__, error);
                goto out_garbage;               /* bad verifier, retry */
        }
        len = p - (__be32 *)iov->iov_base - 1;
@@ -2199,8 +2204,6 @@ out_garbage:
 out_retry:
                return ERR_PTR(-EAGAIN);
        }
-out_eio:
-       error = -EIO;
 out_err:
        rpc_exit(task, error);
        dprintk("RPC: %5u %s: call failed with error %d\n", task->tk_pid,