Skip to content

Commit a0584ee

Browse files
chuckleveramschuma-ntap
authored andcommitted
SUNRPC: Use struct xdr_stream when decoding RPC Reply header
Modernize and harden the code path that parses an RPC Reply message. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent 7f5667a commit a0584ee

File tree

7 files changed

+243
-201
lines changed

7 files changed

+243
-201
lines changed

include/linux/sunrpc/auth.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,12 @@ struct rpc_credops {
134134
int (*crmarshal)(struct rpc_task *task,
135135
struct xdr_stream *xdr);
136136
int (*crrefresh)(struct rpc_task *);
137-
__be32 * (*crvalidate)(struct rpc_task *, __be32 *);
137+
int (*crvalidate)(struct rpc_task *task,
138+
struct xdr_stream *xdr);
138139
int (*crwrap_req)(struct rpc_task *task,
139140
struct xdr_stream *xdr);
140-
int (*crunwrap_resp)(struct rpc_task *, kxdrdproc_t,
141-
void *, __be32 *, void *);
141+
int (*crunwrap_resp)(struct rpc_task *task,
142+
struct xdr_stream *xdr);
142143
int (*crkey_timeout)(struct rpc_cred *);
143144
char * (*crstringify_acceptor)(struct rpc_cred *);
144145
bool (*crneed_reencode)(struct rpc_task *);
@@ -168,12 +169,16 @@ struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int);
168169
void put_rpccred(struct rpc_cred *);
169170
int rpcauth_marshcred(struct rpc_task *task,
170171
struct xdr_stream *xdr);
171-
__be32 * rpcauth_checkverf(struct rpc_task *, __be32 *);
172+
int rpcauth_checkverf(struct rpc_task *task,
173+
struct xdr_stream *xdr);
172174
int rpcauth_wrap_req_encode(struct rpc_task *task,
173175
struct xdr_stream *xdr);
174176
int rpcauth_wrap_req(struct rpc_task *task,
175177
struct xdr_stream *xdr);
176-
int rpcauth_unwrap_resp(struct rpc_task *task, kxdrdproc_t decode, void *rqstp, __be32 *data, void *obj);
178+
int rpcauth_unwrap_resp_decode(struct rpc_task *task,
179+
struct xdr_stream *xdr);
180+
int rpcauth_unwrap_resp(struct rpc_task *task,
181+
struct xdr_stream *xdr);
177182
bool rpcauth_xmit_need_reencode(struct rpc_task *task);
178183
int rpcauth_refreshcred(struct rpc_task *);
179184
void rpcauth_invalcred(struct rpc_task *);

include/linux/sunrpc/xdr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ xdr_buf_init(struct xdr_buf *buf, void *start, size_t len)
8989

9090
#define rpc_auth_null cpu_to_be32(RPC_AUTH_NULL)
9191
#define rpc_auth_unix cpu_to_be32(RPC_AUTH_UNIX)
92+
#define rpc_auth_short cpu_to_be32(RPC_AUTH_SHORT)
9293
#define rpc_auth_gss cpu_to_be32(RPC_AUTH_GSS)
9394

9495
#define rpc_call cpu_to_be32(RPC_CALL)

net/sunrpc/auth.c

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include <linux/sunrpc/gss_api.h>
1818
#include <linux/spinlock.h>
1919

20+
#include <trace/events/sunrpc.h>
21+
2022
#define RPC_CREDCACHE_DEFAULT_HASHBITS (4)
2123
struct rpc_cred_cache {
2224
struct hlist_head *hashtable;
@@ -773,14 +775,6 @@ int rpcauth_marshcred(struct rpc_task *task, struct xdr_stream *xdr)
773775
return ops->crmarshal(task, xdr);
774776
}
775777

776-
__be32 *
777-
rpcauth_checkverf(struct rpc_task *task, __be32 *p)
778-
{
779-
struct rpc_cred *cred = task->tk_rqstp->rq_cred;
780-
781-
return cred->cr_ops->crvalidate(task, p);
782-
}
783-
784778
/**
785779
* rpcauth_wrap_req_encode - XDR encode the RPC procedure
786780
* @task: controlling RPC task
@@ -814,27 +808,52 @@ int rpcauth_wrap_req(struct rpc_task *task, struct xdr_stream *xdr)
814808
return ops->crwrap_req(task, xdr);
815809
}
816810

817-
static int
818-
rpcauth_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp,
819-
__be32 *data, void *obj)
811+
/**
812+
* rpcauth_checkverf - Validate verifier in RPC Reply header
813+
* @task: controlling RPC task
814+
* @xdr: xdr_stream containing RPC Reply header
815+
*
816+
* On success, @xdr is updated to point past the verifier and
817+
* zero is returned. Otherwise, @xdr is in an undefined state
818+
* and a negative errno is returned.
819+
*/
820+
int
821+
rpcauth_checkverf(struct rpc_task *task, struct xdr_stream *xdr)
820822
{
821-
struct xdr_stream xdr;
823+
const struct rpc_credops *ops = task->tk_rqstp->rq_cred->cr_ops;
822824

823-
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, data, rqstp);
824-
return decode(rqstp, &xdr, obj);
825+
return ops->crvalidate(task, xdr);
825826
}
826827

828+
/**
829+
* rpcauth_unwrap_resp_decode - Invoke XDR decode function
830+
* @task: controlling RPC task
831+
* @xdr: stream where the Reply message resides
832+
*
833+
* Returns zero on success; otherwise a negative errno is returned.
834+
*/
827835
int
828-
rpcauth_unwrap_resp(struct rpc_task *task, kxdrdproc_t decode, void *rqstp,
829-
__be32 *data, void *obj)
836+
rpcauth_unwrap_resp_decode(struct rpc_task *task, struct xdr_stream *xdr)
830837
{
831-
struct rpc_cred *cred = task->tk_rqstp->rq_cred;
838+
kxdrdproc_t decode = task->tk_msg.rpc_proc->p_decode;
839+
840+
return decode(task->tk_rqstp, xdr, task->tk_msg.rpc_resp);
841+
}
842+
EXPORT_SYMBOL_GPL(rpcauth_unwrap_resp_decode);
843+
844+
/**
845+
* rpcauth_unwrap_resp - Invoke unwrap and decode function for the cred
846+
* @task: controlling RPC task
847+
* @xdr: stream where the Reply message resides
848+
*
849+
* Returns zero on success; otherwise a negative errno is returned.
850+
*/
851+
int
852+
rpcauth_unwrap_resp(struct rpc_task *task, struct xdr_stream *xdr)
853+
{
854+
const struct rpc_credops *ops = task->tk_rqstp->rq_cred->cr_ops;
832855

833-
if (cred->cr_ops->crunwrap_resp)
834-
return cred->cr_ops->crunwrap_resp(task, decode, rqstp,
835-
data, obj);
836-
/* By default, we decode the arguments normally. */
837-
return rpcauth_unwrap_req_decode(decode, rqstp, data, obj);
856+
return ops->crunwrap_resp(task, xdr);
838857
}
839858

840859
bool

0 commit comments

Comments
 (0)