aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs
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/afs
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/afs')
-rw-r--r--fs/afs/afs.h11
-rw-r--r--fs/afs/fsclient.c14
-rw-r--r--fs/afs/inode.c6
-rw-r--r--fs/afs/super.c6
4 files changed, 21 insertions, 16 deletions
diff --git a/fs/afs/afs.h b/fs/afs/afs.h
index c548aa346f0d..3c462ff6db63 100644
--- a/fs/afs/afs.h
+++ b/fs/afs/afs.h
@@ -119,8 +119,8 @@ struct afs_file_status {
119 u64 size; /* file size */ 119 u64 size; /* file size */
120 afs_dataversion_t data_version; /* current data version */ 120 afs_dataversion_t data_version; /* current data version */
121 u32 author; /* author ID */ 121 u32 author; /* author ID */
122 u32 owner; /* owner ID */ 122 kuid_t owner; /* owner ID */
123 u32 group; /* group ID */ 123 kgid_t group; /* group ID */
124 afs_access_t caller_access; /* access rights for authenticated caller */ 124 afs_access_t caller_access; /* access rights for authenticated caller */
125 afs_access_t anon_access; /* access rights for unauthenticated caller */ 125 afs_access_t anon_access; /* access rights for unauthenticated caller */
126 umode_t mode; /* UNIX mode */ 126 umode_t mode; /* UNIX mode */
@@ -133,13 +133,6 @@ struct afs_file_status {
133/* 133/*
134 * AFS file status change request 134 * AFS file status change request
135 */ 135 */
136struct afs_store_status {
137 u32 mask; /* which bits of the struct are set */
138 u32 mtime_client; /* last time client changed data */
139 u32 owner; /* owner ID */
140 u32 group; /* group ID */
141 umode_t mode; /* UNIX mode */
142};
143 136
144#define AFS_SET_MTIME 0x01 /* set the mtime */ 137#define AFS_SET_MTIME 0x01 /* set the mtime */
145#define AFS_SET_OWNER 0x02 /* set the owner ID */ 138#define AFS_SET_OWNER 0x02 /* set the owner ID */
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c
index b960ff05ea0b..c2e930ec2888 100644
--- a/fs/afs/fsclient.c
+++ b/fs/afs/fsclient.c
@@ -42,6 +42,8 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
42 umode_t mode; 42 umode_t mode;
43 u64 data_version, size; 43 u64 data_version, size;
44 u32 changed = 0; /* becomes non-zero if ctime-type changes seen */ 44 u32 changed = 0; /* becomes non-zero if ctime-type changes seen */
45 kuid_t owner;
46 kgid_t group;
45 47
46#define EXTRACT(DST) \ 48#define EXTRACT(DST) \
47 do { \ 49 do { \
@@ -56,7 +58,9 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
56 size = ntohl(*bp++); 58 size = ntohl(*bp++);
57 data_version = ntohl(*bp++); 59 data_version = ntohl(*bp++);
58 EXTRACT(status->author); 60 EXTRACT(status->author);
59 EXTRACT(status->owner); 61 owner = make_kuid(&init_user_ns, ntohl(*bp++));
62 changed |= !uid_eq(owner, status->owner);
63 status->owner = owner;
60 EXTRACT(status->caller_access); /* call ticket dependent */ 64 EXTRACT(status->caller_access); /* call ticket dependent */
61 EXTRACT(status->anon_access); 65 EXTRACT(status->anon_access);
62 EXTRACT(status->mode); 66 EXTRACT(status->mode);
@@ -65,7 +69,9 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
65 bp++; /* seg size */ 69 bp++; /* seg size */
66 status->mtime_client = ntohl(*bp++); 70 status->mtime_client = ntohl(*bp++);
67 status->mtime_server = ntohl(*bp++); 71 status->mtime_server = ntohl(*bp++);
68 EXTRACT(status->group); 72 group = make_kgid(&init_user_ns, ntohl(*bp++));
73 changed |= !gid_eq(group, status->group);
74 status->group = group;
69 bp++; /* sync counter */ 75 bp++; /* sync counter */
70 data_version |= (u64) ntohl(*bp++) << 32; 76 data_version |= (u64) ntohl(*bp++) << 32;
71 EXTRACT(status->lock_count); 77 EXTRACT(status->lock_count);
@@ -181,12 +187,12 @@ static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
181 187
182 if (attr->ia_valid & ATTR_UID) { 188 if (attr->ia_valid & ATTR_UID) {
183 mask |= AFS_SET_OWNER; 189 mask |= AFS_SET_OWNER;
184 owner = attr->ia_uid; 190 owner = from_kuid(&init_user_ns, attr->ia_uid);
185 } 191 }
186 192
187 if (attr->ia_valid & ATTR_GID) { 193 if (attr->ia_valid & ATTR_GID) {
188 mask |= AFS_SET_GROUP; 194 mask |= AFS_SET_GROUP;
189 group = attr->ia_gid; 195 group = from_kgid(&init_user_ns, attr->ia_gid);
190 } 196 }
191 197
192 if (attr->ia_valid & ATTR_MODE) { 198 if (attr->ia_valid & ATTR_MODE) {
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index 95cffd38239f..789bc253b5f6 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -69,7 +69,7 @@ static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key)
69 69
70 set_nlink(inode, vnode->status.nlink); 70 set_nlink(inode, vnode->status.nlink);
71 inode->i_uid = vnode->status.owner; 71 inode->i_uid = vnode->status.owner;
72 inode->i_gid = 0; 72 inode->i_gid = GLOBAL_ROOT_GID;
73 inode->i_size = vnode->status.size; 73 inode->i_size = vnode->status.size;
74 inode->i_ctime.tv_sec = vnode->status.mtime_server; 74 inode->i_ctime.tv_sec = vnode->status.mtime_server;
75 inode->i_ctime.tv_nsec = 0; 75 inode->i_ctime.tv_nsec = 0;
@@ -175,8 +175,8 @@ struct inode *afs_iget_autocell(struct inode *dir, const char *dev_name,
175 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO; 175 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
176 inode->i_op = &afs_autocell_inode_operations; 176 inode->i_op = &afs_autocell_inode_operations;
177 set_nlink(inode, 2); 177 set_nlink(inode, 2);
178 inode->i_uid = 0; 178 inode->i_uid = GLOBAL_ROOT_UID;
179 inode->i_gid = 0; 179 inode->i_gid = GLOBAL_ROOT_GID;
180 inode->i_ctime.tv_sec = get_seconds(); 180 inode->i_ctime.tv_sec = get_seconds();
181 inode->i_ctime.tv_nsec = 0; 181 inode->i_ctime.tv_nsec = 0;
182 inode->i_atime = inode->i_mtime = inode->i_ctime; 182 inode->i_atime = inode->i_mtime = inode->i_ctime;
diff --git a/fs/afs/super.c b/fs/afs/super.c
index 43165009428d..7c31ec399575 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -24,6 +24,8 @@
24#include <linux/parser.h> 24#include <linux/parser.h>
25#include <linux/statfs.h> 25#include <linux/statfs.h>
26#include <linux/sched.h> 26#include <linux/sched.h>
27#include <linux/nsproxy.h>
28#include <net/net_namespace.h>
27#include "internal.h" 29#include "internal.h"
28 30
29#define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ 31#define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */
@@ -363,6 +365,10 @@ static struct dentry *afs_mount(struct file_system_type *fs_type,
363 365
364 memset(&params, 0, sizeof(params)); 366 memset(&params, 0, sizeof(params));
365 367
368 ret = -EINVAL;
369 if (current->nsproxy->net_ns != &init_net)
370 goto error;
371
366 /* parse the options and device name */ 372 /* parse the options and device name */
367 if (options) { 373 if (options) {
368 ret = afs_parse_options(&params, options, &dev_name); 374 ret = afs_parse_options(&params, options, &dev_name);