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

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
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -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,
+2 −2
Original line number Diff line number Diff line
@@ -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;
+2 −2
Original line number Diff line number Diff line
@@ -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);
+10 −7
Original line number Diff line number Diff line
@@ -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,