Commit 35fa5f7b authored by Andy Adamson's avatar Andy Adamson Committed by Trond Myklebust

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: default avatarAndy Adamson <andros@netapp.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent dc24826b
...@@ -1501,6 +1501,7 @@ gss_validate(struct rpc_task *task, __be32 *p) ...@@ -1501,6 +1501,7 @@ gss_validate(struct rpc_task *task, __be32 *p)
struct xdr_netobj mic; struct xdr_netobj mic;
u32 flav,len; u32 flav,len;
u32 maj_stat; u32 maj_stat;
__be32 *ret = ERR_PTR(-EIO);
dprintk("RPC: %5u %s\n", task->tk_pid, __func__); dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
...@@ -1516,6 +1517,7 @@ gss_validate(struct rpc_task *task, __be32 *p) ...@@ -1516,6 +1517,7 @@ gss_validate(struct rpc_task *task, __be32 *p)
mic.data = (u8 *)p; mic.data = (u8 *)p;
mic.len = len; mic.len = len;
ret = ERR_PTR(-EACCES);
maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic); maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
if (maj_stat == GSS_S_CONTEXT_EXPIRED) if (maj_stat == GSS_S_CONTEXT_EXPIRED)
clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
...@@ -1533,8 +1535,9 @@ gss_validate(struct rpc_task *task, __be32 *p) ...@@ -1533,8 +1535,9 @@ gss_validate(struct rpc_task *task, __be32 *p)
return p + XDR_QUADLEN(len); return p + XDR_QUADLEN(len);
out_bad: out_bad:
gss_put_ctx(ctx); gss_put_ctx(ctx);
dprintk("RPC: %5u %s failed.\n", task->tk_pid, __func__); dprintk("RPC: %5u %s failed ret %ld.\n", task->tk_pid, __func__,
return NULL; PTR_ERR(ret));
return ret;
} }
static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp, static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp,
......
...@@ -88,13 +88,13 @@ nul_validate(struct rpc_task *task, __be32 *p) ...@@ -88,13 +88,13 @@ nul_validate(struct rpc_task *task, __be32 *p)
flavor = ntohl(*p++); flavor = ntohl(*p++);
if (flavor != RPC_AUTH_NULL) { if (flavor != RPC_AUTH_NULL) {
printk("RPC: bad verf flavor: %u\n", flavor); printk("RPC: bad verf flavor: %u\n", flavor);
return NULL; return ERR_PTR(-EIO);
} }
size = ntohl(*p++); size = ntohl(*p++);
if (size != 0) { if (size != 0) {
printk("RPC: bad verf size: %u\n", size); printk("RPC: bad verf size: %u\n", size);
return NULL; return ERR_PTR(-EIO);
} }
return p; return p;
......
...@@ -192,13 +192,13 @@ unx_validate(struct rpc_task *task, __be32 *p) ...@@ -192,13 +192,13 @@ unx_validate(struct rpc_task *task, __be32 *p)
flavor != RPC_AUTH_UNIX && flavor != RPC_AUTH_UNIX &&
flavor != RPC_AUTH_SHORT) { flavor != RPC_AUTH_SHORT) {
printk("RPC: bad verf flavor: %u\n", flavor); printk("RPC: bad verf flavor: %u\n", flavor);
return NULL; return ERR_PTR(-EIO);
} }
size = ntohl(*p++); size = ntohl(*p++);
if (size > RPC_MAX_AUTH_SIZE) { if (size > RPC_MAX_AUTH_SIZE) {
printk("RPC: giant verf size: %u\n", 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; task->tk_rqstp->rq_cred->cr_auth->au_rslack = (size >> 2) + 2;
p += (size >> 2); p += (size >> 2);
......
...@@ -2072,7 +2072,8 @@ rpc_verify_header(struct rpc_task *task) ...@@ -2072,7 +2072,8 @@ rpc_verify_header(struct rpc_task *task)
dprintk("RPC: %5u %s: XDR representation not a multiple of" dprintk("RPC: %5u %s: XDR representation not a multiple of"
" 4 bytes: 0x%x\n", task->tk_pid, __func__, " 4 bytes: 0x%x\n", task->tk_pid, __func__,
task->tk_rqstp->rq_rcv_buf.len); task->tk_rqstp->rq_rcv_buf.len);
goto out_eio; error = -EIO;
goto out_err;
} }
if ((len -= 3) < 0) if ((len -= 3) < 0)
goto out_overflow; goto out_overflow;
...@@ -2081,6 +2082,7 @@ rpc_verify_header(struct rpc_task *task) ...@@ -2081,6 +2082,7 @@ rpc_verify_header(struct rpc_task *task)
if ((n = ntohl(*p++)) != RPC_REPLY) { if ((n = ntohl(*p++)) != RPC_REPLY) {
dprintk("RPC: %5u %s: not an RPC reply: %x\n", dprintk("RPC: %5u %s: not an RPC reply: %x\n",
task->tk_pid, __func__, n); task->tk_pid, __func__, n);
error = -EIO;
goto out_garbage; goto out_garbage;
} }
...@@ -2099,7 +2101,8 @@ rpc_verify_header(struct rpc_task *task) ...@@ -2099,7 +2101,8 @@ rpc_verify_header(struct rpc_task *task)
dprintk("RPC: %5u %s: RPC call rejected, " dprintk("RPC: %5u %s: RPC call rejected, "
"unknown error: %x\n", "unknown error: %x\n",
task->tk_pid, __func__, n); task->tk_pid, __func__, n);
goto out_eio; error = -EIO;
goto out_err;
} }
if (--len < 0) if (--len < 0)
goto out_overflow; goto out_overflow;
...@@ -2144,9 +2147,11 @@ rpc_verify_header(struct rpc_task *task) ...@@ -2144,9 +2147,11 @@ rpc_verify_header(struct rpc_task *task)
task->tk_pid, __func__, n); task->tk_pid, __func__, n);
goto out_err; goto out_err;
} }
if (!(p = rpcauth_checkverf(task, p))) { p = rpcauth_checkverf(task, p);
dprintk("RPC: %5u %s: auth check failed\n", if (IS_ERR(p)) {
task->tk_pid, __func__); 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 */ goto out_garbage; /* bad verifier, retry */
} }
len = p - (__be32 *)iov->iov_base - 1; len = p - (__be32 *)iov->iov_base - 1;
...@@ -2199,8 +2204,6 @@ rpc_verify_header(struct rpc_task *task) ...@@ -2199,8 +2204,6 @@ rpc_verify_header(struct rpc_task *task)
out_retry: out_retry:
return ERR_PTR(-EAGAIN); return ERR_PTR(-EAGAIN);
} }
out_eio:
error = -EIO;
out_err: out_err:
rpc_exit(task, error); rpc_exit(task, error);
dprintk("RPC: %5u %s: call failed with error %d\n", task->tk_pid, dprintk("RPC: %5u %s: call failed with error %d\n", task->tk_pid,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment