diff options
author | Andy Adamson <andros@netapp.com> | 2013-08-14 11:59:17 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-09-03 15:25:09 -0400 |
commit | 35fa5f7b35ca2076d594b2670a32d66dd3ae9eec (patch) | |
tree | 9a0a384c4c00efc3bef6585b6d7f084dad904964 | |
parent | dc24826bfca8d788d05f625208f06d90be5560b3 (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.c | 7 | ||||
-rw-r--r-- | net/sunrpc/auth_null.c | 4 | ||||
-rw-r--r-- | net/sunrpc/auth_unix.c | 4 | ||||
-rw-r--r-- | net/sunrpc/clnt.c | 17 |
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); |
1534 | out_bad: | 1536 | out_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 | ||
1540 | static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp, | 1543 | static 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: | |||
2199 | out_retry: | 2204 | out_retry: |
2200 | return ERR_PTR(-EAGAIN); | 2205 | return ERR_PTR(-EAGAIN); |
2201 | } | 2206 | } |
2202 | out_eio: | ||
2203 | error = -EIO; | ||
2204 | out_err: | 2207 | out_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, |