aboutsummaryrefslogtreecommitdiffstats
path: root/fs/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 /fs/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 'fs/9p')
-rw-r--r--fs/9p/fid.c17
-rw-r--r--fs/9p/v9fs.c34
-rw-r--r--fs/9p/v9fs.h10
-rw-r--r--fs/9p/vfs_inode.c6
-rw-r--r--fs/9p/vfs_inode_dotl.c10
5 files changed, 49 insertions, 28 deletions
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index da8eefbe830d..afd4724b2d92 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -74,19 +74,20 @@ int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
74 * 74 *
75 */ 75 */
76 76
77static struct p9_fid *v9fs_fid_find(struct dentry *dentry, u32 uid, int any) 77static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
78{ 78{
79 struct v9fs_dentry *dent; 79 struct v9fs_dentry *dent;
80 struct p9_fid *fid, *ret; 80 struct p9_fid *fid, *ret;
81 81
82 p9_debug(P9_DEBUG_VFS, " dentry: %s (%p) uid %d any %d\n", 82 p9_debug(P9_DEBUG_VFS, " dentry: %s (%p) uid %d any %d\n",
83 dentry->d_name.name, dentry, uid, any); 83 dentry->d_name.name, dentry, from_kuid(&init_user_ns, uid),
84 any);
84 dent = (struct v9fs_dentry *) dentry->d_fsdata; 85 dent = (struct v9fs_dentry *) dentry->d_fsdata;
85 ret = NULL; 86 ret = NULL;
86 if (dent) { 87 if (dent) {
87 spin_lock(&dent->lock); 88 spin_lock(&dent->lock);
88 list_for_each_entry(fid, &dent->fidlist, dlist) { 89 list_for_each_entry(fid, &dent->fidlist, dlist) {
89 if (any || fid->uid == uid) { 90 if (any || uid_eq(fid->uid, uid)) {
90 ret = fid; 91 ret = fid;
91 break; 92 break;
92 } 93 }
@@ -126,7 +127,7 @@ err_out:
126} 127}
127 128
128static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry, 129static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
129 uid_t uid, int any) 130 kuid_t uid, int any)
130{ 131{
131 struct dentry *ds; 132 struct dentry *ds;
132 char **wnames, *uname; 133 char **wnames, *uname;
@@ -233,7 +234,7 @@ err_out:
233 234
234struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) 235struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
235{ 236{
236 uid_t uid; 237 kuid_t uid;
237 int any, access; 238 int any, access;
238 struct v9fs_session_info *v9ses; 239 struct v9fs_session_info *v9ses;
239 240
@@ -253,7 +254,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
253 break; 254 break;
254 255
255 default: 256 default:
256 uid = ~0; 257 uid = INVALID_UID;
257 any = 0; 258 any = 0;
258 break; 259 break;
259 } 260 }
@@ -272,7 +273,7 @@ struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
272 return ret; 273 return ret;
273} 274}
274 275
275static struct p9_fid *v9fs_fid_clone_with_uid(struct dentry *dentry, uid_t uid) 276static struct p9_fid *v9fs_fid_clone_with_uid(struct dentry *dentry, kuid_t uid)
276{ 277{
277 struct p9_fid *fid, *ret; 278 struct p9_fid *fid, *ret;
278 279
@@ -289,7 +290,7 @@ struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
289 int err; 290 int err;
290 struct p9_fid *fid; 291 struct p9_fid *fid;
291 292
292 fid = v9fs_fid_clone_with_uid(dentry, 0); 293 fid = v9fs_fid_clone_with_uid(dentry, GLOBAL_ROOT_UID);
293 if (IS_ERR(fid)) 294 if (IS_ERR(fid))
294 goto error_out; 295 goto error_out;
295 /* 296 /*
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index d934f04e7736..58e6cbce4156 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -161,7 +161,13 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
161 ret = r; 161 ret = r;
162 continue; 162 continue;
163 } 163 }
164 v9ses->dfltuid = option; 164 v9ses->dfltuid = make_kuid(current_user_ns(), option);
165 if (!uid_valid(v9ses->dfltuid)) {
166 p9_debug(P9_DEBUG_ERROR,
167 "uid field, but not a uid?\n");
168 ret = -EINVAL;
169 continue;
170 }
165 break; 171 break;
166 case Opt_dfltgid: 172 case Opt_dfltgid:
167 r = match_int(&args[0], &option); 173 r = match_int(&args[0], &option);
@@ -171,7 +177,13 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
171 ret = r; 177 ret = r;
172 continue; 178 continue;
173 } 179 }
174 v9ses->dfltgid = option; 180 v9ses->dfltgid = make_kgid(current_user_ns(), option);
181 if (!gid_valid(v9ses->dfltgid)) {
182 p9_debug(P9_DEBUG_ERROR,
183 "gid field, but not a gid?\n");
184 ret = -EINVAL;
185 continue;
186 }
175 break; 187 break;
176 case Opt_afid: 188 case Opt_afid:
177 r = match_int(&args[0], &option); 189 r = match_int(&args[0], &option);
@@ -248,8 +260,9 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
248 else if (strcmp(s, "client") == 0) { 260 else if (strcmp(s, "client") == 0) {
249 v9ses->flags |= V9FS_ACCESS_CLIENT; 261 v9ses->flags |= V9FS_ACCESS_CLIENT;
250 } else { 262 } else {
263 uid_t uid;
251 v9ses->flags |= V9FS_ACCESS_SINGLE; 264 v9ses->flags |= V9FS_ACCESS_SINGLE;
252 v9ses->uid = simple_strtoul(s, &e, 10); 265 uid = simple_strtoul(s, &e, 10);
253 if (*e != '\0') { 266 if (*e != '\0') {
254 ret = -EINVAL; 267 ret = -EINVAL;
255 pr_info("Unknown access argument %s\n", 268 pr_info("Unknown access argument %s\n",
@@ -257,6 +270,13 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
257 kfree(s); 270 kfree(s);
258 goto free_and_return; 271 goto free_and_return;
259 } 272 }
273 v9ses->uid = make_kuid(current_user_ns(), uid);
274 if (!uid_valid(v9ses->uid)) {
275 ret = -EINVAL;
276 pr_info("Uknown uid %s\n", s);
277 kfree(s);
278 goto free_and_return;
279 }
260 } 280 }
261 281
262 kfree(s); 282 kfree(s);
@@ -319,7 +339,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
319 list_add(&v9ses->slist, &v9fs_sessionlist); 339 list_add(&v9ses->slist, &v9fs_sessionlist);
320 spin_unlock(&v9fs_sessionlist_lock); 340 spin_unlock(&v9fs_sessionlist_lock);
321 341
322 v9ses->uid = ~0; 342 v9ses->uid = INVALID_UID;
323 v9ses->dfltuid = V9FS_DEFUID; 343 v9ses->dfltuid = V9FS_DEFUID;
324 v9ses->dfltgid = V9FS_DEFGID; 344 v9ses->dfltgid = V9FS_DEFGID;
325 345
@@ -364,7 +384,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
364 384
365 v9ses->flags &= ~V9FS_ACCESS_MASK; 385 v9ses->flags &= ~V9FS_ACCESS_MASK;
366 v9ses->flags |= V9FS_ACCESS_ANY; 386 v9ses->flags |= V9FS_ACCESS_ANY;
367 v9ses->uid = ~0; 387 v9ses->uid = INVALID_UID;
368 } 388 }
369 if (!v9fs_proto_dotl(v9ses) || 389 if (!v9fs_proto_dotl(v9ses) ||
370 !((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) { 390 !((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) {
@@ -375,7 +395,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
375 v9ses->flags &= ~V9FS_ACL_MASK; 395 v9ses->flags &= ~V9FS_ACL_MASK;
376 } 396 }
377 397
378 fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, ~0, 398 fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, INVALID_UID,
379 v9ses->aname); 399 v9ses->aname);
380 if (IS_ERR(fid)) { 400 if (IS_ERR(fid)) {
381 retval = PTR_ERR(fid); 401 retval = PTR_ERR(fid);
@@ -387,7 +407,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
387 if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_SINGLE) 407 if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_SINGLE)
388 fid->uid = v9ses->uid; 408 fid->uid = v9ses->uid;
389 else 409 else
390 fid->uid = ~0; 410 fid->uid = INVALID_UID;
391 411
392#ifdef CONFIG_9P_FSCACHE 412#ifdef CONFIG_9P_FSCACHE
393 /* register the session for caching */ 413 /* register the session for caching */
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index 34c59f14a1c9..a8e127c89627 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -109,9 +109,9 @@ struct v9fs_session_info {
109 char *uname; /* user name to mount as */ 109 char *uname; /* user name to mount as */
110 char *aname; /* name of remote hierarchy being mounted */ 110 char *aname; /* name of remote hierarchy being mounted */
111 unsigned int maxdata; /* max data for client interface */ 111 unsigned int maxdata; /* max data for client interface */
112 unsigned int dfltuid; /* default uid/muid for legacy support */ 112 kuid_t dfltuid; /* default uid/muid for legacy support */
113 unsigned int dfltgid; /* default gid for legacy support */ 113 kgid_t dfltgid; /* default gid for legacy support */
114 u32 uid; /* if ACCESS_SINGLE, the uid that has access */ 114 kuid_t uid; /* if ACCESS_SINGLE, the uid that has access */
115 struct p9_client *clnt; /* 9p client */ 115 struct p9_client *clnt; /* 9p client */
116 struct list_head slist; /* list of sessions registered with v9fs */ 116 struct list_head slist; /* list of sessions registered with v9fs */
117 struct backing_dev_info bdi; 117 struct backing_dev_info bdi;
@@ -165,8 +165,8 @@ extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,
165#define V9FS_PORT 564 165#define V9FS_PORT 564
166#define V9FS_DEFUSER "nobody" 166#define V9FS_DEFUSER "nobody"
167#define V9FS_DEFANAME "" 167#define V9FS_DEFANAME ""
168#define V9FS_DEFUID (-2) 168#define V9FS_DEFUID KUIDT_INIT(-2)
169#define V9FS_DEFGID (-2) 169#define V9FS_DEFGID KGIDT_INIT(-2)
170 170
171static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode) 171static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode)
172{ 172{
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 57d017ac68e4..b5340c829de1 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -225,9 +225,9 @@ v9fs_blank_wstat(struct p9_wstat *wstat)
225 wstat->uid = NULL; 225 wstat->uid = NULL;
226 wstat->gid = NULL; 226 wstat->gid = NULL;
227 wstat->muid = NULL; 227 wstat->muid = NULL;
228 wstat->n_uid = ~0; 228 wstat->n_uid = INVALID_UID;
229 wstat->n_gid = ~0; 229 wstat->n_gid = INVALID_GID;
230 wstat->n_muid = ~0; 230 wstat->n_muid = INVALID_UID;
231 wstat->extension = NULL; 231 wstat->extension = NULL;
232} 232}
233 233
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index 8d24ad66dfb8..07f409288d1b 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -57,7 +57,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
57 * group of the new file system object. 57 * group of the new file system object.
58 */ 58 */
59 59
60static gid_t v9fs_get_fsgid_for_create(struct inode *dir_inode) 60static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
61{ 61{
62 BUG_ON(dir_inode == NULL); 62 BUG_ON(dir_inode == NULL);
63 63
@@ -245,7 +245,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
245 int *opened) 245 int *opened)
246{ 246{
247 int err = 0; 247 int err = 0;
248 gid_t gid; 248 kgid_t gid;
249 umode_t mode; 249 umode_t mode;
250 char *name = NULL; 250 char *name = NULL;
251 struct p9_qid qid; 251 struct p9_qid qid;
@@ -396,7 +396,7 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
396 int err; 396 int err;
397 struct v9fs_session_info *v9ses; 397 struct v9fs_session_info *v9ses;
398 struct p9_fid *fid = NULL, *dfid = NULL; 398 struct p9_fid *fid = NULL, *dfid = NULL;
399 gid_t gid; 399 kgid_t gid;
400 char *name; 400 char *name;
401 umode_t mode; 401 umode_t mode;
402 struct inode *inode; 402 struct inode *inode;
@@ -697,7 +697,7 @@ v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
697 const char *symname) 697 const char *symname)
698{ 698{
699 int err; 699 int err;
700 gid_t gid; 700 kgid_t gid;
701 char *name; 701 char *name;
702 struct p9_qid qid; 702 struct p9_qid qid;
703 struct inode *inode; 703 struct inode *inode;
@@ -837,7 +837,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
837 dev_t rdev) 837 dev_t rdev)
838{ 838{
839 int err; 839 int err;
840 gid_t gid; 840 kgid_t gid;
841 char *name; 841 char *name;
842 umode_t mode; 842 umode_t mode;
843 struct v9fs_session_info *v9ses; 843 struct v9fs_session_info *v9ses;