diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2019-02-11 11:24:48 -0500 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2019-02-13 13:45:17 -0500 |
commit | e8680a24a269bd6dcb533f4e4a5faba9ae58925c (patch) | |
tree | 04b8b8e697090b86f314c5ae1e024122c240d3a4 /net/sunrpc/auth_unix.c | |
parent | fe9a270519c72bccb3af524db7ea6c7b67700d50 (diff) |
SUNRPC: Use struct xdr_stream when constructing RPC Call header
Modernize and harden the code path that constructs each RPC Call
message.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'net/sunrpc/auth_unix.c')
-rw-r--r-- | net/sunrpc/auth_unix.c | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index fc8a59134640..1d5b7ed9c6f7 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c | |||
@@ -99,37 +99,55 @@ unx_match(struct auth_cred *acred, struct rpc_cred *cred, int flags) | |||
99 | * Marshal credentials. | 99 | * Marshal credentials. |
100 | * Maybe we should keep a cached credential for performance reasons. | 100 | * Maybe we should keep a cached credential for performance reasons. |
101 | */ | 101 | */ |
102 | static __be32 * | 102 | static int |
103 | unx_marshal(struct rpc_task *task, __be32 *p) | 103 | unx_marshal(struct rpc_task *task, struct xdr_stream *xdr) |
104 | { | 104 | { |
105 | struct rpc_clnt *clnt = task->tk_client; | 105 | struct rpc_clnt *clnt = task->tk_client; |
106 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; | 106 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; |
107 | __be32 *base, *hold; | 107 | __be32 *p, *cred_len, *gidarr_len; |
108 | int i; | 108 | int i; |
109 | struct group_info *gi = cred->cr_cred->group_info; | 109 | struct group_info *gi = cred->cr_cred->group_info; |
110 | 110 | ||
111 | *p++ = htonl(RPC_AUTH_UNIX); | 111 | /* Credential */ |
112 | base = p++; | 112 | |
113 | *p++ = htonl(jiffies/HZ); | 113 | p = xdr_reserve_space(xdr, 3 * sizeof(*p)); |
114 | 114 | if (!p) | |
115 | /* | 115 | goto marshal_failed; |
116 | * Copy the UTS nodename captured when the client was created. | 116 | *p++ = rpc_auth_unix; |
117 | */ | 117 | cred_len = p++; |
118 | p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen); | 118 | *p++ = xdr_zero; /* stamp */ |
119 | 119 | if (xdr_stream_encode_opaque(xdr, clnt->cl_nodename, | |
120 | *p++ = htonl((u32) from_kuid(&init_user_ns, cred->cr_cred->fsuid)); | 120 | clnt->cl_nodelen) < 0) |
121 | *p++ = htonl((u32) from_kgid(&init_user_ns, cred->cr_cred->fsgid)); | 121 | goto marshal_failed; |
122 | hold = p++; | 122 | p = xdr_reserve_space(xdr, 3 * sizeof(*p)); |
123 | if (!p) | ||
124 | goto marshal_failed; | ||
125 | *p++ = cpu_to_be32(from_kuid(&init_user_ns, cred->cr_cred->fsuid)); | ||
126 | *p++ = cpu_to_be32(from_kgid(&init_user_ns, cred->cr_cred->fsgid)); | ||
127 | |||
128 | gidarr_len = p++; | ||
123 | if (gi) | 129 | if (gi) |
124 | for (i = 0; i < UNX_NGROUPS && i < gi->ngroups; i++) | 130 | for (i = 0; i < UNX_NGROUPS && i < gi->ngroups; i++) |
125 | *p++ = htonl((u32) from_kgid(&init_user_ns, gi->gid[i])); | 131 | *p++ = cpu_to_be32(from_kgid(&init_user_ns, |
126 | *hold = htonl(p - hold - 1); /* gid array length */ | 132 | gi->gid[i])); |
127 | *base = htonl((p - base - 1) << 2); /* cred length */ | 133 | *gidarr_len = cpu_to_be32(p - gidarr_len - 1); |
134 | *cred_len = cpu_to_be32((p - cred_len - 1) << 2); | ||
135 | p = xdr_reserve_space(xdr, (p - gidarr_len - 1) << 2); | ||
136 | if (!p) | ||
137 | goto marshal_failed; | ||
138 | |||
139 | /* Verifier */ | ||
140 | |||
141 | p = xdr_reserve_space(xdr, 2 * sizeof(*p)); | ||
142 | if (!p) | ||
143 | goto marshal_failed; | ||
144 | *p++ = rpc_auth_null; | ||
145 | *p = xdr_zero; | ||
128 | 146 | ||
129 | *p++ = htonl(RPC_AUTH_NULL); | 147 | return 0; |
130 | *p++ = htonl(0); | ||
131 | 148 | ||
132 | return p; | 149 | marshal_failed: |
150 | return -EMSGSIZE; | ||
133 | } | 151 | } |
134 | 152 | ||
135 | /* | 153 | /* |
@@ -202,6 +220,7 @@ const struct rpc_credops unix_credops = { | |||
202 | .crdestroy = unx_destroy_cred, | 220 | .crdestroy = unx_destroy_cred, |
203 | .crmatch = unx_match, | 221 | .crmatch = unx_match, |
204 | .crmarshal = unx_marshal, | 222 | .crmarshal = unx_marshal, |
223 | .crwrap_req = rpcauth_wrap_req_encode, | ||
205 | .crrefresh = unx_refresh, | 224 | .crrefresh = unx_refresh, |
206 | .crvalidate = unx_validate, | 225 | .crvalidate = unx_validate, |
207 | }; | 226 | }; |