aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-25 19:00:49 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-25 19:00:49 -0500
commit94f2f14234178f118545a0be60a6371ddeb229b7 (patch)
tree313af6e9e255e9060fc24c836cd71ce712502b17 /net
parent8d168f71551ec2a6528d01d0389b7a73c091e3e7 (diff)
parent139321c65c0584cd65c4c87a5eb3fdb4fdbd0e19 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull user namespace and namespace infrastructure changes from Eric W Biederman: "This set of changes starts with a few small enhnacements to the user namespace. reboot support, allowing more arbitrary mappings, and support for mounting devpts, ramfs, tmpfs, and mqueuefs as just the user namespace root. I do my best to document that if you care about limiting your unprivileged users that when you have the user namespace support enabled you will need to enable memory control groups. There is a minor bug fix to prevent overflowing the stack if someone creates way too many user namespaces. The bulk of the changes are a continuation of the kuid/kgid push down work through the filesystems. These changes make using uids and gids typesafe which ensures that these filesystems are safe to use when multiple user namespaces are in use. The filesystems converted for 3.9 are ceph, 9p, afs, ocfs2, gfs2, ncpfs, nfs, nfsd, and cifs. The changes for these filesystems were a little more involved so I split the changes into smaller hopefully obviously correct changes. XFS is the only filesystem that remains. I was hoping I could get that in this release so that user namespace support would be enabled with an allyesconfig or an allmodconfig but it looks like the xfs changes need another couple of days before it they are ready." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: (93 commits) cifs: Enable building with user namespaces enabled. cifs: Convert struct cifs_ses to use a kuid_t and a kgid_t cifs: Convert struct cifs_sb_info to use kuids and kgids cifs: Modify struct smb_vol to use kuids and kgids cifs: Convert struct cifsFileInfo to use a kuid cifs: Convert struct cifs_fattr to use kuid and kgids cifs: Convert struct tcon_link to use a kuid. cifs: Modify struct cifs_unix_set_info_args to hold a kuid_t and a kgid_t cifs: Convert from a kuid before printing current_fsuid cifs: Use kuids and kgids SID to uid/gid mapping cifs: Pass GLOBAL_ROOT_UID and GLOBAL_ROOT_GID to keyring_alloc cifs: Use BUILD_BUG_ON to validate uids and gids are the same size cifs: Override unmappable incoming uids and gids nfsd: Enable building with user namespaces enabled. nfsd: Properly compare and initialize kuids and kgids nfsd: Store ex_anon_uid and ex_anon_gid as kuids and kgids nfsd: Modify nfsd4_cb_sec to use kuids and kgids nfsd: Handle kuids and kgids in the nfs4acl to posix_acl conversion nfsd: Convert nfsxdr to use kuids and kgids nfsd: Convert nfs3xdr to use kuids and kgids ...
Diffstat (limited to 'net')
-rw-r--r--net/9p/client.c43
-rw-r--r--net/9p/protocol.c49
-rw-r--r--net/ceph/ceph_common.c5
-rw-r--r--net/sunrpc/auth.c6
-rw-r--r--net/sunrpc/auth_generic.c16
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c45
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c18
-rw-r--r--net/sunrpc/auth_unix.c36
-rw-r--r--net/sunrpc/svcauth_unix.c43
9 files changed, 170 insertions, 91 deletions
diff --git a/net/9p/client.c b/net/9p/client.c
index 34d417670935..8eb75425e6e6 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -1100,7 +1100,7 @@ void p9_client_begin_disconnect(struct p9_client *clnt)
1100EXPORT_SYMBOL(p9_client_begin_disconnect); 1100EXPORT_SYMBOL(p9_client_begin_disconnect);
1101 1101
1102struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, 1102struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
1103 char *uname, u32 n_uname, char *aname) 1103 char *uname, kuid_t n_uname, char *aname)
1104{ 1104{
1105 int err = 0; 1105 int err = 0;
1106 struct p9_req_t *req; 1106 struct p9_req_t *req;
@@ -1117,7 +1117,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
1117 goto error; 1117 goto error;
1118 } 1118 }
1119 1119
1120 req = p9_client_rpc(clnt, P9_TATTACH, "ddss?d", fid->fid, 1120 req = p9_client_rpc(clnt, P9_TATTACH, "ddss?u", fid->fid,
1121 afid ? afid->fid : P9_NOFID, uname, aname, n_uname); 1121 afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
1122 if (IS_ERR(req)) { 1122 if (IS_ERR(req)) {
1123 err = PTR_ERR(req); 1123 err = PTR_ERR(req);
@@ -1270,7 +1270,7 @@ error:
1270EXPORT_SYMBOL(p9_client_open); 1270EXPORT_SYMBOL(p9_client_open);
1271 1271
1272int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode, 1272int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode,
1273 gid_t gid, struct p9_qid *qid) 1273 kgid_t gid, struct p9_qid *qid)
1274{ 1274{
1275 int err = 0; 1275 int err = 0;
1276 struct p9_client *clnt; 1276 struct p9_client *clnt;
@@ -1279,13 +1279,14 @@ int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode,
1279 1279
1280 p9_debug(P9_DEBUG_9P, 1280 p9_debug(P9_DEBUG_9P,
1281 ">>> TLCREATE fid %d name %s flags %d mode %d gid %d\n", 1281 ">>> TLCREATE fid %d name %s flags %d mode %d gid %d\n",
1282 ofid->fid, name, flags, mode, gid); 1282 ofid->fid, name, flags, mode,
1283 from_kgid(&init_user_ns, gid));
1283 clnt = ofid->clnt; 1284 clnt = ofid->clnt;
1284 1285
1285 if (ofid->mode != -1) 1286 if (ofid->mode != -1)
1286 return -EINVAL; 1287 return -EINVAL;
1287 1288
1288 req = p9_client_rpc(clnt, P9_TLCREATE, "dsddd", ofid->fid, name, flags, 1289 req = p9_client_rpc(clnt, P9_TLCREATE, "dsddg", ofid->fid, name, flags,
1289 mode, gid); 1290 mode, gid);
1290 if (IS_ERR(req)) { 1291 if (IS_ERR(req)) {
1291 err = PTR_ERR(req); 1292 err = PTR_ERR(req);
@@ -1358,7 +1359,7 @@ error:
1358} 1359}
1359EXPORT_SYMBOL(p9_client_fcreate); 1360EXPORT_SYMBOL(p9_client_fcreate);
1360 1361
1361int p9_client_symlink(struct p9_fid *dfid, char *name, char *symtgt, gid_t gid, 1362int p9_client_symlink(struct p9_fid *dfid, char *name, char *symtgt, kgid_t gid,
1362 struct p9_qid *qid) 1363 struct p9_qid *qid)
1363{ 1364{
1364 int err = 0; 1365 int err = 0;
@@ -1369,7 +1370,7 @@ int p9_client_symlink(struct p9_fid *dfid, char *name, char *symtgt, gid_t gid,
1369 dfid->fid, name, symtgt); 1370 dfid->fid, name, symtgt);
1370 clnt = dfid->clnt; 1371 clnt = dfid->clnt;
1371 1372
1372 req = p9_client_rpc(clnt, P9_TSYMLINK, "dssd", dfid->fid, name, symtgt, 1373 req = p9_client_rpc(clnt, P9_TSYMLINK, "dssg", dfid->fid, name, symtgt,
1373 gid); 1374 gid);
1374 if (IS_ERR(req)) { 1375 if (IS_ERR(req)) {
1375 err = PTR_ERR(req); 1376 err = PTR_ERR(req);
@@ -1710,7 +1711,9 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid)
1710 (unsigned long long)ret->qid.path, ret->qid.version, ret->mode, 1711 (unsigned long long)ret->qid.path, ret->qid.version, ret->mode,
1711 ret->atime, ret->mtime, (unsigned long long)ret->length, 1712 ret->atime, ret->mtime, (unsigned long long)ret->length,
1712 ret->name, ret->uid, ret->gid, ret->muid, ret->extension, 1713 ret->name, ret->uid, ret->gid, ret->muid, ret->extension,
1713 ret->n_uid, ret->n_gid, ret->n_muid); 1714 from_kuid(&init_user_ns, ret->n_uid),
1715 from_kgid(&init_user_ns, ret->n_gid),
1716 from_kuid(&init_user_ns, ret->n_muid));
1714 1717
1715 p9_free_req(clnt, req); 1718 p9_free_req(clnt, req);
1716 return ret; 1719 return ret;
@@ -1764,8 +1767,10 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
1764 "<<< st_btime_sec=%lld st_btime_nsec=%lld\n" 1767 "<<< st_btime_sec=%lld st_btime_nsec=%lld\n"
1765 "<<< st_gen=%lld st_data_version=%lld", 1768 "<<< st_gen=%lld st_data_version=%lld",
1766 ret->st_result_mask, ret->qid.type, ret->qid.path, 1769 ret->st_result_mask, ret->qid.type, ret->qid.path,
1767 ret->qid.version, ret->st_mode, ret->st_nlink, ret->st_uid, 1770 ret->qid.version, ret->st_mode, ret->st_nlink,
1768 ret->st_gid, ret->st_rdev, ret->st_size, ret->st_blksize, 1771 from_kuid(&init_user_ns, ret->st_uid),
1772 from_kgid(&init_user_ns, ret->st_gid),
1773 ret->st_rdev, ret->st_size, ret->st_blksize,
1769 ret->st_blocks, ret->st_atime_sec, ret->st_atime_nsec, 1774 ret->st_blocks, ret->st_atime_sec, ret->st_atime_nsec,
1770 ret->st_mtime_sec, ret->st_mtime_nsec, ret->st_ctime_sec, 1775 ret->st_mtime_sec, ret->st_mtime_nsec, ret->st_ctime_sec,
1771 ret->st_ctime_nsec, ret->st_btime_sec, ret->st_btime_nsec, 1776 ret->st_ctime_nsec, ret->st_btime_sec, ret->st_btime_nsec,
@@ -1828,7 +1833,9 @@ int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst)
1828 (unsigned long long)wst->qid.path, wst->qid.version, wst->mode, 1833 (unsigned long long)wst->qid.path, wst->qid.version, wst->mode,
1829 wst->atime, wst->mtime, (unsigned long long)wst->length, 1834 wst->atime, wst->mtime, (unsigned long long)wst->length,
1830 wst->name, wst->uid, wst->gid, wst->muid, wst->extension, 1835 wst->name, wst->uid, wst->gid, wst->muid, wst->extension,
1831 wst->n_uid, wst->n_gid, wst->n_muid); 1836 from_kuid(&init_user_ns, wst->n_uid),
1837 from_kgid(&init_user_ns, wst->n_gid),
1838 from_kuid(&init_user_ns, wst->n_muid));
1832 1839
1833 req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size+2, wst); 1840 req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size+2, wst);
1834 if (IS_ERR(req)) { 1841 if (IS_ERR(req)) {
@@ -1857,7 +1864,9 @@ int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr)
1857 " valid=%x mode=%x uid=%d gid=%d size=%lld\n" 1864 " valid=%x mode=%x uid=%d gid=%d size=%lld\n"
1858 " atime_sec=%lld atime_nsec=%lld\n" 1865 " atime_sec=%lld atime_nsec=%lld\n"
1859 " mtime_sec=%lld mtime_nsec=%lld\n", 1866 " mtime_sec=%lld mtime_nsec=%lld\n",
1860 p9attr->valid, p9attr->mode, p9attr->uid, p9attr->gid, 1867 p9attr->valid, p9attr->mode,
1868 from_kuid(&init_user_ns, p9attr->uid),
1869 from_kgid(&init_user_ns, p9attr->gid),
1861 p9attr->size, p9attr->atime_sec, p9attr->atime_nsec, 1870 p9attr->size, p9attr->atime_sec, p9attr->atime_nsec,
1862 p9attr->mtime_sec, p9attr->mtime_nsec); 1871 p9attr->mtime_sec, p9attr->mtime_nsec);
1863 1872
@@ -2106,7 +2115,7 @@ error:
2106EXPORT_SYMBOL(p9_client_readdir); 2115EXPORT_SYMBOL(p9_client_readdir);
2107 2116
2108int p9_client_mknod_dotl(struct p9_fid *fid, char *name, int mode, 2117int p9_client_mknod_dotl(struct p9_fid *fid, char *name, int mode,
2109 dev_t rdev, gid_t gid, struct p9_qid *qid) 2118 dev_t rdev, kgid_t gid, struct p9_qid *qid)
2110{ 2119{
2111 int err; 2120 int err;
2112 struct p9_client *clnt; 2121 struct p9_client *clnt;
@@ -2116,7 +2125,7 @@ int p9_client_mknod_dotl(struct p9_fid *fid, char *name, int mode,
2116 clnt = fid->clnt; 2125 clnt = fid->clnt;
2117 p9_debug(P9_DEBUG_9P, ">>> TMKNOD fid %d name %s mode %d major %d " 2126 p9_debug(P9_DEBUG_9P, ">>> TMKNOD fid %d name %s mode %d major %d "
2118 "minor %d\n", fid->fid, name, mode, MAJOR(rdev), MINOR(rdev)); 2127 "minor %d\n", fid->fid, name, mode, MAJOR(rdev), MINOR(rdev));
2119 req = p9_client_rpc(clnt, P9_TMKNOD, "dsdddd", fid->fid, name, mode, 2128 req = p9_client_rpc(clnt, P9_TMKNOD, "dsdddg", fid->fid, name, mode,
2120 MAJOR(rdev), MINOR(rdev), gid); 2129 MAJOR(rdev), MINOR(rdev), gid);
2121 if (IS_ERR(req)) 2130 if (IS_ERR(req))
2122 return PTR_ERR(req); 2131 return PTR_ERR(req);
@@ -2137,7 +2146,7 @@ error:
2137EXPORT_SYMBOL(p9_client_mknod_dotl); 2146EXPORT_SYMBOL(p9_client_mknod_dotl);
2138 2147
2139int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode, 2148int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode,
2140 gid_t gid, struct p9_qid *qid) 2149 kgid_t gid, struct p9_qid *qid)
2141{ 2150{
2142 int err; 2151 int err;
2143 struct p9_client *clnt; 2152 struct p9_client *clnt;
@@ -2146,8 +2155,8 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode,
2146 err = 0; 2155 err = 0;
2147 clnt = fid->clnt; 2156 clnt = fid->clnt;
2148 p9_debug(P9_DEBUG_9P, ">>> TMKDIR fid %d name %s mode %d gid %d\n", 2157 p9_debug(P9_DEBUG_9P, ">>> TMKDIR fid %d name %s mode %d gid %d\n",
2149 fid->fid, name, mode, gid); 2158 fid->fid, name, mode, from_kgid(&init_user_ns, gid));
2150 req = p9_client_rpc(clnt, P9_TMKDIR, "dsdd", fid->fid, name, mode, 2159 req = p9_client_rpc(clnt, P9_TMKDIR, "dsdg", fid->fid, name, mode,
2151 gid); 2160 gid);
2152 if (IS_ERR(req)) 2161 if (IS_ERR(req))
2153 return PTR_ERR(req); 2162 return PTR_ERR(req);
diff --git a/net/9p/protocol.c b/net/9p/protocol.c
index 3d33ecf13327..ab9127ec5b7a 100644
--- a/net/9p/protocol.c
+++ b/net/9p/protocol.c
@@ -85,6 +85,8 @@ pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size)
85 d - int32_t 85 d - int32_t
86 q - int64_t 86 q - int64_t
87 s - string 87 s - string
88 u - numeric uid
89 g - numeric gid
88 S - stat 90 S - stat
89 Q - qid 91 Q - qid
90 D - data blob (int32_t size followed by void *, results are not freed) 92 D - data blob (int32_t size followed by void *, results are not freed)
@@ -163,6 +165,26 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
163 (*sptr)[len] = 0; 165 (*sptr)[len] = 0;
164 } 166 }
165 break; 167 break;
168 case 'u': {
169 kuid_t *uid = va_arg(ap, kuid_t *);
170 __le32 le_val;
171 if (pdu_read(pdu, &le_val, sizeof(le_val))) {
172 errcode = -EFAULT;
173 break;
174 }
175 *uid = make_kuid(&init_user_ns,
176 le32_to_cpu(le_val));
177 } break;
178 case 'g': {
179 kgid_t *gid = va_arg(ap, kgid_t *);
180 __le32 le_val;
181 if (pdu_read(pdu, &le_val, sizeof(le_val))) {
182 errcode = -EFAULT;
183 break;
184 }
185 *gid = make_kgid(&init_user_ns,
186 le32_to_cpu(le_val));
187 } break;
166 case 'Q':{ 188 case 'Q':{
167 struct p9_qid *qid = 189 struct p9_qid *qid =
168 va_arg(ap, struct p9_qid *); 190 va_arg(ap, struct p9_qid *);
@@ -177,11 +199,12 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
177 va_arg(ap, struct p9_wstat *); 199 va_arg(ap, struct p9_wstat *);
178 200
179 memset(stbuf, 0, sizeof(struct p9_wstat)); 201 memset(stbuf, 0, sizeof(struct p9_wstat));
180 stbuf->n_uid = stbuf->n_gid = stbuf->n_muid = 202 stbuf->n_uid = stbuf->n_muid = INVALID_UID;
181 -1; 203 stbuf->n_gid = INVALID_GID;
204
182 errcode = 205 errcode =
183 p9pdu_readf(pdu, proto_version, 206 p9pdu_readf(pdu, proto_version,
184 "wwdQdddqssss?sddd", 207 "wwdQdddqssss?sugu",
185 &stbuf->size, &stbuf->type, 208 &stbuf->size, &stbuf->type,
186 &stbuf->dev, &stbuf->qid, 209 &stbuf->dev, &stbuf->qid,
187 &stbuf->mode, &stbuf->atime, 210 &stbuf->mode, &stbuf->atime,
@@ -294,7 +317,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
294 memset(stbuf, 0, sizeof(struct p9_stat_dotl)); 317 memset(stbuf, 0, sizeof(struct p9_stat_dotl));
295 errcode = 318 errcode =
296 p9pdu_readf(pdu, proto_version, 319 p9pdu_readf(pdu, proto_version,
297 "qQdddqqqqqqqqqqqqqqq", 320 "qQdugqqqqqqqqqqqqqqq",
298 &stbuf->st_result_mask, 321 &stbuf->st_result_mask,
299 &stbuf->qid, 322 &stbuf->qid,
300 &stbuf->st_mode, 323 &stbuf->st_mode,
@@ -377,6 +400,20 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
377 errcode = -EFAULT; 400 errcode = -EFAULT;
378 } 401 }
379 break; 402 break;
403 case 'u': {
404 kuid_t uid = va_arg(ap, kuid_t);
405 __le32 val = cpu_to_le32(
406 from_kuid(&init_user_ns, uid));
407 if (pdu_write(pdu, &val, sizeof(val)))
408 errcode = -EFAULT;
409 } break;
410 case 'g': {
411 kgid_t gid = va_arg(ap, kgid_t);
412 __le32 val = cpu_to_le32(
413 from_kgid(&init_user_ns, gid));
414 if (pdu_write(pdu, &val, sizeof(val)))
415 errcode = -EFAULT;
416 } break;
380 case 'Q':{ 417 case 'Q':{
381 const struct p9_qid *qid = 418 const struct p9_qid *qid =
382 va_arg(ap, const struct p9_qid *); 419 va_arg(ap, const struct p9_qid *);
@@ -390,7 +427,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
390 va_arg(ap, const struct p9_wstat *); 427 va_arg(ap, const struct p9_wstat *);
391 errcode = 428 errcode =
392 p9pdu_writef(pdu, proto_version, 429 p9pdu_writef(pdu, proto_version,
393 "wwdQdddqssss?sddd", 430 "wwdQdddqssss?sugu",
394 stbuf->size, stbuf->type, 431 stbuf->size, stbuf->type,
395 stbuf->dev, &stbuf->qid, 432 stbuf->dev, &stbuf->qid,
396 stbuf->mode, stbuf->atime, 433 stbuf->mode, stbuf->atime,
@@ -468,7 +505,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
468 struct p9_iattr_dotl *); 505 struct p9_iattr_dotl *);
469 506
470 errcode = p9pdu_writef(pdu, proto_version, 507 errcode = p9pdu_writef(pdu, proto_version,
471 "ddddqqqqq", 508 "ddugqqqqq",
472 p9attr->valid, 509 p9attr->valid,
473 p9attr->mode, 510 p9attr->mode,
474 p9attr->uid, 511 p9attr->uid,
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index ee71ea26777a..1deb29af82fd 100644
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -15,6 +15,8 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/statfs.h> 16#include <linux/statfs.h>
17#include <linux/string.h> 17#include <linux/string.h>
18#include <linux/nsproxy.h>
19#include <net/net_namespace.h>
18 20
19 21
20#include <linux/ceph/ceph_features.h> 22#include <linux/ceph/ceph_features.h>
@@ -292,6 +294,9 @@ ceph_parse_options(char *options, const char *dev_name,
292 int err = -ENOMEM; 294 int err = -ENOMEM;
293 substring_t argstr[MAX_OPT_ARGS]; 295 substring_t argstr[MAX_OPT_ARGS];
294 296
297 if (current->nsproxy->net_ns != &init_net)
298 return ERR_PTR(-EINVAL);
299
295 opt = kzalloc(sizeof(*opt), GFP_KERNEL); 300 opt = kzalloc(sizeof(*opt), GFP_KERNEL);
296 if (!opt) 301 if (!opt)
297 return ERR_PTR(-ENOMEM); 302 return ERR_PTR(-ENOMEM);
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index b5c067bccc45..392adc41e2e5 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -412,7 +412,7 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
412 *entry, *new; 412 *entry, *new;
413 unsigned int nr; 413 unsigned int nr;
414 414
415 nr = hash_long(acred->uid, cache->hashbits); 415 nr = hash_long(from_kuid(&init_user_ns, acred->uid), cache->hashbits);
416 416
417 rcu_read_lock(); 417 rcu_read_lock();
418 hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) { 418 hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) {
@@ -519,8 +519,8 @@ rpcauth_bind_root_cred(struct rpc_task *task, int lookupflags)
519{ 519{
520 struct rpc_auth *auth = task->tk_client->cl_auth; 520 struct rpc_auth *auth = task->tk_client->cl_auth;
521 struct auth_cred acred = { 521 struct auth_cred acred = {
522 .uid = 0, 522 .uid = GLOBAL_ROOT_UID,
523 .gid = 0, 523 .gid = GLOBAL_ROOT_GID,
524 }; 524 };
525 525
526 dprintk("RPC: %5u looking up %s cred\n", 526 dprintk("RPC: %5u looking up %s cred\n",
diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c
index 6ed6f201b022..b6badafc6494 100644
--- a/net/sunrpc/auth_generic.c
+++ b/net/sunrpc/auth_generic.c
@@ -18,8 +18,8 @@
18# define RPCDBG_FACILITY RPCDBG_AUTH 18# define RPCDBG_FACILITY RPCDBG_AUTH
19#endif 19#endif
20 20
21#define RPC_MACHINE_CRED_USERID ((uid_t)0) 21#define RPC_MACHINE_CRED_USERID GLOBAL_ROOT_UID
22#define RPC_MACHINE_CRED_GROUPID ((gid_t)0) 22#define RPC_MACHINE_CRED_GROUPID GLOBAL_ROOT_GID
23 23
24struct generic_cred { 24struct generic_cred {
25 struct rpc_cred gc_base; 25 struct rpc_cred gc_base;
@@ -96,7 +96,9 @@ generic_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
96 96
97 dprintk("RPC: allocated %s cred %p for uid %d gid %d\n", 97 dprintk("RPC: allocated %s cred %p for uid %d gid %d\n",
98 gcred->acred.machine_cred ? "machine" : "generic", 98 gcred->acred.machine_cred ? "machine" : "generic",
99 gcred, acred->uid, acred->gid); 99 gcred,
100 from_kuid(&init_user_ns, acred->uid),
101 from_kgid(&init_user_ns, acred->gid));
100 return &gcred->gc_base; 102 return &gcred->gc_base;
101} 103}
102 104
@@ -129,8 +131,8 @@ machine_cred_match(struct auth_cred *acred, struct generic_cred *gcred, int flag
129{ 131{
130 if (!gcred->acred.machine_cred || 132 if (!gcred->acred.machine_cred ||
131 gcred->acred.principal != acred->principal || 133 gcred->acred.principal != acred->principal ||
132 gcred->acred.uid != acred->uid || 134 !uid_eq(gcred->acred.uid, acred->uid) ||
133 gcred->acred.gid != acred->gid) 135 !gid_eq(gcred->acred.gid, acred->gid))
134 return 0; 136 return 0;
135 return 1; 137 return 1;
136} 138}
@@ -147,8 +149,8 @@ generic_match(struct auth_cred *acred, struct rpc_cred *cred, int flags)
147 if (acred->machine_cred) 149 if (acred->machine_cred)
148 return machine_cred_match(acred, gcred, flags); 150 return machine_cred_match(acred, gcred, flags);
149 151
150 if (gcred->acred.uid != acred->uid || 152 if (!uid_eq(gcred->acred.uid, acred->uid) ||
151 gcred->acred.gid != acred->gid || 153 !gid_eq(gcred->acred.gid, acred->gid) ||
152 gcred->acred.machine_cred != 0) 154 gcred->acred.machine_cred != 0)
153 goto out_nomatch; 155 goto out_nomatch;
154 156
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 911ef008b701..6ea29f4ed6c0 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -255,7 +255,7 @@ err:
255 255
256struct gss_upcall_msg { 256struct gss_upcall_msg {
257 atomic_t count; 257 atomic_t count;
258 uid_t uid; 258 kuid_t uid;
259 struct rpc_pipe_msg msg; 259 struct rpc_pipe_msg msg;
260 struct list_head list; 260 struct list_head list;
261 struct gss_auth *auth; 261 struct gss_auth *auth;
@@ -302,11 +302,11 @@ gss_release_msg(struct gss_upcall_msg *gss_msg)
302} 302}
303 303
304static struct gss_upcall_msg * 304static struct gss_upcall_msg *
305__gss_find_upcall(struct rpc_pipe *pipe, uid_t uid) 305__gss_find_upcall(struct rpc_pipe *pipe, kuid_t uid)
306{ 306{
307 struct gss_upcall_msg *pos; 307 struct gss_upcall_msg *pos;
308 list_for_each_entry(pos, &pipe->in_downcall, list) { 308 list_for_each_entry(pos, &pipe->in_downcall, list) {
309 if (pos->uid != uid) 309 if (!uid_eq(pos->uid, uid))
310 continue; 310 continue;
311 atomic_inc(&pos->count); 311 atomic_inc(&pos->count);
312 dprintk("RPC: %s found msg %p\n", __func__, pos); 312 dprintk("RPC: %s found msg %p\n", __func__, pos);
@@ -394,8 +394,11 @@ gss_upcall_callback(struct rpc_task *task)
394 394
395static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg) 395static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg)
396{ 396{
397 gss_msg->msg.data = &gss_msg->uid; 397 uid_t uid = from_kuid(&init_user_ns, gss_msg->uid);
398 gss_msg->msg.len = sizeof(gss_msg->uid); 398 memcpy(gss_msg->databuf, &uid, sizeof(uid));
399 gss_msg->msg.data = gss_msg->databuf;
400 gss_msg->msg.len = sizeof(uid);
401 BUG_ON(sizeof(uid) > UPCALL_BUF_LEN);
399} 402}
400 403
401static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, 404static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
@@ -408,7 +411,7 @@ static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
408 411
409 gss_msg->msg.len = sprintf(gss_msg->databuf, "mech=%s uid=%d ", 412 gss_msg->msg.len = sprintf(gss_msg->databuf, "mech=%s uid=%d ",
410 mech->gm_name, 413 mech->gm_name,
411 gss_msg->uid); 414 from_kuid(&init_user_ns, gss_msg->uid));
412 p += gss_msg->msg.len; 415 p += gss_msg->msg.len;
413 if (clnt->cl_principal) { 416 if (clnt->cl_principal) {
414 len = sprintf(p, "target=%s ", clnt->cl_principal); 417 len = sprintf(p, "target=%s ", clnt->cl_principal);
@@ -444,7 +447,7 @@ static void gss_encode_msg(struct gss_upcall_msg *gss_msg,
444 447
445static struct gss_upcall_msg * 448static struct gss_upcall_msg *
446gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt, 449gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt,
447 uid_t uid, const char *service_name) 450 kuid_t uid, const char *service_name)
448{ 451{
449 struct gss_upcall_msg *gss_msg; 452 struct gss_upcall_msg *gss_msg;
450 int vers; 453 int vers;
@@ -474,7 +477,7 @@ gss_setup_upcall(struct rpc_clnt *clnt, struct gss_auth *gss_auth, struct rpc_cr
474 struct gss_cred *gss_cred = container_of(cred, 477 struct gss_cred *gss_cred = container_of(cred,
475 struct gss_cred, gc_base); 478 struct gss_cred, gc_base);
476 struct gss_upcall_msg *gss_new, *gss_msg; 479 struct gss_upcall_msg *gss_new, *gss_msg;
477 uid_t uid = cred->cr_uid; 480 kuid_t uid = cred->cr_uid;
478 481
479 gss_new = gss_alloc_msg(gss_auth, clnt, uid, gss_cred->gc_principal); 482 gss_new = gss_alloc_msg(gss_auth, clnt, uid, gss_cred->gc_principal);
480 if (IS_ERR(gss_new)) 483 if (IS_ERR(gss_new))
@@ -516,7 +519,7 @@ gss_refresh_upcall(struct rpc_task *task)
516 int err = 0; 519 int err = 0;
517 520
518 dprintk("RPC: %5u %s for uid %u\n", 521 dprintk("RPC: %5u %s for uid %u\n",
519 task->tk_pid, __func__, cred->cr_uid); 522 task->tk_pid, __func__, from_kuid(&init_user_ns, cred->cr_uid));
520 gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred); 523 gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred);
521 if (PTR_ERR(gss_msg) == -EAGAIN) { 524 if (PTR_ERR(gss_msg) == -EAGAIN) {
522 /* XXX: warning on the first, under the assumption we 525 /* XXX: warning on the first, under the assumption we
@@ -548,7 +551,8 @@ gss_refresh_upcall(struct rpc_task *task)
548 gss_release_msg(gss_msg); 551 gss_release_msg(gss_msg);
549out: 552out:
550 dprintk("RPC: %5u %s for uid %u result %d\n", 553 dprintk("RPC: %5u %s for uid %u result %d\n",
551 task->tk_pid, __func__, cred->cr_uid, err); 554 task->tk_pid, __func__,
555 from_kuid(&init_user_ns, cred->cr_uid), err);
552 return err; 556 return err;
553} 557}
554 558
@@ -561,7 +565,8 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
561 DEFINE_WAIT(wait); 565 DEFINE_WAIT(wait);
562 int err = 0; 566 int err = 0;
563 567
564 dprintk("RPC: %s for uid %u\n", __func__, cred->cr_uid); 568 dprintk("RPC: %s for uid %u\n",
569 __func__, from_kuid(&init_user_ns, cred->cr_uid));
565retry: 570retry:
566 gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred); 571 gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred);
567 if (PTR_ERR(gss_msg) == -EAGAIN) { 572 if (PTR_ERR(gss_msg) == -EAGAIN) {
@@ -603,7 +608,7 @@ out_intr:
603 gss_release_msg(gss_msg); 608 gss_release_msg(gss_msg);
604out: 609out:
605 dprintk("RPC: %s for uid %u result %d\n", 610 dprintk("RPC: %s for uid %u result %d\n",
606 __func__, cred->cr_uid, err); 611 __func__, from_kuid(&init_user_ns, cred->cr_uid), err);
607 return err; 612 return err;
608} 613}
609 614
@@ -617,7 +622,8 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
617 struct gss_upcall_msg *gss_msg; 622 struct gss_upcall_msg *gss_msg;
618 struct rpc_pipe *pipe = RPC_I(filp->f_dentry->d_inode)->pipe; 623 struct rpc_pipe *pipe = RPC_I(filp->f_dentry->d_inode)->pipe;
619 struct gss_cl_ctx *ctx; 624 struct gss_cl_ctx *ctx;
620 uid_t uid; 625 uid_t id;
626 kuid_t uid;
621 ssize_t err = -EFBIG; 627 ssize_t err = -EFBIG;
622 628
623 if (mlen > MSG_BUF_MAXSIZE) 629 if (mlen > MSG_BUF_MAXSIZE)
@@ -632,12 +638,18 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
632 goto err; 638 goto err;
633 639
634 end = (const void *)((char *)buf + mlen); 640 end = (const void *)((char *)buf + mlen);
635 p = simple_get_bytes(buf, end, &uid, sizeof(uid)); 641 p = simple_get_bytes(buf, end, &id, sizeof(id));
636 if (IS_ERR(p)) { 642 if (IS_ERR(p)) {
637 err = PTR_ERR(p); 643 err = PTR_ERR(p);
638 goto err; 644 goto err;
639 } 645 }
640 646
647 uid = make_kuid(&init_user_ns, id);
648 if (!uid_valid(uid)) {
649 err = -EINVAL;
650 goto err;
651 }
652
641 err = -ENOMEM; 653 err = -ENOMEM;
642 ctx = gss_alloc_context(); 654 ctx = gss_alloc_context();
643 if (ctx == NULL) 655 if (ctx == NULL)
@@ -1058,7 +1070,8 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
1058 int err = -ENOMEM; 1070 int err = -ENOMEM;
1059 1071
1060 dprintk("RPC: %s for uid %d, flavor %d\n", 1072 dprintk("RPC: %s for uid %d, flavor %d\n",
1061 __func__, acred->uid, auth->au_flavor); 1073 __func__, from_kuid(&init_user_ns, acred->uid),
1074 auth->au_flavor);
1062 1075
1063 if (!(cred = kzalloc(sizeof(*cred), GFP_NOFS))) 1076 if (!(cred = kzalloc(sizeof(*cred), GFP_NOFS)))
1064 goto out_err; 1077 goto out_err;
@@ -1114,7 +1127,7 @@ out:
1114 } 1127 }
1115 if (gss_cred->gc_principal != NULL) 1128 if (gss_cred->gc_principal != NULL)
1116 return 0; 1129 return 0;
1117 return rc->cr_uid == acred->uid; 1130 return uid_eq(rc->cr_uid, acred->uid);
1118} 1131}
1119 1132
1120/* 1133/*
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 73e957386600..ecd1d58bf611 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -418,6 +418,7 @@ static int rsc_parse(struct cache_detail *cd,
418{ 418{
419 /* contexthandle expiry [ uid gid N <n gids> mechname ...mechdata... ] */ 419 /* contexthandle expiry [ uid gid N <n gids> mechname ...mechdata... ] */
420 char *buf = mesg; 420 char *buf = mesg;
421 int id;
421 int len, rv; 422 int len, rv;
422 struct rsc rsci, *rscp = NULL; 423 struct rsc rsci, *rscp = NULL;
423 time_t expiry; 424 time_t expiry;
@@ -444,7 +445,7 @@ static int rsc_parse(struct cache_detail *cd,
444 goto out; 445 goto out;
445 446
446 /* uid, or NEGATIVE */ 447 /* uid, or NEGATIVE */
447 rv = get_int(&mesg, &rsci.cred.cr_uid); 448 rv = get_int(&mesg, &id);
448 if (rv == -EINVAL) 449 if (rv == -EINVAL)
449 goto out; 450 goto out;
450 if (rv == -ENOENT) 451 if (rv == -ENOENT)
@@ -452,8 +453,16 @@ static int rsc_parse(struct cache_detail *cd,
452 else { 453 else {
453 int N, i; 454 int N, i;
454 455
456 /* uid */
457 rsci.cred.cr_uid = make_kuid(&init_user_ns, id);
458 if (!uid_valid(rsci.cred.cr_uid))
459 goto out;
460
455 /* gid */ 461 /* gid */
456 if (get_int(&mesg, &rsci.cred.cr_gid)) 462 if (get_int(&mesg, &id))
463 goto out;
464 rsci.cred.cr_gid = make_kgid(&init_user_ns, id);
465 if (!gid_valid(rsci.cred.cr_gid))
457 goto out; 466 goto out;
458 467
459 /* number of additional gid's */ 468 /* number of additional gid's */
@@ -467,11 +476,10 @@ static int rsc_parse(struct cache_detail *cd,
467 /* gid's */ 476 /* gid's */
468 status = -EINVAL; 477 status = -EINVAL;
469 for (i=0; i<N; i++) { 478 for (i=0; i<N; i++) {
470 gid_t gid;
471 kgid_t kgid; 479 kgid_t kgid;
472 if (get_int(&mesg, &gid)) 480 if (get_int(&mesg, &id))
473 goto out; 481 goto out;
474 kgid = make_kgid(&init_user_ns, gid); 482 kgid = make_kgid(&init_user_ns, id);
475 if (!gid_valid(kgid)) 483 if (!gid_valid(kgid))
476 goto out; 484 goto out;
477 GROUP_AT(rsci.cred.cr_group_info, i) = kgid; 485 GROUP_AT(rsci.cred.cr_group_info, i) = kgid;
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 52c5abdee211..dc37021fc3e5 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -18,8 +18,8 @@
18 18
19struct unx_cred { 19struct unx_cred {
20 struct rpc_cred uc_base; 20 struct rpc_cred uc_base;
21 gid_t uc_gid; 21 kgid_t uc_gid;
22 gid_t uc_gids[NFS_NGROUPS]; 22 kgid_t uc_gids[NFS_NGROUPS];
23}; 23};
24#define uc_uid uc_base.cr_uid 24#define uc_uid uc_base.cr_uid
25 25
@@ -65,7 +65,8 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
65 unsigned int i; 65 unsigned int i;
66 66
67 dprintk("RPC: allocating UNIX cred for uid %d gid %d\n", 67 dprintk("RPC: allocating UNIX cred for uid %d gid %d\n",
68 acred->uid, acred->gid); 68 from_kuid(&init_user_ns, acred->uid),
69 from_kgid(&init_user_ns, acred->gid));
69 70
70 if (!(cred = kmalloc(sizeof(*cred), GFP_NOFS))) 71 if (!(cred = kmalloc(sizeof(*cred), GFP_NOFS)))
71 return ERR_PTR(-ENOMEM); 72 return ERR_PTR(-ENOMEM);
@@ -79,13 +80,10 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
79 groups = NFS_NGROUPS; 80 groups = NFS_NGROUPS;
80 81
81 cred->uc_gid = acred->gid; 82 cred->uc_gid = acred->gid;
82 for (i = 0; i < groups; i++) { 83 for (i = 0; i < groups; i++)
83 gid_t gid; 84 cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
84 gid = from_kgid(&init_user_ns, GROUP_AT(acred->group_info, i));
85 cred->uc_gids[i] = gid;
86 }
87 if (i < NFS_NGROUPS) 85 if (i < NFS_NGROUPS)
88 cred->uc_gids[i] = NOGROUP; 86 cred->uc_gids[i] = INVALID_GID;
89 87
90 return &cred->uc_base; 88 return &cred->uc_base;
91} 89}
@@ -123,21 +121,17 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
123 unsigned int i; 121 unsigned int i;
124 122
125 123
126 if (cred->uc_uid != acred->uid || cred->uc_gid != acred->gid) 124 if (!uid_eq(cred->uc_uid, acred->uid) || !gid_eq(cred->uc_gid, acred->gid))
127 return 0; 125 return 0;
128 126
129 if (acred->group_info != NULL) 127 if (acred->group_info != NULL)
130 groups = acred->group_info->ngroups; 128 groups = acred->group_info->ngroups;
131 if (groups > NFS_NGROUPS) 129 if (groups > NFS_NGROUPS)
132 groups = NFS_NGROUPS; 130 groups = NFS_NGROUPS;
133 for (i = 0; i < groups ; i++) { 131 for (i = 0; i < groups ; i++)
134 gid_t gid; 132 if (!gid_eq(cred->uc_gids[i], GROUP_AT(acred->group_info, i)))
135 gid = from_kgid(&init_user_ns, GROUP_AT(acred->group_info, i));
136 if (cred->uc_gids[i] != gid)
137 return 0; 133 return 0;
138 } 134 if (groups < NFS_NGROUPS && gid_valid(cred->uc_gids[groups]))
139 if (groups < NFS_NGROUPS &&
140 cred->uc_gids[groups] != NOGROUP)
141 return 0; 135 return 0;
142 return 1; 136 return 1;
143} 137}
@@ -163,11 +157,11 @@ unx_marshal(struct rpc_task *task, __be32 *p)
163 */ 157 */
164 p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen); 158 p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
165 159
166 *p++ = htonl((u32) cred->uc_uid); 160 *p++ = htonl((u32) from_kuid(&init_user_ns, cred->uc_uid));
167 *p++ = htonl((u32) cred->uc_gid); 161 *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gid));
168 hold = p++; 162 hold = p++;
169 for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++) 163 for (i = 0; i < 16 && gid_valid(cred->uc_gids[i]); i++)
170 *p++ = htonl((u32) cred->uc_gids[i]); 164 *p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gids[i]));
171 *hold = htonl(p - hold - 1); /* gid array length */ 165 *hold = htonl(p - hold - 1); /* gid array length */
172 *base = htonl((p - base - 1) << 2); /* cred length */ 166 *base = htonl((p - base - 1) << 2); /* cred length */
173 167
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 4d0129203733..a1852e19ed0c 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -415,10 +415,15 @@ svcauth_unix_info_release(struct svc_xprt *xpt)
415 415
416struct unix_gid { 416struct unix_gid {
417 struct cache_head h; 417 struct cache_head h;
418 uid_t uid; 418 kuid_t uid;
419 struct group_info *gi; 419 struct group_info *gi;
420}; 420};
421 421
422static int unix_gid_hash(kuid_t uid)
423{
424 return hash_long(from_kuid(&init_user_ns, uid), GID_HASHBITS);
425}
426
422static void unix_gid_put(struct kref *kref) 427static void unix_gid_put(struct kref *kref)
423{ 428{
424 struct cache_head *item = container_of(kref, struct cache_head, ref); 429 struct cache_head *item = container_of(kref, struct cache_head, ref);
@@ -433,7 +438,7 @@ static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew)
433{ 438{
434 struct unix_gid *orig = container_of(corig, struct unix_gid, h); 439 struct unix_gid *orig = container_of(corig, struct unix_gid, h);
435 struct unix_gid *new = container_of(cnew, struct unix_gid, h); 440 struct unix_gid *new = container_of(cnew, struct unix_gid, h);
436 return orig->uid == new->uid; 441 return uid_eq(orig->uid, new->uid);
437} 442}
438static void unix_gid_init(struct cache_head *cnew, struct cache_head *citem) 443static void unix_gid_init(struct cache_head *cnew, struct cache_head *citem)
439{ 444{
@@ -465,7 +470,7 @@ static void unix_gid_request(struct cache_detail *cd,
465 char tuid[20]; 470 char tuid[20];
466 struct unix_gid *ug = container_of(h, struct unix_gid, h); 471 struct unix_gid *ug = container_of(h, struct unix_gid, h);
467 472
468 snprintf(tuid, 20, "%u", ug->uid); 473 snprintf(tuid, 20, "%u", from_kuid(&init_user_ns, ug->uid));
469 qword_add(bpp, blen, tuid); 474 qword_add(bpp, blen, tuid);
470 (*bpp)[-1] = '\n'; 475 (*bpp)[-1] = '\n';
471} 476}
@@ -475,13 +480,14 @@ static int unix_gid_upcall(struct cache_detail *cd, struct cache_head *h)
475 return sunrpc_cache_pipe_upcall(cd, h, unix_gid_request); 480 return sunrpc_cache_pipe_upcall(cd, h, unix_gid_request);
476} 481}
477 482
478static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid); 483static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid);
479 484
480static int unix_gid_parse(struct cache_detail *cd, 485static int unix_gid_parse(struct cache_detail *cd,
481 char *mesg, int mlen) 486 char *mesg, int mlen)
482{ 487{
483 /* uid expiry Ngid gid0 gid1 ... gidN-1 */ 488 /* uid expiry Ngid gid0 gid1 ... gidN-1 */
484 int uid; 489 int id;
490 kuid_t uid;
485 int gids; 491 int gids;
486 int rv; 492 int rv;
487 int i; 493 int i;
@@ -493,9 +499,12 @@ static int unix_gid_parse(struct cache_detail *cd,
493 return -EINVAL; 499 return -EINVAL;
494 mesg[mlen-1] = 0; 500 mesg[mlen-1] = 0;
495 501
496 rv = get_int(&mesg, &uid); 502 rv = get_int(&mesg, &id);
497 if (rv) 503 if (rv)
498 return -EINVAL; 504 return -EINVAL;
505 uid = make_kuid(&init_user_ns, id);
506 if (!uid_valid(uid))
507 return -EINVAL;
499 ug.uid = uid; 508 ug.uid = uid;
500 509
501 expiry = get_expiry(&mesg); 510 expiry = get_expiry(&mesg);
@@ -530,7 +539,7 @@ static int unix_gid_parse(struct cache_detail *cd,
530 ug.h.expiry_time = expiry; 539 ug.h.expiry_time = expiry;
531 ch = sunrpc_cache_update(cd, 540 ch = sunrpc_cache_update(cd,
532 &ug.h, &ugp->h, 541 &ug.h, &ugp->h,
533 hash_long(uid, GID_HASHBITS)); 542 unix_gid_hash(uid));
534 if (!ch) 543 if (!ch)
535 err = -ENOMEM; 544 err = -ENOMEM;
536 else { 545 else {
@@ -549,7 +558,7 @@ static int unix_gid_show(struct seq_file *m,
549 struct cache_detail *cd, 558 struct cache_detail *cd,
550 struct cache_head *h) 559 struct cache_head *h)
551{ 560{
552 struct user_namespace *user_ns = current_user_ns(); 561 struct user_namespace *user_ns = &init_user_ns;
553 struct unix_gid *ug; 562 struct unix_gid *ug;
554 int i; 563 int i;
555 int glen; 564 int glen;
@@ -565,7 +574,7 @@ static int unix_gid_show(struct seq_file *m,
565 else 574 else
566 glen = 0; 575 glen = 0;
567 576
568 seq_printf(m, "%u %d:", ug->uid, glen); 577 seq_printf(m, "%u %d:", from_kuid_munged(user_ns, ug->uid), glen);
569 for (i = 0; i < glen; i++) 578 for (i = 0; i < glen; i++)
570 seq_printf(m, " %d", from_kgid_munged(user_ns, GROUP_AT(ug->gi, i))); 579 seq_printf(m, " %d", from_kgid_munged(user_ns, GROUP_AT(ug->gi, i)));
571 seq_printf(m, "\n"); 580 seq_printf(m, "\n");
@@ -615,20 +624,20 @@ void unix_gid_cache_destroy(struct net *net)
615 cache_destroy_net(cd, net); 624 cache_destroy_net(cd, net);
616} 625}
617 626
618static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid) 627static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid)
619{ 628{
620 struct unix_gid ug; 629 struct unix_gid ug;
621 struct cache_head *ch; 630 struct cache_head *ch;
622 631
623 ug.uid = uid; 632 ug.uid = uid;
624 ch = sunrpc_cache_lookup(cd, &ug.h, hash_long(uid, GID_HASHBITS)); 633 ch = sunrpc_cache_lookup(cd, &ug.h, unix_gid_hash(uid));
625 if (ch) 634 if (ch)
626 return container_of(ch, struct unix_gid, h); 635 return container_of(ch, struct unix_gid, h);
627 else 636 else
628 return NULL; 637 return NULL;
629} 638}
630 639
631static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp) 640static struct group_info *unix_gid_find(kuid_t uid, struct svc_rqst *rqstp)
632{ 641{
633 struct unix_gid *ug; 642 struct unix_gid *ug;
634 struct group_info *gi; 643 struct group_info *gi;
@@ -750,8 +759,8 @@ svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp)
750 } 759 }
751 760
752 /* Signal that mapping to nobody uid/gid is required */ 761 /* Signal that mapping to nobody uid/gid is required */
753 cred->cr_uid = (uid_t) -1; 762 cred->cr_uid = INVALID_UID;
754 cred->cr_gid = (gid_t) -1; 763 cred->cr_gid = INVALID_GID;
755 cred->cr_group_info = groups_alloc(0); 764 cred->cr_group_info = groups_alloc(0);
756 if (cred->cr_group_info == NULL) 765 if (cred->cr_group_info == NULL)
757 return SVC_CLOSE; /* kmalloc failure - client must retry */ 766 return SVC_CLOSE; /* kmalloc failure - client must retry */
@@ -812,8 +821,10 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
812 argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */ 821 argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */
813 argv->iov_len -= slen*4; 822 argv->iov_len -= slen*4;
814 823
815 cred->cr_uid = svc_getnl(argv); /* uid */ 824 cred->cr_uid = make_kuid(&init_user_ns, svc_getnl(argv)); /* uid */
816 cred->cr_gid = svc_getnl(argv); /* gid */ 825 cred->cr_gid = make_kgid(&init_user_ns, svc_getnl(argv)); /* gid */
826 if (!uid_valid(cred->cr_uid) || !gid_valid(cred->cr_gid))
827 goto badcred;
817 slen = svc_getnl(argv); /* gids length */ 828 slen = svc_getnl(argv); /* gids length */
818 if (slen > 16 || (len -= (slen + 2)*4) < 0) 829 if (slen > 16 || (len -= (slen + 2)*4) < 0)
819 goto badcred; 830 goto badcred;