aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2013-08-14 11:59:17 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-09-03 15:25:09 -0400
commit35fa5f7b35ca2076d594b2670a32d66dd3ae9eec (patch)
tree9a0a384c4c00efc3bef6585b6d7f084dad904964
parentdc24826bfca8d788d05f625208f06d90be5560b3 (diff)
SUNRPC refactor rpcauth_checkverf error returns
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>
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c7
-rw-r--r--net/sunrpc/auth_null.c4
-rw-r--r--net/sunrpc/auth_unix.c4
-rw-r--r--net/sunrpc/clnt.c17
4 files changed, 19 insertions, 13 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index a9b1edca917c..30eb502135bb 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -1501,6 +1501,7 @@ gss_validate(struct rpc_task *task, __be32 *p)
1501 struct xdr_netobj mic; 1501 struct xdr_netobj mic;
1502 u32 flav,len; 1502 u32 flav,len;
1503 u32 maj_stat; 1503 u32 maj_stat;
1504 __be32 *ret = ERR_PTR(-EIO);
1504 1505
1505 dprintk("RPC: %5u %s\n", task->tk_pid, __func__); 1506 dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
1506 1507
@@ -1516,6 +1517,7 @@ gss_validate(struct rpc_task *task, __be32 *p)
1516 mic.data = (u8 *)p; 1517 mic.data = (u8 *)p;
1517 mic.len = len; 1518 mic.len = len;
1518 1519
1520 ret = ERR_PTR(-EACCES);
1519 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic); 1521 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
1520 if (maj_stat == GSS_S_CONTEXT_EXPIRED) 1522 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1521 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); 1523 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
@@ -1533,8 +1535,9 @@ gss_validate(struct rpc_task *task, __be32 *p)
1533 return p + XDR_QUADLEN(len); 1535 return p + XDR_QUADLEN(len);
1534out_bad: 1536out_bad:
1535 gss_put_ctx(ctx); 1537 gss_put_ctx(ctx);
1536 dprintk("RPC: %5u %s failed.\n", task->tk_pid, __func__); 1538 dprintk("RPC: %5u %s failed ret %ld.\n", task->tk_pid, __func__,
1537 return NULL; 1539 PTR_ERR(ret));
1540 return ret;
1538} 1541}
1539 1542
1540static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp, 1543static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp,
diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
index 4664eb46baa0..f0ebe07978a2 100644
--- a/net/sunrpc/auth_null.c
+++ b/net/sunrpc/auth_null.c
@@ -88,13 +88,13 @@ nul_validate(struct rpc_task *task, __be32 *p)
88 flavor = ntohl(*p++); 88 flavor = ntohl(*p++);
89 if (flavor != RPC_AUTH_NULL) { 89 if (flavor != RPC_AUTH_NULL) {
90 printk("RPC: bad verf flavor: %u\n", flavor); 90 printk("RPC: bad verf flavor: %u\n", flavor);
91 return NULL; 91 return ERR_PTR(-EIO);
92 } 92 }
93 93
94 size = ntohl(*p++); 94 size = ntohl(*p++);
95 if (size != 0) { 95 if (size != 0) {
96 printk("RPC: bad verf size: %u\n", size); 96 printk("RPC: bad verf size: %u\n", size);
97 return NULL; 97 return ERR_PTR(-EIO);
98 } 98 }
99 99
100 return p; 100 return p;
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index e52d832f9a2a..d5d692366294 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -192,13 +192,13 @@ unx_validate(struct rpc_task *task, __be32 *p)
192 flavor != RPC_AUTH_UNIX && 192 flavor != RPC_AUTH_UNIX &&
193 flavor != RPC_AUTH_SHORT) { 193 flavor != RPC_AUTH_SHORT) {
194 printk("RPC: bad verf flavor: %u\n", flavor); 194 printk("RPC: bad verf flavor: %u\n", flavor);
195 return NULL; 195 return ERR_PTR(-EIO);
196 } 196 }
197 197
198 size = ntohl(*p++); 198 size = ntohl(*p++);
199 if (size > RPC_MAX_AUTH_SIZE) { 199 if (size > RPC_MAX_AUTH_SIZE) {
200 printk("RPC: giant verf size: %u\n", size); 200 printk("RPC: giant verf size: %u\n", size);
201 return NULL; 201 return ERR_PTR(-EIO);
202 } 202 }
203 task->tk_rqstp->rq_cred->cr_auth->au_rslack = (size >> 2) + 2; 203 task->tk_rqstp->rq_cred->cr_auth->au_rslack = (size >> 2) + 2;
204 p += (size >> 2); 204 p += (size >> 2);
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 631085ff0ad9..0cd5b6d5c75e 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -2072,7 +2072,8 @@ rpc_verify_header(struct rpc_task *task)
2072 dprintk("RPC: %5u %s: XDR representation not a multiple of" 2072 dprintk("RPC: %5u %s: XDR representation not a multiple of"
2073 " 4 bytes: 0x%x\n", task->tk_pid, __func__, 2073 " 4 bytes: 0x%x\n", task->tk_pid, __func__,
2074 task->tk_rqstp->rq_rcv_buf.len); 2074 task->tk_rqstp->rq_rcv_buf.len);
2075 goto out_eio; 2075 error = -EIO;
2076 goto out_err;
2076 } 2077 }
2077 if ((len -= 3) < 0) 2078 if ((len -= 3) < 0)
2078 goto out_overflow; 2079 goto out_overflow;
@@ -2081,6 +2082,7 @@ rpc_verify_header(struct rpc_task *task)
2081 if ((n = ntohl(*p++)) != RPC_REPLY) { 2082 if ((n = ntohl(*p++)) != RPC_REPLY) {
2082 dprintk("RPC: %5u %s: not an RPC reply: %x\n", 2083 dprintk("RPC: %5u %s: not an RPC reply: %x\n",
2083 task->tk_pid, __func__, n); 2084 task->tk_pid, __func__, n);
2085 error = -EIO;
2084 goto out_garbage; 2086 goto out_garbage;
2085 } 2087 }
2086 2088
@@ -2099,7 +2101,8 @@ rpc_verify_header(struct rpc_task *task)
2099 dprintk("RPC: %5u %s: RPC call rejected, " 2101 dprintk("RPC: %5u %s: RPC call rejected, "
2100 "unknown error: %x\n", 2102 "unknown error: %x\n",
2101 task->tk_pid, __func__, n); 2103 task->tk_pid, __func__, n);
2102 goto out_eio; 2104 error = -EIO;
2105 goto out_err;
2103 } 2106 }
2104 if (--len < 0) 2107 if (--len < 0)
2105 goto out_overflow; 2108 goto out_overflow;
@@ -2144,9 +2147,11 @@ rpc_verify_header(struct rpc_task *task)
2144 task->tk_pid, __func__, n); 2147 task->tk_pid, __func__, n);
2145 goto out_err; 2148 goto out_err;
2146 } 2149 }
2147 if (!(p = rpcauth_checkverf(task, p))) { 2150 p = rpcauth_checkverf(task, p);
2148 dprintk("RPC: %5u %s: auth check failed\n", 2151 if (IS_ERR(p)) {
2149 task->tk_pid, __func__); 2152 error = PTR_ERR(p);
2153 dprintk("RPC: %5u %s: auth check failed with %d\n",
2154 task->tk_pid, __func__, error);
2150 goto out_garbage; /* bad verifier, retry */ 2155 goto out_garbage; /* bad verifier, retry */
2151 } 2156 }
2152 len = p - (__be32 *)iov->iov_base - 1; 2157 len = p - (__be32 *)iov->iov_base - 1;
@@ -2199,8 +2204,6 @@ out_garbage:
2199out_retry: 2204out_retry:
2200 return ERR_PTR(-EAGAIN); 2205 return ERR_PTR(-EAGAIN);
2201 } 2206 }
2202out_eio:
2203 error = -EIO;
2204out_err: 2207out_err:
2205 rpc_exit(task, error); 2208 rpc_exit(task, error);
2206 dprintk("RPC: %5u %s: call failed with error %d\n", task->tk_pid, 2209 dprintk("RPC: %5u %s: call failed with error %d\n", task->tk_pid,