aboutsummaryrefslogtreecommitdiffstats
path: root/net/9p
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/9p
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/9p')
-rw-r--r--net/9p/client.c43
-rw-r--r--net/9p/protocol.c49
2 files changed, 69 insertions, 23 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,