aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2013-08-23 11:17:53 -0400
committerJ. Bruce Fields <bfields@redhat.com>2013-09-06 11:45:57 -0400
commit6a36978e6931e6601be586eb313375335f2cfaa3 (patch)
tree537c869b262ebdcbd97ada7697fa6b05a15735ce /net
parent778e512bb1d3315c6b55832248cd30c566c081d7 (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')
-rw-r--r--net/sunrpc/auth_gss/gss_rpc_xdr.c18
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
169static int get_s32(struct xdr_stream *xdr, s32 *res) 169static 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;