diff options
author | J. Bruce Fields <bfields@redhat.com> | 2013-08-23 11:17:53 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2013-09-06 11:45:57 -0400 |
commit | 6a36978e6931e6601be586eb313375335f2cfaa3 (patch) | |
tree | 537c869b262ebdcbd97ada7697fa6b05a15735ce /net/sunrpc/auth_gss | |
parent | 778e512bb1d3315c6b55832248cd30c566c081d7 (diff) |
rpc: comment on linux_cred encoding, treat all as unsigned
The encoding of linux creds is a bit confusing.
Also: I think in practice it doesn't really matter whether we treat any
of these things as signed or unsigned, but unsigned seems more
straightforward: uid_t/gid_t are unsigned and it simplifies the ngroups
overflow check.
Tested-by: Simo Sorce <simo@redhat.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net/sunrpc/auth_gss')
-rw-r--r-- | net/sunrpc/auth_gss/gss_rpc_xdr.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c index f5067b2e0a08..3c19c7d48899 100644 --- a/net/sunrpc/auth_gss/gss_rpc_xdr.c +++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c | |||
@@ -166,14 +166,15 @@ static int dummy_dec_opt_array(struct xdr_stream *xdr, | |||
166 | return 0; | 166 | return 0; |
167 | } | 167 | } |
168 | 168 | ||
169 | static int get_s32(struct xdr_stream *xdr, s32 *res) | 169 | static int get_host_u32(struct xdr_stream *xdr, u32 *res) |
170 | { | 170 | { |
171 | __be32 *p; | 171 | __be32 *p; |
172 | 172 | ||
173 | p = xdr_inline_decode(xdr, 4); | 173 | p = xdr_inline_decode(xdr, 4); |
174 | if (!p) | 174 | if (!p) |
175 | return -EINVAL; | 175 | return -EINVAL; |
176 | memcpy(res, p, sizeof(s32)); | 176 | /* Contents of linux creds are all host-endian: */ |
177 | memcpy(res, p, sizeof(u32)); | ||
177 | return 0; | 178 | return 0; |
178 | } | 179 | } |
179 | 180 | ||
@@ -182,8 +183,9 @@ static int gssx_dec_linux_creds(struct xdr_stream *xdr, | |||
182 | { | 183 | { |
183 | u32 length; | 184 | u32 length; |
184 | __be32 *p; | 185 | __be32 *p; |
185 | s32 tmp; | 186 | u32 tmp; |
186 | int N, i, err; | 187 | u32 N; |
188 | int i, err; | ||
187 | 189 | ||
188 | p = xdr_inline_decode(xdr, 4); | 190 | p = xdr_inline_decode(xdr, 4); |
189 | if (unlikely(p == NULL)) | 191 | if (unlikely(p == NULL)) |
@@ -195,19 +197,19 @@ static int gssx_dec_linux_creds(struct xdr_stream *xdr, | |||
195 | return -ENOSPC; | 197 | return -ENOSPC; |
196 | 198 | ||
197 | /* uid */ | 199 | /* uid */ |
198 | err = get_s32(xdr, &tmp); | 200 | err = get_host_u32(xdr, &tmp); |
199 | if (err) | 201 | if (err) |
200 | return err; | 202 | return err; |
201 | creds->cr_uid = make_kuid(&init_user_ns, tmp); | 203 | creds->cr_uid = make_kuid(&init_user_ns, tmp); |
202 | 204 | ||
203 | /* gid */ | 205 | /* gid */ |
204 | err = get_s32(xdr, &tmp); | 206 | err = get_host_u32(xdr, &tmp); |
205 | if (err) | 207 | if (err) |
206 | return err; | 208 | return err; |
207 | creds->cr_gid = make_kgid(&init_user_ns, tmp); | 209 | creds->cr_gid = make_kgid(&init_user_ns, tmp); |
208 | 210 | ||
209 | /* number of additional gid's */ | 211 | /* number of additional gid's */ |
210 | err = get_s32(xdr, &tmp); | 212 | err = get_host_u32(xdr, &tmp); |
211 | if (err) | 213 | if (err) |
212 | return err; | 214 | return err; |
213 | N = tmp; | 215 | N = tmp; |
@@ -220,7 +222,7 @@ static int gssx_dec_linux_creds(struct xdr_stream *xdr, | |||
220 | /* gid's */ | 222 | /* gid's */ |
221 | for (i = 0; i < N; i++) { | 223 | for (i = 0; i < N; i++) { |
222 | kgid_t kgid; | 224 | kgid_t kgid; |
223 | err = get_s32(xdr, &tmp); | 225 | err = get_host_u32(xdr, &tmp); |
224 | if (err) | 226 | if (err) |
225 | goto out_free_groups; | 227 | goto out_free_groups; |
226 | err = -EINVAL; | 228 | err = -EINVAL; |