linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace
       [not found] <87621w14vs.fsf@xmission.com>
@ 2013-02-13 17:50 ` Eric W. Biederman
  2013-02-13 17:50   ` [PATCH review 02/85] ceph: Translate between uid and gids in cap messages and kuids and kgids Eric W. Biederman
                     ` (83 more replies)
  0 siblings, 84 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:50 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Sage Weil

From: "Eric W. Biederman" <ebiederm@xmission.com>

Today ceph opens tcp sockets from a delayed work callback.  Delayed
work happens from kernel threads which are always in the initial
network namespace.   Therefore fail early if someone attempts
to mount a ceph filesystem from something other than the initial
network namespace.

Cc: Sage Weil <sage@inktank.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 net/ceph/ceph_common.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index ee71ea2..1deb29a 100644
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -15,6 +15,8 @@
 #include <linux/slab.h>
 #include <linux/statfs.h>
 #include <linux/string.h>
+#include <linux/nsproxy.h>
+#include <net/net_namespace.h>
 
 
 #include <linux/ceph/ceph_features.h>
@@ -292,6 +294,9 @@ ceph_parse_options(char *options, const char *dev_name,
 	int err = -ENOMEM;
 	substring_t argstr[MAX_OPT_ARGS];
 
+	if (current->nsproxy->net_ns != &init_net)
+		return ERR_PTR(-EINVAL);
+
 	opt = kzalloc(sizeof(*opt), GFP_KERNEL);
 	if (!opt)
 		return ERR_PTR(-ENOMEM);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 02/85] ceph: Translate between uid and gids in cap messages and kuids and kgids
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
@ 2013-02-13 17:50   ` Eric W. Biederman
  2013-02-13 17:50   ` [PATCH review 03/85] ceph: Translate inode uid and gid attributes to/from " Eric W. Biederman
                     ` (82 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:50 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Sage Weil

From: "Eric W. Biederman" <ebiederm@xmission.com>

- Make the uid and gid arguments of send_cap_msg() used to compose
  ceph_mds_caps messages of type kuid_t and kgid_t.

- Pass inode->i_uid and inode->i_gid in __send_cap to send_cap_msg()
  through variables of type kuid_t and kgid_t.

- Modify struct ceph_cap_snap to store uids and gids in types kuid_t
  and kgid_t.  This allows capturing inode->i_uid and inode->i_gid in
  ceph_queue_cap_snap() without loss and pssing them to
  __ceph_flush_snaps() where they are removed from struct
  ceph_cap_snap and passed to send_cap_msg().

- In handle_cap_grant translate uid and gids in the initial user
  namespace stored in struct ceph_mds_cap into kuids and kgids
  before setting inode->i_uid and inode->i_gid.

Cc: Sage Weil <sage@inktank.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/ceph/caps.c  |   14 +++++++-------
 fs/ceph/super.h |    4 ++--
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index a1d9bb3..39eb466 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -930,7 +930,7 @@ static int send_cap_msg(struct ceph_mds_session *session,
 			u64 size, u64 max_size,
 			struct timespec *mtime, struct timespec *atime,
 			u64 time_warp_seq,
-			uid_t uid, gid_t gid, umode_t mode,
+			kuid_t uid, kgid_t gid, umode_t mode,
 			u64 xattr_version,
 			struct ceph_buffer *xattrs_buf,
 			u64 follows)
@@ -974,8 +974,8 @@ static int send_cap_msg(struct ceph_mds_session *session,
 		ceph_encode_timespec(&fc->atime, atime);
 	fc->time_warp_seq = cpu_to_le32(time_warp_seq);
 
-	fc->uid = cpu_to_le32(uid);
-	fc->gid = cpu_to_le32(gid);
+	fc->uid = cpu_to_le32(from_kuid(&init_user_ns, uid));
+	fc->gid = cpu_to_le32(from_kgid(&init_user_ns, gid));
 	fc->mode = cpu_to_le32(mode);
 
 	fc->xattr_version = cpu_to_le64(xattr_version);
@@ -1081,8 +1081,8 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
 	struct timespec mtime, atime;
 	int wake = 0;
 	umode_t mode;
-	uid_t uid;
-	gid_t gid;
+	kuid_t uid;
+	kgid_t gid;
 	struct ceph_mds_session *session;
 	u64 xattr_version = 0;
 	struct ceph_buffer *xattr_blob = NULL;
@@ -2359,8 +2359,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
 
 	if ((issued & CEPH_CAP_AUTH_EXCL) == 0) {
 		inode->i_mode = le32_to_cpu(grant->mode);
-		inode->i_uid = le32_to_cpu(grant->uid);
-		inode->i_gid = le32_to_cpu(grant->gid);
+		inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(grant->uid));
+		inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(grant->gid));
 		dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode,
 		     inode->i_uid, inode->i_gid);
 	}
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 66ebe72..f053bbd 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -138,8 +138,8 @@ struct ceph_cap_snap {
 	struct ceph_snap_context *context;
 
 	umode_t mode;
-	uid_t uid;
-	gid_t gid;
+	kuid_t uid;
+	kgid_t gid;
 
 	struct ceph_buffer *xattr_blob;
 	u64 xattr_version;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 03/85] ceph: Translate inode uid and gid attributes to/from kuids and kgids.
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
  2013-02-13 17:50   ` [PATCH review 02/85] ceph: Translate between uid and gids in cap messages and kuids and kgids Eric W. Biederman
@ 2013-02-13 17:50   ` Eric W. Biederman
  2013-02-13 17:50   ` [PATCH review 04/85] ceph: Convert struct ceph_mds_request to use kuid_t and kgid_t Eric W. Biederman
                     ` (81 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:50 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Sage Weil

From: "Eric W. Biederman" <ebiederm@xmission.com>

- In fill_inode() transate uids and gids in the initial user namespace
  into kuids and kgids stored in inode->i_uid and inode->i_gid.

- In ceph_setattr() if they have changed convert inode->i_uid and
  inode->i_gid into initial user namespace uids and gids for
  transmission.

Cc: Sage Weil <sage@inktank.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/ceph/inode.c |   14 ++++++++------
 1 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 2971eaa..40e0787 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -612,8 +612,8 @@ static int fill_inode(struct inode *inode,
 
 	if ((issued & CEPH_CAP_AUTH_EXCL) == 0) {
 		inode->i_mode = le32_to_cpu(info->mode);
-		inode->i_uid = le32_to_cpu(info->uid);
-		inode->i_gid = le32_to_cpu(info->gid);
+		inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(info->uid));
+		inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(info->gid));
 		dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode,
 		     inode->i_uid, inode->i_gid);
 	}
@@ -1570,8 +1570,9 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
 			inode->i_uid = attr->ia_uid;
 			dirtied |= CEPH_CAP_AUTH_EXCL;
 		} else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
-			   attr->ia_uid != inode->i_uid) {
-			req->r_args.setattr.uid = cpu_to_le32(attr->ia_uid);
+			   !uid_eq(attr->ia_uid, inode->i_uid)) {
+			req->r_args.setattr.uid = cpu_to_le32(
+				from_kuid(&init_user_ns, attr->ia_uid));
 			mask |= CEPH_SETATTR_UID;
 			release |= CEPH_CAP_AUTH_SHARED;
 		}
@@ -1583,8 +1584,9 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
 			inode->i_gid = attr->ia_gid;
 			dirtied |= CEPH_CAP_AUTH_EXCL;
 		} else if ((issued & CEPH_CAP_AUTH_SHARED) == 0 ||
-			   attr->ia_gid != inode->i_gid) {
-			req->r_args.setattr.gid = cpu_to_le32(attr->ia_gid);
+			   !gid_eq(attr->ia_gid, inode->i_gid)) {
+			req->r_args.setattr.gid = cpu_to_le32(
+				from_kgid(&init_user_ns, attr->ia_gid));
 			mask |= CEPH_SETATTR_GID;
 			release |= CEPH_CAP_AUTH_SHARED;
 		}
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 04/85] ceph: Convert struct ceph_mds_request to use kuid_t and kgid_t
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
  2013-02-13 17:50   ` [PATCH review 02/85] ceph: Translate between uid and gids in cap messages and kuids and kgids Eric W. Biederman
  2013-02-13 17:50   ` [PATCH review 03/85] ceph: Translate inode uid and gid attributes to/from " Eric W. Biederman
@ 2013-02-13 17:50   ` Eric W. Biederman
  2013-02-13 17:50   ` [PATCH review 05/85] ceph: Convert kuids and kgids before printing them Eric W. Biederman
                     ` (80 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:50 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Sage Weil

From: "Eric W. Biederman" <ebiederm@xmission.com>

Hold the uid and gid for a pending ceph mds request using the types
kuid_t and kgid_t.  When a request message is finally created convert
the kuid_t and kgid_t values into uids and gids in the initial user
namespace.

Cc: Sage Weil <sage@inktank.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/ceph/mds_client.c |    4 ++--
 fs/ceph/mds_client.h |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 9165eb8..7a3dfe0 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -1658,8 +1658,8 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
 
 	head->mdsmap_epoch = cpu_to_le32(mdsc->mdsmap->m_epoch);
 	head->op = cpu_to_le32(req->r_op);
-	head->caller_uid = cpu_to_le32(req->r_uid);
-	head->caller_gid = cpu_to_le32(req->r_gid);
+	head->caller_uid = cpu_to_le32(from_kuid(&init_user_ns, req->r_uid));
+	head->caller_gid = cpu_to_le32(from_kgid(&init_user_ns, req->r_gid));
 	head->args = req->r_args;
 
 	ceph_encode_filepath(&p, end, ino1, path1);
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
index dd26846..ff4188b 100644
--- a/fs/ceph/mds_client.h
+++ b/fs/ceph/mds_client.h
@@ -184,8 +184,8 @@ struct ceph_mds_request {
 
 	union ceph_mds_request_args r_args;
 	int r_fmode;        /* file mode, if expecting cap */
-	uid_t r_uid;
-	gid_t r_gid;
+	kuid_t r_uid;
+	kgid_t r_gid;
 
 	/* for choosing which mds to send this request to */
 	int r_direct_mode;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 05/85] ceph: Convert kuids and kgids before printing them.
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (2 preceding siblings ...)
  2013-02-13 17:50   ` [PATCH review 04/85] ceph: Convert struct ceph_mds_request to use kuid_t and kgid_t Eric W. Biederman
@ 2013-02-13 17:50   ` Eric W. Biederman
  2013-02-13 17:50   ` [PATCH review 06/85] ceph: Enable building when user namespaces are enabled Eric W. Biederman
                     ` (79 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:50 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Sage Weil

From: "Eric W. Biederman" <ebiederm@xmission.com>

Before printing kuid and kgids values convert them into
the initial user namespace.

Cc: Sage Weil <sage@inktank.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/ceph/caps.c  |    3 ++-
 fs/ceph/inode.c |    9 ++++++---
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 39eb466..ae2be69 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -2362,7 +2362,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
 		inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(grant->uid));
 		inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(grant->gid));
 		dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode,
-		     inode->i_uid, inode->i_gid);
+		     from_kuid(&init_user_ns, inode->i_uid),
+		     from_kgid(&init_user_ns, inode->i_gid));
 	}
 
 	if ((issued & CEPH_CAP_LINK_EXCL) == 0)
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 40e0787..d45895f 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -615,7 +615,8 @@ static int fill_inode(struct inode *inode,
 		inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(info->uid));
 		inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(info->gid));
 		dout("%p mode 0%o uid.gid %d.%d\n", inode, inode->i_mode,
-		     inode->i_uid, inode->i_gid);
+		     from_kuid(&init_user_ns, inode->i_uid),
+		     from_kgid(&init_user_ns, inode->i_gid));
 	}
 
 	if ((issued & CEPH_CAP_LINK_EXCL) == 0)
@@ -1565,7 +1566,8 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
 
 	if (ia_valid & ATTR_UID) {
 		dout("setattr %p uid %d -> %d\n", inode,
-		     inode->i_uid, attr->ia_uid);
+		     from_kuid(&init_user_ns, inode->i_uid),
+		     from_kuid(&init_user_ns, attr->ia_uid));
 		if (issued & CEPH_CAP_AUTH_EXCL) {
 			inode->i_uid = attr->ia_uid;
 			dirtied |= CEPH_CAP_AUTH_EXCL;
@@ -1579,7 +1581,8 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
 	}
 	if (ia_valid & ATTR_GID) {
 		dout("setattr %p gid %d -> %d\n", inode,
-		     inode->i_gid, attr->ia_gid);
+		     from_kgid(&init_user_ns, inode->i_gid),
+		     from_kgid(&init_user_ns, attr->ia_gid));
 		if (issued & CEPH_CAP_AUTH_EXCL) {
 			inode->i_gid = attr->ia_gid;
 			dirtied |= CEPH_CAP_AUTH_EXCL;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 06/85] ceph: Enable building when user namespaces are enabled.
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (3 preceding siblings ...)
  2013-02-13 17:50   ` [PATCH review 05/85] ceph: Convert kuids and kgids before printing them Eric W. Biederman
@ 2013-02-13 17:50   ` Eric W. Biederman
  2013-02-13 17:50   ` [PATCH review 07/85] 9p: Add 'u' and 'g' format specifies for kuids and kgids Eric W. Biederman
                     ` (78 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:50 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Sage Weil

From: "Eric W. Biederman" <ebiederm@xmission.com>

Now that conversions happen from kuids and kgids when generating ceph
messages and conversion happen to kuids and kgids after receiving
celph messages, and all intermediate data structures store uids and
gids as type kuid_t and kgid_t it is safe to enable ceph with
user namespace support enabled.

Cc: Sage Weil <sage@inktank.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 init/Kconfig |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/init/Kconfig b/init/Kconfig
index c8c58bd..7170d54 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1076,7 +1076,6 @@ config UIDGID_CONVERTED
 	# Filesystems
 	depends on 9P_FS = n
 	depends on AFS_FS = n
-	depends on CEPH_FS = n
 	depends on CIFS = n
 	depends on CODA_FS = n
 	depends on GFS2_FS = n
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 07/85] 9p: Add 'u' and 'g' format specifies for kuids and kgids
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (4 preceding siblings ...)
  2013-02-13 17:50   ` [PATCH review 06/85] ceph: Enable building when user namespaces are enabled Eric W. Biederman
@ 2013-02-13 17:50   ` Eric W. Biederman
  2013-02-13 17:50   ` [PATCH review 08/85] 9p: Transmit kuid and kgid values Eric W. Biederman
                     ` (77 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:50 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Eric Van Hensbergen, Ron Minnich,
	Latchesar Ionkov

From: "Eric W. Biederman" <ebiederm@xmission.com>

This allows concentrating all of the conversion to and from kuids and
kgids into the format needed by the 9p protocol into one location.

Cc: Eric Van Hensbergen <ericvh@gmail.com>
Cc: Ron Minnich <rminnich@gmail.com>
Cc: Latchesar Ionkov <lucho@ionkov.net>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 net/9p/protocol.c |   36 ++++++++++++++++++++++++++++++++++++
 1 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/net/9p/protocol.c b/net/9p/protocol.c
index 3d33ecf..c289c6c 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)
 	d - int32_t
 	q - int64_t
 	s - string
+	u - numeric uid
+	g - numeric gid
 	S - stat
 	Q - qid
 	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,
 					(*sptr)[len] = 0;
 			}
 			break;
+		case 'u': {
+				kuid_t *uid = va_arg(ap, kuid_t *);
+				__le32 le_val;
+				if (pdu_read(pdu, &le_val, sizeof(le_val))) {
+					errcode = -EFAULT;
+					break;
+				}
+				*uid = make_kuid(&init_user_ns,
+						 le32_to_cpu(le_val));
+			} break;
+		case 'g': {
+				kgid_t *gid = va_arg(ap, kgid_t *);
+				__le32 le_val;
+				if (pdu_read(pdu, &le_val, sizeof(le_val))) {
+					errcode = -EFAULT;
+					break;
+				}
+				*gid = make_kgid(&init_user_ns,
+						 le32_to_cpu(le_val));
+			} break;
 		case 'Q':{
 				struct p9_qid *qid =
 				    va_arg(ap, struct p9_qid *);
@@ -377,6 +399,20 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
 					errcode = -EFAULT;
 			}
 			break;
+		case 'u': {
+				kuid_t uid = va_arg(ap, kuid_t);
+				__le32 val = cpu_to_le32(
+						from_kuid(&init_user_ns, uid));
+				if (pdu_write(pdu, &val, sizeof(val)))
+					errcode = -EFAULT;
+			} break;
+		case 'g': {
+				kgid_t gid = va_arg(ap, kgid_t);
+				__le32 val = cpu_to_le32(
+						from_kgid(&init_user_ns, gid));
+				if (pdu_write(pdu, &val, sizeof(val)))
+					errcode = -EFAULT;
+			} break;
 		case 'Q':{
 				const struct p9_qid *qid =
 				    va_arg(ap, const struct p9_qid *);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 08/85] 9p: Transmit kuid and kgid values
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (5 preceding siblings ...)
  2013-02-13 17:50   ` [PATCH review 07/85] 9p: Add 'u' and 'g' format specifies for kuids and kgids Eric W. Biederman
@ 2013-02-13 17:50   ` Eric W. Biederman
  2013-02-13 17:50   ` [PATCH review 09/85] 9p: Modify the stat structures to use kuid_t and kgid_t Eric W. Biederman
                     ` (76 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:50 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Eric Van Hensbergen, Ron Minnich,
	Latchesar Ionkov

From: "Eric W. Biederman" <ebiederm@xmission.com>

Modify the p9_client_rpc format specifiers of every function that
directly transmits a uid or a gid from 'd' to 'u' or 'g' as
appropriate.

Modify those same functions to take kuid_t and kgid_t parameters
instead of uid_t and gid_t parameters.

Cc: Eric Van Hensbergen <ericvh@gmail.com>
Cc: Ron Minnich <rminnich@gmail.com>
Cc: Latchesar Ionkov <lucho@ionkov.net>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 fs/9p/v9fs.c            |    2 +-
 include/net/9p/client.h |   10 +++++-----
 net/9p/client.c         |   25 +++++++++++++------------
 3 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index d934f04..4e0bd9d 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -375,7 +375,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
 		v9ses->flags &= ~V9FS_ACL_MASK;
 	}
 
-	fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, ~0,
+	fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, INVALID_UID,
 							v9ses->aname);
 	if (IS_ERR(fid)) {
 		retval = PTR_ERR(fid);
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index fc9b90b..6b031ab 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -220,17 +220,17 @@ void p9_client_destroy(struct p9_client *clnt);
 void p9_client_disconnect(struct p9_client *clnt);
 void p9_client_begin_disconnect(struct p9_client *clnt);
 struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
-					char *uname, u32 n_uname, char *aname);
+				char *uname, kuid_t n_uname, char *aname);
 struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
 		char **wnames, int clone);
 int p9_client_open(struct p9_fid *fid, int mode);
 int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,
 							char *extension);
 int p9_client_link(struct p9_fid *fid, struct p9_fid *oldfid, char *newname);
-int p9_client_symlink(struct p9_fid *fid, char *name, char *symname, gid_t gid,
+int p9_client_symlink(struct p9_fid *fid, char *name, char *symname, kgid_t gid,
 							struct p9_qid *qid);
 int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode,
-		gid_t gid, struct p9_qid *qid);
+		kgid_t gid, struct p9_qid *qid);
 int p9_client_clunk(struct p9_fid *fid);
 int p9_client_fsync(struct p9_fid *fid, int datasync);
 int p9_client_remove(struct p9_fid *fid);
@@ -250,9 +250,9 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
 							u64 request_mask);
 
 int p9_client_mknod_dotl(struct p9_fid *oldfid, char *name, int mode,
-			dev_t rdev, gid_t gid, struct p9_qid *);
+			dev_t rdev, kgid_t gid, struct p9_qid *);
 int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode,
-				gid_t gid, struct p9_qid *);
+				kgid_t gid, struct p9_qid *);
 int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status);
 int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *fl);
 struct p9_req_t *p9_tag_lookup(struct p9_client *, u16);
diff --git a/net/9p/client.c b/net/9p/client.c
index 34d4176..17855f0 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -1100,7 +1100,7 @@ void p9_client_begin_disconnect(struct p9_client *clnt)
 EXPORT_SYMBOL(p9_client_begin_disconnect);
 
 struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
-	char *uname, u32 n_uname, char *aname)
+	char *uname, kuid_t n_uname, char *aname)
 {
 	int err = 0;
 	struct p9_req_t *req;
@@ -1117,7 +1117,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
 		goto error;
 	}
 
-	req = p9_client_rpc(clnt, P9_TATTACH, "ddss?d", fid->fid,
+	req = p9_client_rpc(clnt, P9_TATTACH, "ddss?u", fid->fid,
 			afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
 	if (IS_ERR(req)) {
 		err = PTR_ERR(req);
@@ -1270,7 +1270,7 @@ error:
 EXPORT_SYMBOL(p9_client_open);
 
 int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode,
-		gid_t gid, struct p9_qid *qid)
+		kgid_t gid, struct p9_qid *qid)
 {
 	int err = 0;
 	struct p9_client *clnt;
@@ -1279,13 +1279,14 @@ int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode,
 
 	p9_debug(P9_DEBUG_9P,
 			">>> TLCREATE fid %d name %s flags %d mode %d gid %d\n",
-			ofid->fid, name, flags, mode, gid);
+			ofid->fid, name, flags, mode,
+		 	from_kgid(&init_user_ns, gid));
 	clnt = ofid->clnt;
 
 	if (ofid->mode != -1)
 		return -EINVAL;
 
-	req = p9_client_rpc(clnt, P9_TLCREATE, "dsddd", ofid->fid, name, flags,
+	req = p9_client_rpc(clnt, P9_TLCREATE, "dsddg", ofid->fid, name, flags,
 			mode, gid);
 	if (IS_ERR(req)) {
 		err = PTR_ERR(req);
@@ -1358,7 +1359,7 @@ error:
 }
 EXPORT_SYMBOL(p9_client_fcreate);
 
-int p9_client_symlink(struct p9_fid *dfid, char *name, char *symtgt, gid_t gid,
+int p9_client_symlink(struct p9_fid *dfid, char *name, char *symtgt, kgid_t gid,
 		struct p9_qid *qid)
 {
 	int err = 0;
@@ -1369,7 +1370,7 @@ int p9_client_symlink(struct p9_fid *dfid, char *name, char *symtgt, gid_t gid,
 			dfid->fid, name, symtgt);
 	clnt = dfid->clnt;
 
-	req = p9_client_rpc(clnt, P9_TSYMLINK, "dssd", dfid->fid, name, symtgt,
+	req = p9_client_rpc(clnt, P9_TSYMLINK, "dssg", dfid->fid, name, symtgt,
 			gid);
 	if (IS_ERR(req)) {
 		err = PTR_ERR(req);
@@ -2106,7 +2107,7 @@ error:
 EXPORT_SYMBOL(p9_client_readdir);
 
 int p9_client_mknod_dotl(struct p9_fid *fid, char *name, int mode,
-			dev_t rdev, gid_t gid, struct p9_qid *qid)
+			dev_t rdev, kgid_t gid, struct p9_qid *qid)
 {
 	int err;
 	struct p9_client *clnt;
@@ -2116,7 +2117,7 @@ int p9_client_mknod_dotl(struct p9_fid *fid, char *name, int mode,
 	clnt = fid->clnt;
 	p9_debug(P9_DEBUG_9P, ">>> TMKNOD fid %d name %s mode %d major %d "
 		"minor %d\n", fid->fid, name, mode, MAJOR(rdev), MINOR(rdev));
-	req = p9_client_rpc(clnt, P9_TMKNOD, "dsdddd", fid->fid, name, mode,
+	req = p9_client_rpc(clnt, P9_TMKNOD, "dsdddg", fid->fid, name, mode,
 		MAJOR(rdev), MINOR(rdev), gid);
 	if (IS_ERR(req))
 		return PTR_ERR(req);
@@ -2137,7 +2138,7 @@ error:
 EXPORT_SYMBOL(p9_client_mknod_dotl);
 
 int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode,
-				gid_t gid, struct p9_qid *qid)
+				kgid_t gid, struct p9_qid *qid)
 {
 	int err;
 	struct p9_client *clnt;
@@ -2146,8 +2147,8 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode,
 	err = 0;
 	clnt = fid->clnt;
 	p9_debug(P9_DEBUG_9P, ">>> TMKDIR fid %d name %s mode %d gid %d\n",
-		 fid->fid, name, mode, gid);
-	req = p9_client_rpc(clnt, P9_TMKDIR, "dsdd", fid->fid, name, mode,
+		 fid->fid, name, mode, from_kgid(&init_user_ns, gid));
+	req = p9_client_rpc(clnt, P9_TMKDIR, "dsdg", fid->fid, name, mode,
 		gid);
 	if (IS_ERR(req))
 		return PTR_ERR(req);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 09/85] 9p: Modify the stat structures to use kuid_t and kgid_t
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (6 preceding siblings ...)
  2013-02-13 17:50   ` [PATCH review 08/85] 9p: Transmit kuid and kgid values Eric W. Biederman
@ 2013-02-13 17:50   ` Eric W. Biederman
  2013-02-13 17:50   ` [PATCH review 10/85] 9p: Modify struct 9p_fid to use a kuid_t not a uid_t Eric W. Biederman
                     ` (75 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:50 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Eric Van Hensbergen, Ron Minnich,
	Latchesar Ionkov

From: "Eric W. Biederman" <ebiederm@xmission.com>

9p has thre strucrtures that can encode inode stat information.  Modify
all of those structures to contain kuid_t and kgid_t values.  Modify
he wire encoders and decoders of those structures to use 'u' and 'g' instead of
'd' in the format string where uids and gids are present.

This results in all kuid and kgid conversion to and from on the wire values
being performed by the same code in protocol.c where the client is known
at the time of the conversion.

Cc: Eric Van Hensbergen <ericvh@gmail.com>
Cc: Ron Minnich <rminnich@gmail.com>
Cc: Latchesar Ionkov <lucho@ionkov.net>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 fs/9p/vfs_inode.c   |    6 +++---
 include/net/9p/9p.h |   14 +++++++-------
 net/9p/client.c     |   18 +++++++++++++-----
 net/9p/protocol.c   |   13 +++++++------
 4 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 890bed5..1581fe2 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -228,9 +228,9 @@ v9fs_blank_wstat(struct p9_wstat *wstat)
 	wstat->uid = NULL;
 	wstat->gid = NULL;
 	wstat->muid = NULL;
-	wstat->n_uid = ~0;
-	wstat->n_gid = ~0;
-	wstat->n_muid = ~0;
+	wstat->n_uid = INVALID_UID;
+	wstat->n_gid = INVALID_GID;
+	wstat->n_muid = INVALID_UID;
 	wstat->extension = NULL;
 }
 
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
index 7184853..27dfe85 100644
--- a/include/net/9p/9p.h
+++ b/include/net/9p/9p.h
@@ -407,17 +407,17 @@ struct p9_wstat {
 	char *gid;
 	char *muid;
 	char *extension;	/* 9p2000.u extensions */
-	u32 n_uid;		/* 9p2000.u extensions */
-	u32 n_gid;		/* 9p2000.u extensions */
-	u32 n_muid;		/* 9p2000.u extensions */
+	kuid_t n_uid;		/* 9p2000.u extensions */
+	kgid_t n_gid;		/* 9p2000.u extensions */
+	kuid_t n_muid;		/* 9p2000.u extensions */
 };
 
 struct p9_stat_dotl {
 	u64 st_result_mask;
 	struct p9_qid qid;
 	u32 st_mode;
-	u32 st_uid;
-	u32 st_gid;
+	kuid_t st_uid;
+	kgid_t st_gid;
 	u64 st_nlink;
 	u64 st_rdev;
 	u64 st_size;
@@ -471,8 +471,8 @@ struct p9_stat_dotl {
 struct p9_iattr_dotl {
 	u32 valid;
 	u32 mode;
-	u32 uid;
-	u32 gid;
+	kuid_t uid;
+	kgid_t gid;
 	u64 size;
 	u64 atime_sec;
 	u64 atime_nsec;
diff --git a/net/9p/client.c b/net/9p/client.c
index 17855f0..8eb7542 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -1711,7 +1711,9 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid)
 		(unsigned long long)ret->qid.path, ret->qid.version, ret->mode,
 		ret->atime, ret->mtime, (unsigned long long)ret->length,
 		ret->name, ret->uid, ret->gid, ret->muid, ret->extension,
-		ret->n_uid, ret->n_gid, ret->n_muid);
+		from_kuid(&init_user_ns, ret->n_uid),
+		from_kgid(&init_user_ns, ret->n_gid),
+		from_kuid(&init_user_ns, ret->n_muid));
 
 	p9_free_req(clnt, req);
 	return ret;
@@ -1765,8 +1767,10 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
 		"<<< st_btime_sec=%lld st_btime_nsec=%lld\n"
 		"<<< st_gen=%lld st_data_version=%lld",
 		ret->st_result_mask, ret->qid.type, ret->qid.path,
-		ret->qid.version, ret->st_mode, ret->st_nlink, ret->st_uid,
-		ret->st_gid, ret->st_rdev, ret->st_size, ret->st_blksize,
+		ret->qid.version, ret->st_mode, ret->st_nlink,
+		from_kuid(&init_user_ns, ret->st_uid),
+		from_kgid(&init_user_ns, ret->st_gid),
+		ret->st_rdev, ret->st_size, ret->st_blksize,
 		ret->st_blocks, ret->st_atime_sec, ret->st_atime_nsec,
 		ret->st_mtime_sec, ret->st_mtime_nsec, ret->st_ctime_sec,
 		ret->st_ctime_nsec, ret->st_btime_sec, ret->st_btime_nsec,
@@ -1829,7 +1833,9 @@ int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst)
 		(unsigned long long)wst->qid.path, wst->qid.version, wst->mode,
 		wst->atime, wst->mtime, (unsigned long long)wst->length,
 		wst->name, wst->uid, wst->gid, wst->muid, wst->extension,
-		wst->n_uid, wst->n_gid, wst->n_muid);
+		from_kuid(&init_user_ns, wst->n_uid),
+		from_kgid(&init_user_ns, wst->n_gid),
+		from_kuid(&init_user_ns, wst->n_muid));
 
 	req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size+2, wst);
 	if (IS_ERR(req)) {
@@ -1858,7 +1864,9 @@ int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr)
 		"    valid=%x mode=%x uid=%d gid=%d size=%lld\n"
 		"    atime_sec=%lld atime_nsec=%lld\n"
 		"    mtime_sec=%lld mtime_nsec=%lld\n",
-		p9attr->valid, p9attr->mode, p9attr->uid, p9attr->gid,
+		p9attr->valid, p9attr->mode,
+		from_kuid(&init_user_ns, p9attr->uid),
+		from_kgid(&init_user_ns, p9attr->gid),
 		p9attr->size, p9attr->atime_sec, p9attr->atime_nsec,
 		p9attr->mtime_sec, p9attr->mtime_nsec);
 
diff --git a/net/9p/protocol.c b/net/9p/protocol.c
index c289c6c..ab9127e 100644
--- a/net/9p/protocol.c
+++ b/net/9p/protocol.c
@@ -199,11 +199,12 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
 				    va_arg(ap, struct p9_wstat *);
 
 				memset(stbuf, 0, sizeof(struct p9_wstat));
-				stbuf->n_uid = stbuf->n_gid = stbuf->n_muid =
-									-1;
+				stbuf->n_uid = stbuf->n_muid = INVALID_UID;
+				stbuf->n_gid = INVALID_GID;
+
 				errcode =
 				    p9pdu_readf(pdu, proto_version,
-						"wwdQdddqssss?sddd",
+						"wwdQdddqssss?sugu",
 						&stbuf->size, &stbuf->type,
 						&stbuf->dev, &stbuf->qid,
 						&stbuf->mode, &stbuf->atime,
@@ -316,7 +317,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
 				memset(stbuf, 0, sizeof(struct p9_stat_dotl));
 				errcode =
 				    p9pdu_readf(pdu, proto_version,
-					"qQdddqqqqqqqqqqqqqqq",
+					"qQdugqqqqqqqqqqqqqqq",
 					&stbuf->st_result_mask,
 					&stbuf->qid,
 					&stbuf->st_mode,
@@ -426,7 +427,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
 				    va_arg(ap, const struct p9_wstat *);
 				errcode =
 				    p9pdu_writef(pdu, proto_version,
-						 "wwdQdddqssss?sddd",
+						 "wwdQdddqssss?sugu",
 						 stbuf->size, stbuf->type,
 						 stbuf->dev, &stbuf->qid,
 						 stbuf->mode, stbuf->atime,
@@ -504,7 +505,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
 							struct p9_iattr_dotl *);
 
 				errcode = p9pdu_writef(pdu, proto_version,
-							"ddddqqqqq",
+							"ddugqqqqq",
 							p9attr->valid,
 							p9attr->mode,
 							p9attr->uid,
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 10/85] 9p: Modify struct 9p_fid to use a kuid_t not a uid_t
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (7 preceding siblings ...)
  2013-02-13 17:50   ` [PATCH review 09/85] 9p: Modify the stat structures to use kuid_t and kgid_t Eric W. Biederman
@ 2013-02-13 17:50   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 11/85] 9p: Modify struct v9fs_session_info to use a kuids and kgids Eric W. Biederman
                     ` (74 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:50 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Eric Van Hensbergen, Ron Minnich,
	Latchesar Ionkov

From: "Eric W. Biederman" <ebiederm@xmission.com>

Change struct 9p_fid and it's associated functions to
use kuid_t's instead of uid_t.

Cc: Eric Van Hensbergen <ericvh@gmail.com>
Cc: Ron Minnich <rminnich@gmail.com>
Cc: Latchesar Ionkov <lucho@ionkov.net>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/9p/fid.c             |   17 +++++++++--------
 fs/9p/v9fs.c            |    2 +-
 include/net/9p/client.h |    2 +-
 3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index da8eefb..afd4724 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)
  *
  */
 
-static struct p9_fid *v9fs_fid_find(struct dentry *dentry, u32 uid, int any)
+static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
 {
 	struct v9fs_dentry *dent;
 	struct p9_fid *fid, *ret;
 
 	p9_debug(P9_DEBUG_VFS, " dentry: %s (%p) uid %d any %d\n",
-		 dentry->d_name.name, dentry, uid, any);
+		 dentry->d_name.name, dentry, from_kuid(&init_user_ns, uid),
+		 any);
 	dent = (struct v9fs_dentry *) dentry->d_fsdata;
 	ret = NULL;
 	if (dent) {
 		spin_lock(&dent->lock);
 		list_for_each_entry(fid, &dent->fidlist, dlist) {
-			if (any || fid->uid == uid) {
+			if (any || uid_eq(fid->uid, uid)) {
 				ret = fid;
 				break;
 			}
@@ -126,7 +127,7 @@ err_out:
 }
 
 static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
-					       uid_t uid, int any)
+					       kuid_t uid, int any)
 {
 	struct dentry *ds;
 	char **wnames, *uname;
@@ -233,7 +234,7 @@ err_out:
 
 struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
 {
-	uid_t uid;
+	kuid_t uid;
 	int  any, access;
 	struct v9fs_session_info *v9ses;
 
@@ -253,7 +254,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
 		break;
 
 	default:
-		uid = ~0;
+		uid = INVALID_UID;
 		any = 0;
 		break;
 	}
@@ -272,7 +273,7 @@ struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
 	return ret;
 }
 
-static struct p9_fid *v9fs_fid_clone_with_uid(struct dentry *dentry, uid_t uid)
+static struct p9_fid *v9fs_fid_clone_with_uid(struct dentry *dentry, kuid_t uid)
 {
 	struct p9_fid *fid, *ret;
 
@@ -289,7 +290,7 @@ struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
 	int err;
 	struct p9_fid *fid;
 
-	fid = v9fs_fid_clone_with_uid(dentry, 0);
+	fid = v9fs_fid_clone_with_uid(dentry, GLOBAL_ROOT_UID);
 	if (IS_ERR(fid))
 		goto error_out;
 	/*
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 4e0bd9d..d64967c 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -387,7 +387,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
 	if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_SINGLE)
 		fid->uid = v9ses->uid;
 	else
-		fid->uid = ~0;
+		fid->uid = INVALID_UID;
 
 #ifdef CONFIG_9P_FSCACHE
 	/* register the session for caching */
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index 6b031ab..5ff70f4 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -187,7 +187,7 @@ struct p9_fid {
 	int mode;
 	struct p9_qid qid;
 	u32 iounit;
-	uid_t uid;
+	kuid_t uid;
 
 	void *rdir;
 
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 11/85] 9p: Modify struct v9fs_session_info to use a kuids and kgids
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (8 preceding siblings ...)
  2013-02-13 17:50   ` [PATCH review 10/85] 9p: Modify struct 9p_fid to use a kuid_t not a uid_t Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 12/85] 9p: Modify v9fs_get_fsgid_for_create to return a kgid Eric W. Biederman
                     ` (73 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Eric Van Hensbergen, Ron Minnich,
	Latchesar Ionkov

From: "Eric W. Biederman" <ebiederm@xmission.com>

Change struct v9fs_session_info and the code that popluates it to use
kuids and kgids.  When parsing the 9p mount options convert the
dfltuid, dflutgid, and the session uid from the current user namespace
into kuids and kgids.  Modify V9FS_DEFUID and V9FS_DEFGUID to be kuid
and kgid values.

Cc: Eric Van Hensbergen <ericvh@gmail.com>
Cc: Ron Minnich <rminnich@gmail.com>
Cc: Latchesar Ionkov <lucho@ionkov.net>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/9p/v9fs.c |   30 +++++++++++++++++++++++++-----
 fs/9p/v9fs.h |   10 +++++-----
 2 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index d64967c..58e6cbc 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)
 				ret = r;
 				continue;
 			}
-			v9ses->dfltuid = option;
+			v9ses->dfltuid = make_kuid(current_user_ns(), option);
+			if (!uid_valid(v9ses->dfltuid)) {
+				p9_debug(P9_DEBUG_ERROR,
+					 "uid field, but not a uid?\n");
+				ret = -EINVAL;
+				continue;
+			}
 			break;
 		case Opt_dfltgid:
 			r = match_int(&args[0], &option);
@@ -171,7 +177,13 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
 				ret = r;
 				continue;
 			}
-			v9ses->dfltgid = option;
+			v9ses->dfltgid = make_kgid(current_user_ns(), option);
+			if (!gid_valid(v9ses->dfltgid)) {
+				p9_debug(P9_DEBUG_ERROR,
+					 "gid field, but not a gid?\n");
+				ret = -EINVAL;
+				continue;
+			}
 			break;
 		case Opt_afid:
 			r = match_int(&args[0], &option);
@@ -248,8 +260,9 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
 			else if (strcmp(s, "client") == 0) {
 				v9ses->flags |= V9FS_ACCESS_CLIENT;
 			} else {
+				uid_t uid;
 				v9ses->flags |= V9FS_ACCESS_SINGLE;
-				v9ses->uid = simple_strtoul(s, &e, 10);
+				uid = simple_strtoul(s, &e, 10);
 				if (*e != '\0') {
 					ret = -EINVAL;
 					pr_info("Unknown access argument %s\n",
@@ -257,6 +270,13 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
 					kfree(s);
 					goto free_and_return;
 				}
+				v9ses->uid = make_kuid(current_user_ns(), uid);
+				if (!uid_valid(v9ses->uid)) {
+					ret = -EINVAL;
+					pr_info("Uknown uid %s\n", s);
+					kfree(s);
+					goto free_and_return;
+				}
 			}
 
 			kfree(s);
@@ -319,7 +339,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
 	list_add(&v9ses->slist, &v9fs_sessionlist);
 	spin_unlock(&v9fs_sessionlist_lock);
 
-	v9ses->uid = ~0;
+	v9ses->uid = INVALID_UID;
 	v9ses->dfltuid = V9FS_DEFUID;
 	v9ses->dfltgid = V9FS_DEFGID;
 
@@ -364,7 +384,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
 
 		v9ses->flags &= ~V9FS_ACCESS_MASK;
 		v9ses->flags |= V9FS_ACCESS_ANY;
-		v9ses->uid = ~0;
+		v9ses->uid = INVALID_UID;
 	}
 	if (!v9fs_proto_dotl(v9ses) ||
 		!((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) {
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index 34c59f1..a8e127c 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -109,9 +109,9 @@ struct v9fs_session_info {
 	char *uname;		/* user name to mount as */
 	char *aname;		/* name of remote hierarchy being mounted */
 	unsigned int maxdata;	/* max data for client interface */
-	unsigned int dfltuid;	/* default uid/muid for legacy support */
-	unsigned int dfltgid;	/* default gid for legacy support */
-	u32 uid;		/* if ACCESS_SINGLE, the uid that has access */
+	kuid_t dfltuid;		/* default uid/muid for legacy support */
+	kgid_t dfltgid;		/* default gid for legacy support */
+	kuid_t uid;		/* if ACCESS_SINGLE, the uid that has access */
 	struct p9_client *clnt;	/* 9p client */
 	struct list_head slist; /* list of sessions registered with v9fs */
 	struct backing_dev_info bdi;
@@ -165,8 +165,8 @@ extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,
 #define V9FS_PORT	564
 #define V9FS_DEFUSER	"nobody"
 #define V9FS_DEFANAME	""
-#define V9FS_DEFUID	(-2)
-#define V9FS_DEFGID	(-2)
+#define V9FS_DEFUID	KUIDT_INIT(-2)
+#define V9FS_DEFGID	KGIDT_INIT(-2)
 
 static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode)
 {
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 12/85] 9p: Modify v9fs_get_fsgid_for_create to return a kgid
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (9 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 11/85] 9p: Modify struct v9fs_session_info to use a kuids and kgids Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 13/85] 9p: Allow building 9p with user namespaces enabled Eric W. Biederman
                     ` (72 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Eric Van Hensbergen, Ron Minnich,
	Latchesar Ionkov

From: "Eric W. Biederman" <ebiederm@xmission.com>

Modify v9fs_get_fsgid_for_create to return a kgid and modify all of
the variables that hold the result of v9fs_get_fsgid_for_create to be
of type kgid_t.

Cc: Eric Van Hensbergen <ericvh@gmail.com>
Cc: Ron Minnich <rminnich@gmail.com>
Cc: Latchesar Ionkov <lucho@ionkov.net>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/9p/vfs_inode_dotl.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index 4089554..e278865 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,
  * group of the new file system object.
  */
 
-static gid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
+static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
 {
 	BUG_ON(dir_inode == NULL);
 
@@ -246,7 +246,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
 			  int *opened)
 {
 	int err = 0;
-	gid_t gid;
+	kgid_t gid;
 	umode_t mode;
 	char *name = NULL;
 	struct p9_qid qid;
@@ -391,7 +391,7 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
 	int err;
 	struct v9fs_session_info *v9ses;
 	struct p9_fid *fid = NULL, *dfid = NULL;
-	gid_t gid;
+	kgid_t gid;
 	char *name;
 	umode_t mode;
 	struct inode *inode;
@@ -692,7 +692,7 @@ v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
 		const char *symname)
 {
 	int err;
-	gid_t gid;
+	kgid_t gid;
 	char *name;
 	struct p9_qid qid;
 	struct inode *inode;
@@ -832,7 +832,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
 		dev_t rdev)
 {
 	int err;
-	gid_t gid;
+	kgid_t gid;
 	char *name;
 	umode_t mode;
 	struct v9fs_session_info *v9ses;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 13/85] 9p: Allow building 9p with user namespaces enabled.
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (10 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 12/85] 9p: Modify v9fs_get_fsgid_for_create to return a kgid Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 14/85] afs: Remove unused structure afs_store_status Eric W. Biederman
                     ` (71 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Eric Van Hensbergen, Ron Minnich,
	Latchesar Ionkov

From: "Eric W. Biederman" <ebiederm@xmission.com>

Now that the uid_t -> kuid_t, gid_t -> kgid_t conversion
has been completed in 9p allow 9p to be built when user
namespaces are enabled.

Cc: Eric Van Hensbergen <ericvh@gmail.com>
Cc: Ron Minnich <rminnich@gmail.com>
Cc: Latchesar Ionkov <lucho@ionkov.net>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 init/Kconfig |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/init/Kconfig b/init/Kconfig
index 7170d54..394d24f 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1070,11 +1070,7 @@ config UIDGID_CONVERTED
 	bool
 	default y
 
-	# Networking
-	depends on NET_9P = n
-
 	# Filesystems
-	depends on 9P_FS = n
 	depends on AFS_FS = n
 	depends on CIFS = n
 	depends on CODA_FS = n
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 14/85] afs: Remove unused structure afs_store_status
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (11 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 13/85] 9p: Allow building 9p with user namespaces enabled Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 15/85] afs: Only allow mounting afs in the intial network namespace Eric W. Biederman
                     ` (70 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, David Howells

From: "Eric W. Biederman" <ebiederm@xmission.com>

While looking for kuid_t and kgid_t conversions I found this
structure that has never been used since it was added to the
kernel in 2007.  The obvious for this structure to be used
is in xdr_encode_AFS_StoreStatus and that function uses a
small handful of local variables instead.

So remove the unnecessary structure to prevent confusion.

Cc: David Howells <dhowells@redhat.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/afs/afs.h |    7 -------
 1 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/fs/afs/afs.h b/fs/afs/afs.h
index c548aa3..3d8fd35 100644
--- a/fs/afs/afs.h
+++ b/fs/afs/afs.h
@@ -133,13 +133,6 @@ struct afs_file_status {
 /*
  * AFS file status change request
  */
-struct afs_store_status {
-	u32			mask;		/* which bits of the struct are set */
-	u32			mtime_client;	/* last time client changed data */
-	u32			owner;		/* owner ID */
-	u32			group;		/* group ID */
-	umode_t			mode;		/* UNIX mode */
-};
 
 #define AFS_SET_MTIME		0x01		/* set the mtime */
 #define AFS_SET_OWNER		0x02		/* set the owner ID */
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 15/85] afs: Only allow mounting afs in the intial network namespace
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (12 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 14/85] afs: Remove unused structure afs_store_status Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 16/85] afs: Support interacting with multiple user namespaces Eric W. Biederman
                     ` (69 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, David Howells

From: "Eric W. Biederman" <ebiederm@xmission.com>

rxrpc sockets only work in the initial network namespace so it isn't
possible to support afs in any other network namespace.

Cc: David Howells <dhowells@redhat.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/afs/super.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/fs/afs/super.c b/fs/afs/super.c
index 4316500..7c31ec3 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -24,6 +24,8 @@
 #include <linux/parser.h>
 #include <linux/statfs.h>
 #include <linux/sched.h>
+#include <linux/nsproxy.h>
+#include <net/net_namespace.h>
 #include "internal.h"
 
 #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */
@@ -363,6 +365,10 @@ static struct dentry *afs_mount(struct file_system_type *fs_type,
 
 	memset(&params, 0, sizeof(params));
 
+	ret = -EINVAL;
+	if (current->nsproxy->net_ns != &init_net)
+		goto error;
+
 	/* parse the options and device name */
 	if (options) {
 		ret = afs_parse_options(&params, options, &dev_name);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 16/85] afs: Support interacting with multiple user namespaces
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (13 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 15/85] afs: Only allow mounting afs in the intial network namespace Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 17/85] coda: Restrict coda messages to the initial pid namespace Eric W. Biederman
                     ` (68 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, David Howells

From: "Eric W. Biederman" <ebiederm@xmission.com>

Modify struct afs_file_status to store owner as a kuid_t and group as
a kgid_t.

In xdr_decode_AFSFetchStatus as owner is now a kuid_t and group is now
a kgid_t don't use the EXTRACT macro.  Instead perform the work of
the extract macro explicitly.  Read the value with ntohl and
convert it to the appropriate type with make_kuid or make_kgid.
Test if the value is different from what is stored in status and
update changed.   Update the value in status.

In xdr_encode_AFS_StoreStatus call from_kuid or from_kgid as
we are computing the on the wire encoding.

Initialize uids with GLOBAL_ROOT_UID instead of 0.
Initialize gids with GLOBAL_ROOT_GID instead of 0.

Cc: David Howells <dhowells@redhat.com>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 fs/afs/afs.h      |    4 ++--
 fs/afs/fsclient.c |   14 ++++++++++----
 fs/afs/inode.c    |    6 +++---
 init/Kconfig      |    1 -
 4 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/fs/afs/afs.h b/fs/afs/afs.h
index 3d8fd35..3c462ff 100644
--- a/fs/afs/afs.h
+++ b/fs/afs/afs.h
@@ -119,8 +119,8 @@ struct afs_file_status {
 	u64			size;		/* file size */
 	afs_dataversion_t	data_version;	/* current data version */
 	u32			author;		/* author ID */
-	u32			owner;		/* owner ID */
-	u32			group;		/* group ID */
+	kuid_t			owner;		/* owner ID */
+	kgid_t			group;		/* group ID */
 	afs_access_t		caller_access;	/* access rights for authenticated caller */
 	afs_access_t		anon_access;	/* access rights for unauthenticated caller */
 	umode_t			mode;		/* UNIX mode */
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c
index b960ff0..c2e930e 100644
--- a/fs/afs/fsclient.c
+++ b/fs/afs/fsclient.c
@@ -42,6 +42,8 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
 	umode_t mode;
 	u64 data_version, size;
 	u32 changed = 0; /* becomes non-zero if ctime-type changes seen */
+	kuid_t owner;
+	kgid_t group;
 
 #define EXTRACT(DST)				\
 	do {					\
@@ -56,7 +58,9 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
 	size = ntohl(*bp++);
 	data_version = ntohl(*bp++);
 	EXTRACT(status->author);
-	EXTRACT(status->owner);
+	owner = make_kuid(&init_user_ns, ntohl(*bp++));
+	changed |= !uid_eq(owner, status->owner);
+	status->owner = owner;
 	EXTRACT(status->caller_access); /* call ticket dependent */
 	EXTRACT(status->anon_access);
 	EXTRACT(status->mode);
@@ -65,7 +69,9 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
 	bp++; /* seg size */
 	status->mtime_client = ntohl(*bp++);
 	status->mtime_server = ntohl(*bp++);
-	EXTRACT(status->group);
+	group = make_kgid(&init_user_ns, ntohl(*bp++));
+	changed |= !gid_eq(group, status->group);
+	status->group = group;
 	bp++; /* sync counter */
 	data_version |= (u64) ntohl(*bp++) << 32;
 	EXTRACT(status->lock_count);
@@ -181,12 +187,12 @@ static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
 
 	if (attr->ia_valid & ATTR_UID) {
 		mask |= AFS_SET_OWNER;
-		owner = attr->ia_uid;
+		owner = from_kuid(&init_user_ns, attr->ia_uid);
 	}
 
 	if (attr->ia_valid & ATTR_GID) {
 		mask |= AFS_SET_GROUP;
-		group = attr->ia_gid;
+		group = from_kgid(&init_user_ns, attr->ia_gid);
 	}
 
 	if (attr->ia_valid & ATTR_MODE) {
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index 95cffd3..789bc25 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)
 
 	set_nlink(inode, vnode->status.nlink);
 	inode->i_uid		= vnode->status.owner;
-	inode->i_gid		= 0;
+	inode->i_gid		= GLOBAL_ROOT_GID;
 	inode->i_size		= vnode->status.size;
 	inode->i_ctime.tv_sec	= vnode->status.mtime_server;
 	inode->i_ctime.tv_nsec	= 0;
@@ -175,8 +175,8 @@ struct inode *afs_iget_autocell(struct inode *dir, const char *dev_name,
 	inode->i_mode		= S_IFDIR | S_IRUGO | S_IXUGO;
 	inode->i_op		= &afs_autocell_inode_operations;
 	set_nlink(inode, 2);
-	inode->i_uid		= 0;
-	inode->i_gid		= 0;
+	inode->i_uid		= GLOBAL_ROOT_UID;
+	inode->i_gid		= GLOBAL_ROOT_GID;
 	inode->i_ctime.tv_sec	= get_seconds();
 	inode->i_ctime.tv_nsec	= 0;
 	inode->i_atime		= inode->i_mtime = inode->i_ctime;
diff --git a/init/Kconfig b/init/Kconfig
index 394d24f..4570b02 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1071,7 +1071,6 @@ config UIDGID_CONVERTED
 	default y
 
 	# Filesystems
-	depends on AFS_FS = n
 	depends on CIFS = n
 	depends on CODA_FS = n
 	depends on GFS2_FS = n
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 17/85] coda: Restrict coda messages to the initial pid namespace
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (14 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 16/85] afs: Support interacting with multiple user namespaces Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 18/85] coda: Restrict coda messages to the initial user namespace Eric W. Biederman
                     ` (67 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Jan Harkes

From: "Eric W. Biederman" <ebiederm@xmission.com>

Remove the slight chance that pids in coda messages will be
interpreted in the wrong pid namespace.

- Explicitly send all pids in coda messages in the initial pid
  namespace.
- Only allow mounts from processes in the initial pid namespace.
- Only allow processes in the initial pid namespace to open the coda
  character device to communicate with coda.

Cc: Jan Harkes <jaharkes@cs.cmu.edu>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/coda/inode.c  |    4 ++++
 fs/coda/psdev.c  |    4 ++++
 fs/coda/upcall.c |    4 ++--
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index be2aa49..77bbaf4 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -20,6 +20,7 @@
 #include <linux/file.h>
 #include <linux/vfs.h>
 #include <linux/slab.h>
+#include <linux/pid_namespace.h>
 
 #include <asm/uaccess.h>
 
@@ -157,6 +158,9 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
 	int error;
 	int idx;
 
+	if (task_active_pid_ns(current) != &init_pid_ns)
+		return -EINVAL;
+
 	idx = get_device_index((struct coda_mount_data *) data);
 
 	/* Ignore errors in data, for backward compatibility */
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index 761d5b3..dd60f90 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -37,6 +37,7 @@
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
+#include <linux/pid_namespace.h>
 #include <asm/io.h>
 #include <asm/poll.h>
 #include <asm/uaccess.h>
@@ -266,6 +267,9 @@ static int coda_psdev_open(struct inode * inode, struct file * file)
 	struct venus_comm *vcp;
 	int idx, err;
 
+	if (task_active_pid_ns(current) != &init_pid_ns)
+		return -EINVAL;
+
 	idx = iminor(inode);
 	if (idx < 0 || idx >= MAX_CODADEVS)
 		return -ENODEV;
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c
index 0c68fd3..5c6d2cd 100644
--- a/fs/coda/upcall.c
+++ b/fs/coda/upcall.c
@@ -50,8 +50,8 @@ static void *alloc_upcall(int opcode, int size)
 		return ERR_PTR(-ENOMEM);
 
         inp->ih.opcode = opcode;
-	inp->ih.pid = current->pid;
-	inp->ih.pgid = task_pgrp_nr(current);
+	inp->ih.pid = task_pid_nr_ns(current, &init_pid_ns);
+	inp->ih.pgid = task_pgrp_nr_ns(current, &init_pid_ns);
 	inp->ih.uid = current_fsuid();
 
 	return (void*)inp;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 18/85] coda: Restrict coda messages to the initial user namespace
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (15 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 17/85] coda: Restrict coda messages to the initial pid namespace Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 18:14     ` Jan Harkes
  2013-02-13 17:51   ` [PATCH review 19/85] coda: Cache permisions in struct coda_inode_info in a kuid_t Eric W. Biederman
                     ` (66 subsequent siblings)
  83 siblings, 1 reply; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Jan Harkes

From: "Eric W. Biederman" <ebiederm@xmission.com>

Remove the slight chance that uids and gids in coda messages will be
interpreted in the wrong user namespace.

- Only allow processes in the initial user namespace to open the coda
  character device to communicate with coda filesystems.
- Explicitly convert the uids in the coda header into the initial user
  namespace.
- In coda_vattr_to_attr make kuids and kgids from the initial user
  namespace uids and gids in struct coda_vattr that just came from
  userspace.
- In coda_iattr_to_vattr convert kuids and kgids into uids and gids
  in the intial user namespace and store them in struct coda_vattr for
  sending to coda userspace programs.

Nothing needs to be changed with mounts as coda does not support
being mounted in anything other than the initial user namespace.

Cc: Jan Harkes <jaharkes@cs.cmu.edu>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/coda/coda_linux.c       |    8 ++++----
 fs/coda/psdev.c            |    3 +++
 fs/coda/upcall.c           |    6 +++---
 include/linux/coda_psdev.h |    2 +-
 4 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/fs/coda/coda_linux.c b/fs/coda/coda_linux.c
index 854ace7..2849f41 100644
--- a/fs/coda/coda_linux.c
+++ b/fs/coda/coda_linux.c
@@ -100,9 +100,9 @@ void coda_vattr_to_iattr(struct inode *inode, struct coda_vattr *attr)
 	if (attr->va_mode != (u_short) -1)
 	        inode->i_mode = attr->va_mode | inode_type;
         if (attr->va_uid != -1) 
-	        inode->i_uid = (uid_t) attr->va_uid;
+	        inode->i_uid = make_kuid(&init_user_ns, (uid_t) attr->va_uid);
         if (attr->va_gid != -1)
-	        inode->i_gid = (gid_t) attr->va_gid;
+	        inode->i_gid = make_kgid(&init_user_ns, (gid_t) attr->va_gid);
 	if (attr->va_nlink != -1)
 		set_nlink(inode, attr->va_nlink);
 	if (attr->va_size != -1)
@@ -171,10 +171,10 @@ void coda_iattr_to_vattr(struct iattr *iattr, struct coda_vattr *vattr)
                 vattr->va_mode = iattr->ia_mode;
 	}
         if ( valid & ATTR_UID ) {
-                vattr->va_uid = (vuid_t) iattr->ia_uid;
+                vattr->va_uid = (vuid_t) from_kuid(&init_user_ns, iattr->ia_uid);
 	}
         if ( valid & ATTR_GID ) {
-                vattr->va_gid = (vgid_t) iattr->ia_gid;
+                vattr->va_gid = (vgid_t) from_kgid(&init_user_ns, iattr->ia_gid);
 	}
         if ( valid & ATTR_SIZE ) {
                 vattr->va_size = iattr->ia_size;
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index dd60f90..ebc2bae 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -270,6 +270,9 @@ static int coda_psdev_open(struct inode * inode, struct file * file)
 	if (task_active_pid_ns(current) != &init_pid_ns)
 		return -EINVAL;
 
+	if (current_user_ns() != &init_user_ns)
+		return -EINVAL;
+
 	idx = iminor(inode);
 	if (idx < 0 || idx >= MAX_CODADEVS)
 		return -ENODEV;
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c
index 5c6d2cd..3a73197 100644
--- a/fs/coda/upcall.c
+++ b/fs/coda/upcall.c
@@ -52,7 +52,7 @@ static void *alloc_upcall(int opcode, int size)
         inp->ih.opcode = opcode;
 	inp->ih.pid = task_pid_nr_ns(current, &init_pid_ns);
 	inp->ih.pgid = task_pgrp_nr_ns(current, &init_pid_ns);
-	inp->ih.uid = current_fsuid();
+	inp->ih.uid = from_kuid(&init_user_ns, current_fsuid());
 
 	return (void*)inp;
 }
@@ -157,7 +157,7 @@ int venus_lookup(struct super_block *sb, struct CodaFid *fid,
 }
 
 int venus_close(struct super_block *sb, struct CodaFid *fid, int flags,
-		vuid_t uid)
+		kuid_t uid)
 {
 	union inputArgs *inp;
 	union outputArgs *outp;
@@ -166,7 +166,7 @@ int venus_close(struct super_block *sb, struct CodaFid *fid, int flags,
 	insize = SIZE(release);
 	UPARG(CODA_CLOSE);
 	
-	inp->ih.uid = uid;
+	inp->ih.uid = from_kuid(&init_user_ns, uid);
         inp->coda_close.VFid = *fid;
         inp->coda_close.flags = flags;
 
diff --git a/include/linux/coda_psdev.h b/include/linux/coda_psdev.h
index 8031d6e..5b8721e 100644
--- a/include/linux/coda_psdev.h
+++ b/include/linux/coda_psdev.h
@@ -34,7 +34,7 @@ int venus_lookup(struct super_block *sb, struct CodaFid *fid,
 		 const char *name, int length, int *type, 
 		 struct CodaFid *resfid);
 int venus_close(struct super_block *sb, struct CodaFid *fid, int flags,
-		vuid_t uid);
+		kuid_t uid);
 int venus_open(struct super_block *sb, struct CodaFid *fid, int flags,
 	       struct file **f);
 int venus_mkdir(struct super_block *sb, struct CodaFid *dirfid, 
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 19/85] coda: Cache permisions in struct coda_inode_info in a kuid_t.
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (16 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 18/85] coda: Restrict coda messages to the initial user namespace Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 20/85] coda: Allow coda to be built when user namespace support is enabled Eric W. Biederman
                     ` (65 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Jan Harkes

From: "Eric W. Biederman" <ebiederm@xmission.com>

- Change c_uid in struct coda_indoe_info from a vuid_t to a kuid_t.
- Initialize c_uid to GLOBAL_ROOT_UID instead of 0.
- Use uid_eq to compare cached kuids.

Cc: Jan Harkes <jaharkes@cs.cmu.edu>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/coda/cache.c     |    4 ++--
 fs/coda/coda_fs_i.h |    2 +-
 fs/coda/inode.c     |    2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/coda/cache.c b/fs/coda/cache.c
index 958ae0e..1da168c 100644
--- a/fs/coda/cache.c
+++ b/fs/coda/cache.c
@@ -33,7 +33,7 @@ void coda_cache_enter(struct inode *inode, int mask)
 
 	spin_lock(&cii->c_lock);
 	cii->c_cached_epoch = atomic_read(&permission_epoch);
-	if (cii->c_uid != current_fsuid()) {
+	if (!uid_eq(cii->c_uid, current_fsuid())) {
 		cii->c_uid = current_fsuid();
                 cii->c_cached_perm = mask;
         } else
@@ -65,7 +65,7 @@ int coda_cache_check(struct inode *inode, int mask)
 	
 	spin_lock(&cii->c_lock);
 	hit = (mask & cii->c_cached_perm) == mask &&
-	    cii->c_uid == current_fsuid() &&
+	    uid_eq(cii->c_uid, current_fsuid()) &&
 	    cii->c_cached_epoch == atomic_read(&permission_epoch);
 	spin_unlock(&cii->c_lock);
 
diff --git a/fs/coda/coda_fs_i.h b/fs/coda/coda_fs_i.h
index b24fdfd..c640752 100644
--- a/fs/coda/coda_fs_i.h
+++ b/fs/coda/coda_fs_i.h
@@ -25,7 +25,7 @@ struct coda_inode_info {
 	u_short	           c_flags;     /* flags (see below) */
 	unsigned int	   c_mapcount;  /* nr of times this inode is mapped */
 	unsigned int	   c_cached_epoch; /* epoch for cached permissions */
-	vuid_t		   c_uid;	/* fsuid for cached permissions */
+	kuid_t		   c_uid;	/* fsuid for cached permissions */
 	unsigned int       c_cached_perm; /* cached access permissions */
 	spinlock_t	   c_lock;
 	struct inode	   vfs_inode;
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index 77bbaf4..cf674e9 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -49,7 +49,7 @@ static struct inode *coda_alloc_inode(struct super_block *sb)
 		return NULL;
 	memset(&ei->c_fid, 0, sizeof(struct CodaFid));
 	ei->c_flags = 0;
-	ei->c_uid = 0;
+	ei->c_uid = GLOBAL_ROOT_UID;
 	ei->c_cached_perm = 0;
 	spin_lock_init(&ei->c_lock);
 	return &ei->vfs_inode;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 20/85] coda: Allow coda to be built when user namespace support is enabled
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (17 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 19/85] coda: Cache permisions in struct coda_inode_info in a kuid_t Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 21/85] ocfs2: Handle kuids and kgids in acl/xattr conversions Eric W. Biederman
                     ` (64 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Jan Harkes

From: "Eric W. Biederman" <ebiederm@xmission.com>

Now that the coda kernel to userspace has been modified to convert
between kuids and kgids and uids and gids, and all internal
coda structures have be modified to store uids and gids as
kuids and kgids it is safe to allow code to be built with
user namespace support enabled.

Cc: Jan Harkes <jaharkes@cs.cmu.edu>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 init/Kconfig |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/init/Kconfig b/init/Kconfig
index 4570b02..f516d52 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1072,7 +1072,6 @@ config UIDGID_CONVERTED
 
 	# Filesystems
 	depends on CIFS = n
-	depends on CODA_FS = n
 	depends on GFS2_FS = n
 	depends on NCP_FS = n
 	depends on NFSD = n
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 21/85] ocfs2: Handle kuids and kgids in acl/xattr conversions.
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (18 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 20/85] coda: Allow coda to be built when user namespace support is enabled Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 22/85] ocfs2: convert between kuids and kgids and DLM locks Eric W. Biederman
                     ` (63 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Mark Fasheh, Joel Becker

From: "Eric W. Biederman" <ebiederm@xmission.com>

Explicitly deal with the different kinds of acls because they need
different conversions.

Cc: Mark Fasheh <mfasheh@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/ocfs2/acl.c |   31 +++++++++++++++++++++++++++++--
 1 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c
index 260b162..8a40457 100644
--- a/fs/ocfs2/acl.c
+++ b/fs/ocfs2/acl.c
@@ -65,7 +65,20 @@ static struct posix_acl *ocfs2_acl_from_xattr(const void *value, size_t size)
 
 		acl->a_entries[n].e_tag  = le16_to_cpu(entry->e_tag);
 		acl->a_entries[n].e_perm = le16_to_cpu(entry->e_perm);
-		acl->a_entries[n].e_id   = le32_to_cpu(entry->e_id);
+		switch(acl->a_entries[n].e_tag) {
+		case ACL_USER:
+			acl->a_entries[n].e_uid =
+				make_kuid(&init_user_ns,
+					  le32_to_cpu(entry->e_id));
+			break;
+		case ACL_GROUP:
+			acl->a_entries[n].e_gid =
+				make_kgid(&init_user_ns,
+					  le32_to_cpu(entry->e_id));
+			break;
+		default:
+			break;
+		}
 		value += sizeof(struct posix_acl_entry);
 
 	}
@@ -91,7 +104,21 @@ static void *ocfs2_acl_to_xattr(const struct posix_acl *acl, size_t *size)
 	for (n = 0; n < acl->a_count; n++, entry++) {
 		entry->e_tag  = cpu_to_le16(acl->a_entries[n].e_tag);
 		entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm);
-		entry->e_id   = cpu_to_le32(acl->a_entries[n].e_id);
+		switch(acl->a_entries[n].e_tag) {
+		case ACL_USER:
+			entry->e_id = cpu_to_le32(
+				from_kuid(&init_user_ns,
+					  acl->a_entries[n].e_uid));
+			break;
+		case ACL_GROUP:
+			entry->e_id = cpu_to_le32(
+				from_kgid(&init_user_ns,
+					  acl->a_entries[n].e_gid));
+			break;
+		default:
+			entry->e_id = cpu_to_le32(ACL_UNDEFINED_ID);
+			break;
+		}
 	}
 	return ocfs2_acl;
 }
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 22/85] ocfs2: convert between kuids and kgids and DLM locks
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (19 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 21/85] ocfs2: Handle kuids and kgids in acl/xattr conversions Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-14  8:34     ` Joel Becker
  2013-02-13 17:51   ` [PATCH review 23/85] ocfs2: Convert uid and gids between in core and on disk inodes Eric W. Biederman
                     ` (62 subsequent siblings)
  83 siblings, 1 reply; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Mark Fasheh, Joel Becker

From: "Eric W. Biederman" <ebiederm@xmission.com>

Convert between uid and gids stored in the on the wire format of dlm
locks aka struct ocfs2_meta_lvb and kuids and kgids stored in
inode->i_uid and inode->i_gid.

Cc: Mark Fasheh <mfasheh@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/ocfs2/dlmglue.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 4f7795f..f99af1c 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -2045,8 +2045,8 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode)
 	lvb->lvb_version   = OCFS2_LVB_VERSION;
 	lvb->lvb_isize	   = cpu_to_be64(i_size_read(inode));
 	lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters);
-	lvb->lvb_iuid      = cpu_to_be32(inode->i_uid);
-	lvb->lvb_igid      = cpu_to_be32(inode->i_gid);
+	lvb->lvb_iuid      = cpu_to_be32(i_uid_read(inode));
+	lvb->lvb_igid      = cpu_to_be32(i_gid_read(inode));
 	lvb->lvb_imode     = cpu_to_be16(inode->i_mode);
 	lvb->lvb_inlink    = cpu_to_be16(inode->i_nlink);
 	lvb->lvb_iatime_packed  =
@@ -2095,8 +2095,8 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
 	else
 		inode->i_blocks = ocfs2_inode_sector_count(inode);
 
-	inode->i_uid     = be32_to_cpu(lvb->lvb_iuid);
-	inode->i_gid     = be32_to_cpu(lvb->lvb_igid);
+	i_uid_write(inode, be32_to_cpu(lvb->lvb_iuid));
+	i_gid_write(inode, be32_to_cpu(lvb->lvb_igid));
 	inode->i_mode    = be16_to_cpu(lvb->lvb_imode);
 	set_nlink(inode, be16_to_cpu(lvb->lvb_inlink));
 	ocfs2_unpack_timespec(&inode->i_atime,
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 23/85] ocfs2: Convert uid and gids between in core and on disk inodes
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (20 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 22/85] ocfs2: convert between kuids and kgids and DLM locks Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-14  8:35     ` Joel Becker
  2013-02-13 17:51   ` [PATCH review 24/85] ocfs2: For tracing report the uid and gid values in the initial user namespace Eric W. Biederman
                     ` (61 subsequent siblings)
  83 siblings, 1 reply; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Mark Fasheh, Joel Becker

From: "Eric W. Biederman" <ebiederm@xmission.com>

Cc: Mark Fasheh <mfasheh@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/ocfs2/inode.c |   12 ++++++------
 fs/ocfs2/namei.c |    4 ++--
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index d89e08a..f87f9bd 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -269,8 +269,8 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
 	inode->i_generation = le32_to_cpu(fe->i_generation);
 	inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
 	inode->i_mode = le16_to_cpu(fe->i_mode);
-	inode->i_uid = le32_to_cpu(fe->i_uid);
-	inode->i_gid = le32_to_cpu(fe->i_gid);
+	i_uid_write(inode, le32_to_cpu(fe->i_uid));
+	i_gid_write(inode, le32_to_cpu(fe->i_gid));
 
 	/* Fast symlinks will have i_size but no allocated clusters. */
 	if (S_ISLNK(inode->i_mode) && !fe->i_clusters) {
@@ -1259,8 +1259,8 @@ int ocfs2_mark_inode_dirty(handle_t *handle,
 
 	fe->i_size = cpu_to_le64(i_size_read(inode));
 	ocfs2_set_links_count(fe, inode->i_nlink);
-	fe->i_uid = cpu_to_le32(inode->i_uid);
-	fe->i_gid = cpu_to_le32(inode->i_gid);
+	fe->i_uid = cpu_to_le32(i_uid_read(inode));
+	fe->i_gid = cpu_to_le32(i_gid_read(inode));
 	fe->i_mode = cpu_to_le16(inode->i_mode);
 	fe->i_atime = cpu_to_le64(inode->i_atime.tv_sec);
 	fe->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
@@ -1290,8 +1290,8 @@ void ocfs2_refresh_inode(struct inode *inode,
 	ocfs2_set_inode_flags(inode);
 	i_size_write(inode, le64_to_cpu(fe->i_size));
 	set_nlink(inode, ocfs2_read_links_count(fe));
-	inode->i_uid = le32_to_cpu(fe->i_uid);
-	inode->i_gid = le32_to_cpu(fe->i_gid);
+	i_uid_write(inode, le32_to_cpu(fe->i_uid));
+	i_gid_write(inode, le32_to_cpu(fe->i_gid));
 	inode->i_mode = le16_to_cpu(fe->i_mode);
 	if (S_ISLNK(inode->i_mode) && le32_to_cpu(fe->i_clusters) == 0)
 		inode->i_blocks = 0;
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index f1fd074..04ee1b5 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -512,8 +512,8 @@ static int __ocfs2_mknod_locked(struct inode *dir,
 	fe->i_suballoc_loc = cpu_to_le64(suballoc_loc);
 	fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
 	fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot);
-	fe->i_uid = cpu_to_le32(inode->i_uid);
-	fe->i_gid = cpu_to_le32(inode->i_gid);
+	fe->i_uid = cpu_to_le32(i_uid_read(inode));
+	fe->i_gid = cpu_to_le32(i_gid_read(inode));
 	fe->i_mode = cpu_to_le16(inode->i_mode);
 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 		fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 24/85] ocfs2: For tracing report the uid and gid values in the initial user namespace
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (21 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 23/85] ocfs2: Convert uid and gids between in core and on disk inodes Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 25/85] ocfs2: Compare kuids and kgids using uid_eq and gid_eq Eric W. Biederman
                     ` (60 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Mark Fasheh, Joel Becker

From: "Eric W. Biederman" <ebiederm@xmission.com>

Cc: Mark Fasheh <mfasheh@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/ocfs2/file.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 37d313e..8ee9332 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1116,7 +1116,8 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
 			    (unsigned long long)OCFS2_I(inode)->ip_blkno,
 			    dentry->d_name.len, dentry->d_name.name,
 			    attr->ia_valid, attr->ia_mode,
-			    attr->ia_uid, attr->ia_gid);
+			    from_kuid(&init_user_ns, attr->ia_uid),
+			    from_kgid(&init_user_ns, attr->ia_gid));
 
 	/* ensuring we don't even attempt to truncate a symlink */
 	if (S_ISLNK(inode->i_mode))
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 25/85] ocfs2: Compare kuids and kgids using uid_eq and gid_eq
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (22 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 24/85] ocfs2: For tracing report the uid and gid values in the initial user namespace Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-14  8:37     ` Joel Becker
  2013-02-13 17:51   ` [PATCH review 26/85] ocfs2: Enable building with user namespaces enabled Eric W. Biederman
                     ` (59 subsequent siblings)
  83 siblings, 1 reply; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Mark Fasheh, Joel Becker

From: "Eric W. Biederman" <ebiederm@xmission.com>

Cc: Mark Fasheh <mfasheh@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/ocfs2/file.c         |    8 ++++----
 fs/ocfs2/refcounttree.c |    2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 8ee9332..0a2924a 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1175,14 +1175,14 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
 		}
 	}
 
-	if ((attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
-	    (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
+	if ((attr->ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) ||
+	    (attr->ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) {
 		/*
 		 * Gather pointers to quota structures so that allocation /
 		 * freeing of quota structures happens here and not inside
 		 * dquot_transfer() where we have problems with lock ordering
 		 */
-		if (attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid
+		if (attr->ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)
 		    && OCFS2_HAS_RO_COMPAT_FEATURE(sb,
 		    OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) {
 			transfer_to[USRQUOTA] = dqget(sb, make_kqid_uid(attr->ia_uid));
@@ -1191,7 +1191,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
 				goto bail_unlock;
 			}
 		}
-		if (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid
+		if (attr->ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid)
 		    && OCFS2_HAS_RO_COMPAT_FEATURE(sb,
 		    OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) {
 			transfer_to[GRPQUOTA] = dqget(sb, make_kqid_gid(attr->ia_gid));
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index 30a0550..934a4ac 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -4407,7 +4407,7 @@ static int ocfs2_vfs_reflink(struct dentry *old_dentry, struct inode *dir,
 	 * rights to do so.
 	 */
 	if (preserve) {
-		if ((current_fsuid() != inode->i_uid) && !capable(CAP_CHOWN))
+		if (!uid_eq(current_fsuid(), inode->i_uid) && !capable(CAP_CHOWN))
 			return -EPERM;
 		if (!in_group_p(inode->i_gid) && !capable(CAP_CHOWN))
 			return -EPERM;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 26/85] ocfs2: Enable building with user namespaces enabled
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (23 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 25/85] ocfs2: Compare kuids and kgids using uid_eq and gid_eq Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-14  8:38     ` Joel Becker
  2013-02-13 17:51   ` [PATCH review 27/85] gfs2: Remove improper checks in gfs2_set_dqblk Eric W. Biederman
                     ` (58 subsequent siblings)
  83 siblings, 1 reply; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Mark Fasheh, Joel Becker

From: "Eric W. Biederman" <ebiederm@xmission.com>

Now that ocfs2 has been converted to store uids and gids in
kuid_t and kgid_t and all of the conversions have been added
to the appropriate places it is safe to allow building and
using ocfs2 with user namespace support enabled.

Cc: Mark Fasheh <mfasheh@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 init/Kconfig |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/init/Kconfig b/init/Kconfig
index f516d52..9cb63c9 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1076,7 +1076,6 @@ config UIDGID_CONVERTED
 	depends on NCP_FS = n
 	depends on NFSD = n
 	depends on NFS_FS = n
-	depends on OCFS2_FS = n
 	depends on XFS_FS = n
 
 config UIDGID_STRICT_TYPE_CHECKS
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 27/85] gfs2: Remove improper checks in gfs2_set_dqblk.
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (24 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 26/85] ocfs2: Enable building with user namespaces enabled Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 28/85] gfs2: Split NO_QUOTA_CHANGE inot NO_UID_QUTOA_CHANGE and NO_GID_QUTOA_CHANGE Eric W. Biederman
                     ` (57 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steven Whitehouse

From: "Eric W. Biederman" <ebiederm@xmission.com>

In set_dqblk it is an error to look at fdq->d_id or fdq->d_flags.
Userspace quota applications do not set these fields when calling
quotactl(Q_XSETQLIM,...), and the kernel does not set those fields
when quota_setquota calls set_dqblk.

gfs2 never looks at fdq->d_id or fdq->d_flags after checking
to see if they match the id and type supplied to set_dqblk.

No other linux filesystem in set_dqblk looks at either fdq->d_id
or fdq->d_flags.

Therefore remove these bogus checks from gfs2 and allow normal
quota setting applications to work.

Cc: Steven Whitehouse <swhiteho@redhat.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/gfs2/quota.c |    6 ------
 1 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index ae55e24..e4f6ccf 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -1543,13 +1543,9 @@ static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid,
 	switch(qid.type) {
 	case USRQUOTA:
 		type = QUOTA_USER;
-		if (fdq->d_flags != FS_USER_QUOTA)
-			return -EINVAL;
 		break;
 	case GRPQUOTA:
 		type = QUOTA_GROUP;
-		if (fdq->d_flags != FS_GROUP_QUOTA)
-			return -EINVAL;
 		break;
 	default:
 		return -EINVAL;
@@ -1557,8 +1553,6 @@ static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid,
 
 	if (fdq->d_fieldmask & ~GFS2_FIELDMASK)
 		return -EINVAL;
-	if (fdq->d_id != from_kqid(&init_user_ns, qid))
-		return -EINVAL;
 
 	error = qd_get(sdp, type, from_kqid(&init_user_ns, qid), &qd);
 	if (error)
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 28/85] gfs2: Split NO_QUOTA_CHANGE inot NO_UID_QUTOA_CHANGE and NO_GID_QUTOA_CHANGE
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (25 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 27/85] gfs2: Remove improper checks in gfs2_set_dqblk Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 29/85] gfs2: Report quotas in the caller's user namespace Eric W. Biederman
                     ` (56 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steven Whitehouse

From: "Eric W. Biederman" <ebiederm@xmission.com>

Split NO_QUOTA_CHANGE into NO_UID_QUTOA_CHANGE and NO_GID_QUTOA_CHANGE
so the constants may be well typed.

Cc: Steven Whitehouse <swhiteho@redhat.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/gfs2/bmap.c  |    2 +-
 fs/gfs2/dir.c   |    2 +-
 fs/gfs2/inode.c |   10 +++++-----
 fs/gfs2/quota.c |    4 ++--
 fs/gfs2/quota.h |    5 +++--
 fs/gfs2/super.c |    2 +-
 fs/gfs2/xattr.c |    4 ++--
 7 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index a68e91b..10c54e3 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -1098,7 +1098,7 @@ static int trunc_dealloc(struct gfs2_inode *ip, u64 size)
 	if (error)
 		return error;
 
-	error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
+	error = gfs2_quota_hold(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
 	if (error)
 		return error;
 
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 9a35670..6d3e3e2 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -1849,7 +1849,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
 	if (!ht)
 		return -ENOMEM;
 
-	error = gfs2_quota_hold(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
+	error = gfs2_quota_hold(dip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
 	if (error)
 		goto out;
 
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 2b6f569..aa10502 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -548,7 +548,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
 	if (error)
 		return error;
 
-	error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
+	error = gfs2_quota_lock(dip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
 	if (error)
 		goto fail;
 
@@ -1589,15 +1589,15 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
 	ngid = attr->ia_gid;
 
 	if (!(attr->ia_valid & ATTR_UID) || ouid == nuid)
-		ouid = nuid = NO_QUOTA_CHANGE;
+		ouid = nuid = NO_UID_QUOTA_CHANGE;
 	if (!(attr->ia_valid & ATTR_GID) || ogid == ngid)
-		ogid = ngid = NO_QUOTA_CHANGE;
+		ogid = ngid = NO_GID_QUOTA_CHANGE;
 
 	error = gfs2_quota_lock(ip, nuid, ngid);
 	if (error)
 		return error;
 
-	if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) {
+	if (ouid != NO_UID_QUOTA_CHANGE || ogid != NO_GID_QUOTA_CHANGE) {
 		error = gfs2_quota_check(ip, nuid, ngid);
 		if (error)
 			goto out_gunlock_q;
@@ -1611,7 +1611,7 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
 	if (error)
 		goto out_end_trans;
 
-	if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) {
+	if (ouid != NO_UID_QUOTA_CHANGE || ogid != NO_GID_QUOTA_CHANGE) {
 		u64 blocks = gfs2_get_inode_blocks(&ip->i_inode);
 		gfs2_quota_change(ip, -blocks, ouid, ogid);
 		gfs2_quota_change(ip, blocks, nuid, ngid);
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index e4f6ccf..dbfacaa 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -524,7 +524,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
 	ip->i_res->rs_qa_qd_num++;
 	qd++;
 
-	if (uid != NO_QUOTA_CHANGE && uid != ip->i_inode.i_uid) {
+	if (uid != NO_UID_QUOTA_CHANGE && uid != ip->i_inode.i_uid) {
 		error = qdsb_get(sdp, QUOTA_USER, uid, qd);
 		if (error)
 			goto out;
@@ -532,7 +532,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
 		qd++;
 	}
 
-	if (gid != NO_QUOTA_CHANGE && gid != ip->i_inode.i_gid) {
+	if (gid != NO_GID_QUOTA_CHANGE && gid != ip->i_inode.i_gid) {
 		error = qdsb_get(sdp, QUOTA_GROUP, gid, qd);
 		if (error)
 			goto out;
diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h
index f25d98b..7f67323 100644
--- a/fs/gfs2/quota.h
+++ b/fs/gfs2/quota.h
@@ -14,7 +14,8 @@ struct gfs2_inode;
 struct gfs2_sbd;
 struct shrink_control;
 
-#define NO_QUOTA_CHANGE ((u32)-1)
+#define NO_UID_QUOTA_CHANGE INVALID_UID
+#define NO_GID_QUOTA_CHANGE INVALID_GID
 
 extern int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid);
 extern void gfs2_quota_unhold(struct gfs2_inode *ip);
@@ -41,7 +42,7 @@ static inline int gfs2_quota_lock_check(struct gfs2_inode *ip)
 	int ret;
 	if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
 		return 0;
-	ret = gfs2_quota_lock(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
+	ret = gfs2_quota_lock(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
 	if (ret)
 		return ret;
 	if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON)
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index d648867..7cc5a60 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1429,7 +1429,7 @@ static int gfs2_dinode_dealloc(struct gfs2_inode *ip)
 	if (error)
 		return error;
 
-	error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
+	error = gfs2_quota_hold(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
 	if (error)
 		return error;
 
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index 76c144b..80c25ae 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
@@ -331,7 +331,7 @@ static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
 	if (error)
 		return error;
 
-	error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
+	error = gfs2_quota_hold(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
 	if (error)
 		goto out_alloc;
 
@@ -1461,7 +1461,7 @@ int gfs2_ea_dealloc(struct gfs2_inode *ip)
 	if (error)
 		return error;
 
-	error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
+	error = gfs2_quota_hold(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
 	if (error)
 		return error;
 
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 29/85] gfs2: Report quotas in the caller's user namespace.
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (26 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 28/85] gfs2: Split NO_QUOTA_CHANGE inot NO_UID_QUTOA_CHANGE and NO_GID_QUTOA_CHANGE Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 30/85] gfs2: Introduce qd2index Eric W. Biederman
                     ` (55 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steven Whitehouse

From: "Eric W. Biederman" <ebiederm@xmission.com>

When a quota is queried return the uid or the gid in the mapped into
the caller's user namespace.  In addition perform the munged version
of the mapping so that instead of -1 a value that does not map is
reported as the overflowuid or the overflowgid.

Cc: Steven Whitehouse <swhiteho@redhat.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/gfs2/quota.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index dbfacaa..f8279ee 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -1509,7 +1509,7 @@ static int gfs2_get_dqblk(struct super_block *sb, struct kqid qid,
 	qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lksb.sb_lvbptr;
 	fdq->d_version = FS_DQUOT_VERSION;
 	fdq->d_flags = (type == QUOTA_USER) ? FS_USER_QUOTA : FS_GROUP_QUOTA;
-	fdq->d_id = from_kqid(&init_user_ns, qid);
+	fdq->d_id = from_kqid_munged(current_user_ns(), qid);
 	fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit) << sdp->sd_fsb2bb_shift;
 	fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn) << sdp->sd_fsb2bb_shift;
 	fdq->d_bcount = be64_to_cpu(qlvb->qb_value) << sdp->sd_fsb2bb_shift;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 30/85] gfs2: Introduce qd2index
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (27 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 29/85] gfs2: Report quotas in the caller's user namespace Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 31/85] gfs2: Modify struct gfs2_quota_change_host to use struct kqid Eric W. Biederman
                     ` (54 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steven Whitehouse

From: "Eric W. Biederman" <ebiederm@xmission.com>

Both qd_alloc and qd2offset perform the exact same computation
to get an index from a gfs2_quota_data.   Make life a little
simpler and factor out this index computation.

Cc: Steven Whitehouse <swhiteho@redhat.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/gfs2/quota.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index f8279ee..0e7c982 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -120,11 +120,17 @@ out:
 	return (atomic_read(&qd_lru_count) * sysctl_vfs_cache_pressure) / 100;
 }
 
+static u64 qd2index(struct gfs2_quota_data *qd)
+{
+	return (2 * (u64)qd->qd_id) +
+		test_bit(QDF_USER, &qd->qd_flags) ? 0 : 1;
+}
+
 static u64 qd2offset(struct gfs2_quota_data *qd)
 {
 	u64 offset;
 
-	offset = 2 * (u64)qd->qd_id + !test_bit(QDF_USER, &qd->qd_flags);
+	offset = qd2index(qd);
 	offset *= sizeof(struct gfs2_quota);
 
 	return offset;
@@ -147,7 +153,7 @@ static int qd_alloc(struct gfs2_sbd *sdp, int user, u32 id,
 	qd->qd_slot = -1;
 	INIT_LIST_HEAD(&qd->qd_reclaim);
 
-	error = gfs2_glock_get(sdp, 2 * (u64)id + !user,
+	error = gfs2_glock_get(sdp, qd2index(qd),
 			      &gfs2_quota_glops, CREATE, &qd->qd_gl);
 	if (error)
 		goto fail;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 31/85] gfs2: Modify struct gfs2_quota_change_host to use struct kqid
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (28 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 30/85] gfs2: Introduce qd2index Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 32/85] gfs2: Modify qdsb_get to take a " Eric W. Biederman
                     ` (53 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steven Whitehouse

From: "Eric W. Biederman" <ebiederm@xmission.com>

Cc: Steven Whitehouse <swhiteho@redhat.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/gfs2/quota.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 0e7c982..02913e9 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -71,7 +71,7 @@
 struct gfs2_quota_change_host {
 	u64 qc_change;
 	u32 qc_flags; /* GFS2_QCF_... */
-	u32 qc_id;
+	struct kqid qc_id;
 };
 
 static LIST_HEAD(qd_lru_list);
@@ -1200,7 +1200,9 @@ static void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *
 
 	qc->qc_change = be64_to_cpu(str->qc_change);
 	qc->qc_flags = be32_to_cpu(str->qc_flags);
-	qc->qc_id = be32_to_cpu(str->qc_id);
+	qc->qc_id = make_kqid(&init_user_ns,
+			      (qc->qc_flags & GFS2_QCF_USER)?USRQUOTA:GRPQUOTA,
+			      be32_to_cpu(str->qc_id));
 }
 
 int gfs2_quota_init(struct gfs2_sbd *sdp)
@@ -1264,7 +1266,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp)
 				continue;
 
 			error = qd_alloc(sdp, (qc.qc_flags & GFS2_QCF_USER),
-					 qc.qc_id, &qd);
+					 from_kqid(&init_user_ns, qc.qc_id), &qd);
 			if (error) {
 				brelse(bh);
 				goto fail;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 32/85] gfs2: Modify qdsb_get to take a struct kqid
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (29 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 31/85] gfs2: Modify struct gfs2_quota_change_host to use struct kqid Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 33/85] gfs2: Convert gfs2_quota_refresh to take a kqid Eric W. Biederman
                     ` (52 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steven Whitehouse

From: "Eric W. Biederman" <ebiederm@xmission.com>

Cc: Steven Whitehouse <swhiteho@redhat.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/gfs2/quota.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 02913e9..20762ae 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -464,12 +464,13 @@ static void qd_unlock(struct gfs2_quota_data *qd)
 	qd_put(qd);
 }
 
-static int qdsb_get(struct gfs2_sbd *sdp, int user, u32 id,
+static int qdsb_get(struct gfs2_sbd *sdp, struct kqid qid,
 		    struct gfs2_quota_data **qdp)
 {
 	int error;
 
-	error = qd_get(sdp, user, id, qdp);
+	error = qd_get(sdp, qid.type == USRQUOTA ? QUOTA_USER : QUOTA_GROUP,
+		       from_kqid(&init_user_ns, qid), qdp);
 	if (error)
 		return error;
 
@@ -518,20 +519,20 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
 	if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
 		return 0;
 
-	error = qdsb_get(sdp, QUOTA_USER, ip->i_inode.i_uid, qd);
+	error = qdsb_get(sdp, make_kqid_uid(ip->i_inode.i_uid), qd);
 	if (error)
 		goto out;
 	ip->i_res->rs_qa_qd_num++;
 	qd++;
 
-	error = qdsb_get(sdp, QUOTA_GROUP, ip->i_inode.i_gid, qd);
+	error = qdsb_get(sdp, make_kqid_gid(ip->i_inode.i_gid), qd);
 	if (error)
 		goto out;
 	ip->i_res->rs_qa_qd_num++;
 	qd++;
 
 	if (uid != NO_UID_QUOTA_CHANGE && uid != ip->i_inode.i_uid) {
-		error = qdsb_get(sdp, QUOTA_USER, uid, qd);
+		error = qdsb_get(sdp, make_kqid_uid(uid), qd);
 		if (error)
 			goto out;
 		ip->i_res->rs_qa_qd_num++;
@@ -539,7 +540,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
 	}
 
 	if (gid != NO_GID_QUOTA_CHANGE && gid != ip->i_inode.i_gid) {
-		error = qdsb_get(sdp, QUOTA_GROUP, gid, qd);
+		error = qdsb_get(sdp, make_kqid_gid(gid), qd);
 		if (error)
 			goto out;
 		ip->i_res->rs_qa_qd_num++;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 33/85] gfs2: Convert gfs2_quota_refresh to take a kqid
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (30 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 32/85] gfs2: Modify qdsb_get to take a " Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 34/85] gfs2: Store qd_id in struct gfs2_quota_data as a struct kqid Eric W. Biederman
                     ` (51 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steven Whitehouse

From: "Eric W. Biederman" <ebiederm@xmission.com>

- In quota_refresh_user_store convert the user supplied uid
  into a kqid and pass it to gfs2_quota_refresh.

- In quota_refresh_group_store convert the user supplied gid
  into a kqid and pass it to gfs2_quota_refresh.

Cc: Steven Whitehouse <swhiteho@redhat.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/gfs2/quota.c |    5 +++--
 fs/gfs2/quota.h |    2 +-
 fs/gfs2/sys.c   |   14 ++++++++++++--
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 20762ae..47315c0 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -1177,13 +1177,14 @@ static int gfs2_quota_sync_timeo(struct super_block *sb, int type)
 	return gfs2_quota_sync(sb, type);
 }
 
-int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id)
+int gfs2_quota_refresh(struct gfs2_sbd *sdp, struct kqid qid)
 {
 	struct gfs2_quota_data *qd;
 	struct gfs2_holder q_gh;
 	int error;
 
-	error = qd_get(sdp, user, id, &qd);
+	error = qd_get(sdp, qid.type == USRQUOTA ? QUOTA_USER : QUOTA_GROUP,
+		       from_kqid(&init_user_ns, qid), &qd);
 	if (error)
 		return error;
 
diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h
index 7f67323..bef805d 100644
--- a/fs/gfs2/quota.h
+++ b/fs/gfs2/quota.h
@@ -28,7 +28,7 @@ extern void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
 			      u32 uid, u32 gid);
 
 extern int gfs2_quota_sync(struct super_block *sb, int type);
-extern int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id);
+extern int gfs2_quota_refresh(struct gfs2_sbd *sdp, struct kqid qid);
 
 extern int gfs2_quota_init(struct gfs2_sbd *sdp);
 extern void gfs2_quota_cleanup(struct gfs2_sbd *sdp);
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index 8056b7b..e6d8d48 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -175,6 +175,7 @@ static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf,
 static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf,
 					size_t len)
 {
+	struct kqid qid;
 	int error;
 	u32 id;
 
@@ -183,13 +184,18 @@ static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf,
 
 	id = simple_strtoul(buf, NULL, 0);
 
-	error = gfs2_quota_refresh(sdp, 1, id);
+	qid = make_kqid(current_user_ns(), USRQUOTA, id);
+	if (!qid_valid(qid))
+		return -EINVAL;
+
+	error = gfs2_quota_refresh(sdp, qid);
 	return error ? error : len;
 }
 
 static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf,
 					 size_t len)
 {
+	struct kqid qid;
 	int error;
 	u32 id;
 
@@ -198,7 +204,11 @@ static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf,
 
 	id = simple_strtoul(buf, NULL, 0);
 
-	error = gfs2_quota_refresh(sdp, 0, id);
+	qid = make_kqid(current_user_ns(), GRPQUOTA, id);
+	if (!qid_valid(qid))
+		return -EINVAL;
+
+	error = gfs2_quota_refresh(sdp, qid);
 	return error ? error : len;
 }
 
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 34/85] gfs2: Store qd_id in struct gfs2_quota_data as a struct kqid
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (31 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 33/85] gfs2: Convert gfs2_quota_refresh to take a kqid Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 35/85] gfs2: Remove the QUOTA_USER and QUOTA_GROUP defines Eric W. Biederman
                     ` (50 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steven Whitehouse

From: "Eric W. Biederman" <ebiederm@xmission.com>

- Change qd_id in struct gfs2_qutoa_data to struct kqid.
- Remove the now unnecessary QDF_USER bit field in qd_flags.
- Propopoage this change through the code generally making
  things simpler along the way.

Cc: Steven Whitehouse <swhiteho@redhat.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/gfs2/incore.h |    3 +-
 fs/gfs2/quota.c  |   69 +++++++++++++++++++----------------------------------
 2 files changed, 26 insertions(+), 46 deletions(-)

diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index c373a24..5b298bd 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -391,7 +391,6 @@ struct gfs2_revoke_replay {
 };
 
 enum {
-	QDF_USER		= 0,
 	QDF_CHANGE		= 1,
 	QDF_LOCKED		= 2,
 	QDF_REFRESH		= 3,
@@ -403,7 +402,7 @@ struct gfs2_quota_data {
 
 	atomic_t qd_count;
 
-	u32 qd_id;
+	struct kqid qd_id;
 	unsigned long qd_flags;		/* QDF_... */
 
 	s64 qd_change;
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 47315c0..8cb4d10 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -122,8 +122,9 @@ out:
 
 static u64 qd2index(struct gfs2_quota_data *qd)
 {
-	return (2 * (u64)qd->qd_id) +
-		test_bit(QDF_USER, &qd->qd_flags) ? 0 : 1;
+	struct kqid qid = qd->qd_id;
+	return (2 * (u64)from_kqid(&init_user_ns, qid)) +
+		(qid.type == USRQUOTA) ? 0 : 1;
 }
 
 static u64 qd2offset(struct gfs2_quota_data *qd)
@@ -136,7 +137,7 @@ static u64 qd2offset(struct gfs2_quota_data *qd)
 	return offset;
 }
 
-static int qd_alloc(struct gfs2_sbd *sdp, int user, u32 id,
+static int qd_alloc(struct gfs2_sbd *sdp, struct kqid qid,
 		    struct gfs2_quota_data **qdp)
 {
 	struct gfs2_quota_data *qd;
@@ -147,9 +148,7 @@ static int qd_alloc(struct gfs2_sbd *sdp, int user, u32 id,
 		return -ENOMEM;
 
 	atomic_set(&qd->qd_count, 1);
-	qd->qd_id = id;
-	if (user)
-		set_bit(QDF_USER, &qd->qd_flags);
+	qd->qd_id = qid;
 	qd->qd_slot = -1;
 	INIT_LIST_HEAD(&qd->qd_reclaim);
 
@@ -167,7 +166,7 @@ fail:
 	return error;
 }
 
-static int qd_get(struct gfs2_sbd *sdp, int user, u32 id,
+static int qd_get(struct gfs2_sbd *sdp, struct kqid qid,
 		  struct gfs2_quota_data **qdp)
 {
 	struct gfs2_quota_data *qd = NULL, *new_qd = NULL;
@@ -179,8 +178,7 @@ static int qd_get(struct gfs2_sbd *sdp, int user, u32 id,
 		found = 0;
 		spin_lock(&qd_lru_lock);
 		list_for_each_entry(qd, &sdp->sd_quota_list, qd_list) {
-			if (qd->qd_id == id &&
-			    !test_bit(QDF_USER, &qd->qd_flags) == !user) {
+			if (qid_eq(qd->qd_id, qid)) {
 				if (!atomic_read(&qd->qd_count) &&
 				    !list_empty(&qd->qd_reclaim)) {
 					/* Remove it from reclaim list */
@@ -214,7 +212,7 @@ static int qd_get(struct gfs2_sbd *sdp, int user, u32 id,
 			return 0;
 		}
 
-		error = qd_alloc(sdp, user, id, &new_qd);
+		error = qd_alloc(sdp, qid, &new_qd);
 		if (error)
 			return error;
 	}
@@ -469,8 +467,7 @@ static int qdsb_get(struct gfs2_sbd *sdp, struct kqid qid,
 {
 	int error;
 
-	error = qd_get(sdp, qid.type == USRQUOTA ? QUOTA_USER : QUOTA_GROUP,
-		       from_kqid(&init_user_ns, qid), qdp);
+	error = qd_get(sdp, qid, qdp);
 	if (error)
 		return error;
 
@@ -574,18 +571,10 @@ static int sort_qd(const void *a, const void *b)
 	const struct gfs2_quota_data *qd_a = *(const struct gfs2_quota_data **)a;
 	const struct gfs2_quota_data *qd_b = *(const struct gfs2_quota_data **)b;
 
-	if (!test_bit(QDF_USER, &qd_a->qd_flags) !=
-	    !test_bit(QDF_USER, &qd_b->qd_flags)) {
-		if (test_bit(QDF_USER, &qd_a->qd_flags))
-			return -1;
-		else
-			return 1;
-	}
-	if (qd_a->qd_id < qd_b->qd_id)
+	if (qid_lt(qd_a->qd_id, qd_b->qd_id))
 		return -1;
-	if (qd_a->qd_id > qd_b->qd_id)
+	if (qid_lt(qd_b->qd_id, qd_a->qd_id))
 		return 1;
-
 	return 0;
 }
 
@@ -602,9 +591,9 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change)
 	if (!test_bit(QDF_CHANGE, &qd->qd_flags)) {
 		qc->qc_change = 0;
 		qc->qc_flags = 0;
-		if (test_bit(QDF_USER, &qd->qd_flags))
+		if (qd->qd_id.type == USRQUOTA)
 			qc->qc_flags = cpu_to_be32(GFS2_QCF_USER);
-		qc->qc_id = cpu_to_be32(qd->qd_id);
+		qc->qc_id = cpu_to_be32(from_kqid(&init_user_ns, qd->qd_id));
 	}
 
 	x = be64_to_cpu(qc->qc_change) + change;
@@ -1047,8 +1036,8 @@ static int print_message(struct gfs2_quota_data *qd, char *type)
 
 	printk(KERN_INFO "GFS2: fsid=%s: quota %s for %s %u\n",
 	       sdp->sd_fsname, type,
-	       (test_bit(QDF_USER, &qd->qd_flags)) ? "user" : "group",
-	       qd->qd_id);
+	       (qd->qd_id.type == USRQUOTA) ? "user" : "group",
+	       from_kqid(&init_user_ns, qd->qd_id));
 
 	return 0;
 }
@@ -1070,8 +1059,8 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
 	for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) {
 		qd = ip->i_res->rs_qa_qd[x];
 
-		if (!((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) ||
-		      (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags))))
+		if (!(qid_eq(qd->qd_id, make_kqid_uid(uid)) ||
+		      qid_eq(qd->qd_id, make_kqid_gid(gid))))
 			continue;
 
 		value = (s64)be64_to_cpu(qd->qd_qb.qb_value);
@@ -1081,10 +1070,7 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
 
 		if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) {
 			print_message(qd, "exceeded");
-			quota_send_warning(make_kqid(&init_user_ns,
-						     test_bit(QDF_USER, &qd->qd_flags) ?
-						     USRQUOTA : GRPQUOTA,
-						     qd->qd_id),
+			quota_send_warning(qd->qd_id,
 					   sdp->sd_vfs->s_dev, QUOTA_NL_BHARDWARN);
 
 			error = -EDQUOT;
@@ -1094,10 +1080,7 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
 			   time_after_eq(jiffies, qd->qd_last_warn +
 					 gfs2_tune_get(sdp,
 						gt_quota_warn_period) * HZ)) {
-			quota_send_warning(make_kqid(&init_user_ns,
-						     test_bit(QDF_USER, &qd->qd_flags) ?
-						     USRQUOTA : GRPQUOTA,
-						     qd->qd_id),
+			quota_send_warning(qd->qd_id,
 					   sdp->sd_vfs->s_dev, QUOTA_NL_BSOFTWARN);
 			error = print_message(qd, "warning");
 			qd->qd_last_warn = jiffies;
@@ -1121,8 +1104,8 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
 	for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) {
 		qd = ip->i_res->rs_qa_qd[x];
 
-		if ((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) ||
-		    (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags))) {
+		if (qid_eq(qd->qd_id, make_kqid_uid(uid)) ||
+		    qid_eq(qd->qd_id, make_kqid_gid(gid))) {
 			do_qc(qd, change);
 		}
 	}
@@ -1183,8 +1166,7 @@ int gfs2_quota_refresh(struct gfs2_sbd *sdp, struct kqid qid)
 	struct gfs2_holder q_gh;
 	int error;
 
-	error = qd_get(sdp, qid.type == USRQUOTA ? QUOTA_USER : QUOTA_GROUP,
-		       from_kqid(&init_user_ns, qid), &qd);
+	error = qd_get(sdp, qid, &qd);
 	if (error)
 		return error;
 
@@ -1267,8 +1249,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp)
 			if (!qc.qc_change)
 				continue;
 
-			error = qd_alloc(sdp, (qc.qc_flags & GFS2_QCF_USER),
-					 from_kqid(&init_user_ns, qc.qc_id), &qd);
+			error = qd_alloc(sdp, qc.qc_id, &qd);
 			if (error) {
 				brelse(bh);
 				goto fail;
@@ -1509,7 +1490,7 @@ static int gfs2_get_dqblk(struct super_block *sb, struct kqid qid,
 	else
 		return -EINVAL;
 
-	error = qd_get(sdp, type, from_kqid(&init_user_ns, qid), &qd);
+	error = qd_get(sdp, qid, &qd);
 	if (error)
 		return error;
 	error = do_glock(qd, FORCE, &q_gh);
@@ -1564,7 +1545,7 @@ static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid,
 	if (fdq->d_fieldmask & ~GFS2_FIELDMASK)
 		return -EINVAL;
 
-	error = qd_get(sdp, type, from_kqid(&init_user_ns, qid), &qd);
+	error = qd_get(sdp, qid, &qd);
 	if (error)
 		return error;
 
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 35/85] gfs2: Remove the QUOTA_USER and QUOTA_GROUP defines
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (32 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 34/85] gfs2: Store qd_id in struct gfs2_quota_data as a struct kqid Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 36/85] gfs2: Use kuid_t and kgid_t types where appropriate Eric W. Biederman
                     ` (49 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steven Whitehouse

From: "Eric W. Biederman" <ebiederm@xmission.com>

Remove the QUOTA_USER and QUOTA_GRUP defines.  Remove
the last vestigal users of QUOTA_USER and QUOTA_GROUP.

Now that struct kqid is used throughout the gfs2 quota
code the need there is to use QUOTA_USER and QUOTA_GROUP
and the defines are just extraneous and confusing.

Cc: Steven Whitehouse <swhiteho@redhat.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/gfs2/quota.c |   25 +++++--------------------
 1 files changed, 5 insertions(+), 20 deletions(-)

diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 8cb4d10..0bbb040 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -65,9 +65,6 @@
 #include "inode.h"
 #include "util.h"
 
-#define QUOTA_USER 1
-#define QUOTA_GROUP 0
-
 struct gfs2_quota_change_host {
 	u64 qc_change;
 	u32 qc_flags; /* GFS2_QCF_... */
@@ -1476,18 +1473,14 @@ static int gfs2_get_dqblk(struct super_block *sb, struct kqid qid,
 	struct gfs2_quota_data *qd;
 	struct gfs2_holder q_gh;
 	int error;
-	int type;
 
 	memset(fdq, 0, sizeof(struct fs_disk_quota));
 
 	if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
 		return -ESRCH; /* Crazy XFS error code */
 
-	if (qid.type == USRQUOTA)
-		type = QUOTA_USER;
-	else if (qid.type == GRPQUOTA)
-		type = QUOTA_GROUP;
-	else
+	if ((qid.type != USRQUOTA) &&
+	    (qid.type != GRPQUOTA))
 		return -EINVAL;
 
 	error = qd_get(sdp, qid, &qd);
@@ -1499,7 +1492,7 @@ static int gfs2_get_dqblk(struct super_block *sb, struct kqid qid,
 
 	qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lksb.sb_lvbptr;
 	fdq->d_version = FS_DQUOT_VERSION;
-	fdq->d_flags = (type == QUOTA_USER) ? FS_USER_QUOTA : FS_GROUP_QUOTA;
+	fdq->d_flags = (qid.type == USRQUOTA) ? FS_USER_QUOTA : FS_GROUP_QUOTA;
 	fdq->d_id = from_kqid_munged(current_user_ns(), qid);
 	fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit) << sdp->sd_fsb2bb_shift;
 	fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn) << sdp->sd_fsb2bb_shift;
@@ -1526,21 +1519,13 @@ static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid,
 	int alloc_required;
 	loff_t offset;
 	int error;
-	int type;
 
 	if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
 		return -ESRCH; /* Crazy XFS error code */
 
-	switch(qid.type) {
-	case USRQUOTA:
-		type = QUOTA_USER;
-		break;
-	case GRPQUOTA:
-		type = QUOTA_GROUP;
-		break;
-	default:
+	if ((qid.type != USRQUOTA) &&
+	    (qid.type != GRPQUOTA))
 		return -EINVAL;
-	}
 
 	if (fdq->d_fieldmask & ~GFS2_FIELDMASK)
 		return -EINVAL;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 36/85] gfs2: Use kuid_t and kgid_t types where appropriate.
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (33 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 35/85] gfs2: Remove the QUOTA_USER and QUOTA_GROUP defines Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 37/85] gfs2: Use uid_eq and gid_eq " Eric W. Biederman
                     ` (48 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steven Whitehouse

From: "Eric W. Biederman" <ebiederm@xmission.com>

Cc: Steven Whitehouse <swhiteho@redhat.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/gfs2/inode.c |    3 ++-
 fs/gfs2/quota.c |    8 ++++----
 fs/gfs2/quota.h |    8 ++++----
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index aa10502..ce07ce4 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -1580,7 +1580,8 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
 {
 	struct gfs2_inode *ip = GFS2_I(inode);
 	struct gfs2_sbd *sdp = GFS2_SB(inode);
-	u32 ouid, ogid, nuid, ngid;
+	kuid_t ouid, nuid;
+	kgid_t ogid, ngid;
 	int error;
 
 	ouid = inode->i_uid;
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 0bbb040..87f2740 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -492,7 +492,7 @@ static void qdsb_put(struct gfs2_quota_data *qd)
 	qd_put(qd);
 }
 
-int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
+int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid)
 {
 	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_quota_data **qd;
@@ -918,7 +918,7 @@ fail:
 	return error;
 }
 
-int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid)
+int gfs2_quota_lock(struct gfs2_inode *ip, kuid_t uid, kgid_t gid)
 {
 	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_quota_data *qd;
@@ -1039,7 +1039,7 @@ static int print_message(struct gfs2_quota_data *qd, char *type)
 	return 0;
 }
 
-int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
+int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid)
 {
 	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 	struct gfs2_quota_data *qd;
@@ -1088,7 +1088,7 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
 }
 
 void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
-		       u32 uid, u32 gid)
+		       kuid_t uid, kgid_t gid)
 {
 	struct gfs2_quota_data *qd;
 	unsigned int x;
diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h
index bef805d..4f5e6e4 100644
--- a/fs/gfs2/quota.h
+++ b/fs/gfs2/quota.h
@@ -17,15 +17,15 @@ struct shrink_control;
 #define NO_UID_QUOTA_CHANGE INVALID_UID
 #define NO_GID_QUOTA_CHANGE INVALID_GID
 
-extern int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid);
+extern int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid);
 extern void gfs2_quota_unhold(struct gfs2_inode *ip);
 
-extern int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid);
+extern int gfs2_quota_lock(struct gfs2_inode *ip, kuid_t uid, kgid_t gid);
 extern void gfs2_quota_unlock(struct gfs2_inode *ip);
 
-extern int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid);
+extern int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid);
 extern void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
-			      u32 uid, u32 gid);
+			      kuid_t uid, kgid_t gid);
 
 extern int gfs2_quota_sync(struct super_block *sb, int type);
 extern int gfs2_quota_refresh(struct gfs2_sbd *sdp, struct kqid qid);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 37/85] gfs2: Use uid_eq and gid_eq where appropriate
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (34 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 36/85] gfs2: Use kuid_t and kgid_t types where appropriate Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 38/85] gfs2: Convert uids and gids between dinodes and vfs inodes Eric W. Biederman
                     ` (47 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steven Whitehouse

From: "Eric W. Biederman" <ebiederm@xmission.com>

Where kuid_t values are compared use uid_eq and where kgid_t values
are compared use gid_eq.  This is unfortunately necessary because
of the type safety that keeps someone from accidentally mixing
kuids and kgids with other types.

Cc: Steven Whitehouse <swhiteho@redhat.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/gfs2/acl.c   |    2 +-
 fs/gfs2/inode.c |   19 +++++++++++--------
 fs/gfs2/quota.c |    6 ++++--
 3 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c
index f850020..f69ac0a 100644
--- a/fs/gfs2/acl.c
+++ b/fs/gfs2/acl.c
@@ -237,7 +237,7 @@ static int gfs2_xattr_system_set(struct dentry *dentry, const char *name,
 		return -EINVAL;
 	if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
 		return value ? -EACCES : 0;
-	if ((current_fsuid() != inode->i_uid) && !capable(CAP_FOWNER))
+	if (!uid_eq(current_fsuid(), inode->i_uid) && !capable(CAP_FOWNER))
 		return -EPERM;
 	if (S_ISLNK(inode->i_mode))
 		return -EOPNOTSUPP;
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index ce07ce4..bb7c754 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -368,10 +368,11 @@ static void munge_mode_uid_gid(const struct gfs2_inode *dip,
 			       struct inode *inode)
 {
 	if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir &&
-	    (dip->i_inode.i_mode & S_ISUID) && dip->i_inode.i_uid) {
+	    (dip->i_inode.i_mode & S_ISUID) &&
+	    !uid_eq(dip->i_inode.i_uid, GLOBAL_ROOT_UID)) {
 		if (S_ISDIR(inode->i_mode))
 			inode->i_mode |= S_ISUID;
-		else if (dip->i_inode.i_uid != current_fsuid())
+		else if (!uid_eq(dip->i_inode.i_uid, current_fsuid()))
 			inode->i_mode &= ~07111;
 		inode->i_uid = dip->i_inode.i_uid;
 	} else
@@ -978,8 +979,8 @@ static int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
 		return -EPERM;
 
 	if ((dip->i_inode.i_mode & S_ISVTX) &&
-	    dip->i_inode.i_uid != current_fsuid() &&
-	    ip->i_inode.i_uid != current_fsuid() && !capable(CAP_FOWNER))
+	    !uid_eq(dip->i_inode.i_uid, current_fsuid()) &&
+	    !uid_eq(ip->i_inode.i_uid, current_fsuid()) && !capable(CAP_FOWNER))
 		return -EPERM;
 
 	if (IS_APPEND(&dip->i_inode))
@@ -1589,16 +1590,17 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
 	nuid = attr->ia_uid;
 	ngid = attr->ia_gid;
 
-	if (!(attr->ia_valid & ATTR_UID) || ouid == nuid)
+	if (!(attr->ia_valid & ATTR_UID) || uid_eq(ouid, nuid))
 		ouid = nuid = NO_UID_QUOTA_CHANGE;
-	if (!(attr->ia_valid & ATTR_GID) || ogid == ngid)
+	if (!(attr->ia_valid & ATTR_GID) || gid_eq(ogid, ngid))
 		ogid = ngid = NO_GID_QUOTA_CHANGE;
 
 	error = gfs2_quota_lock(ip, nuid, ngid);
 	if (error)
 		return error;
 
-	if (ouid != NO_UID_QUOTA_CHANGE || ogid != NO_GID_QUOTA_CHANGE) {
+	if (!uid_eq(ouid, NO_UID_QUOTA_CHANGE) ||
+	    !gid_eq(ogid, NO_GID_QUOTA_CHANGE)) {
 		error = gfs2_quota_check(ip, nuid, ngid);
 		if (error)
 			goto out_gunlock_q;
@@ -1612,7 +1614,8 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
 	if (error)
 		goto out_end_trans;
 
-	if (ouid != NO_UID_QUOTA_CHANGE || ogid != NO_GID_QUOTA_CHANGE) {
+	if (!uid_eq(ouid, NO_UID_QUOTA_CHANGE) ||
+	    !gid_eq(ogid, NO_GID_QUOTA_CHANGE)) {
 		u64 blocks = gfs2_get_inode_blocks(&ip->i_inode);
 		gfs2_quota_change(ip, -blocks, ouid, ogid);
 		gfs2_quota_change(ip, blocks, nuid, ngid);
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 87f2740..afd2e5d 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -525,7 +525,8 @@ int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid)
 	ip->i_res->rs_qa_qd_num++;
 	qd++;
 
-	if (uid != NO_UID_QUOTA_CHANGE && uid != ip->i_inode.i_uid) {
+	if (!uid_eq(uid, NO_UID_QUOTA_CHANGE) &&
+	    !uid_eq(uid, ip->i_inode.i_uid)) {
 		error = qdsb_get(sdp, make_kqid_uid(uid), qd);
 		if (error)
 			goto out;
@@ -533,7 +534,8 @@ int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid)
 		qd++;
 	}
 
-	if (gid != NO_GID_QUOTA_CHANGE && gid != ip->i_inode.i_gid) {
+	if (!gid_eq(gid, NO_GID_QUOTA_CHANGE) &&
+	    !gid_eq(gid, ip->i_inode.i_gid)) {
 		error = qdsb_get(sdp, make_kqid_gid(gid), qd);
 		if (error)
 			goto out;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 38/85] gfs2: Convert uids and gids between dinodes and vfs inodes.
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (35 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 37/85] gfs2: Use uid_eq and gid_eq " Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 39/85] gfs2: Enable building with user namespaces enabled Eric W. Biederman
                     ` (46 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steven Whitehouse

From: "Eric W. Biederman" <ebiederm@xmission.com>

When reading dinodes from the disk convert uids and gids
into kuids and kgids to store in vfs data structures.

When writing to dinodes to the disk convert kuids and kgids
in the in memory structures into plain uids and gids.

For now all on disk data structures are assumed to be
stored in the initial user namespace.

Cc: Steven Whitehouse <swhiteho@redhat.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/gfs2/glops.c |    4 ++--
 fs/gfs2/inode.c |    4 ++--
 fs/gfs2/super.c |    4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 78d4184..444b650 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -322,8 +322,8 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
 		break;
 	};
 
-	ip->i_inode.i_uid = be32_to_cpu(str->di_uid);
-	ip->i_inode.i_gid = be32_to_cpu(str->di_gid);
+	i_uid_write(&ip->i_inode, be32_to_cpu(str->di_uid));
+	i_gid_write(&ip->i_inode, be32_to_cpu(str->di_gid));
 	gfs2_set_nlink(&ip->i_inode, be32_to_cpu(str->di_nlink));
 	i_size_write(&ip->i_inode, be64_to_cpu(str->di_size));
 	gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks));
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index bb7c754..b862d11 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -456,8 +456,8 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_inode *ip,
 	di->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino);
 	di->di_num.no_addr = cpu_to_be64(ip->i_no_addr);
 	di->di_mode = cpu_to_be32(ip->i_inode.i_mode);
-	di->di_uid = cpu_to_be32(ip->i_inode.i_uid);
-	di->di_gid = cpu_to_be32(ip->i_inode.i_gid);
+	di->di_uid = cpu_to_be32(i_uid_read(&ip->i_inode));
+	di->di_gid = cpu_to_be32(i_gid_read(&ip->i_inode));
 	di->di_nlink = 0;
 	di->di_size = cpu_to_be64(ip->i_inode.i_size);
 	di->di_blocks = cpu_to_be64(1);
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 7cc5a60..a034253 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -721,8 +721,8 @@ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf)
 	str->di_num.no_addr = cpu_to_be64(ip->i_no_addr);
 	str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino);
 	str->di_mode = cpu_to_be32(ip->i_inode.i_mode);
-	str->di_uid = cpu_to_be32(ip->i_inode.i_uid);
-	str->di_gid = cpu_to_be32(ip->i_inode.i_gid);
+	str->di_uid = cpu_to_be32(i_uid_read(&ip->i_inode));
+	str->di_gid = cpu_to_be32(i_gid_read(&ip->i_inode));
 	str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink);
 	str->di_size = cpu_to_be64(i_size_read(&ip->i_inode));
 	str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode));
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 39/85] gfs2: Enable building with user namespaces enabled
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (36 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 38/85] gfs2: Convert uids and gids between dinodes and vfs inodes Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 40/85] ncpfs: Support interacting with multiple user namespaces Eric W. Biederman
                     ` (45 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steven Whitehouse

From: "Eric W. Biederman" <ebiederm@xmission.com>

Now that all of the necessary work has been done to push kuids and
kgids throughout gfs2 and to convert between kuids and kgids when
reading and writing the on disk structures it is safe to enable gfs2
when multiple user namespaces are enabled.

Cc: Steven Whitehouse <swhiteho@redhat.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 init/Kconfig |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/init/Kconfig b/init/Kconfig
index 9cb63c9..591fc75 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1072,7 +1072,6 @@ config UIDGID_CONVERTED
 
 	# Filesystems
 	depends on CIFS = n
-	depends on GFS2_FS = n
 	depends on NCP_FS = n
 	depends on NFSD = n
 	depends on NFS_FS = n
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 40/85] ncpfs: Support interacting with multiple user namespaces
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (37 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 39/85] gfs2: Enable building with user namespaces enabled Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 41/85] nfs_common: Update the translation between nfsv3 acls linux posix acls Eric W. Biederman
                     ` (44 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Petr Vandrovec

From: "Eric W. Biederman" <ebiederm@xmission.com>

ncpfs does not natively support uids and gids so this conversion was
simply a matter of updating the the type of the mounteduid, the uid
and the gid on the superblock. Fixing the ioctls that read them,
updating the mount option parser and the mount option printer.

Cc: Petr Vandrovec <petr@vandrovec.name>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
 fs/ncpfs/inode.c     |   55 ++++++++++++++++++++++++++++++--------------------
 fs/ncpfs/ioctl.c     |   25 ++++++++++++----------
 fs/ncpfs/ncp_fs_sb.h |    6 ++--
 init/Kconfig         |    1 -
 4 files changed, 50 insertions(+), 37 deletions(-)

diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 1acdad7..e2be336 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -331,12 +331,15 @@ static int  ncp_show_options(struct seq_file *seq, struct dentry *root)
 	struct ncp_server *server = NCP_SBP(root->d_sb);
 	unsigned int tmp;
 
-	if (server->m.uid != 0)
-		seq_printf(seq, ",uid=%u", server->m.uid);
-	if (server->m.gid != 0)
-		seq_printf(seq, ",gid=%u", server->m.gid);
-	if (server->m.mounted_uid != 0)
-		seq_printf(seq, ",owner=%u", server->m.mounted_uid);
+	if (!uid_eq(server->m.uid, GLOBAL_ROOT_UID))
+		seq_printf(seq, ",uid=%u",
+			   from_kuid_munged(&init_user_ns, server->m.uid));
+	if (!gid_eq(server->m.gid, GLOBAL_ROOT_GID))
+		seq_printf(seq, ",gid=%u",
+			   from_kgid_munged(&init_user_ns, server->m.gid));
+	if (!uid_eq(server->m.mounted_uid, GLOBAL_ROOT_UID))
+		seq_printf(seq, ",owner=%u",
+			   from_kuid_munged(&init_user_ns, server->m.mounted_uid));
 	tmp = server->m.file_mode & S_IALLUGO;
 	if (tmp != NCP_DEFAULT_FILE_MODE)
 		seq_printf(seq, ",mode=0%o", tmp);
@@ -381,13 +384,13 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
 
 	data->flags = 0;
 	data->int_flags = 0;
-	data->mounted_uid = 0;
+	data->mounted_uid = GLOBAL_ROOT_UID;
 	data->wdog_pid = NULL;
 	data->ncp_fd = ~0;
 	data->time_out = NCP_DEFAULT_TIME_OUT;
 	data->retry_count = NCP_DEFAULT_RETRY_COUNT;
-	data->uid = 0;
-	data->gid = 0;
+	data->uid = GLOBAL_ROOT_UID;
+	data->gid = GLOBAL_ROOT_GID;
 	data->file_mode = NCP_DEFAULT_FILE_MODE;
 	data->dir_mode = NCP_DEFAULT_DIR_MODE;
 	data->info_fd = -1;
@@ -399,13 +402,19 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
 			goto err;
 		switch (optval) {
 			case 'u':
-				data->uid = optint;
+				data->uid = make_kuid(current_user_ns(), optint);
+				if (!uid_valid(data->uid))
+					goto err;
 				break;
 			case 'g':
-				data->gid = optint;
+				data->gid = make_kgid(current_user_ns(), optint);
+				if (!gid_valid(data->gid))
+					goto err;
 				break;
 			case 'o':
-				data->mounted_uid = optint;
+				data->mounted_uid = make_kuid(current_user_ns(), optint);
+				if (!uid_valid(data->mounted_uid))
+					goto err;
 				break;
 			case 'm':
 				data->file_mode = optint;
@@ -480,13 +489,13 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
 
 				data.flags = md->flags;
 				data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
-				data.mounted_uid = md->mounted_uid;
+				data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
 				data.wdog_pid = find_get_pid(md->wdog_pid);
 				data.ncp_fd = md->ncp_fd;
 				data.time_out = md->time_out;
 				data.retry_count = md->retry_count;
-				data.uid = md->uid;
-				data.gid = md->gid;
+				data.uid = make_kuid(current_user_ns(), md->uid);
+				data.gid = make_kgid(current_user_ns(), md->gid);
 				data.file_mode = md->file_mode;
 				data.dir_mode = md->dir_mode;
 				data.info_fd = -1;
@@ -499,13 +508,13 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
 				struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
 
 				data.flags = md->flags;
-				data.mounted_uid = md->mounted_uid;
+				data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
 				data.wdog_pid = find_get_pid(md->wdog_pid);
 				data.ncp_fd = md->ncp_fd;
 				data.time_out = md->time_out;
 				data.retry_count = md->retry_count;
-				data.uid = md->uid;
-				data.gid = md->gid;
+				data.uid = make_kuid(current_user_ns(), md->uid);
+				data.gid = make_kgid(current_user_ns(), md->gid);
 				data.file_mode = md->file_mode;
 				data.dir_mode = md->dir_mode;
 				data.info_fd = -1;
@@ -520,6 +529,10 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
 				goto out;
 			break;
 	}
+	error = -EINVAL;
+	if (!uid_valid(data.mounted_uid) || !uid_valid(data.uid) ||
+	    !gid_valid(data.gid))
+		goto out;
 	error = -EBADF;
 	ncp_filp = fget(data.ncp_fd);
 	if (!ncp_filp)
@@ -886,12 +899,10 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
 		goto out;
 
 	result = -EPERM;
-	if (((attr->ia_valid & ATTR_UID) &&
-	     (attr->ia_uid != server->m.uid)))
+	if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid))
 		goto out;
 
-	if (((attr->ia_valid & ATTR_GID) &&
-	     (attr->ia_gid != server->m.gid)))
+	if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid))
 		goto out;
 
 	if (((attr->ia_valid & ATTR_MODE) &&
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c
index 6958adf..d44318d 100644
--- a/fs/ncpfs/ioctl.c
+++ b/fs/ncpfs/ioctl.c
@@ -45,7 +45,7 @@ ncp_get_fs_info(struct ncp_server * server, struct inode *inode,
 		return -EINVAL;
 	}
 	/* TODO: info.addr = server->m.serv_addr; */
-	SET_UID(info.mounted_uid, server->m.mounted_uid);
+	SET_UID(info.mounted_uid, from_kuid_munged(current_user_ns(), server->m.mounted_uid));
 	info.connection		= server->connection;
 	info.buffer_size	= server->buffer_size;
 	info.volume_number	= NCP_FINFO(inode)->volNumber;
@@ -69,7 +69,7 @@ ncp_get_fs_info_v2(struct ncp_server * server, struct inode *inode,
 		DPRINTK("info.version invalid: %d\n", info2.version);
 		return -EINVAL;
 	}
-	info2.mounted_uid   = server->m.mounted_uid;
+	info2.mounted_uid   = from_kuid_munged(current_user_ns(), server->m.mounted_uid);
 	info2.connection    = server->connection;
 	info2.buffer_size   = server->buffer_size;
 	info2.volume_number = NCP_FINFO(inode)->volNumber;
@@ -135,7 +135,7 @@ ncp_get_compat_fs_info_v2(struct ncp_server * server, struct inode *inode,
 		DPRINTK("info.version invalid: %d\n", info2.version);
 		return -EINVAL;
 	}
-	info2.mounted_uid   = server->m.mounted_uid;
+	info2.mounted_uid   = from_kuid_munged(current_user_ns(), server->m.mounted_uid);
 	info2.connection    = server->connection;
 	info2.buffer_size   = server->buffer_size;
 	info2.volume_number = NCP_FINFO(inode)->volNumber;
@@ -348,22 +348,25 @@ static long __ncp_ioctl(struct inode *inode, unsigned int cmd, unsigned long arg
 		{
 			u16 uid;
 
-			SET_UID(uid, server->m.mounted_uid);
+			SET_UID(uid, from_kuid_munged(current_user_ns(), server->m.mounted_uid));
 			if (put_user(uid, (u16 __user *)argp))
 				return -EFAULT;
 			return 0;
 		}
 	case NCP_IOC_GETMOUNTUID32:
-		if (put_user(server->m.mounted_uid,
-			     (u32 __user *)argp))
+	{
+		uid_t uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid);
+		if (put_user(uid, (u32 __user *)argp))
 			return -EFAULT;
 		return 0;
+	}
 	case NCP_IOC_GETMOUNTUID64:
-		if (put_user(server->m.mounted_uid,
-			     (u64 __user *)argp))
+	{
+		uid_t uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid);
+		if (put_user(uid, (u64 __user *)argp))
 			return -EFAULT;
 		return 0;
-
+	}
 	case NCP_IOC_GETROOT:
 		{
 			struct ncp_setroot_ioctl sr;
@@ -810,7 +813,7 @@ long ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
 	struct ncp_server *server = NCP_SERVER(inode);
-	uid_t uid = current_uid();
+	kuid_t uid = current_uid();
 	int need_drop_write = 0;
 	long ret;
 
@@ -824,7 +827,7 @@ long ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 		}
 		break;
 	}
-	if (server->m.mounted_uid != uid) {
+	if (!uid_eq(server->m.mounted_uid, uid)) {
 		switch (cmd) {
 		/*
 		 * Only mount owner can issue these ioctls.  Information
diff --git a/fs/ncpfs/ncp_fs_sb.h b/fs/ncpfs/ncp_fs_sb.h
index 54cc0cd..c51b2c5 100644
--- a/fs/ncpfs/ncp_fs_sb.h
+++ b/fs/ncpfs/ncp_fs_sb.h
@@ -23,15 +23,15 @@ struct ncp_mount_data_kernel {
 	unsigned long    flags;		/* NCP_MOUNT_* flags */
 	unsigned int	 int_flags;	/* internal flags */
 #define NCP_IMOUNT_LOGGEDIN_POSSIBLE	0x0001
-	uid_t		 mounted_uid;	/* Who may umount() this filesystem? */
+	kuid_t		 mounted_uid;	/* Who may umount() this filesystem? */
 	struct pid      *wdog_pid;	/* Who cares for our watchdog packets? */
 	unsigned int     ncp_fd;	/* The socket to the ncp port */
 	unsigned int     time_out;	/* How long should I wait after
 					   sending a NCP request? */
 	unsigned int     retry_count;	/* And how often should I retry? */
 	unsigned char	 mounted_vol[NCP_VOLNAME_LEN + 1];
-	uid_t		 uid;
-	gid_t		 gid;
+	kuid_t		 uid;
+	kgid_t		 gid;
 	umode_t		 file_mode;
 	umode_t		 dir_mode;
 	int		 info_fd;
diff --git a/init/Kconfig b/init/Kconfig
index 591fc75..b526f4c 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1072,7 +1072,6 @@ config UIDGID_CONVERTED
 
 	# Filesystems
 	depends on CIFS = n
-	depends on NCP_FS = n
 	depends on NFSD = n
 	depends on NFS_FS = n
 	depends on XFS_FS = n
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 41/85] nfs_common: Update the translation between nfsv3 acls linux posix acls
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (38 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 40/85] ncpfs: Support interacting with multiple user namespaces Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 42/85] sunrpc: Use userns friendly constants Eric W. Biederman
                     ` (43 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

- Use kuid_t and kgit in struct nfsacl_encode_desc.
- Convert from kuids and kgids when generating on the wire values.
- Convert on the wire values to kuids and kgids when read.
- Modify cmp_acl_entry to be type safe comparison on posix acls.
  Only acls with type ACL_USER and ACL_GROUP can appear more
  than once and as such need to compare more than their tag.
- The e_id field is being removed from posix acls so don't initialize it.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/nfs_common/nfsacl.c |   41 ++++++++++++++++++++++++++---------------
 1 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/fs/nfs_common/nfsacl.c b/fs/nfs_common/nfsacl.c
index 6940439..ed628f7 100644
--- a/fs/nfs_common/nfsacl.c
+++ b/fs/nfs_common/nfsacl.c
@@ -38,8 +38,8 @@ struct nfsacl_encode_desc {
 	unsigned int count;
 	struct posix_acl *acl;
 	int typeflag;
-	uid_t uid;
-	gid_t gid;
+	kuid_t uid;
+	kgid_t gid;
 };
 
 struct nfsacl_simple_acl {
@@ -60,14 +60,16 @@ xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem)
 	*p++ = htonl(entry->e_tag | nfsacl_desc->typeflag);
 	switch(entry->e_tag) {
 		case ACL_USER_OBJ:
-			*p++ = htonl(nfsacl_desc->uid);
+			*p++ = htonl(from_kuid(&init_user_ns, nfsacl_desc->uid));
 			break;
 		case ACL_GROUP_OBJ:
-			*p++ = htonl(nfsacl_desc->gid);
+			*p++ = htonl(from_kgid(&init_user_ns, nfsacl_desc->gid));
 			break;
 		case ACL_USER:
+			*p++ = htonl(from_kuid(&init_user_ns, entry->e_uid));
+			break;
 		case ACL_GROUP:
-			*p++ = htonl(entry->e_id);
+			*p++ = htonl(from_kgid(&init_user_ns, entry->e_gid));
 			break;
 		default:  /* Solaris depends on that! */
 			*p++ = 0;
@@ -148,6 +150,7 @@ xdr_nfsace_decode(struct xdr_array2_desc *desc, void *elem)
 		(struct nfsacl_decode_desc *) desc;
 	__be32 *p = elem;
 	struct posix_acl_entry *entry;
+	unsigned int id;
 
 	if (!nfsacl_desc->acl) {
 		if (desc->array_len > NFS_ACL_MAX_ENTRIES)
@@ -160,14 +163,22 @@ xdr_nfsace_decode(struct xdr_array2_desc *desc, void *elem)
 
 	entry = &nfsacl_desc->acl->a_entries[nfsacl_desc->count++];
 	entry->e_tag = ntohl(*p++) & ~NFS_ACL_DEFAULT;
-	entry->e_id = ntohl(*p++);
+	id = ntohl(*p++);
 	entry->e_perm = ntohl(*p++);
 
 	switch(entry->e_tag) {
-		case ACL_USER_OBJ:
 		case ACL_USER:
-		case ACL_GROUP_OBJ:
+			entry->e_uid = make_kuid(&init_user_ns, id);
+			if (!uid_valid(entry->e_uid))
+				return -EINVAL;
+			break;
 		case ACL_GROUP:
+			entry->e_gid = make_kgid(&init_user_ns, id);
+			if (!gid_valid(entry->e_gid))
+				return -EINVAL;
+			break;
+		case ACL_USER_OBJ:
+		case ACL_GROUP_OBJ:
 		case ACL_OTHER:
 			if (entry->e_perm & ~S_IRWXO)
 				return -EINVAL;
@@ -190,9 +201,13 @@ cmp_acl_entry(const void *x, const void *y)
 
 	if (a->e_tag != b->e_tag)
 		return a->e_tag - b->e_tag;
-	else if (a->e_id > b->e_id)
+	else if ((a->e_tag == ACL_USER) && uid_gt(a->e_uid, b->e_uid))
+		return 1;
+	else if ((a->e_tag == ACL_USER) && uid_lt(a->e_uid, b->e_uid))
+		return -1;
+	else if ((a->e_tag == ACL_GROUP) && gid_gt(a->e_gid, b->e_gid))
 		return 1;
-	else if (a->e_id < b->e_id)
+	else if ((a->e_tag == ACL_GROUP) && gid_lt(a->e_gid, b->e_gid))
 		return -1;
 	else
 		return 0;
@@ -213,22 +228,18 @@ posix_acl_from_nfsacl(struct posix_acl *acl)
 	sort(acl->a_entries, acl->a_count, sizeof(struct posix_acl_entry),
 	     cmp_acl_entry, NULL);
 
-	/* Clear undefined identifier fields and find the ACL_GROUP_OBJ
-	   and ACL_MASK entries. */
+	/* Find the ACL_GROUP_OBJ and ACL_MASK entries. */
 	FOREACH_ACL_ENTRY(pa, acl, pe) {
 		switch(pa->e_tag) {
 			case ACL_USER_OBJ:
-				pa->e_id = ACL_UNDEFINED_ID;
 				break;
 			case ACL_GROUP_OBJ:
-				pa->e_id = ACL_UNDEFINED_ID;
 				group_obj = pa;
 				break;
 			case ACL_MASK:
 				mask = pa;
 				/* fall through */
 			case ACL_OTHER:
-				pa->e_id = ACL_UNDEFINED_ID;
 				break;
 		}
 	}
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 42/85] sunrpc: Use userns friendly constants.
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (39 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 41/85] nfs_common: Update the translation between nfsv3 acls linux posix acls Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 43/85] sunrpc: Use kuid_t and kgid_t where appropriate Eric W. Biederman
                     ` (42 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

Instead of (uid_t)0 use GLOBAL_ROOT_UID.
Instead of (gid_t)0 use GLOBAL_ROOT_GID.
Instead of (uid_t)-1 use INVALID_UID
Instead of (gid_t)-1 use INVALID_GID.
Instead of NOGROUP use INVALID_GID.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 net/sunrpc/auth.c         |    4 ++--
 net/sunrpc/auth_generic.c |    4 ++--
 net/sunrpc/auth_unix.c    |    6 +++---
 net/sunrpc/svcauth_unix.c |    4 ++--
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index b5c067b..4cd0ecf 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -519,8 +519,8 @@ rpcauth_bind_root_cred(struct rpc_task *task, int lookupflags)
 {
 	struct rpc_auth *auth = task->tk_client->cl_auth;
 	struct auth_cred acred = {
-		.uid = 0,
-		.gid = 0,
+		.uid = GLOBAL_ROOT_UID,
+		.gid = GLOBAL_ROOT_GID,
 	};
 
 	dprintk("RPC: %5u looking up %s cred\n",
diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c
index 6ed6f20..9d2e0b0 100644
--- a/net/sunrpc/auth_generic.c
+++ b/net/sunrpc/auth_generic.c
@@ -18,8 +18,8 @@
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
 
-#define RPC_MACHINE_CRED_USERID		((uid_t)0)
-#define RPC_MACHINE_CRED_GROUPID	((gid_t)0)
+#define RPC_MACHINE_CRED_USERID		GLOBAL_ROOT_UID
+#define RPC_MACHINE_CRED_GROUPID	GLOBAL_ROOT_GID
 
 struct generic_cred {
 	struct rpc_cred gc_base;
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 52c5abd..2f86270 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -85,7 +85,7 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
 		cred->uc_gids[i] = gid;
 	}
 	if (i < NFS_NGROUPS)
-		cred->uc_gids[i] = NOGROUP;
+		cred->uc_gids[i] = INVALID_GID;
 
 	return &cred->uc_base;
 }
@@ -137,7 +137,7 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
 			return 0;
 	}
 	if (groups < NFS_NGROUPS &&
-	    cred->uc_gids[groups] != NOGROUP)
+	    cred->uc_gids[groups] != INVALID_GID)
 		return 0;
 	return 1;
 }
@@ -166,7 +166,7 @@ unx_marshal(struct rpc_task *task, __be32 *p)
 	*p++ = htonl((u32) cred->uc_uid);
 	*p++ = htonl((u32) cred->uc_gid);
 	hold = p++;
-	for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++)
+	for (i = 0; i < 16 && cred->uc_gids[i] != INVALID_GID; i++)
 		*p++ = htonl((u32) cred->uc_gids[i]);
 	*hold = htonl(p - hold - 1);		/* gid array length */
 	*base = htonl((p - base - 1) << 2);	/* cred length */
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 4d01292..c8cb5dc 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -750,8 +750,8 @@ svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp)
 	}
 
 	/* Signal that mapping to nobody uid/gid is required */
-	cred->cr_uid = (uid_t) -1;
-	cred->cr_gid = (gid_t) -1;
+	cred->cr_uid = INVALID_UID;
+	cred->cr_gid = INVALID_GID;
 	cred->cr_group_info = groups_alloc(0);
 	if (cred->cr_group_info == NULL)
 		return SVC_CLOSE; /* kmalloc failure - client must retry */
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 43/85] sunrpc: Use kuid_t and kgid_t where appropriate
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (40 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 42/85] sunrpc: Use userns friendly constants Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 44/85] sunrpc: Use uid_eq and gid_eq " Eric W. Biederman
                     ` (41 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

Convert variables that store uids and gids to be of type
kuid_t and kgid_t instead of type uid_t and gid_t.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 include/linux/sunrpc/auth.h    |    7 ++++---
 include/linux/sunrpc/svcauth.h |    4 ++--
 net/sunrpc/auth_gss/auth_gss.c |    8 ++++----
 net/sunrpc/auth_unix.c         |    4 ++--
 net/sunrpc/svcauth_unix.c      |    8 ++++----
 5 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index f25ba92..58fda1c 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -17,14 +17,15 @@
 
 #include <linux/atomic.h>
 #include <linux/rcupdate.h>
+#include <linux/uidgid.h>
 
 /* size of the nodename buffer */
 #define UNX_MAXNODENAME	32
 
 /* Work around the lack of a VFS credential */
 struct auth_cred {
-	uid_t	uid;
-	gid_t	gid;
+	kuid_t	uid;
+	kgid_t	gid;
 	struct group_info *group_info;
 	const char *principal;
 	unsigned char machine_cred : 1;
@@ -48,7 +49,7 @@ struct rpc_cred {
 	unsigned long		cr_flags;	/* various flags */
 	atomic_t		cr_count;	/* ref count */
 
-	uid_t			cr_uid;
+	kuid_t			cr_uid;
 
 	/* per-flavor data */
 };
diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h
index dd74084..ff374ab 100644
--- a/include/linux/sunrpc/svcauth.h
+++ b/include/linux/sunrpc/svcauth.h
@@ -18,8 +18,8 @@
 #include <linux/cred.h>
 
 struct svc_cred {
-	uid_t			cr_uid;
-	gid_t			cr_gid;
+	kuid_t			cr_uid;
+	kgid_t			cr_gid;
 	struct group_info	*cr_group_info;
 	u32			cr_flavor; /* pseudoflavor */
 	char			*cr_principal; /* for gss */
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 6e5c824..4daab81 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -256,7 +256,7 @@ err:
 
 struct gss_upcall_msg {
 	atomic_t count;
-	uid_t	uid;
+	kuid_t	uid;
 	struct rpc_pipe_msg msg;
 	struct list_head list;
 	struct gss_auth *auth;
@@ -303,7 +303,7 @@ gss_release_msg(struct gss_upcall_msg *gss_msg)
 }
 
 static struct gss_upcall_msg *
-__gss_find_upcall(struct rpc_pipe *pipe, uid_t uid)
+__gss_find_upcall(struct rpc_pipe *pipe, kuid_t uid)
 {
 	struct gss_upcall_msg *pos;
 	list_for_each_entry(pos, &pipe->in_downcall, list) {
@@ -445,7 +445,7 @@ static void gss_encode_msg(struct gss_upcall_msg *gss_msg,
 
 static struct gss_upcall_msg *
 gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt,
-		uid_t uid, const char *service_name)
+		kuid_t uid, const char *service_name)
 {
 	struct gss_upcall_msg *gss_msg;
 	int vers;
@@ -475,7 +475,7 @@ gss_setup_upcall(struct rpc_clnt *clnt, struct gss_auth *gss_auth, struct rpc_cr
 	struct gss_cred *gss_cred = container_of(cred,
 			struct gss_cred, gc_base);
 	struct gss_upcall_msg *gss_new, *gss_msg;
-	uid_t uid = cred->cr_uid;
+	kuid_t uid = cred->cr_uid;
 
 	gss_new = gss_alloc_msg(gss_auth, clnt, uid, gss_cred->gc_principal);
 	if (IS_ERR(gss_new))
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 2f86270..372d915 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -18,8 +18,8 @@
 
 struct unx_cred {
 	struct rpc_cred		uc_base;
-	gid_t			uc_gid;
-	gid_t			uc_gids[NFS_NGROUPS];
+	kgid_t			uc_gid;
+	kgid_t			uc_gids[NFS_NGROUPS];
 };
 #define uc_uid			uc_base.cr_uid
 
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index c8cb5dc..caae662 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -415,7 +415,7 @@ svcauth_unix_info_release(struct svc_xprt *xpt)
 
 struct unix_gid {
 	struct cache_head	h;
-	uid_t			uid;
+	kuid_t			uid;
 	struct group_info	*gi;
 };
 
@@ -475,7 +475,7 @@ static int unix_gid_upcall(struct cache_detail *cd, struct cache_head *h)
 	return sunrpc_cache_pipe_upcall(cd, h, unix_gid_request);
 }
 
-static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid);
+static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid);
 
 static int unix_gid_parse(struct cache_detail *cd,
 			char *mesg, int mlen)
@@ -615,7 +615,7 @@ void unix_gid_cache_destroy(struct net *net)
 	cache_destroy_net(cd, net);
 }
 
-static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid)
+static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid)
 {
 	struct unix_gid ug;
 	struct cache_head *ch;
@@ -628,7 +628,7 @@ static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid)
 		return NULL;
 }
 
-static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp)
+static struct group_info *unix_gid_find(kuid_t uid, struct svc_rqst *rqstp)
 {
 	struct unix_gid *ug;
 	struct group_info *gi;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 44/85] sunrpc: Use uid_eq and gid_eq where appropriate
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (41 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 43/85] sunrpc: Use kuid_t and kgid_t where appropriate Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 45/85] sunrpc: Simplify auth_unix now that everything is a kgid_t Eric W. Biederman
                     ` (40 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

When comparing uids use uid_eq instead of ==.
When comparing gids use gid_eq instead of ==.

And unfortunate cost of type safety.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 net/sunrpc/auth_generic.c      |    8 ++++----
 net/sunrpc/auth_gss/auth_gss.c |    4 ++--
 net/sunrpc/auth_unix.c         |    2 +-
 net/sunrpc/svcauth_unix.c      |    2 +-
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c
index 9d2e0b0..bff3e47 100644
--- a/net/sunrpc/auth_generic.c
+++ b/net/sunrpc/auth_generic.c
@@ -129,8 +129,8 @@ machine_cred_match(struct auth_cred *acred, struct generic_cred *gcred, int flag
 {
 	if (!gcred->acred.machine_cred ||
 	    gcred->acred.principal != acred->principal ||
-	    gcred->acred.uid != acred->uid ||
-	    gcred->acred.gid != acred->gid)
+	    !uid_eq(gcred->acred.uid, acred->uid) ||
+	    !gid_eq(gcred->acred.gid, acred->gid))
 		return 0;
 	return 1;
 }
@@ -147,8 +147,8 @@ generic_match(struct auth_cred *acred, struct rpc_cred *cred, int flags)
 	if (acred->machine_cred)
 		return machine_cred_match(acred, gcred, flags);
 
-	if (gcred->acred.uid != acred->uid ||
-	    gcred->acred.gid != acred->gid ||
+	if (!uid_eq(gcred->acred.uid, acred->uid) ||
+	    !gid_eq(gcred->acred.gid, acred->gid) ||
 	    gcred->acred.machine_cred != 0)
 		goto out_nomatch;
 
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 4daab81..1b8b3e4 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -307,7 +307,7 @@ __gss_find_upcall(struct rpc_pipe *pipe, kuid_t uid)
 {
 	struct gss_upcall_msg *pos;
 	list_for_each_entry(pos, &pipe->in_downcall, list) {
-		if (pos->uid != uid)
+		if (!uid_eq(pos->uid, uid))
 			continue;
 		atomic_inc(&pos->count);
 		dprintk("RPC:       %s found msg %p\n", __func__, pos);
@@ -1115,7 +1115,7 @@ out:
 	}
 	if (gss_cred->gc_principal != NULL)
 		return 0;
-	return rc->cr_uid == acred->uid;
+	return uid_eq(rc->cr_uid, acred->uid);
 }
 
 /*
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 372d915..8365a9c 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -123,7 +123,7 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
 	unsigned int i;
 
 
-	if (cred->uc_uid != acred->uid || cred->uc_gid != acred->gid)
+	if (!uid_eq(cred->uc_uid, acred->uid) || !gid_eq(cred->uc_gid, acred->gid))
 		return 0;
 
 	if (acred->group_info != NULL)
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index caae662..92166b5 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -433,7 +433,7 @@ static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew)
 {
 	struct unix_gid *orig = container_of(corig, struct unix_gid, h);
 	struct unix_gid *new = container_of(cnew, struct unix_gid, h);
-	return orig->uid == new->uid;
+	return uid_eq(orig->uid, new->uid);
 }
 static void unix_gid_init(struct cache_head *cnew, struct cache_head *citem)
 {
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 45/85] sunrpc: Simplify auth_unix now that everything is a kgid_t
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (42 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 44/85] sunrpc: Use uid_eq and gid_eq " Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 46/85] sunrpc: Convert kuids and kgids to uids and gids for printing Eric W. Biederman
                     ` (39 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

In unx_create_cred directly assign gids from acred->group_info
to cred->uc_gids.

In unx_match directly compare uc_gids with group_info.

Now that both group_info and unx_cred gids are stored as kgids
this is valid and the extra layer of translation can be removed.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 net/sunrpc/auth_unix.c |   14 ++++----------
 1 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 8365a9c..9f38857 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -79,11 +79,8 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
 		groups = NFS_NGROUPS;
 
 	cred->uc_gid = acred->gid;
-	for (i = 0; i < groups; i++) {
-		gid_t gid;
-		gid = from_kgid(&init_user_ns, GROUP_AT(acred->group_info, i));
-		cred->uc_gids[i] = gid;
-	}
+	for (i = 0; i < groups; i++)
+		cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
 	if (i < NFS_NGROUPS)
 		cred->uc_gids[i] = INVALID_GID;
 
@@ -130,12 +127,9 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
 		groups = acred->group_info->ngroups;
 	if (groups > NFS_NGROUPS)
 		groups = NFS_NGROUPS;
-	for (i = 0; i < groups ; i++) {
-		gid_t gid;
-		gid = from_kgid(&init_user_ns, GROUP_AT(acred->group_info, i));
-		if (cred->uc_gids[i] != gid)
+	for (i = 0; i < groups ; i++)
+		if (!gid_eq(cred->uc_gids[i], GROUP_AT(acred->group_info, i)))
 			return 0;
-	}
 	if (groups < NFS_NGROUPS &&
 	    cred->uc_gids[groups] != INVALID_GID)
 		return 0;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 46/85] sunrpc: Convert kuids and kgids to uids and gids for printing
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (43 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 45/85] sunrpc: Simplify auth_unix now that everything is a kgid_t Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 47/85] sunrpc: Use gid_valid to test for gid != INVALID_GID Eric W. Biederman
                     ` (38 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

When printing kuids and kgids for debugging purpropses convert them
to ordinary integers so their values can be fed to the oridnary
print functions.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 net/sunrpc/auth_generic.c      |    4 +++-
 net/sunrpc/auth_gss/auth_gss.c |   13 ++++++++-----
 net/sunrpc/auth_unix.c         |    3 ++-
 3 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c
index bff3e47..b6badaf 100644
--- a/net/sunrpc/auth_generic.c
+++ b/net/sunrpc/auth_generic.c
@@ -96,7 +96,9 @@ generic_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
 
 	dprintk("RPC:       allocated %s cred %p for uid %d gid %d\n",
 			gcred->acred.machine_cred ? "machine" : "generic",
-			gcred, acred->uid, acred->gid);
+			gcred,
+			from_kuid(&init_user_ns, acred->uid),
+			from_kgid(&init_user_ns, acred->gid));
 	return &gcred->gc_base;
 }
 
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 1b8b3e4..afbbcfb 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -517,7 +517,7 @@ gss_refresh_upcall(struct rpc_task *task)
 	int err = 0;
 
 	dprintk("RPC: %5u %s for uid %u\n",
-		task->tk_pid, __func__, cred->cr_uid);
+		task->tk_pid, __func__, from_kuid(&init_user_ns, cred->cr_uid));
 	gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred);
 	if (PTR_ERR(gss_msg) == -EAGAIN) {
 		/* XXX: warning on the first, under the assumption we
@@ -549,7 +549,8 @@ gss_refresh_upcall(struct rpc_task *task)
 	gss_release_msg(gss_msg);
 out:
 	dprintk("RPC: %5u %s for uid %u result %d\n",
-		task->tk_pid, __func__, cred->cr_uid, err);
+		task->tk_pid, __func__,
+		from_kuid(&init_user_ns, cred->cr_uid),	err);
 	return err;
 }
 
@@ -562,7 +563,8 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
 	DEFINE_WAIT(wait);
 	int err = 0;
 
-	dprintk("RPC:       %s for uid %u\n", __func__, cred->cr_uid);
+	dprintk("RPC:       %s for uid %u\n",
+		__func__, from_kuid(&init_user_ns, cred->cr_uid));
 retry:
 	gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred);
 	if (PTR_ERR(gss_msg) == -EAGAIN) {
@@ -604,7 +606,7 @@ out_intr:
 	gss_release_msg(gss_msg);
 out:
 	dprintk("RPC:       %s for uid %u result %d\n",
-		__func__, cred->cr_uid, err);
+		__func__, from_kuid(&init_user_ns, cred->cr_uid), err);
 	return err;
 }
 
@@ -1059,7 +1061,8 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
 	int err = -ENOMEM;
 
 	dprintk("RPC:       %s for uid %d, flavor %d\n",
-		__func__, acred->uid, auth->au_flavor);
+		__func__, from_kuid(&init_user_ns, acred->uid),
+		auth->au_flavor);
 
 	if (!(cred = kzalloc(sizeof(*cred), GFP_NOFS)))
 		goto out_err;
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 9f38857..55b6ca6 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -65,7 +65,8 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
 	unsigned int i;
 
 	dprintk("RPC:       allocating UNIX cred for uid %d gid %d\n",
-			acred->uid, acred->gid);
+			from_kuid(&init_user_ns, acred->uid),
+			from_kgid(&init_user_ns, acred->gid));
 
 	if (!(cred = kmalloc(sizeof(*cred), GFP_NOFS)))
 		return ERR_PTR(-ENOMEM);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 47/85] sunrpc: Use gid_valid to test for gid != INVALID_GID
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (44 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 46/85] sunrpc: Convert kuids and kgids to uids and gids for printing Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 48/85] sunrpc: Update gss uid to security context mapping Eric W. Biederman
                     ` (37 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

In auth unix there are a couple of places INVALID_GID is used a
sentinel to mark the end of uc_gids array.  Use gid_valid
as a type safe way to verify we have not hit the end of
valid data in the array.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 net/sunrpc/auth_unix.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 55b6ca6..c434fde 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -131,8 +131,7 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
 	for (i = 0; i < groups ; i++)
 		if (!gid_eq(cred->uc_gids[i], GROUP_AT(acred->group_info, i)))
 			return 0;
-	if (groups < NFS_NGROUPS &&
-	    cred->uc_gids[groups] != INVALID_GID)
+	if (groups < NFS_NGROUPS && gid_valid(cred->uc_gids[groups]))
 		return 0;
 	return 1;
 }
@@ -161,7 +160,7 @@ unx_marshal(struct rpc_task *task, __be32 *p)
 	*p++ = htonl((u32) cred->uc_uid);
 	*p++ = htonl((u32) cred->uc_gid);
 	hold = p++;
-	for (i = 0; i < 16 && cred->uc_gids[i] != INVALID_GID; i++)
+	for (i = 0; i < 16 && gid_valid(cred->uc_gids[i]); i++)
 		*p++ = htonl((u32) cred->uc_gids[i]);
 	*hold = htonl(p - hold - 1);		/* gid array length */
 	*base = htonl((p - base - 1) << 2);	/* cred length */
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 48/85] sunrpc: Update gss uid to security context mapping.
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (45 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 47/85] sunrpc: Use gid_valid to test for gid != INVALID_GID Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 20:35     ` J. Bruce Fields
  2013-02-13 17:51   ` [PATCH review 49/85] sunrpc: Update svcgss xdr handle to rpsec_contect cache Eric W. Biederman
                     ` (36 subsequent siblings)
  83 siblings, 1 reply; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

- Use from_kuid when generating the on the wire uid values.
- Use make_kuid when reading on the wire values.

In gss_encode_v0_msg, since the uid in gss_upcall_msg is now a kuid_t
generate the necessary uid_t value on the stack copy it into
gss_msg->databuf where it can safely live until the message is no
longer needed.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 net/sunrpc/auth_gss/auth_gss.c |   20 +++++++++++++++-----
 1 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index afbbcfb..a360067 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -395,8 +395,11 @@ gss_upcall_callback(struct rpc_task *task)
 
 static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg)
 {
-	gss_msg->msg.data = &gss_msg->uid;
-	gss_msg->msg.len = sizeof(gss_msg->uid);
+	uid_t uid = from_kuid(&init_user_ns, gss_msg->uid);
+	memcpy(gss_msg->databuf, &uid, sizeof(uid));
+	gss_msg->msg.data = gss_msg->databuf;
+	gss_msg->msg.len = sizeof(uid);
+	BUG_ON(sizeof(uid) > UPCALL_BUF_LEN);
 }
 
 static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
@@ -409,7 +412,7 @@ static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
 
 	gss_msg->msg.len = sprintf(gss_msg->databuf, "mech=%s uid=%d ",
 				   mech->gm_name,
-				   gss_msg->uid);
+				   from_kuid(&init_user_ns, gss_msg->uid));
 	p += gss_msg->msg.len;
 	if (clnt->cl_principal) {
 		len = sprintf(p, "target=%s ", clnt->cl_principal);
@@ -620,7 +623,8 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
 	struct gss_upcall_msg *gss_msg;
 	struct rpc_pipe *pipe = RPC_I(filp->f_dentry->d_inode)->pipe;
 	struct gss_cl_ctx *ctx;
-	uid_t uid;
+	uid_t id;
+	kuid_t uid;
 	ssize_t err = -EFBIG;
 
 	if (mlen > MSG_BUF_MAXSIZE)
@@ -635,12 +639,18 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
 		goto err;
 
 	end = (const void *)((char *)buf + mlen);
-	p = simple_get_bytes(buf, end, &uid, sizeof(uid));
+	p = simple_get_bytes(buf, end, &id, sizeof(id));
 	if (IS_ERR(p)) {
 		err = PTR_ERR(p);
 		goto err;
 	}
 
+	uid = make_kuid(&init_user_ns, id);
+	if (!uid_valid(uid)) {
+		err = -EINVAL;
+		goto err;
+	}
+
 	err = -ENOMEM;
 	ctx = gss_alloc_context();
 	if (ctx == NULL)
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 49/85] sunrpc: Update svcgss xdr handle to rpsec_contect cache
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (46 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 48/85] sunrpc: Update gss uid to security context mapping Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-03-04 14:12     ` J. Bruce Fields
  2013-02-13 17:51   ` [PATCH review 50/85] sunrpc: Hash uids by first computing their value in the initial userns Eric W. Biederman
                     ` (35 subsequent siblings)
  83 siblings, 1 reply; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

For each received uid call make_kuid and validate the result.
For each received gid call make_kgid and validate the result.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 net/sunrpc/auth_gss/svcauth_gss.c |   18 +++++++++++++-----
 1 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 73e9573..ecd1d58 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,
 {
 	/* contexthandle expiry [ uid gid N <n gids> mechname ...mechdata... ] */
 	char *buf = mesg;
+	int id;
 	int len, rv;
 	struct rsc rsci, *rscp = NULL;
 	time_t expiry;
@@ -444,7 +445,7 @@ static int rsc_parse(struct cache_detail *cd,
 		goto out;
 
 	/* uid, or NEGATIVE */
-	rv = get_int(&mesg, &rsci.cred.cr_uid);
+	rv = get_int(&mesg, &id);
 	if (rv == -EINVAL)
 		goto out;
 	if (rv == -ENOENT)
@@ -452,8 +453,16 @@ static int rsc_parse(struct cache_detail *cd,
 	else {
 		int N, i;
 
+		/* uid */
+		rsci.cred.cr_uid = make_kuid(&init_user_ns, id);
+		if (!uid_valid(rsci.cred.cr_uid))
+			goto out;
+
 		/* gid */
-		if (get_int(&mesg, &rsci.cred.cr_gid))
+		if (get_int(&mesg, &id))
+			goto out;
+		rsci.cred.cr_gid = make_kgid(&init_user_ns, id);
+		if (!gid_valid(rsci.cred.cr_gid))
 			goto out;
 
 		/* number of additional gid's */
@@ -467,11 +476,10 @@ static int rsc_parse(struct cache_detail *cd,
 		/* gid's */
 		status = -EINVAL;
 		for (i=0; i<N; i++) {
-			gid_t gid;
 			kgid_t kgid;
-			if (get_int(&mesg, &gid))
+			if (get_int(&mesg, &id))
 				goto out;
-			kgid = make_kgid(&init_user_ns, gid);
+			kgid = make_kgid(&init_user_ns, id);
 			if (!gid_valid(kgid))
 				goto out;
 			GROUP_AT(rsci.cred.cr_group_info, i) = kgid;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 50/85] sunrpc: Hash uids by first computing their value in the initial userns
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (47 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 49/85] sunrpc: Update svcgss xdr handle to rpsec_contect cache Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 51/85] sunrpc: Properly encode kuids and kgids in RPC_AUTH_UNIX credentials Eric W. Biederman
                     ` (34 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

In svcauth_unix introduce a helper unix_gid_hash as otherwise the
expresion to generate the hash value is just too long.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 net/sunrpc/auth.c         |    2 +-
 net/sunrpc/svcauth_unix.c |    9 +++++++--
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 4cd0ecf..392adc4 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,
 			*entry, *new;
 	unsigned int nr;
 
-	nr = hash_long(acred->uid, cache->hashbits);
+	nr = hash_long(from_kuid(&init_user_ns, acred->uid), cache->hashbits);
 
 	rcu_read_lock();
 	hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) {
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 92166b5..faf1719 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -419,6 +419,11 @@ struct unix_gid {
 	struct group_info	*gi;
 };
 
+static int unix_gid_hash(kuid_t uid)
+{
+	return hash_long(from_kuid(&init_user_ns, uid), GID_HASHBITS);
+}
+
 static void unix_gid_put(struct kref *kref)
 {
 	struct cache_head *item = container_of(kref, struct cache_head, ref);
@@ -530,7 +535,7 @@ static int unix_gid_parse(struct cache_detail *cd,
 		ug.h.expiry_time = expiry;
 		ch = sunrpc_cache_update(cd,
 					 &ug.h, &ugp->h,
-					 hash_long(uid, GID_HASHBITS));
+					 unix_gid_hash(uid));
 		if (!ch)
 			err = -ENOMEM;
 		else {
@@ -621,7 +626,7 @@ static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid)
 	struct cache_head *ch;
 
 	ug.uid = uid;
-	ch = sunrpc_cache_lookup(cd, &ug.h, hash_long(uid, GID_HASHBITS));
+	ch = sunrpc_cache_lookup(cd, &ug.h, unix_gid_hash(uid));
 	if (ch)
 		return container_of(ch, struct unix_gid, h);
 	else
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 51/85] sunrpc: Properly encode kuids and kgids in RPC_AUTH_UNIX credentials
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (48 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 50/85] sunrpc: Hash uids by first computing their value in the initial userns Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 52/85] sunrpc: Properly encode kuids and kgids in auth.unix.gid rpc pipe upcalls Eric W. Biederman
                     ` (33 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

When writing kuids onto the wire first map them into the initial user
namespace.

When writing kgids onto the wire first map them into the initial user
namespace.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 net/sunrpc/auth_unix.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index c434fde..dc37021 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -157,11 +157,11 @@ unx_marshal(struct rpc_task *task, __be32 *p)
 	 */
 	p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
 
-	*p++ = htonl((u32) cred->uc_uid);
-	*p++ = htonl((u32) cred->uc_gid);
+	*p++ = htonl((u32) from_kuid(&init_user_ns, cred->uc_uid));
+	*p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gid));
 	hold = p++;
 	for (i = 0; i < 16 && gid_valid(cred->uc_gids[i]); i++)
-		*p++ = htonl((u32) cred->uc_gids[i]);
+		*p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gids[i]));
 	*hold = htonl(p - hold - 1);		/* gid array length */
 	*base = htonl((p - base - 1) << 2);	/* cred length */
 
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 52/85] sunrpc: Properly encode kuids and kgids in auth.unix.gid rpc pipe upcalls.
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (49 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 51/85] sunrpc: Properly encode kuids and kgids in RPC_AUTH_UNIX credentials Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 21:05     ` J. Bruce Fields
  2013-02-13 17:51   ` [PATCH review 53/85] sunrpc: Properly decode kuids and kgids in RPC_AUTH_UNIX credentials Eric W. Biederman
                     ` (32 subsequent siblings)
  83 siblings, 1 reply; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

When a new rpc connection is established with an in-kernel server, the
traffic passes through svc_process_common, and svc_set_client and down
into svcauth_unix_set_client if it is of type RPC_AUTH_NULL or
RPC_AUTH_UNIX.

svcauth_unix_set_client then looks at the uid of the credential we
have assigned to the incomming client and if we don't have the groups
already cached makes an upcall to get a list of groups that the client
can use.

The upcall encodes send a rpc message to user space encoding the uid
of the user whose groups we want to know.  Encode the kuid of the user
in the initial user namespace as nfs mounts can only happen today in
the initial user namespace.

When a reply to an upcall comes in convert interpret the uid and gid values
from the rpc pipe as uids and gids in the initial user namespace and convert
them into kuids and kgids before processing them further.

When reading proc files listing the uid to gid list cache convert the
kuids and kgids from into uids and gids the initial user namespace.  As we are
displaying server internal details it makes sense to display these values
from the servers perspective.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 net/sunrpc/svcauth_unix.c |   14 +++++++++-----
 1 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index faf1719..bdea0a1 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -470,7 +470,7 @@ static void unix_gid_request(struct cache_detail *cd,
 	char tuid[20];
 	struct unix_gid *ug = container_of(h, struct unix_gid, h);
 
-	snprintf(tuid, 20, "%u", ug->uid);
+	snprintf(tuid, 20, "%u", from_kuid(&init_user_ns, ug->uid));
 	qword_add(bpp, blen, tuid);
 	(*bpp)[-1] = '\n';
 }
@@ -486,7 +486,8 @@ static int unix_gid_parse(struct cache_detail *cd,
 			char *mesg, int mlen)
 {
 	/* uid expiry Ngid gid0 gid1 ... gidN-1 */
-	int uid;
+	int id;
+	kuid_t uid;
 	int gids;
 	int rv;
 	int i;
@@ -498,9 +499,12 @@ static int unix_gid_parse(struct cache_detail *cd,
 		return -EINVAL;
 	mesg[mlen-1] = 0;
 
-	rv = get_int(&mesg, &uid);
+	rv = get_int(&mesg, &id);
 	if (rv)
 		return -EINVAL;
+	uid = make_kuid(&init_user_ns, id);
+	if (!uid_valid(uid))
+		return -EINVAL;
 	ug.uid = uid;
 
 	expiry = get_expiry(&mesg);
@@ -554,7 +558,7 @@ static int unix_gid_show(struct seq_file *m,
 			 struct cache_detail *cd,
 			 struct cache_head *h)
 {
-	struct user_namespace *user_ns = current_user_ns();
+	struct user_namespace *user_ns = &init_user_ns;
 	struct unix_gid *ug;
 	int i;
 	int glen;
@@ -570,7 +574,7 @@ static int unix_gid_show(struct seq_file *m,
 	else
 		glen = 0;
 
-	seq_printf(m, "%u %d:", ug->uid, glen);
+	seq_printf(m, "%u %d:", from_kuid_munged(user_ns, ug->uid), glen);
 	for (i = 0; i < glen; i++)
 		seq_printf(m, " %d", from_kgid_munged(user_ns, GROUP_AT(ug->gi, i)));
 	seq_printf(m, "\n");
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 53/85] sunrpc: Properly decode kuids and kgids in RPC_AUTH_UNIX credentials
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (50 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 52/85] sunrpc: Properly encode kuids and kgids in auth.unix.gid rpc pipe upcalls Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 54/85] nfs: Pass GLOBAL_ROOT_UID and GLOBAL_ROOT_GID to keyring alloc Eric W. Biederman
                     ` (31 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

When reading kuids from the wire map them into the initial user
namespace, and validate the mapping succeded.

When reading kgids from the wire map them into the initial user
namespace, and validate the mapping succeded.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 net/sunrpc/svcauth_unix.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index bdea0a1..a1852e1 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -821,8 +821,10 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
 	argv->iov_base = (void*)((__be32*)argv->iov_base + slen);	/* skip machname */
 	argv->iov_len -= slen*4;
 
-	cred->cr_uid = svc_getnl(argv);		/* uid */
-	cred->cr_gid = svc_getnl(argv);		/* gid */
+	cred->cr_uid = make_kuid(&init_user_ns, svc_getnl(argv)); /* uid */
+	cred->cr_gid = make_kgid(&init_user_ns, svc_getnl(argv)); /* gid */
+	if (!uid_valid(cred->cr_uid) || !gid_valid(cred->cr_gid))
+		goto badcred;
 	slen = svc_getnl(argv);			/* gids length */
 	if (slen > 16 || (len -= (slen + 2)*4) < 0)
 		goto badcred;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 54/85] nfs: Pass GLOBAL_ROOT_UID and GLOBAL_ROOT_GID to keyring alloc
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (51 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 53/85] sunrpc: Properly decode kuids and kgids in RPC_AUTH_UNIX credentials Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 55/85] nfs: Convert struct nfs_fattr to Use kuid_t and kgid_t Eric W. Biederman
                     ` (30 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/nfs/idmap.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index bc3968f..f77017c 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -193,7 +193,8 @@ static int nfs_idmap_init_keyring(void)
 	if (!cred)
 		return -ENOMEM;
 
-	keyring = keyring_alloc(".id_resolver", 0, 0, cred,
+	keyring = keyring_alloc(".id_resolver",
+				GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
 				(KEY_POS_ALL & ~KEY_POS_SETATTR) |
 				KEY_USR_VIEW | KEY_USR_READ,
 				KEY_ALLOC_NOT_IN_QUOTA, NULL);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 55/85] nfs: Convert struct nfs_fattr to Use kuid_t and kgid_t
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (52 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 54/85] nfs: Pass GLOBAL_ROOT_UID and GLOBAL_ROOT_GID to keyring alloc Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 56/85] nfs: Convert idmap to use kuids and kgids Eric W. Biederman
                     ` (29 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 include/linux/nfs_xdr.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 29adb12..13441dd 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -48,8 +48,8 @@ struct nfs_fattr {
 	unsigned int		valid;		/* which fields are valid */
 	umode_t			mode;
 	__u32			nlink;
-	__u32			uid;
-	__u32			gid;
+	kuid_t			uid;
+	kgid_t			gid;
 	dev_t			rdev;
 	__u64			size;
 	union {
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 56/85] nfs: Convert idmap to use kuids and kgids
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (53 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 55/85] nfs: Convert struct nfs_fattr to Use kuid_t and kgid_t Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 57/85] nfs: Convert nfs2xdr " Eric W. Biederman
                     ` (28 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

Convert nfs_map_name_to_uid to return a kuid_t value.
Convert nfs_map_name_to_gid to return a kgid_t value.
Convert nfs_map_uid_to_name to take a kuid_t paramater.
Convert nfs_map_gid_to_name to take a kgid_t paramater.

Tweak nfs_fattr_map_owner_to_name to use a kuid_t intermediate value.
Tweak nfs_fattr_map_group_to_name to use a kgid_t intermediate value.

Which makes these functions properly handle kuids and kgids, including
erroring of the generated kuid or kgid is invalid.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/nfs/idmap.c            |   50 ++++++++++++++++++++++++++++++--------------
 include/linux/nfs_idmap.h |    9 ++++---
 2 files changed, 39 insertions(+), 20 deletions(-)

diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index f77017c..b9623d1 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -97,7 +97,7 @@ static void nfs_fattr_free_group_name(struct nfs_fattr *fattr)
 static bool nfs_fattr_map_owner_name(struct nfs_server *server, struct nfs_fattr *fattr)
 {
 	struct nfs4_string *owner = fattr->owner_name;
-	__u32 uid;
+	kuid_t uid;
 
 	if (!(fattr->valid & NFS_ATTR_FATTR_OWNER_NAME))
 		return false;
@@ -111,7 +111,7 @@ static bool nfs_fattr_map_owner_name(struct nfs_server *server, struct nfs_fattr
 static bool nfs_fattr_map_group_name(struct nfs_server *server, struct nfs_fattr *fattr)
 {
 	struct nfs4_string *group = fattr->group_name;
-	__u32 gid;
+	kgid_t gid;
 
 	if (!(fattr->valid & NFS_ATTR_FATTR_GROUP_NAME))
 		return false;
@@ -837,43 +837,61 @@ idmap_release_pipe(struct inode *inode)
 	nfs_idmap_abort_pipe_upcall(idmap, -EPIPE);
 }
 
-int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid)
+int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, kuid_t *uid)
 {
 	struct idmap *idmap = server->nfs_client->cl_idmap;
+	__u32 id = -1;
+	int ret = 0;
 
-	if (nfs_map_string_to_numeric(name, namelen, uid))
-		return 0;
-	return nfs_idmap_lookup_id(name, namelen, "uid", uid, idmap);
+	if (!nfs_map_string_to_numeric(name, namelen, &id))
+		ret = nfs_idmap_lookup_id(name, namelen, "uid", &id, idmap);
+	if (ret == 0) {
+		*uid = make_kuid(&init_user_ns, id);
+		if (!uid_valid(*uid))
+			ret = -ERANGE;
+	}
+	return ret;
 }
 
-int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *gid)
+int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size_t namelen, kgid_t *gid)
 {
 	struct idmap *idmap = server->nfs_client->cl_idmap;
+	__u32 id = -1;
+	int ret = 0;
 
-	if (nfs_map_string_to_numeric(name, namelen, gid))
-		return 0;
-	return nfs_idmap_lookup_id(name, namelen, "gid", gid, idmap);
+	if (!nfs_map_string_to_numeric(name, namelen, &id))
+		ret = nfs_idmap_lookup_id(name, namelen, "gid", &id, idmap);
+	if (ret == 0) {
+		*gid = make_kgid(&init_user_ns, id);
+		if (!gid_valid(*gid))
+			ret = -ERANGE;
+	}
+	return ret;
 }
 
-int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen)
+int nfs_map_uid_to_name(const struct nfs_server *server, kuid_t uid, char *buf, size_t buflen)
 {
 	struct idmap *idmap = server->nfs_client->cl_idmap;
 	int ret = -EINVAL;
+	__u32 id;
 
+	id = from_kuid(&init_user_ns, uid);
 	if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
-		ret = nfs_idmap_lookup_name(uid, "user", buf, buflen, idmap);
+		ret = nfs_idmap_lookup_name(id, "user", buf, buflen, idmap);
 	if (ret < 0)
-		ret = nfs_map_numeric_to_string(uid, buf, buflen);
+		ret = nfs_map_numeric_to_string(id, buf, buflen);
 	return ret;
 }
-int nfs_map_gid_to_group(const struct nfs_server *server, __u32 gid, char *buf, size_t buflen)
+int nfs_map_gid_to_group(const struct nfs_server *server, kgid_t gid, char *buf, size_t buflen)
 {
 	struct idmap *idmap = server->nfs_client->cl_idmap;
 	int ret = -EINVAL;
+	__u32 id;
 
+	id = from_kgid(&init_user_ns, gid);
 	if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
-		ret = nfs_idmap_lookup_name(gid, "group", buf, buflen, idmap);
+		ret = nfs_idmap_lookup_name(id, "group", buf, buflen, idmap);
 	if (ret < 0)
-		ret = nfs_map_numeric_to_string(gid, buf, buflen);
+		ret = nfs_map_numeric_to_string(id, buf, buflen);
 	return ret;
 }
diff --git a/include/linux/nfs_idmap.h b/include/linux/nfs_idmap.h
index 2dcef3a..0f4b79d 100644
--- a/include/linux/nfs_idmap.h
+++ b/include/linux/nfs_idmap.h
@@ -36,6 +36,7 @@
 #ifndef NFS_IDMAP_H
 #define NFS_IDMAP_H
 
+#include <linux/uidgid.h>
 #include <uapi/linux/nfs_idmap.h>
 
 
@@ -67,10 +68,10 @@ void nfs_fattr_init_names(struct nfs_fattr *fattr,
 void nfs_fattr_free_names(struct nfs_fattr *);
 void nfs_fattr_map_and_free_names(struct nfs_server *, struct nfs_fattr *);
 
-int nfs_map_name_to_uid(const struct nfs_server *, const char *, size_t, __u32 *);
-int nfs_map_group_to_gid(const struct nfs_server *, const char *, size_t, __u32 *);
-int nfs_map_uid_to_name(const struct nfs_server *, __u32, char *, size_t);
-int nfs_map_gid_to_group(const struct nfs_server *, __u32, char *, size_t);
+int nfs_map_name_to_uid(const struct nfs_server *, const char *, size_t, kuid_t *);
+int nfs_map_group_to_gid(const struct nfs_server *, const char *, size_t, kgid_t *);
+int nfs_map_uid_to_name(const struct nfs_server *, kuid_t, char *, size_t);
+int nfs_map_gid_to_group(const struct nfs_server *, kgid_t, char *, size_t);
 
 extern unsigned int nfs_idmap_cache_timeout;
 #endif /* NFS_IDMAP_H */
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 57/85] nfs: Convert nfs2xdr to use kuids and kgids
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (54 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 56/85] nfs: Convert idmap to use kuids and kgids Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 58/85] nfs: Convert nfs3xdr " Eric W. Biederman
                     ` (27 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

When reading uids and gids off the wire convert them to
kuids and kgids.

When putting kuids and kgids onto the wire first convert
them to uids and gids the other side will understand.

Add an additional failure mode for incoming uid or
gids that are invalid.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/nfs/nfs2xdr.c |   19 +++++++++++++++----
 1 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 06b9df4..62db136 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -290,8 +290,13 @@ static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
 
 	fattr->mode = be32_to_cpup(p++);
 	fattr->nlink = be32_to_cpup(p++);
-	fattr->uid = be32_to_cpup(p++);
-	fattr->gid = be32_to_cpup(p++);
+	fattr->uid = make_kuid(&init_user_ns, be32_to_cpup(p++));
+	if (!uid_valid(fattr->uid))
+		goto out_uid;
+	fattr->gid = make_kgid(&init_user_ns, be32_to_cpup(p++));
+	if (!gid_valid(fattr->gid))
+		goto out_gid;
+		
 	fattr->size = be32_to_cpup(p++);
 	fattr->du.nfs2.blocksize = be32_to_cpup(p++);
 
@@ -313,6 +318,12 @@ static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
 	fattr->change_attr = nfs_timespec_to_change_attr(&fattr->ctime);
 
 	return 0;
+out_uid:
+	dprintk("NFS: returned invalid uid\n");
+	return -EINVAL;
+out_gid:
+	dprintk("NFS: returned invalid gid\n");
+	return -EINVAL;
 out_overflow:
 	print_overflow_msg(__func__, xdr);
 	return -EIO;
@@ -351,11 +362,11 @@ static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr)
 	else
 		*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
 	if (attr->ia_valid & ATTR_UID)
-		*p++ = cpu_to_be32(attr->ia_uid);
+		*p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid));
 	else
 		*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
 	if (attr->ia_valid & ATTR_GID)
-		*p++ = cpu_to_be32(attr->ia_gid);
+		*p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid));
 	else
 		*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
 	if (attr->ia_valid & ATTR_SIZE)
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 58/85] nfs: Convert nfs3xdr to use kuids and kgids
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (55 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 57/85] nfs: Convert nfs2xdr " Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 59/85] nfs: Convert nfs4xdr " Eric W. Biederman
                     ` (26 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

When reading uids and gids off the wire convert them to
kuids and kgids.

When putting kuids and kgids onto the wire first convert
them to uids and gids the other side will understand.

Add an additional failure mode incoming for uids or gids
that are invalid.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/nfs/nfs3xdr.c |   18 ++++++++++++++----
 1 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index bffc324..fa6d721 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -592,13 +592,13 @@ static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
 
 	if (attr->ia_valid & ATTR_UID) {
 		*p++ = xdr_one;
-		*p++ = cpu_to_be32(attr->ia_uid);
+		*p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid));
 	} else
 		*p++ = xdr_zero;
 
 	if (attr->ia_valid & ATTR_GID) {
 		*p++ = xdr_one;
-		*p++ = cpu_to_be32(attr->ia_gid);
+		*p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid));
 	} else
 		*p++ = xdr_zero;
 
@@ -657,8 +657,12 @@ static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr)
 
 	fattr->mode = (be32_to_cpup(p++) & ~S_IFMT) | fmode;
 	fattr->nlink = be32_to_cpup(p++);
-	fattr->uid = be32_to_cpup(p++);
-	fattr->gid = be32_to_cpup(p++);
+	fattr->uid = make_kuid(&init_user_ns, be32_to_cpup(p++));
+	if (!uid_valid(fattr->uid))
+		goto out_uid;
+	fattr->gid = make_kgid(&init_user_ns, be32_to_cpup(p++));
+	if (!gid_valid(fattr->gid))
+		goto out_gid;
 
 	p = xdr_decode_size3(p, &fattr->size);
 	p = xdr_decode_size3(p, &fattr->du.nfs3.used);
@@ -675,6 +679,12 @@ static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr)
 
 	fattr->valid |= NFS_ATTR_FATTR_V3;
 	return 0;
+out_uid:
+	dprintk("NFS: returned invalid uid\n");
+	return -EINVAL;
+out_gid:
+	dprintk("NFS: returned invalid gid\n");
+	return -EINVAL;
 out_overflow:
 	print_overflow_msg(__func__, xdr);
 	return -EIO;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 59/85] nfs: Convert nfs4xdr to use kuids and kgids
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (56 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 58/85] nfs: Convert nfs3xdr " Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 60/85] nfs: kuid and kgid conversions for nfs/inode.c Eric W. Biederman
                     ` (25 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

When reading uids and gids off the wire convert them to
kuids and kgids.

When putting kuids and kgids onto the wire first convert
them to uids and gids the other side will understand.

When printing kuids and kgids convert them to values in
the initial user namespace then use normal printf formats.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/nfs/nfs4xdr.c |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 26b1439..e3edda5 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1002,7 +1002,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const
 		owner_namelen = nfs_map_uid_to_name(server, iap->ia_uid, owner_name, IDMAP_NAMESZ);
 		if (owner_namelen < 0) {
 			dprintk("nfs: couldn't resolve uid %d to string\n",
-					iap->ia_uid);
+					from_kuid(&init_user_ns, iap->ia_uid));
 			/* XXX */
 			strcpy(owner_name, "nobody");
 			owner_namelen = sizeof("nobody") - 1;
@@ -1014,7 +1014,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const
 		owner_grouplen = nfs_map_gid_to_group(server, iap->ia_gid, owner_group, IDMAP_NAMESZ);
 		if (owner_grouplen < 0) {
 			dprintk("nfs: couldn't resolve gid %d to string\n",
-					iap->ia_gid);
+					from_kgid(&init_user_ns, iap->ia_gid));
 			strcpy(owner_group, "nobody");
 			owner_grouplen = sizeof("nobody") - 1;
 			/* goto out; */
@@ -3778,14 +3778,14 @@ out_overflow:
 }
 
 static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap,
-		const struct nfs_server *server, uint32_t *uid,
+		const struct nfs_server *server, kuid_t *uid,
 		struct nfs4_string *owner_name)
 {
 	uint32_t len;
 	__be32 *p;
 	int ret = 0;
 
-	*uid = -2;
+	*uid = make_kuid(&init_user_ns, -2);
 	if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER - 1U)))
 		return -EIO;
 	if (likely(bitmap[1] & FATTR4_WORD1_OWNER)) {
@@ -3813,7 +3813,7 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap,
 					__func__, len);
 		bitmap[1] &= ~FATTR4_WORD1_OWNER;
 	}
-	dprintk("%s: uid=%d\n", __func__, (int)*uid);
+	dprintk("%s: uid=%d\n", __func__, (int)from_kuid(&init_user_ns, *uid));
 	return ret;
 out_overflow:
 	print_overflow_msg(__func__, xdr);
@@ -3821,14 +3821,14 @@ out_overflow:
 }
 
 static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap,
-		const struct nfs_server *server, uint32_t *gid,
+		const struct nfs_server *server, kgid_t *gid,
 		struct nfs4_string *group_name)
 {
 	uint32_t len;
 	__be32 *p;
 	int ret = 0;
 
-	*gid = -2;
+	*gid = make_kgid(&init_user_ns, -2);
 	if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER_GROUP - 1U)))
 		return -EIO;
 	if (likely(bitmap[1] & FATTR4_WORD1_OWNER_GROUP)) {
@@ -3856,7 +3856,7 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap,
 					__func__, len);
 		bitmap[1] &= ~FATTR4_WORD1_OWNER_GROUP;
 	}
-	dprintk("%s: gid=%d\n", __func__, (int)*gid);
+	dprintk("%s: gid=%d\n", __func__, (int)from_kgid(&init_user_ns, *gid));
 	return ret;
 out_overflow:
 	print_overflow_msg(__func__, xdr);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 60/85] nfs: kuid and kgid conversions for nfs/inode.c
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (57 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 59/85] nfs: Convert nfs4xdr " Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 61/85] nfs: Enable building with user namespaces enabled Eric W. Biederman
                     ` (24 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

- Use uid_eq and gid_eq when comparing kuids and kgids.
- Use make_kuid(&init_user_ns, -2) and make_kgid(&init_user_ns, -2) as
  the initial uid and gid on nfs inodes, instead of using the typeunsafe
  value of -2.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/nfs/inode.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index ebeb94c..ce2b039 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -332,8 +332,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
 		inode->i_version = 0;
 		inode->i_size = 0;
 		clear_nlink(inode);
-		inode->i_uid = -2;
-		inode->i_gid = -2;
+		inode->i_uid = make_kuid(&init_user_ns, -2);
+		inode->i_gid = make_kgid(&init_user_ns, -2);
 		inode->i_blocks = 0;
 		memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
 		nfsi->write_io = 0;
@@ -1009,9 +1009,9 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
 	/* Have any file permissions changed? */
 	if ((fattr->valid & NFS_ATTR_FATTR_MODE) && (inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO))
 		invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
-	if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && inode->i_uid != fattr->uid)
+	if ((fattr->valid & NFS_ATTR_FATTR_OWNER) && !uid_eq(inode->i_uid, fattr->uid))
 		invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
-	if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && inode->i_gid != fattr->gid)
+	if ((fattr->valid & NFS_ATTR_FATTR_GROUP) && !gid_eq(inode->i_gid, fattr->gid))
 		invalid |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
 
 	/* Has the link count changed? */
@@ -1440,7 +1440,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 				| NFS_INO_REVAL_FORCED);
 
 	if (fattr->valid & NFS_ATTR_FATTR_OWNER) {
-		if (inode->i_uid != fattr->uid) {
+		if (!uid_eq(inode->i_uid, fattr->uid)) {
 			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
 			inode->i_uid = fattr->uid;
 		}
@@ -1451,7 +1451,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 				| NFS_INO_REVAL_FORCED);
 
 	if (fattr->valid & NFS_ATTR_FATTR_GROUP) {
-		if (inode->i_gid != fattr->gid) {
+		if (!gid_eq(inode->i_gid, fattr->gid)) {
 			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
 			inode->i_gid = fattr->gid;
 		}
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 61/85] nfs: Enable building with user namespaces enabled.
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (58 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 60/85] nfs: kuid and kgid conversions for nfs/inode.c Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 62/85] nfsd: Remove declaration of nonexistent nfs4_acl_permisison Eric W. Biederman
                     ` (23 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

Now that the kuids and kgids conversion have propogated
through net/sunrpc/ and the fs/nfs/ it is safe to enable
building nfs when user namespaces are enabled.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 init/Kconfig |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/init/Kconfig b/init/Kconfig
index b526f4c..d7b926a 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1073,7 +1073,6 @@ config UIDGID_CONVERTED
 	# Filesystems
 	depends on CIFS = n
 	depends on NFSD = n
-	depends on NFS_FS = n
 	depends on XFS_FS = n
 
 config UIDGID_STRICT_TYPE_CHECKS
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 62/85] nfsd: Remove declaration of nonexistent nfs4_acl_permisison
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (59 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 61/85] nfs: Enable building with user namespaces enabled Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 63/85] nfsd: idmap use u32 not uid_t as the intermediate type Eric W. Biederman
                     ` (22 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/nfsd/acl.h |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h
index 34e5c40..8b186a4 100644
--- a/fs/nfsd/acl.h
+++ b/fs/nfsd/acl.h
@@ -44,8 +44,6 @@
 struct nfs4_acl *nfs4_acl_new(int);
 int nfs4_acl_get_whotype(char *, u32);
 int nfs4_acl_write_who(int who, char *p);
-int nfs4_acl_permission(struct nfs4_acl *acl, uid_t owner, gid_t group,
-		                        uid_t who, u32 mask);
 
 #define NFS4_ACL_TYPE_DEFAULT	0x01
 #define NFS4_ACL_DIR		0x02
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 63/85] nfsd: idmap use u32 not uid_t as the intermediate type
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (60 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 62/85] nfsd: Remove declaration of nonexistent nfs4_acl_permisison Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 64/85] nfsd: Convert idmap to use kuids and kgids Eric W. Biederman
                     ` (21 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

u32 and uid_t have the same size and semantics so this change
should have no operational effect.  This just removes the WTF
factor when looking at variables that hold both uids and gids
whos type is uid_t.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/nfsd/nfs4idmap.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index a1f10c0..7e84dfa 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -65,7 +65,7 @@ MODULE_PARM_DESC(nfs4_disable_idmapping,
 struct ent {
 	struct cache_head h;
 	int               type;		       /* User / Group */
-	uid_t             id;
+	u32               id;
 	char              name[IDMAP_NAMESZ];
 	char              authname[IDMAP_NAMESZ];
 };
@@ -540,7 +540,7 @@ rqst_authname(struct svc_rqst *rqstp)
 
 static __be32
 idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen,
-		uid_t *id)
+		u32 *id)
 {
 	struct ent *item, key = {
 		.type = type,
@@ -564,7 +564,7 @@ idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen
 }
 
 static int
-idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
+idmap_id_to_name(struct svc_rqst *rqstp, int type, u32 id, char *name)
 {
 	struct ent *item, key = {
 		.id = id,
@@ -587,7 +587,7 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
 }
 
 static bool
-numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, uid_t *id)
+numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u32 *id)
 {
 	int ret;
 	char buf[11];
@@ -603,7 +603,7 @@ numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namel
 }
 
 static __be32
-do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, uid_t *id)
+do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u32 *id)
 {
 	if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS)
 		if (numeric_name_to_id(rqstp, type, name, namelen, id))
@@ -616,7 +616,7 @@ do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u
 }
 
 static int
-do_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
+do_id_to_name(struct svc_rqst *rqstp, int type, u32 id, char *name)
 {
 	if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS)
 		return sprintf(name, "%u", id);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 64/85] nfsd: Convert idmap to use kuids and kgids
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (61 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 63/85] nfsd: idmap use u32 not uid_t as the intermediate type Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 65/85] nfsd: Remove nfsd_luid, nfsd_lgid, nfsd_ruid and nfsd_rgid Eric W. Biederman
                     ` (20 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

Convert nfsd_map_name_to_uid to return a kuid_t value.
Convert nfsd_map_name_to_gid to return a kgid_t value.
Convert nfsd_map_uid_to_name to take a kuid_t parameter.
Convert nfsd_map_gid_to_name to take a kgid_t paramater.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/nfsd/idmap.h     |    8 ++++----
 fs/nfsd/nfs4idmap.c |   26 ++++++++++++++++++++------
 2 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/fs/nfsd/idmap.h b/fs/nfsd/idmap.h
index 9d513ef..bf95f6b 100644
--- a/fs/nfsd/idmap.h
+++ b/fs/nfsd/idmap.h
@@ -54,9 +54,9 @@ static inline void nfsd_idmap_shutdown(struct net *net)
 }
 #endif
 
-__be32 nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *);
-__be32 nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, __u32 *);
-int nfsd_map_uid_to_name(struct svc_rqst *, __u32, char *);
-int nfsd_map_gid_to_name(struct svc_rqst *, __u32, char *);
+__be32 nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, kuid_t *);
+__be32 nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, kgid_t *);
+int nfsd_map_uid_to_name(struct svc_rqst *, kuid_t, char *);
+int nfsd_map_gid_to_name(struct svc_rqst *, kgid_t, char *);
 
 #endif /* LINUX_NFSD_IDMAP_H */
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index 7e84dfa..0ce1234 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -625,26 +625,40 @@ do_id_to_name(struct svc_rqst *rqstp, int type, u32 id, char *name)
 
 __be32
 nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen,
-		__u32 *id)
+		kuid_t *uid)
 {
-	return do_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, id);
+	__be32 status;
+	u32 id = -1;
+	status = do_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, &id);
+	*uid = make_kuid(&init_user_ns, id);
+	if (!uid_valid(*uid))
+		status = nfserr_badowner;
+	return status;
 }
 
 __be32
 nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen,
-		__u32 *id)
+		kgid_t *gid)
 {
-	return do_name_to_id(rqstp, IDMAP_TYPE_GROUP, name, namelen, id);
+	__be32 status;
+	u32 id = -1;
+	status = do_name_to_id(rqstp, IDMAP_TYPE_GROUP, name, namelen, &id);
+	*gid = make_kgid(&init_user_ns, id);
+	if (!gid_valid(*gid))
+		status = nfserr_badowner;
+	return status;
 }
 
 int
-nfsd_map_uid_to_name(struct svc_rqst *rqstp, __u32 id, char *name)
+nfsd_map_uid_to_name(struct svc_rqst *rqstp, kuid_t uid, char *name)
 {
+	u32 id = from_kuid(&init_user_ns, uid);
 	return do_id_to_name(rqstp, IDMAP_TYPE_USER, id, name);
 }
 
 int
-nfsd_map_gid_to_name(struct svc_rqst *rqstp, __u32 id, char *name)
+nfsd_map_gid_to_name(struct svc_rqst *rqstp, kgid_t gid, char *name)
 {
+	u32 id = from_kgid(&init_user_ns, gid);
 	return do_id_to_name(rqstp, IDMAP_TYPE_GROUP, id, name);
 }
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 65/85] nfsd: Remove nfsd_luid, nfsd_lgid, nfsd_ruid and nfsd_rgid
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (62 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 64/85] nfsd: Convert idmap to use kuids and kgids Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 66/85] nfsd: Convert nfs3xdr to use kuids and kgids Eric W. Biederman
                     ` (19 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

These trivial macros that don't currently do anything are the last
vestiages of an old attempt at uid mapping that was removed from the
kernel in September of 2002.  Remove them to make it clear what the
code is currently doing.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/nfsd/auth.h    |    6 ------
 fs/nfsd/nfs3xdr.c |    4 ++--
 fs/nfsd/nfsxdr.c  |    4 ++--
 3 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/fs/nfsd/auth.h b/fs/nfsd/auth.h
index 78b3c0e..53325a1 100644
--- a/fs/nfsd/auth.h
+++ b/fs/nfsd/auth.h
@@ -1,6 +1,5 @@
 /*
  * nfsd-specific authentication stuff.
- * uid/gid mapping not yet implemented.
  *
  * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
  */
@@ -8,11 +7,6 @@
 #ifndef LINUX_NFSD_AUTH_H
 #define LINUX_NFSD_AUTH_H
 
-#define nfsd_luid(rq, uid)	((u32)(uid))
-#define nfsd_lgid(rq, gid)	((u32)(gid))
-#define nfsd_ruid(rq, uid)	((u32)(uid))
-#define nfsd_rgid(rq, gid)	((u32)(gid))
-
 /*
  * Set the current process's fsuid/fsgid etc to those of the NFS
  * client user
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 324c0ba..1884a3f 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -167,8 +167,8 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
 	*p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
 	*p++ = htonl((u32) stat->mode);
 	*p++ = htonl((u32) stat->nlink);
-	*p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid));
-	*p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid));
+	*p++ = htonl((u32) stat->uid);
+	*p++ = htonl((u32) stat->gid);
 	if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
 		p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
 	} else {
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 979b421..1e51e70 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -151,8 +151,8 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
 	*p++ = htonl(nfs_ftypes[type >> 12]);
 	*p++ = htonl((u32) stat->mode);
 	*p++ = htonl((u32) stat->nlink);
-	*p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid));
-	*p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid));
+	*p++ = htonl((u32) stat->uid);
+	*p++ = htonl((u32) stat->gid);
 
 	if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
 		*p++ = htonl(NFS_MAXPATHLEN);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 66/85] nfsd: Convert nfs3xdr to use kuids and kgids
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (63 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 65/85] nfsd: Remove nfsd_luid, nfsd_lgid, nfsd_ruid and nfsd_rgid Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 67/85] nfsd: Convert nfsxdr " Eric W. Biederman
                     ` (18 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

When reading uids and gids off the wire convert them to kuids and
kgids.

When putting kuids and kgids onto the wire first convert them to uids
and gids the other side will understand.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/nfsd/nfs3xdr.c |   14 ++++++++------
 1 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 1884a3f..925c944 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -105,12 +105,14 @@ decode_sattr3(__be32 *p, struct iattr *iap)
 		iap->ia_mode = ntohl(*p++);
 	}
 	if (*p++) {
-		iap->ia_valid |= ATTR_UID;
-		iap->ia_uid = ntohl(*p++);
+		iap->ia_uid = make_kuid(&init_user_ns, ntohl(*p++));
+		if (uid_valid(iap->ia_uid))
+			iap->ia_valid |= ATTR_UID;
 	}
 	if (*p++) {
-		iap->ia_valid |= ATTR_GID;
-		iap->ia_gid = ntohl(*p++);
+		iap->ia_gid = make_kgid(&init_user_ns, ntohl(*p++));
+		if (gid_valid(iap->ia_gid))
+			iap->ia_valid |= ATTR_GID;
 	}
 	if (*p++) {
 		u64	newsize;
@@ -167,8 +169,8 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
 	*p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
 	*p++ = htonl((u32) stat->mode);
 	*p++ = htonl((u32) stat->nlink);
-	*p++ = htonl((u32) stat->uid);
-	*p++ = htonl((u32) stat->gid);
+	*p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
+	*p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
 	if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
 		p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
 	} else {
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 67/85] nfsd: Convert nfsxdr to use kuids and kgids
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (64 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 66/85] nfsd: Convert nfs3xdr to use kuids and kgids Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 68/85] nfsd: Handle kuids and kgids in the nfs4acl to posix_acl conversion Eric W. Biederman
                     ` (17 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

When reading uids and gids off the wire convert them to
kuids and kgids.  If the conversion results in an invalid
result don't set the ATTR_UID or ATTR_GID.

When putting kuids and kgids onto the wire first convert
them to uids and gids the other side will understand.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/nfsd/nfsxdr.c |   14 ++++++++------
 1 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 1e51e70..4201ede 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -100,12 +100,14 @@ decode_sattr(__be32 *p, struct iattr *iap)
 		iap->ia_mode = tmp;
 	}
 	if ((tmp = ntohl(*p++)) != (u32)-1) {
-		iap->ia_valid |= ATTR_UID;
-		iap->ia_uid = tmp;
+		iap->ia_uid = make_kuid(&init_user_ns, tmp);
+		if (uid_valid(iap->ia_uid))
+			iap->ia_valid |= ATTR_UID;
 	}
 	if ((tmp = ntohl(*p++)) != (u32)-1) {
-		iap->ia_valid |= ATTR_GID;
-		iap->ia_gid = tmp;
+		iap->ia_gid = make_kgid(&init_user_ns, tmp);
+		if (gid_valid(iap->ia_gid))
+			iap->ia_valid |= ATTR_GID;
 	}
 	if ((tmp = ntohl(*p++)) != (u32)-1) {
 		iap->ia_valid |= ATTR_SIZE;
@@ -151,8 +153,8 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
 	*p++ = htonl(nfs_ftypes[type >> 12]);
 	*p++ = htonl((u32) stat->mode);
 	*p++ = htonl((u32) stat->nlink);
-	*p++ = htonl((u32) stat->uid);
-	*p++ = htonl((u32) stat->gid);
+	*p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
+	*p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
 
 	if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
 		*p++ = htonl(NFS_MAXPATHLEN);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 68/85] nfsd: Handle kuids and kgids in the nfs4acl to posix_acl conversion
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (65 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 67/85] nfsd: Convert nfsxdr " Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 69/85] nfsd: Modify nfsd4_cb_sec to use kuids and kgids Eric W. Biederman
                     ` (16 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

In struct nfs4_ace remove the member who and replace it with an
anonymous union holding who_uid and who_gid.  Allowing typesafe
storage uids and gids.

Add a helper pace_gt for sorting posix_acl_entries.

In struct posix_user_ace_state to replace uid with a union
of kuid_t uid and kgid_t gid.

Remove all initializations of the deprecated posic_acl_entry
e_id field.  Which is not present when user namespaces are enabled.

Split find_uid into two functions find_uid and find_gid that work
in a typesafe manner.

In nfs4xdr update nfsd4_encode_fattr to deal with the changes
in struct nfs4_ace.

Rewrite nfsd4_encode_name to take a kuid_t and a kgid_t instead
of a generic id and flag if it is a group or a uid.  Replace
the group flag with a test for a valid gid.

Modify nfsd4_encode_user to take a kuid_t and call the modifed
nfsd4_encode_name.

Modify nfsd4_encode_group to take a kgid_t and call the modified
nfsd4_encode_name.

Modify nfsd4_encode_aclname to take an ace instead of taking the
fields of an ace broken out.  This allows it to detect if the ace is
for a user or a group and to pass the appropriate value while still
being typesafe.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/nfsd/nfs4acl.c    |   63 ++++++++++++++++++++++++++++++++++++-------------
 fs/nfsd/nfs4xdr.c    |   41 +++++++++++++++++++------------
 include/linux/nfs4.h |    6 ++++-
 3 files changed, 76 insertions(+), 34 deletions(-)

diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index 9c51aff..8a50b3c 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -264,7 +264,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,
 			ace->flag = eflag;
 			ace->access_mask = deny_mask_from_posix(deny, flags);
 			ace->whotype = NFS4_ACL_WHO_NAMED;
-			ace->who = pa->e_id;
+			ace->who_uid = pa->e_uid;
 			ace++;
 			acl->naces++;
 		}
@@ -273,7 +273,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,
 		ace->access_mask = mask_from_posix(pa->e_perm & pas.mask,
 						   flags);
 		ace->whotype = NFS4_ACL_WHO_NAMED;
-		ace->who = pa->e_id;
+		ace->who_uid = pa->e_uid;
 		ace++;
 		acl->naces++;
 		pa++;
@@ -300,7 +300,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,
 		ace->access_mask = mask_from_posix(pa->e_perm & pas.mask,
 						   flags);
 		ace->whotype = NFS4_ACL_WHO_NAMED;
-		ace->who = pa->e_id;
+		ace->who_gid = pa->e_gid;
 		ace++;
 		acl->naces++;
 		pa++;
@@ -329,7 +329,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,
 			ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP;
 			ace->access_mask = deny_mask_from_posix(deny, flags);
 			ace->whotype = NFS4_ACL_WHO_NAMED;
-			ace->who = pa->e_id;
+			ace->who_gid = pa->e_gid;
 			ace++;
 			acl->naces++;
 		}
@@ -345,6 +345,18 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,
 	acl->naces++;
 }
 
+static bool
+pace_gt(struct posix_acl_entry *pace1, struct posix_acl_entry *pace2)
+{
+	if (pace1->e_tag != pace2->e_tag)
+		return pace1->e_tag > pace2->e_tag;
+	if (pace1->e_tag == ACL_USER)
+		return uid_gt(pace1->e_uid, pace2->e_uid);
+	if (pace1->e_tag == ACL_GROUP)
+		return gid_gt(pace1->e_gid, pace2->e_gid);
+	return false;
+}
+
 static void
 sort_pacl_range(struct posix_acl *pacl, int start, int end) {
 	int sorted = 0, i;
@@ -355,8 +367,8 @@ sort_pacl_range(struct posix_acl *pacl, int start, int end) {
 	while (!sorted) {
 		sorted = 1;
 		for (i = start; i < end; i++) {
-			if (pacl->a_entries[i].e_id
-					> pacl->a_entries[i+1].e_id) {
+			if (pace_gt(&pacl->a_entries[i],
+				    &pacl->a_entries[i+1])) {
 				sorted = 0;
 				tmp = pacl->a_entries[i];
 				pacl->a_entries[i] = pacl->a_entries[i+1];
@@ -398,7 +410,10 @@ struct posix_ace_state {
 };
 
 struct posix_user_ace_state {
-	uid_t uid;
+	union {
+		kuid_t uid;
+		kgid_t gid;
+	};
 	struct posix_ace_state perms;
 };
 
@@ -521,7 +536,6 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
 	if (error)
 		goto out_err;
 	low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags);
-	pace->e_id = ACL_UNDEFINED_ID;
 
 	for (i=0; i < state->users->n; i++) {
 		pace++;
@@ -531,7 +545,7 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
 			goto out_err;
 		low_mode_from_nfs4(state->users->aces[i].perms.allow,
 					&pace->e_perm, flags);
-		pace->e_id = state->users->aces[i].uid;
+		pace->e_uid = state->users->aces[i].uid;
 		add_to_mask(state, &state->users->aces[i].perms);
 	}
 
@@ -541,7 +555,6 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
 	if (error)
 		goto out_err;
 	low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags);
-	pace->e_id = ACL_UNDEFINED_ID;
 	add_to_mask(state, &state->group);
 
 	for (i=0; i < state->groups->n; i++) {
@@ -552,14 +565,13 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
 			goto out_err;
 		low_mode_from_nfs4(state->groups->aces[i].perms.allow,
 					&pace->e_perm, flags);
-		pace->e_id = state->groups->aces[i].uid;
+		pace->e_gid = state->groups->aces[i].gid;
 		add_to_mask(state, &state->groups->aces[i].perms);
 	}
 
 	pace++;
 	pace->e_tag = ACL_MASK;
 	low_mode_from_nfs4(state->mask.allow, &pace->e_perm, flags);
-	pace->e_id = ACL_UNDEFINED_ID;
 
 	pace++;
 	pace->e_tag = ACL_OTHER;
@@ -567,7 +579,6 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
 	if (error)
 		goto out_err;
 	low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags);
-	pace->e_id = ACL_UNDEFINED_ID;
 
 	return pacl;
 out_err:
@@ -587,12 +598,13 @@ static inline void deny_bits(struct posix_ace_state *astate, u32 mask)
 	astate->deny |= mask & ~astate->allow;
 }
 
-static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array *a, uid_t uid)
+static int find_uid(struct posix_acl_state *state, kuid_t uid)
 {
+	struct posix_ace_state_array *a = state->users;
 	int i;
 
 	for (i = 0; i < a->n; i++)
-		if (a->aces[i].uid == uid)
+		if (uid_eq(a->aces[i].uid, uid))
 			return i;
 	/* Not found: */
 	a->n++;
@@ -603,6 +615,23 @@ static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array
 	return i;
 }
 
+static int find_gid(struct posix_acl_state *state, kgid_t gid)
+{
+	struct posix_ace_state_array *a = state->groups;
+	int i;
+
+	for (i = 0; i < a->n; i++)
+		if (gid_eq(a->aces[i].gid, gid))
+			return i;
+	/* Not found: */
+	a->n++;
+	a->aces[i].gid = gid;
+	a->aces[i].perms.allow = state->everyone.allow;
+	a->aces[i].perms.deny  = state->everyone.deny;
+
+	return i;
+}
+
 static void deny_bits_array(struct posix_ace_state_array *a, u32 mask)
 {
 	int i;
@@ -636,7 +665,7 @@ static void process_one_v4_ace(struct posix_acl_state *state,
 		}
 		break;
 	case ACL_USER:
-		i = find_uid(state, state->users, ace->who);
+		i = find_uid(state, ace->who_uid);
 		if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
 			allow_bits(&state->users->aces[i].perms, mask);
 		} else {
@@ -658,7 +687,7 @@ static void process_one_v4_ace(struct posix_acl_state *state,
 		}
 		break;
 	case ACL_GROUP:
-		i = find_uid(state, state->groups, ace->who);
+		i = find_gid(state, ace->who_gid);
 		if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
 			allow_bits(&state->groups->aces[i].perms, mask);
 		} else {
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 0dc1158..3812b06 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -293,13 +293,13 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 			ace->whotype = nfs4_acl_get_whotype(buf, dummy32);
 			status = nfs_ok;
 			if (ace->whotype != NFS4_ACL_WHO_NAMED)
-				ace->who = 0;
+				;
 			else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
 				status = nfsd_map_name_to_gid(argp->rqstp,
-						buf, dummy32, &ace->who);
+						buf, dummy32, &ace->who_gid);
 			else
 				status = nfsd_map_name_to_uid(argp->rqstp,
-						buf, dummy32, &ace->who);
+						buf, dummy32, &ace->who_uid);
 			if (status)
 				return status;
 		}
@@ -1926,7 +1926,7 @@ static u32 nfs4_file_type(umode_t mode)
 }
 
 static __be32
-nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
+nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, kuid_t uid, kgid_t gid,
 			__be32 **p, int *buflen)
 {
 	int status;
@@ -1935,10 +1935,10 @@ nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
 		return nfserr_resource;
 	if (whotype != NFS4_ACL_WHO_NAMED)
 		status = nfs4_acl_write_who(whotype, (u8 *)(*p + 1));
-	else if (group)
-		status = nfsd_map_gid_to_name(rqstp, id, (u8 *)(*p + 1));
+	else if (gid_valid(gid))
+		status = nfsd_map_gid_to_name(rqstp, gid, (u8 *)(*p + 1));
 	else
-		status = nfsd_map_uid_to_name(rqstp, id, (u8 *)(*p + 1));
+		status = nfsd_map_uid_to_name(rqstp, uid, (u8 *)(*p + 1));
 	if (status < 0)
 		return nfserrno(status);
 	*p = xdr_encode_opaque(*p, NULL, status);
@@ -1948,22 +1948,33 @@ nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
 }
 
 static inline __be32
-nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, __be32 **p, int *buflen)
+nfsd4_encode_user(struct svc_rqst *rqstp, kuid_t user, __be32 **p, int *buflen)
 {
-	return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, uid, 0, p, buflen);
+	return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, user, INVALID_GID,
+				 p, buflen);
 }
 
 static inline __be32
-nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, __be32 **p, int *buflen)
+nfsd4_encode_group(struct svc_rqst *rqstp, kgid_t group, __be32 **p, int *buflen)
 {
-	return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, gid, 1, p, buflen);
+	return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, INVALID_UID, group,
+				 p, buflen);
 }
 
 static inline __be32
-nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
+nfsd4_encode_aclname(struct svc_rqst *rqstp, struct nfs4_ace *ace,
 		__be32 **p, int *buflen)
 {
-	return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen);
+	kuid_t uid = INVALID_UID;
+	kgid_t gid = INVALID_GID;
+
+	if (ace->whotype == NFS4_ACL_WHO_NAMED) {
+		if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
+			gid = ace->who_gid;
+		else
+			uid = ace->who_uid;
+	}
+	return nfsd4_encode_name(rqstp, ace->whotype, uid, gid, p, buflen);
 }
 
 #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
@@ -2224,9 +2235,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
 			WRITE32(ace->type);
 			WRITE32(ace->flag);
 			WRITE32(ace->access_mask & NFS4_ACE_MASK_ALL);
-			status = nfsd4_encode_aclname(rqstp, ace->whotype,
-				ace->who, ace->flag & NFS4_ACE_IDENTIFIER_GROUP,
-				&p, &buflen);
+			status = nfsd4_encode_aclname(rqstp, ace, &p, &buflen);
 			if (status == nfserr_resource)
 				goto out_resource;
 			if (status)
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index e111fa4..7b8fc73 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -13,6 +13,7 @@
 #define _LINUX_NFS4_H
 
 #include <linux/list.h>
+#include <linux/uidgid.h>
 #include <uapi/linux/nfs4.h>
 
 struct nfs4_ace {
@@ -20,7 +21,10 @@ struct nfs4_ace {
 	uint32_t	flag;
 	uint32_t	access_mask;
 	int		whotype;
-	uid_t		who;
+	union {
+		kuid_t	who_uid;
+		kgid_t	who_gid;
+	};
 };
 
 struct nfs4_acl {
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 69/85] nfsd: Modify nfsd4_cb_sec to use kuids and kgids
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (66 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 68/85] nfsd: Handle kuids and kgids in the nfs4acl to posix_acl conversion Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:51   ` [PATCH review 70/85] nfsd: Store ex_anon_uid and ex_anon_gid as " Eric W. Biederman
                     ` (15 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

Change uid and gid in struct nfsd4_cb_sec to be of type kuid_t and
kgid_t.

In nfsd4_decode_cb_sec when reading uids and gids off the wire convert
them to kuids and kgids, and if they don't convert to valid kuids or
valid kuids ignore RPC_AUTH_UNIX and don't fill in any of the fields.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/nfsd/nfs4xdr.c |   13 ++++++++++---
 fs/nfsd/state.h   |    4 ++--
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 3812b06..2d1d06b 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -464,9 +464,16 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_
 			READ32(dummy);
 			READ_BUF(dummy * 4);
 			if (cbs->flavor == (u32)(-1)) {
-				cbs->uid = uid;
-				cbs->gid = gid;
-				cbs->flavor = RPC_AUTH_UNIX;
+				kuid_t kuid = make_kuid(&init_user_ns, uid);
+				kgid_t kgid = make_kgid(&init_user_ns, gid);
+				if (uid_valid(kuid) && gid_valid(kgid)) {
+					cbs->uid = kuid;
+					cbs->gid = kgid;
+					cbs->flavor = RPC_AUTH_UNIX;
+				} else {
+					dprintk("RPC_AUTH_UNIX with invalid"
+						"uid or gid ignoring!\n");
+				}
 			}
 			break;
 		case RPC_AUTH_GSS:
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index d1c229f..1a8c739 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -152,8 +152,8 @@ struct nfsd4_channel_attrs {
 
 struct nfsd4_cb_sec {
 	u32	flavor; /* (u32)(-1) used to mean "no valid flavor" */
-	u32	uid;
-	u32	gid;
+	kuid_t	uid;
+	kgid_t	gid;
 };
 
 struct nfsd4_create_session {
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 70/85] nfsd: Store ex_anon_uid and ex_anon_gid as kuids and kgids
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (67 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 69/85] nfsd: Modify nfsd4_cb_sec to use kuids and kgids Eric W. Biederman
@ 2013-02-13 17:51   ` Eric W. Biederman
  2013-02-13 17:52   ` [PATCH review 71/85] nfsd: Properly compare and initialize " Eric W. Biederman
                     ` (14 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:51 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/nfsd/auth.c              |    2 +-
 fs/nfsd/export.c            |   22 ++++++++++++++--------
 include/linux/nfsd/export.h |    4 ++--
 3 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c
index 34a10d7..4d6642b 100644
--- a/fs/nfsd/auth.c
+++ b/fs/nfsd/auth.c
@@ -58,7 +58,7 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
 
 		for (i = 0; i < rqgi->ngroups; i++) {
 			if (gid_eq(GLOBAL_ROOT_GID, GROUP_AT(rqgi, i)))
-				GROUP_AT(gi, i) = make_kgid(&init_user_ns, exp->ex_anon_gid);
+				GROUP_AT(gi, i) = exp->ex_anon_gid;
 			else
 				GROUP_AT(gi, i) = GROUP_AT(rqgi, i);
 		}
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index a3946cf..5681c59 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -544,13 +544,17 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
 		err = get_int(&mesg, &an_int);
 		if (err)
 			goto out3;
-		exp.ex_anon_uid= an_int;
+		exp.ex_anon_uid= make_kuid(&init_user_ns, an_int);
+		if (!uid_valid(exp.ex_anon_uid))
+			goto out3;
 
 		/* anon gid */
 		err = get_int(&mesg, &an_int);
 		if (err)
 			goto out3;
-		exp.ex_anon_gid= an_int;
+		exp.ex_anon_gid= make_kgid(&init_user_ns, an_int);
+		if (!gid_valid(exp.ex_anon_gid))
+			goto out3;
 
 		/* fsid */
 		err = get_int(&mesg, &an_int);
@@ -613,7 +617,7 @@ out:
 }
 
 static void exp_flags(struct seq_file *m, int flag, int fsid,
-		uid_t anonu, uid_t anong, struct nfsd4_fs_locations *fslocs);
+		kuid_t anonu, kgid_t anong, struct nfsd4_fs_locations *fslocs);
 static void show_secinfo(struct seq_file *m, struct svc_export *exp);
 
 static int svc_export_show(struct seq_file *m,
@@ -1179,15 +1183,17 @@ static void show_secinfo(struct seq_file *m, struct svc_export *exp)
 }
 
 static void exp_flags(struct seq_file *m, int flag, int fsid,
-		uid_t anonu, uid_t anong, struct nfsd4_fs_locations *fsloc)
+		kuid_t anonu, kgid_t anong, struct nfsd4_fs_locations *fsloc)
 {
 	show_expflags(m, flag, NFSEXP_ALLFLAGS);
 	if (flag & NFSEXP_FSID)
 		seq_printf(m, ",fsid=%d", fsid);
-	if (anonu != (uid_t)-2 && anonu != (0x10000-2))
-		seq_printf(m, ",anonuid=%u", anonu);
-	if (anong != (gid_t)-2 && anong != (0x10000-2))
-		seq_printf(m, ",anongid=%u", anong);
+	if (!uid_eq(anonu, make_kuid(&init_user_ns, (uid_t)-2)) &&
+	    !uid_eq(anonu, make_kuid(&init_user_ns, 0x10000-2)))
+		seq_printf(m, ",anonuid=%u", from_kuid(&init_user_ns, anonu));
+	if (!gid_eq(anong, make_kgid(&init_user_ns, (gid_t)-2)) &&
+	    !gid_eq(anong, make_kgid(&init_user_ns, 0x10000-2)))
+		seq_printf(m, ",anongid=%u", from_kgid(&init_user_ns, anong));
 	if (fsloc && fsloc->locations_count > 0) {
 		char *loctype = (fsloc->migrated) ? "refer" : "replicas";
 		int i;
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index 24c1392..7898c99 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -49,8 +49,8 @@ struct svc_export {
 	struct auth_domain *	ex_client;
 	int			ex_flags;
 	struct path		ex_path;
-	uid_t			ex_anon_uid;
-	gid_t			ex_anon_gid;
+	kuid_t			ex_anon_uid;
+	kgid_t			ex_anon_gid;
 	int			ex_fsid;
 	unsigned char *		ex_uuid; /* 16 byte fsid */
 	struct nfsd4_fs_locations ex_fslocs;
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 71/85] nfsd: Properly compare and initialize kuids and kgids
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (68 preceding siblings ...)
  2013-02-13 17:51   ` [PATCH review 70/85] nfsd: Store ex_anon_uid and ex_anon_gid as " Eric W. Biederman
@ 2013-02-13 17:52   ` Eric W. Biederman
  2013-02-13 17:52   ` [PATCH review 72/85] nfsd: Enable building with user namespaces enabled Eric W. Biederman
                     ` (13 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:52 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

Use uid_eq(uid, GLOBAL_ROOT_UID) instead of !uid.
Use gid_eq(gid, GLOBAL_ROOT_GID) instead of !gid.
Use uid_eq(uid, INVALID_UID) instead of uid == -1
Use gid_eq(uid, INVALID_GID) instead of gid == -1
Use uid = GLOBAL_ROOT_UID instead of uid = 0;
Use gid = GLOBAL_ROOT_GID instead of gid = 0;
Use !uid_eq(uid1, uid2) instead of uid1 != uid2.
Use !gid_eq(gid1, gid2) instead of gid1 != gid2.
Use uid_eq(uid1, uid2) instead of uid1 == uid2.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/nfsd/auth.c        |   10 +++++-----
 fs/nfsd/nfs4recover.c |    4 ++--
 fs/nfsd/nfs4state.c   |    6 +++---
 fs/nfsd/vfs.c         |    8 ++++----
 4 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c
index 4d6642b..06cddd5 100644
--- a/fs/nfsd/auth.c
+++ b/fs/nfsd/auth.c
@@ -47,9 +47,9 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
 		if (!gi)
 			goto oom;
 	} else if (flags & NFSEXP_ROOTSQUASH) {
-		if (!new->fsuid)
+		if (uid_eq(new->fsuid, GLOBAL_ROOT_UID))
 			new->fsuid = exp->ex_anon_uid;
-		if (!new->fsgid)
+		if (gid_eq(new->fsgid, GLOBAL_ROOT_GID))
 			new->fsgid = exp->ex_anon_gid;
 
 		gi = groups_alloc(rqgi->ngroups);
@@ -66,9 +66,9 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
 		gi = get_group_info(rqgi);
 	}
 
-	if (new->fsuid == (uid_t) -1)
+	if (uid_eq(new->fsuid, INVALID_UID))
 		new->fsuid = exp->ex_anon_uid;
-	if (new->fsgid == (gid_t) -1)
+	if (gid_eq(new->fsgid, INVALID_GID))
 		new->fsgid = exp->ex_anon_gid;
 
 	ret = set_groups(new, gi);
@@ -76,7 +76,7 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
 	if (ret < 0)
 		goto error;
 
-	if (new->fsuid)
+	if (!uid_eq(new->fsuid, GLOBAL_ROOT_UID))
 		new->cap_effective = cap_drop_nfsd_set(new->cap_effective);
 	else
 		new->cap_effective = cap_raise_nfsd_set(new->cap_effective,
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index ba6fdd4..4914af4 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -73,8 +73,8 @@ nfs4_save_creds(const struct cred **original_creds)
 	if (!new)
 		return -ENOMEM;
 
-	new->fsuid = 0;
-	new->fsgid = 0;
+	new->fsuid = GLOBAL_ROOT_UID;
+	new->fsgid = GLOBAL_ROOT_GID;
 	*original_creds = override_creds(new);
 	put_cred(new);
 	return 0;
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index ac8ed96..0af6d3c 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1202,7 +1202,7 @@ static bool groups_equal(struct group_info *g1, struct group_info *g2)
 	if (g1->ngroups != g2->ngroups)
 		return false;
 	for (i=0; i<g1->ngroups; i++)
-		if (GROUP_AT(g1, i) != GROUP_AT(g2, i))
+		if (!gid_eq(GROUP_AT(g1, i), GROUP_AT(g2, i)))
 			return false;
 	return true;
 }
@@ -1227,8 +1227,8 @@ static bool
 same_creds(struct svc_cred *cr1, struct svc_cred *cr2)
 {
 	if ((is_gss_cred(cr1) != is_gss_cred(cr2))
-		|| (cr1->cr_uid != cr2->cr_uid)
-		|| (cr1->cr_gid != cr2->cr_gid)
+		|| (!uid_eq(cr1->cr_uid, cr2->cr_uid))
+		|| (!gid_eq(cr1->cr_gid, cr2->cr_gid))
 		|| !groups_equal(cr1->cr_group_info, cr2->cr_group_info))
 		return false;
 	if (cr1->cr_principal == cr2->cr_principal)
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index d586117..31ff1d6 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -401,8 +401,8 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
 
 	/* Revoke setuid/setgid on chown */
 	if (!S_ISDIR(inode->i_mode) &&
-	    (((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) ||
-	     ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid))) {
+	    (((iap->ia_valid & ATTR_UID) && !uid_eq(iap->ia_uid, inode->i_uid)) ||
+	     ((iap->ia_valid & ATTR_GID) && !gid_eq(iap->ia_gid, inode->i_gid)))) {
 		iap->ia_valid |= ATTR_KILL_PRIV;
 		if (iap->ia_valid & ATTR_MODE) {
 			/* we're setting mode too, just clear the s*id bits */
@@ -1205,7 +1205,7 @@ nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *resfhp,
 	 * send along the gid on create when it tries to implement
 	 * setgid directories via NFS:
 	 */
-	if (current_fsuid() != 0)
+	if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
 		iap->ia_valid &= ~(ATTR_UID|ATTR_GID);
 	if (iap->ia_valid)
 		return nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
@@ -2150,7 +2150,7 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp,
 	 * with NFSv3.
 	 */
 	if ((acc & NFSD_MAY_OWNER_OVERRIDE) &&
-	    inode->i_uid == current_fsuid())
+	    uid_eq(inode->i_uid, current_fsuid()))
 		return 0;
 
 	/* This assumes  NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC} */
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 72/85] nfsd: Enable building with user namespaces enabled.
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (69 preceding siblings ...)
  2013-02-13 17:52   ` [PATCH review 71/85] nfsd: Properly compare and initialize " Eric W. Biederman
@ 2013-02-13 17:52   ` Eric W. Biederman
  2013-02-13 17:52   ` [PATCH review 73/85] cifs: Override unmappable incoming uids and gids Eric W. Biederman
                     ` (12 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:52 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, J. Bruce Fields, Trond Myklebust

From: "Eric W. Biederman" <ebiederm@xmission.com>

Now that the kuids and kgids conversion have propogated
through net/sunrpc/ and the fs/nfsd/ it is safe to enable
building nfsd when user namespaces are enabled.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 init/Kconfig |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/init/Kconfig b/init/Kconfig
index d7b926a..69c5ccc 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1072,7 +1072,6 @@ config UIDGID_CONVERTED
 
 	# Filesystems
 	depends on CIFS = n
-	depends on NFSD = n
 	depends on XFS_FS = n
 
 config UIDGID_STRICT_TYPE_CHECKS
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 73/85] cifs: Override unmappable incoming uids and gids
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (70 preceding siblings ...)
  2013-02-13 17:52   ` [PATCH review 72/85] nfsd: Enable building with user namespaces enabled Eric W. Biederman
@ 2013-02-13 17:52   ` Eric W. Biederman
  2013-02-13 17:52   ` [PATCH review 74/85] cifs: Use BUILD_BUG_ON to validate uids and gids are the same size Eric W. Biederman
                     ` (11 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:52 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steve French

From: "Eric W. Biederman" <ebiederm@xmission.com>

The cifs protocol has a 64bit space for uids and gids, while linux
only supports a 32bit space today.  Instead of silently truncating
64bit cifs ids, replace cifs ids that do not fit in the 32bit linux
id space with the default uid and gids for the cifs mount.

Cc: Steve French <smfrench@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/cifs/inode.c |   22 +++++++++++++---------
 1 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index ed6208f..d7ea2a6 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -244,15 +244,19 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
 		break;
 	}
 
-	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
-		fattr->cf_uid = cifs_sb->mnt_uid;
-	else
-		fattr->cf_uid = le64_to_cpu(info->Uid);
-
-	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
-		fattr->cf_gid = cifs_sb->mnt_gid;
-	else
-		fattr->cf_gid = le64_to_cpu(info->Gid);
+	fattr->cf_uid = cifs_sb->mnt_uid;
+	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) {
+		u64 id = le64_to_cpu(info->Uid);
+		if (id < ((uid_t)-1))
+			fattr->cf_uid = id;
+	}
+	
+	fattr->cf_gid = cifs_sb->mnt_gid;
+	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) {
+		u64 id = le64_to_cpu(info->Gid);
+		if (id < ((gid_t)-1))
+			fattr->cf_gid = id;
+	}
 
 	fattr->cf_nlink = le64_to_cpu(info->Nlinks);
 }
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 74/85] cifs: Use BUILD_BUG_ON to validate uids and gids are the same size
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (71 preceding siblings ...)
  2013-02-13 17:52   ` [PATCH review 73/85] cifs: Override unmappable incoming uids and gids Eric W. Biederman
@ 2013-02-13 17:52   ` Eric W. Biederman
  2013-02-13 17:52   ` [PATCH review 75/85] cifs: Pass GLOBAL_ROOT_UID and GLOBAL_ROOT_GID to keyring_alloc Eric W. Biederman
                     ` (10 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:52 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steve French

From: "Eric W. Biederman" <ebiederm@xmission.com>

The assumption that sizeof(uid_t) is the same as sizeof(gid_t) is
completely reasonable but since we can verify the condition at
compile time.

Cc: Steve French <smfrench@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/cifs/cifsacl.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 5cbd00e..2e811f4 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -297,6 +297,7 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
 	 * probably a safe assumption but might be better to check based on
 	 * sidtype.
 	 */
+	BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
 	if (sidkey->datalen != sizeof(uid_t)) {
 		rc = -EIO;
 		cFYI(1, "%s: Downcall contained malformed key "
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 75/85] cifs: Pass GLOBAL_ROOT_UID and GLOBAL_ROOT_GID to keyring_alloc
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (72 preceding siblings ...)
  2013-02-13 17:52   ` [PATCH review 74/85] cifs: Use BUILD_BUG_ON to validate uids and gids are the same size Eric W. Biederman
@ 2013-02-13 17:52   ` Eric W. Biederman
  2013-02-13 17:52   ` [PATCH review 76/85] cifs: Use kuids and kgids SID to uid/gid mapping Eric W. Biederman
                     ` (9 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:52 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steve French

From: "Eric W. Biederman" <ebiederm@xmission.com>

keyring_alloc has been updated to take a kuid_t and kgid_t so
pass GLOBAL_ROOT_UID instead of 0 for the uid and GLOBAL_ROOT_GID
instead of 0 for the gid.

Cc: Steve French <smfrench@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/cifs/cifsacl.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 2e811f4..aaaf5ce 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -347,7 +347,8 @@ init_cifs_idmap(void)
 	if (!cred)
 		return -ENOMEM;
 
-	keyring = keyring_alloc(".cifs_idmap", 0, 0, cred,
+	keyring = keyring_alloc(".cifs_idmap",
+				GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
 				(KEY_POS_ALL & ~KEY_POS_SETATTR) |
 				KEY_USR_VIEW | KEY_USR_READ,
 				KEY_ALLOC_NOT_IN_QUOTA, NULL);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 76/85] cifs: Use kuids and kgids SID to uid/gid mapping
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (73 preceding siblings ...)
  2013-02-13 17:52   ` [PATCH review 75/85] cifs: Pass GLOBAL_ROOT_UID and GLOBAL_ROOT_GID to keyring_alloc Eric W. Biederman
@ 2013-02-13 17:52   ` Eric W. Biederman
  2013-02-13 17:52   ` [PATCH review 77/85] cifs: Convert from a kuid before printing current_fsuid Eric W. Biederman
                     ` (8 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:52 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steve French

From: "Eric W. Biederman" <ebiederm@xmission.com>

Update id_mode_to_cifs_acl to take a kuid_t and a kgid_t.

Replace NO_CHANGE_32 with INVALID_UID and INVALID_GID, and tests for
NO_CHANGE_32 with uid_valid and gid_valid.

Carefully unpack the value returned from request_key.  memcpy the
value into the expected type.  The convert the uid/gid into a
kuid/kgid.  And then only if the result is a valid kuid or kgid update
fuid/fgid.

Cc: Steve French <smfrench@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/cifs/cifsacl.c   |   43 +++++++++++++++++++++++++++++--------------
 fs/cifs/cifspdu.h   |    1 -
 fs/cifs/cifsproto.h |    2 +-
 fs/cifs/inode.c     |    8 ++++----
 4 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index aaaf5ce..f1e3f25 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -266,8 +266,8 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
 	struct key *sidkey;
 	char *sidstr;
 	const struct cred *saved_cred;
-	uid_t fuid = cifs_sb->mnt_uid;
-	gid_t fgid = cifs_sb->mnt_gid;
+	kuid_t fuid = cifs_sb->mnt_uid;
+	kgid_t fgid = cifs_sb->mnt_gid;
 
 	/*
 	 * If we have too many subauthorities, then something is really wrong.
@@ -306,10 +306,21 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
 		goto out_key_put;
 	}
 
-	if (sidtype == SIDOWNER)
-		memcpy(&fuid, &sidkey->payload.value, sizeof(uid_t));
-	else
-		memcpy(&fgid, &sidkey->payload.value, sizeof(gid_t));
+	if (sidtype == SIDOWNER) {
+		kuid_t uid;
+		uid_t id;
+		memcpy(&id, &sidkey->payload.value, sizeof(uid_t));
+		uid = make_kuid(&init_user_ns, id);
+		if (uid_valid(uid))
+			fuid = uid;
+	} else {
+		kgid_t gid;
+		gid_t id;
+		memcpy(&id, &sidkey->payload.value, sizeof(gid_t));
+		gid = make_kgid(&init_user_ns, id);
+		if (gid_valid(gid))
+			fgid = gid;
+	}
 
 out_key_put:
 	key_put(sidkey);
@@ -776,7 +787,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
 
 /* Convert permission bits from mode to equivalent CIFS ACL */
 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
-	__u32 secdesclen, __u64 nmode, uid_t uid, gid_t gid, int *aclflag)
+	__u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, int *aclflag)
 {
 	int rc = 0;
 	__u32 dacloffset;
@@ -808,17 +819,19 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
 		*aclflag = CIFS_ACL_DACL;
 	} else {
 		memcpy(pnntsd, pntsd, secdesclen);
-		if (uid != NO_CHANGE_32) { /* chown */
+		if (uid_valid(uid)) { /* chown */
+			uid_t id;
 			owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
 					le32_to_cpu(pnntsd->osidoffset));
 			nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
 								GFP_KERNEL);
 			if (!nowner_sid_ptr)
 				return -ENOMEM;
-			rc = id_to_sid(uid, SIDOWNER, nowner_sid_ptr);
+			id = from_kuid(&init_user_ns, uid);
+			rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
 			if (rc) {
 				cFYI(1, "%s: Mapping error %d for owner id %d",
-						__func__, rc, uid);
+						__func__, rc, id);
 				kfree(nowner_sid_ptr);
 				return rc;
 			}
@@ -826,17 +839,19 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
 			kfree(nowner_sid_ptr);
 			*aclflag = CIFS_ACL_OWNER;
 		}
-		if (gid != NO_CHANGE_32) { /* chgrp */
+		if (gid_valid(gid)) { /* chgrp */
+			gid_t id;
 			group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
 					le32_to_cpu(pnntsd->gsidoffset));
 			ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
 								GFP_KERNEL);
 			if (!ngroup_sid_ptr)
 				return -ENOMEM;
-			rc = id_to_sid(gid, SIDGROUP, ngroup_sid_ptr);
+			id = from_kgid(&init_user_ns, gid);
+			rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
 			if (rc) {
 				cFYI(1, "%s: Mapping error %d for group id %d",
-						__func__, rc, gid);
+						__func__, rc, id);
 				kfree(ngroup_sid_ptr);
 				return rc;
 			}
@@ -1004,7 +1019,7 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
 /* Convert mode bits to an ACL so we can update the ACL on the server */
 int
 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
-			uid_t uid, gid_t gid)
+			kuid_t uid, kgid_t gid)
 {
 	int rc = 0;
 	int aclflag = CIFS_ACL_DACL; /* default flag to set */
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index b9d59a9..e996ff6 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -277,7 +277,6 @@
 #define CIFS_NO_HANDLE        0xFFFF
 
 #define NO_CHANGE_64          0xFFFFFFFFFFFFFFFFULL
-#define NO_CHANGE_32          0xFFFFFFFFUL
 
 /* IPC$ in ASCII */
 #define CIFS_IPC_RESOURCE "\x49\x50\x43\x24"
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 1988c1b..0060ec2 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -161,7 +161,7 @@ extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
 			      struct cifs_fattr *fattr, struct inode *inode,
 			      const char *path, const __u16 *pfid);
 extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64,
-					uid_t, gid_t);
+					kuid_t, kgid_t);
 extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *,
 					const char *, u32 *);
 extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *,
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index d7ea2a6..d4cf750 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -2090,8 +2090,8 @@ static int
 cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
 {
 	unsigned int xid;
-	uid_t uid = NO_CHANGE_32;
-	gid_t gid = NO_CHANGE_32;
+	kuid_t uid = INVALID_UID;
+	kgid_t gid = INVALID_GID;
 	struct inode *inode = direntry->d_inode;
 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
 	struct cifsInodeInfo *cifsInode = CIFS_I(inode);
@@ -2150,7 +2150,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
 
 #ifdef CONFIG_CIFS_ACL
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
-		if (uid != NO_CHANGE_32 || gid != NO_CHANGE_32) {
+		if (uid_valid(uid) || gid_valid(gid)) {
 			rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64,
 							uid, gid);
 			if (rc) {
@@ -2174,7 +2174,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
 #ifdef CONFIG_CIFS_ACL
 		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
 			rc = id_mode_to_cifs_acl(inode, full_path, mode,
-						NO_CHANGE_32, NO_CHANGE_32);
+						INVALID_UID, INVALID_GID);
 			if (rc) {
 				cFYI(1, "%s: Setting ACL failed with error: %d",
 					__func__, rc);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 77/85] cifs: Convert from a kuid before printing current_fsuid
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (74 preceding siblings ...)
  2013-02-13 17:52   ` [PATCH review 76/85] cifs: Use kuids and kgids SID to uid/gid mapping Eric W. Biederman
@ 2013-02-13 17:52   ` Eric W. Biederman
  2013-02-13 17:52   ` [PATCH review 78/85] cifs: Modify struct cifs_unix_set_info_args to hold a kuid_t and a kgid_t Eric W. Biederman
                     ` (7 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:52 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steve French

From: "Eric W. Biederman" <ebiederm@xmission.com>

Cc: Steve French <smfrench@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/cifs/cifsproto.h |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 0060ec2..feb9b6e 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -46,7 +46,8 @@ extern void _free_xid(unsigned int);
 ({								\
 	unsigned int __xid = _get_xid();				\
 	cFYI(1, "CIFS VFS: in %s as Xid: %u with uid: %d",	\
-	     __func__, __xid, current_fsuid());			\
+	     __func__, __xid,					\
+	     from_kuid(&init_user_ns, current_fsuid()));	\
 	__xid;							\
 })
 
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 78/85] cifs: Modify struct cifs_unix_set_info_args to hold a kuid_t and a kgid_t
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (75 preceding siblings ...)
  2013-02-13 17:52   ` [PATCH review 77/85] cifs: Convert from a kuid before printing current_fsuid Eric W. Biederman
@ 2013-02-13 17:52   ` Eric W. Biederman
  2013-02-13 17:52   ` [PATCH review 79/85] cifs: Convert struct tcon_link to use a kuid Eric W. Biederman
                     ` (6 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:52 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steve French

From: "Eric W. Biederman" <ebiederm@xmission.com>

Use INVALID_UID and INVALID_GID instead of NO_CHANGE_64 to indicate
the value should not be changed.

In cifs_fill_unix_set_info convert from kuids and kgids into uids and
gids that will fit in FILE_UNIX_BASIC_INFO.

Cc: Steve French <smfrench@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/cifs/cifsproto.h |    4 ++--
 fs/cifs/cifssmb.c   |   10 ++++++++--
 fs/cifs/dir.c       |   18 +++++++++---------
 fs/cifs/file.c      |    4 ++--
 fs/cifs/inode.c     |   14 +++++++-------
 5 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index feb9b6e..f450f06 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -305,8 +305,8 @@ struct cifs_unix_set_info_args {
 	__u64	atime;
 	__u64	mtime;
 	__u64	mode;
-	__u64	uid;
-	__u64	gid;
+	kuid_t	uid;
+	kgid_t	gid;
 	dev_t	device;
 };
 
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 76d0d29..00e12f2 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -5819,8 +5819,14 @@ static void
 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
 			const struct cifs_unix_set_info_args *args)
 {
+	u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64;
 	u64 mode = args->mode;
 
+	if (uid_valid(args->uid))
+		uid = from_kuid(&init_user_ns, args->uid);
+	if (gid_valid(args->gid))
+		gid = from_kgid(&init_user_ns, args->gid);
+
 	/*
 	 * Samba server ignores set of file size to zero due to bugs in some
 	 * older clients, but we should be precise - we use SetFileSize to
@@ -5833,8 +5839,8 @@ cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
 	data_offset->LastStatusChange = cpu_to_le64(args->ctime);
 	data_offset->LastAccessTime = cpu_to_le64(args->atime);
 	data_offset->LastModificationTime = cpu_to_le64(args->mtime);
-	data_offset->Uid = cpu_to_le64(args->uid);
-	data_offset->Gid = cpu_to_le64(args->gid);
+	data_offset->Uid = cpu_to_le64(uid);
+	data_offset->Gid = cpu_to_le64(gid);
 	/* better to leave device as zero when it is  */
 	data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
 	data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 8719bbe..1cd0162 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -342,14 +342,14 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
 
 		*created |= FILE_CREATED;
 		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
-			args.uid = (__u64) current_fsuid();
+			args.uid = current_fsuid();
 			if (inode->i_mode & S_ISGID)
-				args.gid = (__u64) inode->i_gid;
+				args.gid = inode->i_gid;
 			else
-				args.gid = (__u64) current_fsgid();
+				args.gid = current_fsgid();
 		} else {
-			args.uid = NO_CHANGE_64;
-			args.gid = NO_CHANGE_64;
+			args.uid = INVALID_UID; /* no change */
+			args.gid = INVALID_GID; /* no change */
 		}
 		CIFSSMBUnixSetFileInfo(xid, tcon, &args, fid->netfid,
 				       current->tgid);
@@ -588,11 +588,11 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
 			.device	= device_number,
 		};
 		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
-			args.uid = (__u64) current_fsuid();
-			args.gid = (__u64) current_fsgid();
+			args.uid = current_fsuid();
+			args.gid = current_fsgid();
 		} else {
-			args.uid = NO_CHANGE_64;
-			args.gid = NO_CHANGE_64;
+			args.uid = INVALID_UID; /* no change */
+			args.gid = INVALID_GID; /* no change */
 		}
 		rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
 					    cifs_sb->local_nls,
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 0a6677b..b9baf5f 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -487,8 +487,8 @@ int cifs_open(struct inode *inode, struct file *file)
 		 */
 		struct cifs_unix_set_info_args args = {
 			.mode	= inode->i_mode,
-			.uid	= NO_CHANGE_64,
-			.gid	= NO_CHANGE_64,
+			.uid	= INVALID_UID, /* no change */
+			.gid	= INVALID_GID, /* no change */
 			.ctime	= NO_CHANGE_64,
 			.atime	= NO_CHANGE_64,
 			.mtime	= NO_CHANGE_64,
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index d4cf750..7376439 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1249,14 +1249,14 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode,
 			.device	= 0,
 		};
 		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
-			args.uid = (__u64)current_fsuid();
+			args.uid = current_fsuid();
 			if (parent->i_mode & S_ISGID)
-				args.gid = (__u64)parent->i_gid;
+				args.gid = parent->i_gid;
 			else
-				args.gid = (__u64)current_fsgid();
+				args.gid = current_fsgid();
 		} else {
-			args.uid = NO_CHANGE_64;
-			args.gid = NO_CHANGE_64;
+			args.uid = INVALID_UID; /* no change */
+			args.gid = INVALID_GID; /* no change */
 		}
 		CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args,
 				       cifs_sb->local_nls,
@@ -2017,12 +2017,12 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
 	if (attrs->ia_valid & ATTR_UID)
 		args->uid = attrs->ia_uid;
 	else
-		args->uid = NO_CHANGE_64;
+		args->uid = INVALID_UID; /* no change */
 
 	if (attrs->ia_valid & ATTR_GID)
 		args->gid = attrs->ia_gid;
 	else
-		args->gid = NO_CHANGE_64;
+		args->gid = INVALID_GID; /* no change */
 
 	if (attrs->ia_valid & ATTR_ATIME)
 		args->atime = cifs_UnixTimeToNT(attrs->ia_atime);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 79/85] cifs: Convert struct tcon_link to use a kuid.
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (76 preceding siblings ...)
  2013-02-13 17:52   ` [PATCH review 78/85] cifs: Modify struct cifs_unix_set_info_args to hold a kuid_t and a kgid_t Eric W. Biederman
@ 2013-02-13 17:52   ` Eric W. Biederman
  2013-02-13 17:52   ` [PATCH review 80/85] cifs: Convert struct cifs_fattr to use kuid and kgids Eric W. Biederman
                     ` (5 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:52 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steve French

From: "Eric W. Biederman" <ebiederm@xmission.com>

Cc: Steve French <smfrench@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/cifs/cifsglob.h |    2 +-
 fs/cifs/connect.c  |   12 ++++++------
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index aea1eec..7993a7a 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -837,7 +837,7 @@ struct cifs_tcon {
  */
 struct tcon_link {
 	struct rb_node		tl_rbnode;
-	uid_t			tl_uid;
+	kuid_t			tl_uid;
 	unsigned long		tl_flags;
 #define TCON_LINK_MASTER	0
 #define TCON_LINK_PENDING	1
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 17c3643..5411694 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -3919,7 +3919,7 @@ cifs_set_vol_auth(struct smb_vol *vol, struct cifs_ses *ses)
 }
 
 static struct cifs_tcon *
-cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
+cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
 {
 	int rc;
 	struct cifs_tcon *master_tcon = cifs_sb_master_tcon(cifs_sb);
@@ -3989,7 +3989,7 @@ cifs_sb_tcon_pending_wait(void *unused)
 
 /* find and return a tlink with given uid */
 static struct tcon_link *
-tlink_rb_search(struct rb_root *root, uid_t uid)
+tlink_rb_search(struct rb_root *root, kuid_t uid)
 {
 	struct rb_node *node = root->rb_node;
 	struct tcon_link *tlink;
@@ -3997,9 +3997,9 @@ tlink_rb_search(struct rb_root *root, uid_t uid)
 	while (node) {
 		tlink = rb_entry(node, struct tcon_link, tl_rbnode);
 
-		if (tlink->tl_uid > uid)
+		if (uid_gt(tlink->tl_uid, uid))
 			node = node->rb_left;
-		else if (tlink->tl_uid < uid)
+		else if (uid_lt(tlink->tl_uid, uid))
 			node = node->rb_right;
 		else
 			return tlink;
@@ -4018,7 +4018,7 @@ tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink)
 		tlink = rb_entry(*new, struct tcon_link, tl_rbnode);
 		parent = *new;
 
-		if (tlink->tl_uid > new_tlink->tl_uid)
+		if (uid_gt(tlink->tl_uid, new_tlink->tl_uid))
 			new = &((*new)->rb_left);
 		else
 			new = &((*new)->rb_right);
@@ -4048,7 +4048,7 @@ struct tcon_link *
 cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
 {
 	int ret;
-	uid_t fsuid = current_fsuid();
+	kuid_t fsuid = current_fsuid();
 	struct tcon_link *tlink, *newtlink;
 
 	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 80/85] cifs: Convert struct cifs_fattr to use kuid and kgids
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (77 preceding siblings ...)
  2013-02-13 17:52   ` [PATCH review 79/85] cifs: Convert struct tcon_link to use a kuid Eric W. Biederman
@ 2013-02-13 17:52   ` Eric W. Biederman
  2013-02-13 17:52   ` [PATCH review 81/85] cifs: Convert struct cifsFileInfo to use a kuid Eric W. Biederman
                     ` (4 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:52 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steve French

From: "Eric W. Biederman" <ebiederm@xmission.com>

In cifs_unix_to_basic_fattr only update the cifs_fattr with an id if
it is valid after conversion.

Cc: Steve French <smfrench@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/cifs/cifsglob.h |    4 ++--
 fs/cifs/inode.c    |   14 ++++++++++----
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 7993a7a..98312fd 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -1245,8 +1245,8 @@ struct cifs_fattr {
 	u64		cf_eof;
 	u64		cf_bytes;
 	u64		cf_createtime;
-	uid_t		cf_uid;
-	gid_t		cf_gid;
+	kuid_t		cf_uid;
+	kgid_t		cf_gid;
 	umode_t		cf_mode;
 	dev_t		cf_rdev;
 	unsigned int	cf_nlink;
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 7376439..9638233 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -247,15 +247,21 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
 	fattr->cf_uid = cifs_sb->mnt_uid;
 	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) {
 		u64 id = le64_to_cpu(info->Uid);
-		if (id < ((uid_t)-1))
-			fattr->cf_uid = id;
+		if (id < ((uid_t)-1)) {
+			kuid_t uid = make_kuid(&init_user_ns, id);
+			if (uid_valid(uid))
+				fattr->cf_uid = uid;
+		}
 	}
 	
 	fattr->cf_gid = cifs_sb->mnt_gid;
 	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) {
 		u64 id = le64_to_cpu(info->Gid);
-		if (id < ((gid_t)-1))
-			fattr->cf_gid = id;
+		if (id < ((gid_t)-1)) {
+			kgid_t gid = make_kgid(&init_user_ns, id);
+			if (gid_valid(gid))
+				fattr->cf_gid = gid;
+		}
 	}
 
 	fattr->cf_nlink = le64_to_cpu(info->Nlinks);
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 81/85] cifs: Convert struct cifsFileInfo to use a kuid
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (78 preceding siblings ...)
  2013-02-13 17:52   ` [PATCH review 80/85] cifs: Convert struct cifs_fattr to use kuid and kgids Eric W. Biederman
@ 2013-02-13 17:52   ` Eric W. Biederman
  2013-02-13 17:52   ` [PATCH review 82/85] cifs: Modify struct smb_vol to use kuids and kgids Eric W. Biederman
                     ` (3 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:52 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steve French

From: "Eric W. Biederman" <ebiederm@xmission.com>

Cc: Steve French <smfrench@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/cifs/cifsglob.h |    2 +-
 fs/cifs/file.c     |    4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 98312fd..04aa74e 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -930,7 +930,7 @@ struct cifsFileInfo {
 	struct list_head tlist;	/* pointer to next fid owned by tcon */
 	struct list_head flist;	/* next fid (file instance) for this inode */
 	struct cifs_fid_locks *llist;	/* brlocks held by this fid */
-	unsigned int uid;	/* allows finding which FileInfo structure */
+	kuid_t uid;		/* allows finding which FileInfo structure */
 	__u32 pid;		/* process id who opened file */
 	struct cifs_fid fid;	/* file id from remote */
 	/* BB add lock scope info here if needed */ ;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index b9baf5f..c23fbd8 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1649,7 +1649,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
 	   are always at the end of the list but since the first entry might
 	   have a close pending, we go through the whole list */
 	list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
-		if (fsuid_only && open_file->uid != current_fsuid())
+		if (fsuid_only && !uid_eq(open_file->uid, current_fsuid()))
 			continue;
 		if (OPEN_FMODE(open_file->f_flags) & FMODE_READ) {
 			if (!open_file->invalidHandle) {
@@ -1702,7 +1702,7 @@ refind_writable:
 	list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
 		if (!any_available && open_file->pid != current->tgid)
 			continue;
-		if (fsuid_only && open_file->uid != current_fsuid())
+		if (fsuid_only && !uid_eq(open_file->uid, current_fsuid()))
 			continue;
 		if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
 			if (!open_file->invalidHandle) {
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 82/85] cifs: Modify struct smb_vol to use kuids and kgids
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (79 preceding siblings ...)
  2013-02-13 17:52   ` [PATCH review 81/85] cifs: Convert struct cifsFileInfo to use a kuid Eric W. Biederman
@ 2013-02-13 17:52   ` Eric W. Biederman
  2013-02-13 17:52   ` [PATCH review 83/85] cifs: Convert struct cifs_sb_info " Eric W. Biederman
                     ` (2 subsequent siblings)
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:52 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steve French

From: "Eric W. Biederman" <ebiederm@xmission.com>

Add two helper functions get_option_uid and get_option_gid to handle
the work of parsing uid and gids paramaters from the command line and
making kuids and kgids out of them.

Cc: Steve French <smfrench@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/cifs/cifsglob.h |   10 +++++-----
 fs/cifs/connect.c  |   50 ++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 45 insertions(+), 15 deletions(-)

diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 04aa74e..e308e8b 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -399,11 +399,11 @@ struct smb_vol {
 	char *iocharset;  /* local code page for mapping to and from Unicode */
 	char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
 	char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
-	uid_t cred_uid;
-	uid_t linux_uid;
-	gid_t linux_gid;
-	uid_t backupuid;
-	gid_t backupgid;
+	kuid_t cred_uid;
+	kuid_t linux_uid;
+	kgid_t linux_gid;
+	kuid_t backupuid;
+	kgid_t backupgid;
 	umode_t file_mode;
 	umode_t dir_mode;
 	unsigned secFlg;
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 5411694..9bd13a7 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -987,6 +987,41 @@ static int get_option_ul(substring_t args[], unsigned long *option)
 	return rc;
 }
 
+static int get_option_uid(substring_t args[], kuid_t *result)
+{
+	unsigned long value;
+	kuid_t uid;
+	int rc;
+
+	rc = get_option_ul(args, &value);
+	if (rc)
+		return rc;
+
+	uid = make_kuid(current_user_ns(), value);
+	if (!uid_valid(uid))
+		return -EINVAL;
+
+	*result = uid;
+	return 0;
+}
+
+static int get_option_gid(substring_t args[], kgid_t *result)
+{
+	unsigned long value;
+	kgid_t gid;
+	int rc;
+
+	rc = get_option_ul(args, &value);
+	if (rc)
+		return rc;
+
+	gid = make_kgid(current_user_ns(), value);
+	if (!gid_valid(gid))
+		return -EINVAL;
+
+	*result = gid;
+	return 0;
+}
 
 static int cifs_parse_security_flavors(char *value,
 				       struct smb_vol *vol)
@@ -1424,47 +1459,42 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
 
 		/* Numeric Values */
 		case Opt_backupuid:
-			if (get_option_ul(args, &option)) {
+			if (get_option_uid(args, &vol->backupuid)) {
 				cERROR(1, "%s: Invalid backupuid value",
 					__func__);
 				goto cifs_parse_mount_err;
 			}
-			vol->backupuid = option;
 			vol->backupuid_specified = true;
 			break;
 		case Opt_backupgid:
-			if (get_option_ul(args, &option)) {
+			if (get_option_gid(args, &vol->backupgid)) {
 				cERROR(1, "%s: Invalid backupgid value",
 					__func__);
 				goto cifs_parse_mount_err;
 			}
-			vol->backupgid = option;
 			vol->backupgid_specified = true;
 			break;
 		case Opt_uid:
-			if (get_option_ul(args, &option)) {
+			if (get_option_uid(args, &vol->linux_uid)) {
 				cERROR(1, "%s: Invalid uid value",
 					__func__);
 				goto cifs_parse_mount_err;
 			}
-			vol->linux_uid = option;
 			uid_specified = true;
 			break;
 		case Opt_cruid:
-			if (get_option_ul(args, &option)) {
+			if (get_option_uid(args, &vol->cred_uid)) {
 				cERROR(1, "%s: Invalid cruid value",
 					__func__);
 				goto cifs_parse_mount_err;
 			}
-			vol->cred_uid = option;
 			break;
 		case Opt_gid:
-			if (get_option_ul(args, &option)) {
+			if (get_option_gid(args, &vol->linux_gid)) {
 				cERROR(1, "%s: Invalid gid value",
 						__func__);
 				goto cifs_parse_mount_err;
 			}
-			vol->linux_gid = option;
 			gid_specified = true;
 			break;
 		case Opt_file_mode:
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 83/85] cifs: Convert struct cifs_sb_info to use kuids and kgids
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (80 preceding siblings ...)
  2013-02-13 17:52   ` [PATCH review 82/85] cifs: Modify struct smb_vol to use kuids and kgids Eric W. Biederman
@ 2013-02-13 17:52   ` Eric W. Biederman
  2013-02-13 17:52   ` [PATCH review 84/85] cifs: Convert struct cifs_ses to use a kuid_t and a kgid_t Eric W. Biederman
  2013-02-13 17:52   ` [PATCH review 85/85] cifs: Enable building with user namespaces enabled Eric W. Biederman
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:52 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steve French

From: "Eric W. Biederman" <ebiederm@xmission.com>

Cc: Steve French <smfrench@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/cifs/cifs_fs_sb.h |    8 ++++----
 fs/cifs/cifsfs.c     |   14 ++++++++++----
 fs/cifs/connect.c    |    2 +-
 fs/cifs/misc.c       |    2 +-
 4 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index c865bfd..37e4a72 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -55,10 +55,10 @@ struct cifs_sb_info {
 	unsigned int wsize;
 	unsigned long actimeo; /* attribute cache timeout (jiffies) */
 	atomic_t active;
-	uid_t	mnt_uid;
-	gid_t	mnt_gid;
-	uid_t	mnt_backupuid;
-	gid_t	mnt_backupgid;
+	kuid_t	mnt_uid;
+	kgid_t	mnt_gid;
+	kuid_t	mnt_backupuid;
+	kgid_t	mnt_backupgid;
 	umode_t	mnt_file_mode;
 	umode_t	mnt_dir_mode;
 	unsigned int mnt_cifs_flags;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index f653835..1759073 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -376,13 +376,15 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
 				   (int)(srcaddr->sa_family));
 	}
 
-	seq_printf(s, ",uid=%u", cifs_sb->mnt_uid);
+	seq_printf(s, ",uid=%u",
+		   from_kuid_munged(&init_user_ns, cifs_sb->mnt_uid));
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
 		seq_printf(s, ",forceuid");
 	else
 		seq_printf(s, ",noforceuid");
 
-	seq_printf(s, ",gid=%u", cifs_sb->mnt_gid);
+	seq_printf(s, ",gid=%u",
+		   from_kgid_munged(&init_user_ns, cifs_sb->mnt_gid));
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
 		seq_printf(s, ",forcegid");
 	else
@@ -437,9 +439,13 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
 		seq_printf(s, ",noperm");
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID)
-		seq_printf(s, ",backupuid=%u", cifs_sb->mnt_backupuid);
+		seq_printf(s, ",backupuid=%u",
+			   from_kuid_munged(&init_user_ns,
+					    cifs_sb->mnt_backupuid));
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID)
-		seq_printf(s, ",backupgid=%u", cifs_sb->mnt_backupgid);
+		seq_printf(s, ",backupgid=%u",
+			   from_kgid_munged(&init_user_ns,
+					    cifs_sb->mnt_backupgid));
 
 	seq_printf(s, ",rsize=%u", cifs_sb->rsize);
 	seq_printf(s, ",wsize=%u", cifs_sb->wsize);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 9bd13a7..01279b8 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2743,7 +2743,7 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
 	if (new->rsize && new->rsize < old->rsize)
 		return 0;
 
-	if (old->mnt_uid != new->mnt_uid || old->mnt_gid != new->mnt_gid)
+	if (!uid_eq(old->mnt_uid, new->mnt_uid) || !gid_eq(old->mnt_gid, new->mnt_gid))
 		return 0;
 
 	if (old->mnt_file_mode != new->mnt_file_mode ||
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 3a00c0d..1b15bf8 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -569,7 +569,7 @@ bool
 backup_cred(struct cifs_sb_info *cifs_sb)
 {
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) {
-		if (cifs_sb->mnt_backupuid == current_fsuid())
+		if (uid_eq(cifs_sb->mnt_backupuid, current_fsuid()))
 			return true;
 	}
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) {
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 84/85] cifs: Convert struct cifs_ses to use a kuid_t and a kgid_t
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (81 preceding siblings ...)
  2013-02-13 17:52   ` [PATCH review 83/85] cifs: Convert struct cifs_sb_info " Eric W. Biederman
@ 2013-02-13 17:52   ` Eric W. Biederman
  2013-02-13 17:52   ` [PATCH review 85/85] cifs: Enable building with user namespaces enabled Eric W. Biederman
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:52 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steve French

From: "Eric W. Biederman" <ebiederm@xmission.com>

Cc: Steve French <smfrench@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 fs/cifs/cifs_spnego.c |    6 ++++--
 fs/cifs/cifsglob.h    |    4 ++--
 fs/cifs/connect.c     |    2 +-
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
index 086f381..10e7747 100644
--- a/fs/cifs/cifs_spnego.c
+++ b/fs/cifs/cifs_spnego.c
@@ -149,10 +149,12 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo)
 		goto out;
 
 	dp = description + strlen(description);
-	sprintf(dp, ";uid=0x%x", sesInfo->linux_uid);
+	sprintf(dp, ";uid=0x%x",
+		from_kuid_munged(&init_user_ns, sesInfo->linux_uid));
 
 	dp = description + strlen(description);
-	sprintf(dp, ";creduid=0x%x", sesInfo->cred_uid);
+	sprintf(dp, ";creduid=0x%x",
+		from_kuid_munged(&init_user_ns, sesInfo->cred_uid));
 
 	if (sesInfo->user_name) {
 		dp = description + strlen(description);
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index e308e8b..aaef57b 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -702,8 +702,8 @@ struct cifs_ses {
 	char *serverNOS;	/* name of network operating system of server */
 	char *serverDomain;	/* security realm of server */
 	__u64 Suid;		/* remote smb uid  */
-	uid_t linux_uid;        /* overriding owner of files on the mount */
-	uid_t cred_uid;		/* owner of credentials */
+	kuid_t linux_uid;	/* overriding owner of files on the mount */
+	kuid_t cred_uid;	/* owner of credentials */
 	unsigned int capabilities;
 	char serverName[SERVER_NAME_LEN_WITH_NULL * 2];	/* BB make bigger for
 				TCP names - will ipv6 and sctp addresses fit? */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 01279b8..067b0e1 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2271,7 +2271,7 @@ static int match_session(struct cifs_ses *ses, struct smb_vol *vol)
 {
 	switch (ses->server->secType) {
 	case Kerberos:
-		if (vol->cred_uid != ses->cred_uid)
+		if (!uid_eq(vol->cred_uid, ses->cred_uid))
 			return 0;
 		break;
 	default:
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* [PATCH review 85/85] cifs: Enable building with user namespaces enabled.
  2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
                     ` (82 preceding siblings ...)
  2013-02-13 17:52   ` [PATCH review 84/85] cifs: Convert struct cifs_ses to use a kuid_t and a kgid_t Eric W. Biederman
@ 2013-02-13 17:52   ` Eric W. Biederman
  83 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 17:52 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn,
	Eric W. Biederman, Steve French

From: "Eric W. Biederman" <ebiederm@xmission.com>

Cc: Steve French <smfrench@gmail.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 init/Kconfig |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/init/Kconfig b/init/Kconfig
index 69c5ccc..b2de5ed 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1071,7 +1071,6 @@ config UIDGID_CONVERTED
 	default y
 
 	# Filesystems
-	depends on CIFS = n
 	depends on XFS_FS = n
 
 config UIDGID_STRICT_TYPE_CHECKS
-- 
1.7.5.4


^ permalink raw reply related	[flat|nested] 109+ messages in thread

* Re: [PATCH review 18/85] coda: Restrict coda messages to the initial user namespace
  2013-02-13 17:51   ` [PATCH review 18/85] coda: Restrict coda messages to the initial user namespace Eric W. Biederman
@ 2013-02-13 18:14     ` Jan Harkes
  2013-02-13 18:44       ` Eric W. Biederman
  0 siblings, 1 reply; 109+ messages in thread
From: Jan Harkes @ 2013-02-13 18:14 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn

On Wed, Feb 13, 2013 at 09:51:07AM -0800, Eric W. Biederman wrote:
> From: "Eric W. Biederman" <ebiederm@xmission.com>
> 
> Remove the slight chance that uids and gids in coda messages will be
> interpreted in the wrong user namespace.

Awesome, I was wondering how to handle uid's from different namespaces
cleanly in Coda's userspace daemon without resorting to exporting kuids
to userspace.

But this is a much more elegant solution, every namespace that cares
about Coda should just run their own mountpoint and userspace daemon.

Jan

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 18/85] coda: Restrict coda messages to the initial user namespace
  2013-02-13 18:14     ` Jan Harkes
@ 2013-02-13 18:44       ` Eric W. Biederman
  0 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 18:44 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: Linux Containers, linux-kernel, Serge E. Hallyn

Jan Harkes <jaharkes@cs.cmu.edu> writes:

> On Wed, Feb 13, 2013 at 09:51:07AM -0800, Eric W. Biederman wrote:
>> From: "Eric W. Biederman" <ebiederm@xmission.com>
>> 
>> Remove the slight chance that uids and gids in coda messages will be
>> interpreted in the wrong user namespace.
>
> Awesome, I was wondering how to handle uid's from different namespaces
> cleanly in Coda's userspace daemon without resorting to exporting kuids
> to userspace.
>
> But this is a much more elegant solution, every namespace that cares
> about Coda should just run their own mountpoint and userspace daemon.

Do you know if people care enough about coda that they will want to
export run coda multiple mountpoint and userspace daemons?

I have never seen anyone running coda so I was suspecting that coda was
a filesystem that was gradually fading away.

Eric


^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 48/85] sunrpc: Update gss uid to security context mapping.
  2013-02-13 17:51   ` [PATCH review 48/85] sunrpc: Update gss uid to security context mapping Eric W. Biederman
@ 2013-02-13 20:35     ` J. Bruce Fields
  2013-02-13 21:17       ` Eric W. Biederman
  0 siblings, 1 reply; 109+ messages in thread
From: J. Bruce Fields @ 2013-02-13 20:35 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Trond Myklebust

On Wed, Feb 13, 2013 at 09:51:37AM -0800, Eric W. Biederman wrote:
> From: "Eric W. Biederman" <ebiederm@xmission.com>
> 
> - Use from_kuid when generating the on the wire uid values.
> - Use make_kuid when reading on the wire values.
> 
> In gss_encode_v0_msg, since the uid in gss_upcall_msg is now a kuid_t
> generate the necessary uid_t value on the stack copy it into
> gss_msg->databuf where it can safely live until the message is no
> longer needed.

Apologies, I haven't been following the user namespace work.

If I understand correctly, you're expecting the id's seen in nfs
protocol messages to be the same as the id's seen in the initial user
namespace.

Why is that right, and not, say, the user namespace in which the mount
was originally performed?  (Just asking, I honestly haven't thought
about it before.)

Also:

> diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
> index afbbcfb..a360067 100644
> --- a/net/sunrpc/auth_gss/auth_gss.c
> +++ b/net/sunrpc/auth_gss/auth_gss.c
> @@ -395,8 +395,11 @@ gss_upcall_callback(struct rpc_task *task)
>  
>  static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg)
>  {
> -	gss_msg->msg.data = &gss_msg->uid;
> -	gss_msg->msg.len = sizeof(gss_msg->uid);
> +	uid_t uid = from_kuid(&init_user_ns, gss_msg->uid);
> +	memcpy(gss_msg->databuf, &uid, sizeof(uid));
> +	gss_msg->msg.data = gss_msg->databuf;
> +	gss_msg->msg.len = sizeof(uid);
> +	BUG_ON(sizeof(uid) > UPCALL_BUF_LEN);

This message is going to gssd, not to the server.  Should it be encoded
for whatever namespace gssd lives in?

--b.

>  }
>  
>  static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
> @@ -409,7 +412,7 @@ static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
>  
>  	gss_msg->msg.len = sprintf(gss_msg->databuf, "mech=%s uid=%d ",
>  				   mech->gm_name,
> -				   gss_msg->uid);
> +				   from_kuid(&init_user_ns, gss_msg->uid));
>  	p += gss_msg->msg.len;
>  	if (clnt->cl_principal) {
>  		len = sprintf(p, "target=%s ", clnt->cl_principal);
> @@ -620,7 +623,8 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
>  	struct gss_upcall_msg *gss_msg;
>  	struct rpc_pipe *pipe = RPC_I(filp->f_dentry->d_inode)->pipe;
>  	struct gss_cl_ctx *ctx;
> -	uid_t uid;
> +	uid_t id;
> +	kuid_t uid;
>  	ssize_t err = -EFBIG;
>  
>  	if (mlen > MSG_BUF_MAXSIZE)
> @@ -635,12 +639,18 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
>  		goto err;
>  
>  	end = (const void *)((char *)buf + mlen);
> -	p = simple_get_bytes(buf, end, &uid, sizeof(uid));
> +	p = simple_get_bytes(buf, end, &id, sizeof(id));
>  	if (IS_ERR(p)) {
>  		err = PTR_ERR(p);
>  		goto err;
>  	}
>  
> +	uid = make_kuid(&init_user_ns, id);
> +	if (!uid_valid(uid)) {
> +		err = -EINVAL;
> +		goto err;
> +	}
> +
>  	err = -ENOMEM;
>  	ctx = gss_alloc_context();
>  	if (ctx == NULL)
> -- 
> 1.7.5.4
> 

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 52/85] sunrpc: Properly encode kuids and kgids in auth.unix.gid rpc pipe upcalls.
  2013-02-13 17:51   ` [PATCH review 52/85] sunrpc: Properly encode kuids and kgids in auth.unix.gid rpc pipe upcalls Eric W. Biederman
@ 2013-02-13 21:05     ` J. Bruce Fields
  2013-02-13 21:29       ` Eric W. Biederman
  0 siblings, 1 reply; 109+ messages in thread
From: J. Bruce Fields @ 2013-02-13 21:05 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Trond Myklebust

On Wed, Feb 13, 2013 at 09:51:41AM -0800, Eric W. Biederman wrote:
> From: "Eric W. Biederman" <ebiederm@xmission.com>
> 
> When a new rpc connection is established with an in-kernel server, the
> traffic passes through svc_process_common, and svc_set_client and down
> into svcauth_unix_set_client if it is of type RPC_AUTH_NULL or
> RPC_AUTH_UNIX.
> 
> svcauth_unix_set_client then looks at the uid of the credential we
> have assigned to the incomming client and if we don't have the groups
> already cached makes an upcall to get a list of groups that the client
> can use.
> 
> The upcall encodes send a rpc message to user space encoding the uid
> of the user whose groups we want to know.  Encode the kuid of the user
> in the initial user namespace as nfs mounts can only happen today in
> the initial user namespace.

OK, I didn't know that.

(Though I'm unclear how it should matter to the server what user
namespace the client is in?)

> When a reply to an upcall comes in convert interpret the uid and gid values
> from the rpc pipe as uids and gids in the initial user namespace and convert
> them into kuids and kgids before processing them further.
> 
> When reading proc files listing the uid to gid list cache convert the
> kuids and kgids from into uids and gids the initial user namespace.  As we are
> displaying server internal details it makes sense to display these values
> from the servers perspective.

All of these caches are already per-network-namespace.  Ideally wouldn't
we also like to associate a user namespace with each cache somehow?

--b.

> 
> Cc: "J. Bruce Fields" <bfields@fieldses.org>
> Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>  net/sunrpc/svcauth_unix.c |   14 +++++++++-----
>  1 files changed, 9 insertions(+), 5 deletions(-)
> 
> diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
> index faf1719..bdea0a1 100644
> --- a/net/sunrpc/svcauth_unix.c
> +++ b/net/sunrpc/svcauth_unix.c
> @@ -470,7 +470,7 @@ static void unix_gid_request(struct cache_detail *cd,
>  	char tuid[20];
>  	struct unix_gid *ug = container_of(h, struct unix_gid, h);
>  
> -	snprintf(tuid, 20, "%u", ug->uid);
> +	snprintf(tuid, 20, "%u", from_kuid(&init_user_ns, ug->uid));
>  	qword_add(bpp, blen, tuid);
>  	(*bpp)[-1] = '\n';
>  }
> @@ -486,7 +486,8 @@ static int unix_gid_parse(struct cache_detail *cd,
>  			char *mesg, int mlen)
>  {
>  	/* uid expiry Ngid gid0 gid1 ... gidN-1 */
> -	int uid;
> +	int id;
> +	kuid_t uid;
>  	int gids;
>  	int rv;
>  	int i;
> @@ -498,9 +499,12 @@ static int unix_gid_parse(struct cache_detail *cd,
>  		return -EINVAL;
>  	mesg[mlen-1] = 0;
>  
> -	rv = get_int(&mesg, &uid);
> +	rv = get_int(&mesg, &id);
>  	if (rv)
>  		return -EINVAL;
> +	uid = make_kuid(&init_user_ns, id);
> +	if (!uid_valid(uid))
> +		return -EINVAL;
>  	ug.uid = uid;
>  
>  	expiry = get_expiry(&mesg);
> @@ -554,7 +558,7 @@ static int unix_gid_show(struct seq_file *m,
>  			 struct cache_detail *cd,
>  			 struct cache_head *h)
>  {
> -	struct user_namespace *user_ns = current_user_ns();
> +	struct user_namespace *user_ns = &init_user_ns;
>  	struct unix_gid *ug;
>  	int i;
>  	int glen;
> @@ -570,7 +574,7 @@ static int unix_gid_show(struct seq_file *m,
>  	else
>  		glen = 0;
>  
> -	seq_printf(m, "%u %d:", ug->uid, glen);
> +	seq_printf(m, "%u %d:", from_kuid_munged(user_ns, ug->uid), glen);
>  	for (i = 0; i < glen; i++)
>  		seq_printf(m, " %d", from_kgid_munged(user_ns, GROUP_AT(ug->gi, i)));
>  	seq_printf(m, "\n");
> -- 
> 1.7.5.4
> 

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 48/85] sunrpc: Update gss uid to security context mapping.
  2013-02-13 20:35     ` J. Bruce Fields
@ 2013-02-13 21:17       ` Eric W. Biederman
  2013-02-13 21:24         ` J. Bruce Fields
  0 siblings, 1 reply; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 21:17 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Trond Myklebust

"J. Bruce Fields" <bfields@fieldses.org> writes:

> On Wed, Feb 13, 2013 at 09:51:37AM -0800, Eric W. Biederman wrote:
>> From: "Eric W. Biederman" <ebiederm@xmission.com>
>> 
>> - Use from_kuid when generating the on the wire uid values.
>> - Use make_kuid when reading on the wire values.
>> 
>> In gss_encode_v0_msg, since the uid in gss_upcall_msg is now a kuid_t
>> generate the necessary uid_t value on the stack copy it into
>> gss_msg->databuf where it can safely live until the message is no
>> longer needed.
>
> Apologies, I haven't been following the user namespace work.
>
> If I understand correctly, you're expecting the id's seen in nfs
> protocol messages to be the same as the id's seen in the initial user
> namespace.
>
> Why is that right, and not, say, the user namespace in which the mount
> was originally performed?  (Just asking, I honestly haven't thought
> about it before.)

Actually my expectation is the user namespace was originally performed
in.  Currently nfs doesn't support being  mounted in anything other
than the initial user namespace.

> Also:
>
>> diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
>> index afbbcfb..a360067 100644
>> --- a/net/sunrpc/auth_gss/auth_gss.c
>> +++ b/net/sunrpc/auth_gss/auth_gss.c
>> @@ -395,8 +395,11 @@ gss_upcall_callback(struct rpc_task *task)
>>  
>>  static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg)
>>  {
>> -	gss_msg->msg.data = &gss_msg->uid;
>> -	gss_msg->msg.len = sizeof(gss_msg->uid);
>> +	uid_t uid = from_kuid(&init_user_ns, gss_msg->uid);
>> +	memcpy(gss_msg->databuf, &uid, sizeof(uid));
>> +	gss_msg->msg.data = gss_msg->databuf;
>> +	gss_msg->msg.len = sizeof(uid);
>> +	BUG_ON(sizeof(uid) > UPCALL_BUF_LEN);
>
> This message is going to gssd, not to the server.  Should it be encoded
> for whatever namespace gssd lives in?

Good basic question.  The immediate answer is that right now I only
support these things living in user namespace the filesystem was
mounted in, aka the initial user namespace.

There are a handful of things ioctls, and a quota call or two that I
will translate into the callers user namespace.  For network filesystems
and their specialized helpers it would be lossy and unnecessarily
complex to support arbitrary pieces living in different user namespaces.
Historically unix has had syncrhonized password databases to ensure even
multiple machines effectively had the same user namespace.

The really important step for me is to have the kernel using kuid_t and
kgid_t throughout and only converting when talking outside of the kernel
(disk, filesystem on disk data structures, network).

With that step I can enable user namespaces and the various filesystems.
And even if the filesystem itself is restricted to just one user
namespace, the users who read and write files on that filesystem won't
be.

A next step for the filesystems where this is interesting is to support
a user who is not the global root mounting the filesystem and having the
filesystem speak in ids in the user namespace that the filesystem was
mounted in.  That takes a little bit of connecting the dots of which
user namespace goes where, and it takes a little bit of confidence that
the kernel won't fall over if an evil server sends us deliberately bad
protocol messages.  I suspect at some point someone will want to figure
all of that out for nfs, certainly there has been work to figure that
out for network namespaces.

For now though I am happy to have kuid_t and kgid_t pushed down
everywhere they should be.

Eric

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 48/85] sunrpc: Update gss uid to security context mapping.
  2013-02-13 21:17       ` Eric W. Biederman
@ 2013-02-13 21:24         ` J. Bruce Fields
  0 siblings, 0 replies; 109+ messages in thread
From: J. Bruce Fields @ 2013-02-13 21:24 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Trond Myklebust

On Wed, Feb 13, 2013 at 01:17:37PM -0800, Eric W. Biederman wrote:
> "J. Bruce Fields" <bfields@fieldses.org> writes:
> 
> > On Wed, Feb 13, 2013 at 09:51:37AM -0800, Eric W. Biederman wrote:
> >> From: "Eric W. Biederman" <ebiederm@xmission.com>
> >> 
> >> - Use from_kuid when generating the on the wire uid values.
> >> - Use make_kuid when reading on the wire values.
> >> 
> >> In gss_encode_v0_msg, since the uid in gss_upcall_msg is now a kuid_t
> >> generate the necessary uid_t value on the stack copy it into
> >> gss_msg->databuf where it can safely live until the message is no
> >> longer needed.
> >
> > Apologies, I haven't been following the user namespace work.
> >
> > If I understand correctly, you're expecting the id's seen in nfs
> > protocol messages to be the same as the id's seen in the initial user
> > namespace.
> >
> > Why is that right, and not, say, the user namespace in which the mount
> > was originally performed?  (Just asking, I honestly haven't thought
> > about it before.)
> 
> Actually my expectation is the user namespace was originally performed
> in.  Currently nfs doesn't support being  mounted in anything other
> than the initial user namespace.
> 
> > Also:
> >
> >> diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
> >> index afbbcfb..a360067 100644
> >> --- a/net/sunrpc/auth_gss/auth_gss.c
> >> +++ b/net/sunrpc/auth_gss/auth_gss.c
> >> @@ -395,8 +395,11 @@ gss_upcall_callback(struct rpc_task *task)
> >>  
> >>  static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg)
> >>  {
> >> -	gss_msg->msg.data = &gss_msg->uid;
> >> -	gss_msg->msg.len = sizeof(gss_msg->uid);
> >> +	uid_t uid = from_kuid(&init_user_ns, gss_msg->uid);
> >> +	memcpy(gss_msg->databuf, &uid, sizeof(uid));
> >> +	gss_msg->msg.data = gss_msg->databuf;
> >> +	gss_msg->msg.len = sizeof(uid);
> >> +	BUG_ON(sizeof(uid) > UPCALL_BUF_LEN);
> >
> > This message is going to gssd, not to the server.  Should it be encoded
> > for whatever namespace gssd lives in?
> 
> Good basic question.  The immediate answer is that right now I only
> support these things living in user namespace the filesystem was
> mounted in, aka the initial user namespace.
> 
> There are a handful of things ioctls, and a quota call or two that I
> will translate into the callers user namespace.  For network filesystems
> and their specialized helpers it would be lossy and unnecessarily
> complex to support arbitrary pieces living in different user namespaces.
> Historically unix has had syncrhonized password databases to ensure even
> multiple machines effectively had the same user namespace.
> 
> The really important step for me is to have the kernel using kuid_t and
> kgid_t throughout and only converting when talking outside of the kernel
> (disk, filesystem on disk data structures, network).
> 
> With that step I can enable user namespaces and the various filesystems.
> And even if the filesystem itself is restricted to just one user
> namespace, the users who read and write files on that filesystem won't
> be.
> 
> A next step for the filesystems where this is interesting is to support
> a user who is not the global root mounting the filesystem and having the
> filesystem speak in ids in the user namespace that the filesystem was
> mounted in.  That takes a little bit of connecting the dots of which
> user namespace goes where, and it takes a little bit of confidence that
> the kernel won't fall over if an evil server sends us deliberately bad
> protocol messages.  I suspect at some point someone will want to figure
> all of that out for nfs, certainly there has been work to figure that
> out for network namespaces.
> 
> For now though I am happy to have kuid_t and kgid_t pushed down
> everywhere they should be.

OK, makes sense, thanks for the explanation.--b.

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 52/85] sunrpc: Properly encode kuids and kgids in auth.unix.gid rpc pipe upcalls.
  2013-02-13 21:05     ` J. Bruce Fields
@ 2013-02-13 21:29       ` Eric W. Biederman
  2013-02-13 21:50         ` J. Bruce Fields
  0 siblings, 1 reply; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 21:29 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Trond Myklebust

"J. Bruce Fields" <bfields@fieldses.org> writes:

> On Wed, Feb 13, 2013 at 09:51:41AM -0800, Eric W. Biederman wrote:
>> From: "Eric W. Biederman" <ebiederm@xmission.com>
>> 
>> When a new rpc connection is established with an in-kernel server, the
>> traffic passes through svc_process_common, and svc_set_client and down
>> into svcauth_unix_set_client if it is of type RPC_AUTH_NULL or
>> RPC_AUTH_UNIX.
>> 
>> svcauth_unix_set_client then looks at the uid of the credential we
>> have assigned to the incomming client and if we don't have the groups
>> already cached makes an upcall to get a list of groups that the client
>> can use.
>> 
>> The upcall encodes send a rpc message to user space encoding the uid
>> of the user whose groups we want to know.  Encode the kuid of the user
>> in the initial user namespace as nfs mounts can only happen today in
>> the initial user namespace.
>
> OK, I didn't know that.
>
> (Though I'm unclear how it should matter to the server what user
> namespace the client is in?)

Perhaps I have the description a little scrambled.  The short version
is that to start I only support the initial network namespace.

If I haven't succeeded it is my intent to initially limit the servers
to the initial user namespace as well.  I should see if I can figure
that out.

>> When a reply to an upcall comes in convert interpret the uid and gid values
>> from the rpc pipe as uids and gids in the initial user namespace and convert
>> them into kuids and kgids before processing them further.
>> 
>> When reading proc files listing the uid to gid list cache convert the
>> kuids and kgids from into uids and gids the initial user namespace.  As we are
>> displaying server internal details it makes sense to display these values
>> from the servers perspective.
>
> All of these caches are already per-network-namespace.  Ideally wouldn't
> we also like to associate a user namespace with each cache somehow?

Ideally yes.  I read through the caches enough to figure out where there
user space interfaces were, and to make certain we had conversions
to/from kuids and kgids.

I haven't looked at what user namespace makes sense for these
caches.  For this cache my first guess is that net->user_ns
is what we want as it will be shared by all users in network namespace I
presume.

Eric

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 52/85] sunrpc: Properly encode kuids and kgids in auth.unix.gid rpc pipe upcalls.
  2013-02-13 21:29       ` Eric W. Biederman
@ 2013-02-13 21:50         ` J. Bruce Fields
  2013-02-13 22:32           ` Eric W. Biederman
  0 siblings, 1 reply; 109+ messages in thread
From: J. Bruce Fields @ 2013-02-13 21:50 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Trond Myklebust

On Wed, Feb 13, 2013 at 01:29:35PM -0800, Eric W. Biederman wrote:
> "J. Bruce Fields" <bfields@fieldses.org> writes:
> 
> > On Wed, Feb 13, 2013 at 09:51:41AM -0800, Eric W. Biederman wrote:
> >> From: "Eric W. Biederman" <ebiederm@xmission.com>
> >> 
> >> When a new rpc connection is established with an in-kernel server, the
> >> traffic passes through svc_process_common, and svc_set_client and down
> >> into svcauth_unix_set_client if it is of type RPC_AUTH_NULL or
> >> RPC_AUTH_UNIX.
> >> 
> >> svcauth_unix_set_client then looks at the uid of the credential we
> >> have assigned to the incomming client and if we don't have the groups
> >> already cached makes an upcall to get a list of groups that the client
> >> can use.
> >> 
> >> The upcall encodes send a rpc message to user space encoding the uid
> >> of the user whose groups we want to know.  Encode the kuid of the user
> >> in the initial user namespace as nfs mounts can only happen today in
> >> the initial user namespace.
> >
> > OK, I didn't know that.
> >
> > (Though I'm unclear how it should matter to the server what user
> > namespace the client is in?)
> 
> Perhaps I have the description a little scrambled.  The short version
> is that to start I only support the initial network namespace.
> 
> If I haven't succeeded it is my intent to initially limit the servers
> to the initial user namespace as well.  I should see if I can figure
> that out.
> 
> >> When a reply to an upcall comes in convert interpret the uid and gid values
> >> from the rpc pipe as uids and gids in the initial user namespace and convert
> >> them into kuids and kgids before processing them further.
> >> 
> >> When reading proc files listing the uid to gid list cache convert the
> >> kuids and kgids from into uids and gids the initial user namespace.  As we are
> >> displaying server internal details it makes sense to display these values
> >> from the servers perspective.
> >
> > All of these caches are already per-network-namespace.  Ideally wouldn't
> > we also like to associate a user namespace with each cache somehow?
> 
> Ideally yes.  I read through the caches enough to figure out where there
> user space interfaces were, and to make certain we had conversions
> to/from kuids and kgids.
> 
> I haven't looked at what user namespace makes sense for these
> caches.  For this cache my first guess is that net->user_ns
> is what we want as it will be shared by all users in network namespace I
> presume.

Oh, I didn't know about net->user_ns--so each network namespace is
associated with a single user namespace, great, that simplifies life.
Yes, that sounds exactly right.

--b.

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 52/85] sunrpc: Properly encode kuids and kgids in auth.unix.gid rpc pipe upcalls.
  2013-02-13 21:50         ` J. Bruce Fields
@ 2013-02-13 22:32           ` Eric W. Biederman
  2013-02-13 22:58             ` J. Bruce Fields
  0 siblings, 1 reply; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 22:32 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Trond Myklebust

"J. Bruce Fields" <bfields@fieldses.org> writes:

> On Wed, Feb 13, 2013 at 01:29:35PM -0800, Eric W. Biederman wrote:
>> "J. Bruce Fields" <bfields@fieldses.org> writes:
>> 
>> > On Wed, Feb 13, 2013 at 09:51:41AM -0800, Eric W. Biederman wrote:
>> >> From: "Eric W. Biederman" <ebiederm@xmission.com>
>> >> 
>> >> When a new rpc connection is established with an in-kernel server, the
>> >> traffic passes through svc_process_common, and svc_set_client and down
>> >> into svcauth_unix_set_client if it is of type RPC_AUTH_NULL or
>> >> RPC_AUTH_UNIX.
>> >> 
>> >> svcauth_unix_set_client then looks at the uid of the credential we
>> >> have assigned to the incomming client and if we don't have the groups
>> >> already cached makes an upcall to get a list of groups that the client
>> >> can use.
>> >> 
>> >> The upcall encodes send a rpc message to user space encoding the uid
>> >> of the user whose groups we want to know.  Encode the kuid of the user
>> >> in the initial user namespace as nfs mounts can only happen today in
>> >> the initial user namespace.
>> >
>> > OK, I didn't know that.
>> >
>> > (Though I'm unclear how it should matter to the server what user
>> > namespace the client is in?)
>> 
>> Perhaps I have the description a little scrambled.  The short version
>> is that to start I only support the initial network namespace.
>> 
>> If I haven't succeeded it is my intent to initially limit the servers
>> to the initial user namespace as well.  I should see if I can figure
>> that out.
>> 
>> >> When a reply to an upcall comes in convert interpret the uid and gid values
>> >> from the rpc pipe as uids and gids in the initial user namespace and convert
>> >> them into kuids and kgids before processing them further.
>> >> 
>> >> When reading proc files listing the uid to gid list cache convert the
>> >> kuids and kgids from into uids and gids the initial user namespace.  As we are
>> >> displaying server internal details it makes sense to display these values
>> >> from the servers perspective.
>> >
>> > All of these caches are already per-network-namespace.  Ideally wouldn't
>> > we also like to associate a user namespace with each cache somehow?
>> 
>> Ideally yes.  I read through the caches enough to figure out where there
>> user space interfaces were, and to make certain we had conversions
>> to/from kuids and kgids.
>> 
>> I haven't looked at what user namespace makes sense for these
>> caches.  For this cache my first guess is that net->user_ns
>> is what we want as it will be shared by all users in network namespace I
>> presume.
>
> Oh, I didn't know about net->user_ns--so each network namespace is
> associated with a single user namespace, great, that simplifies life.
> Yes, that sounds exactly right.

Yes. net->user_ns is the user namespace the network namespace was
created in.  And it is the user namespace that is used in test
like ns_capable(net->user_ns, CAP_NET_ADMIN) to see if you are allowed
to manipulate the network namespace.  So looks like exactly what we
want for that cache.

Could you double check my understanding of the code?

I want to be certain that I can't _yet_ start an sunrpc server process
outside of the initial user namespace.  While writing an earlier reply I
realized that I hadn't thought about where sunrpc server processes come
from.

Reading through the code it looks like we can have nfs mounts outside of
the initial network namespace.  But because they are mounts they are
still limited to the initial user namespace.

Now looking at the nfs server, seems to be hard coded to only start
in the initial network namespace despite almost having support for
starting in more.

Even more the nfs server is controlled and started through the "nfsd"
filesystem.  Which has to be mounted before you can start the server.
So you can only start the server through a mount in the initial user
namespace.

lockd is started by either the nfs server or the nfs client.

There are no other sunrpc servers in the kernel.

I think all of that is enough to reasonably claim that you can't have
any sunrpc server processes outside of the initial user namespace.  But
if I am wrong I would to find an appropriate spot to put in a line
that says:
	 if (current_user_ns() != &init_user)
         	return -ESORRY_CHARLEY;

Eric


^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 52/85] sunrpc: Properly encode kuids and kgids in auth.unix.gid rpc pipe upcalls.
  2013-02-13 22:32           ` Eric W. Biederman
@ 2013-02-13 22:58             ` J. Bruce Fields
  2013-02-13 23:22               ` Eric W. Biederman
  0 siblings, 1 reply; 109+ messages in thread
From: J. Bruce Fields @ 2013-02-13 22:58 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Trond Myklebust, Stanislav Kinsbursky

On Wed, Feb 13, 2013 at 02:32:29PM -0800, Eric W. Biederman wrote:
> "J. Bruce Fields" <bfields@fieldses.org> writes:
> 
> > On Wed, Feb 13, 2013 at 01:29:35PM -0800, Eric W. Biederman wrote:
> >> "J. Bruce Fields" <bfields@fieldses.org> writes:
> >> 
> >> > On Wed, Feb 13, 2013 at 09:51:41AM -0800, Eric W. Biederman wrote:
> >> >> From: "Eric W. Biederman" <ebiederm@xmission.com>
> >> >> 
> >> >> When a new rpc connection is established with an in-kernel server, the
> >> >> traffic passes through svc_process_common, and svc_set_client and down
> >> >> into svcauth_unix_set_client if it is of type RPC_AUTH_NULL or
> >> >> RPC_AUTH_UNIX.
> >> >> 
> >> >> svcauth_unix_set_client then looks at the uid of the credential we
> >> >> have assigned to the incomming client and if we don't have the groups
> >> >> already cached makes an upcall to get a list of groups that the client
> >> >> can use.
> >> >> 
> >> >> The upcall encodes send a rpc message to user space encoding the uid
> >> >> of the user whose groups we want to know.  Encode the kuid of the user
> >> >> in the initial user namespace as nfs mounts can only happen today in
> >> >> the initial user namespace.
> >> >
> >> > OK, I didn't know that.
> >> >
> >> > (Though I'm unclear how it should matter to the server what user
> >> > namespace the client is in?)
> >> 
> >> Perhaps I have the description a little scrambled.  The short version
> >> is that to start I only support the initial network namespace.
> >> 
> >> If I haven't succeeded it is my intent to initially limit the servers
> >> to the initial user namespace as well.  I should see if I can figure
> >> that out.
> >> 
> >> >> When a reply to an upcall comes in convert interpret the uid and gid values
> >> >> from the rpc pipe as uids and gids in the initial user namespace and convert
> >> >> them into kuids and kgids before processing them further.
> >> >> 
> >> >> When reading proc files listing the uid to gid list cache convert the
> >> >> kuids and kgids from into uids and gids the initial user namespace.  As we are
> >> >> displaying server internal details it makes sense to display these values
> >> >> from the servers perspective.
> >> >
> >> > All of these caches are already per-network-namespace.  Ideally wouldn't
> >> > we also like to associate a user namespace with each cache somehow?
> >> 
> >> Ideally yes.  I read through the caches enough to figure out where there
> >> user space interfaces were, and to make certain we had conversions
> >> to/from kuids and kgids.
> >> 
> >> I haven't looked at what user namespace makes sense for these
> >> caches.  For this cache my first guess is that net->user_ns
> >> is what we want as it will be shared by all users in network namespace I
> >> presume.
> >
> > Oh, I didn't know about net->user_ns--so each network namespace is
> > associated with a single user namespace, great, that simplifies life.
> > Yes, that sounds exactly right.
> 
> Yes. net->user_ns is the user namespace the network namespace was
> created in.  And it is the user namespace that is used in test
> like ns_capable(net->user_ns, CAP_NET_ADMIN) to see if you are allowed
> to manipulate the network namespace.  So looks like exactly what we
> want for that cache.
> 
> Could you double check my understanding of the code?
> 
> I want to be certain that I can't _yet_ start an sunrpc server process
> outside of the initial user namespace.  While writing an earlier reply I
> realized that I hadn't thought about where sunrpc server processes come
> from.
> 
> Reading through the code it looks like we can have nfs mounts outside of
> the initial network namespace.

We're talking about the server side here, not the client, so I'm not
sure what you mean by "nfs mounts".  The nfs server does use various
pseudofilesystems ("proc", "nfsd"), and those can be mounted outside the
initial network namespace.

The server can receive rpc requests over network interfaces outside the
initial network namespace, sure.  The server doesn't perform mounts on
behalf of clients, though, it just accesses previously mounted
filesystems on clients' behalf.

> But because they are mounts they are
> still limited to the initial user namespace.

OK, so that's just a limitation on any mount whatsoever for now.  I'm
catching on, slowly, thanks!

> Now looking at the nfs server, seems to be hard coded to only start
> in the initial network namespace despite almost having support for
> starting in more.

Right, Stanislav's got 4 more patches that should finish the job; see
http://mid.gmane.org/<20130201125210.3257.46454.stgit@localhost.localdomain>
and followups.  That should make it for 3.9, I just need to review
them....

> Even more the nfs server is controlled and started through the "nfsd"
> filesystem.  Which has to be mounted before you can start the server.
> So you can only start the server through a mount in the initial user
> namespace.

Yes.

> lockd is started by either the nfs server or the nfs client.
> 
> There are no other sunrpc servers in the kernel.

There are a couple callback services on the NFS client--those should be
associated with nfs mounts in some obvious way.  There's a confusing ACL
service that's really just an appendage of NFSv2/v3 service.

I think we're fine.

> I think all of that is enough to reasonably claim that you can't have
> any sunrpc server processes outside of the initial user namespace.  But
> if I am wrong I would to find an appropriate spot to put in a line
> that says:
> 	 if (current_user_ns() != &init_user)
>          	return -ESORRY_CHARLEY;

I think you're right.

So for now it's safely confined to one user namespace, and I think we
understand approximately what to do if we want to support nfsd's in user
namespace in the future.  (Mainly, make sure nfsd and proc can be
mounted in them and then most things will be determined by the user_ns
of the network namespace associated with a given rpc.)

--b.

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 52/85] sunrpc: Properly encode kuids and kgids in auth.unix.gid rpc pipe upcalls.
  2013-02-13 22:58             ` J. Bruce Fields
@ 2013-02-13 23:22               ` Eric W. Biederman
  2013-02-14  7:12                 ` Stanislav Kinsbursky
  2013-02-15 17:00                 ` J. Bruce Fields
  0 siblings, 2 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-13 23:22 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Trond Myklebust, Stanislav Kinsbursky

"J. Bruce Fields" <bfields@fieldses.org> writes:

> On Wed, Feb 13, 2013 at 02:32:29PM -0800, Eric W. Biederman wrote:
>> "J. Bruce Fields" <bfields@fieldses.org> writes:
>> 
>> > On Wed, Feb 13, 2013 at 01:29:35PM -0800, Eric W. Biederman wrote:
>> >> "J. Bruce Fields" <bfields@fieldses.org> writes:
>> >> 
>> >> > On Wed, Feb 13, 2013 at 09:51:41AM -0800, Eric W. Biederman wrote:
>> >> >> From: "Eric W. Biederman" <ebiederm@xmission.com>
>> >> >> 
>> >> >> When a new rpc connection is established with an in-kernel server, the
>> >> >> traffic passes through svc_process_common, and svc_set_client and down
>> >> >> into svcauth_unix_set_client if it is of type RPC_AUTH_NULL or
>> >> >> RPC_AUTH_UNIX.
>> >> >> 
>> >> >> svcauth_unix_set_client then looks at the uid of the credential we
>> >> >> have assigned to the incomming client and if we don't have the groups
>> >> >> already cached makes an upcall to get a list of groups that the client
>> >> >> can use.
>> >> >> 
>> >> >> The upcall encodes send a rpc message to user space encoding the uid
>> >> >> of the user whose groups we want to know.  Encode the kuid of the user
>> >> >> in the initial user namespace as nfs mounts can only happen today in
>> >> >> the initial user namespace.
>> >> >
>> >> > OK, I didn't know that.
>> >> >
>> >> > (Though I'm unclear how it should matter to the server what user
>> >> > namespace the client is in?)
>> >> 
>> >> Perhaps I have the description a little scrambled.  The short version
>> >> is that to start I only support the initial network namespace.
>> >> 
>> >> If I haven't succeeded it is my intent to initially limit the servers
>> >> to the initial user namespace as well.  I should see if I can figure
>> >> that out.
>> >> 
>> >> >> When a reply to an upcall comes in convert interpret the uid and gid values
>> >> >> from the rpc pipe as uids and gids in the initial user namespace and convert
>> >> >> them into kuids and kgids before processing them further.
>> >> >> 
>> >> >> When reading proc files listing the uid to gid list cache convert the
>> >> >> kuids and kgids from into uids and gids the initial user namespace.  As we are
>> >> >> displaying server internal details it makes sense to display these values
>> >> >> from the servers perspective.
>> >> >
>> >> > All of these caches are already per-network-namespace.  Ideally wouldn't
>> >> > we also like to associate a user namespace with each cache somehow?
>> >> 
>> >> Ideally yes.  I read through the caches enough to figure out where there
>> >> user space interfaces were, and to make certain we had conversions
>> >> to/from kuids and kgids.
>> >> 
>> >> I haven't looked at what user namespace makes sense for these
>> >> caches.  For this cache my first guess is that net->user_ns
>> >> is what we want as it will be shared by all users in network namespace I
>> >> presume.
>> >
>> > Oh, I didn't know about net->user_ns--so each network namespace is
>> > associated with a single user namespace, great, that simplifies life.
>> > Yes, that sounds exactly right.
>> 
>> Yes. net->user_ns is the user namespace the network namespace was
>> created in.  And it is the user namespace that is used in test
>> like ns_capable(net->user_ns, CAP_NET_ADMIN) to see if you are allowed
>> to manipulate the network namespace.  So looks like exactly what we
>> want for that cache.
>> 
>> Could you double check my understanding of the code?
>> 
>> I want to be certain that I can't _yet_ start an sunrpc server process
>> outside of the initial user namespace.  While writing an earlier reply I
>> realized that I hadn't thought about where sunrpc server processes come
>> from.
>> 
>> Reading through the code it looks like we can have nfs mounts outside of
>> the initial network namespace.
>
> We're talking about the server side here, not the client, so I'm not
> sure what you mean by "nfs mounts".  The nfs server does use various
> pseudofilesystems ("proc", "nfsd"), and those can be mounted outside the
> initial network namespace.

Actually I was seeing that nfs clients were starting lockd.  So I was
just reasoning here that anything that came from a nfs client was
ultimately in the user namespace of that client, which is ultimately
limited by the client out.

> The server can receive rpc requests over network interfaces outside the
> initial network namespace, sure.  The server doesn't perform mounts on
> behalf of clients, though, it just accesses previously mounted
> filesystems on clients' behalf.

But nfsd_init_socks only creates sockets in a single network namespace,
and today we pass only &init_net.

>> But because they are mounts they are
>> still limited to the initial user namespace.
>
> OK, so that's just a limitation on any mount whatsoever for now.  I'm
> catching on, slowly, thanks!

If you set in struct filesystem .fs_flags = FS_USERNS_MOUNT your
filesystem can be mounted outside of the initial user namespace.  But
since that takes extra work and because unprivileged users are allowed
to create user namespaces and perform the mounts by default it is off.

>> Now looking at the nfs server, seems to be hard coded to only start
>> in the initial network namespace despite almost having support for
>> starting in more.
>
> Right, Stanislav's got 4 more patches that should finish the job; see
> http://mid.gmane.org/<20130201125210.3257.46454.stgit@localhost.localdomain>
> and followups.  That should make it for 3.9, I just need to review
> them....

Ok that is interesting.

There is an interesting corner case here where an unprivileged user
can create a user namespace and then can create a network namespace.
Depending on how we interpret things when Stanislaves patches reach
there we might have to add:

if (net->user_ns != &init_user_ns)
	-EINVAL

Somewhere appropriate.

>> Even more the nfs server is controlled and started through the "nfsd"
>> filesystem.  Which has to be mounted before you can start the server.
>> So you can only start the server through a mount in the initial user
>> namespace.
>
> Yes.
>
>> lockd is started by either the nfs server or the nfs client.
>> 
>> There are no other sunrpc servers in the kernel.
>
> There are a couple callback services on the NFS client--those should be
> associated with nfs mounts in some obvious way.  There's a confusing ACL
> service that's really just an appendage of NFSv2/v3 service.
>
> I think we're fine.

Thanks.

>> I think all of that is enough to reasonably claim that you can't have
>> any sunrpc server processes outside of the initial user namespace.  But
>> if I am wrong I would to find an appropriate spot to put in a line
>> that says:
>> 	 if (current_user_ns() != &init_user)
>>          	return -ESORRY_CHARLEY;
>
> I think you're right.
>
> So for now it's safely confined to one user namespace, and I think we
> understand approximately what to do if we want to support nfsd's in user
> namespace in the future.  (Mainly, make sure nfsd and proc can be
> mounted in them and then most things will be determined by the user_ns
> of the network namespace associated with a given rpc.)

For 3.9 the list of filesystems mountable outside the initial user
namespace is: mqueuefs, tmpfs, ramfs, devpts, sysfs, and proc.

I am a touch concerned about /proc/fs/nfsd/exports after my patches
and Stanislavs patches both come in.  As I think that will allow for
cases where net->user_ns != &init_userns.  But we can cross that bridge
when we come to it.

Eric


^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 52/85] sunrpc: Properly encode kuids and kgids in auth.unix.gid rpc pipe upcalls.
  2013-02-13 23:22               ` Eric W. Biederman
@ 2013-02-14  7:12                 ` Stanislav Kinsbursky
  2013-02-14  8:42                   ` Eric W. Biederman
  2013-02-15 17:00                 ` J. Bruce Fields
  1 sibling, 1 reply; 109+ messages in thread
From: Stanislav Kinsbursky @ 2013-02-14  7:12 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: J. Bruce Fields, linux-fsdevel, Linux Containers, linux-kernel,
	Serge E. Hallyn, Trond Myklebust

14.02.2013 03:22, Eric W. Biederman пишет:
> "J. Bruce Fields" <bfields@fieldses.org> writes:
>
>> On Wed, Feb 13, 2013 at 02:32:29PM -0800, Eric W. Biederman wrote:
>>> "J. Bruce Fields" <bfields@fieldses.org> writes:
>>>
>>>> On Wed, Feb 13, 2013 at 01:29:35PM -0800, Eric W. Biederman wrote:
>>>>> "J. Bruce Fields" <bfields@fieldses.org> writes:
>>>>>
>>>>>> On Wed, Feb 13, 2013 at 09:51:41AM -0800, Eric W. Biederman wrote:
>>>>>>> From: "Eric W. Biederman" <ebiederm@xmission.com>
>>>>>>>
>>>>>>> When a new rpc connection is established with an in-kernel server, the
>>>>>>> traffic passes through svc_process_common, and svc_set_client and down
>>>>>>> into svcauth_unix_set_client if it is of type RPC_AUTH_NULL or
>>>>>>> RPC_AUTH_UNIX.
>>>>>>>
>>>>>>> svcauth_unix_set_client then looks at the uid of the credential we
>>>>>>> have assigned to the incomming client and if we don't have the groups
>>>>>>> already cached makes an upcall to get a list of groups that the client
>>>>>>> can use.
>>>>>>>
>>>>>>> The upcall encodes send a rpc message to user space encoding the uid
>>>>>>> of the user whose groups we want to know.  Encode the kuid of the user
>>>>>>> in the initial user namespace as nfs mounts can only happen today in
>>>>>>> the initial user namespace.
>>>>>>
>>>>>> OK, I didn't know that.
>>>>>>
>>>>>> (Though I'm unclear how it should matter to the server what user
>>>>>> namespace the client is in?)
>>>>>
>>>>> Perhaps I have the description a little scrambled.  The short version
>>>>> is that to start I only support the initial network namespace.
>>>>>
>>>>> If I haven't succeeded it is my intent to initially limit the servers
>>>>> to the initial user namespace as well.  I should see if I can figure
>>>>> that out.
>>>>>
>>>>>>> When a reply to an upcall comes in convert interpret the uid and gid values
>>>>>>> from the rpc pipe as uids and gids in the initial user namespace and convert
>>>>>>> them into kuids and kgids before processing them further.
>>>>>>>
>>>>>>> When reading proc files listing the uid to gid list cache convert the
>>>>>>> kuids and kgids from into uids and gids the initial user namespace.  As we are
>>>>>>> displaying server internal details it makes sense to display these values
>>>>>>> from the servers perspective.
>>>>>>
>>>>>> All of these caches are already per-network-namespace.  Ideally wouldn't
>>>>>> we also like to associate a user namespace with each cache somehow?
>>>>>
>>>>> Ideally yes.  I read through the caches enough to figure out where there
>>>>> user space interfaces were, and to make certain we had conversions
>>>>> to/from kuids and kgids.
>>>>>
>>>>> I haven't looked at what user namespace makes sense for these
>>>>> caches.  For this cache my first guess is that net->user_ns
>>>>> is what we want as it will be shared by all users in network namespace I
>>>>> presume.
>>>>
>>>> Oh, I didn't know about net->user_ns--so each network namespace is
>>>> associated with a single user namespace, great, that simplifies life.
>>>> Yes, that sounds exactly right.
>>>
>>> Yes. net->user_ns is the user namespace the network namespace was
>>> created in.  And it is the user namespace that is used in test
>>> like ns_capable(net->user_ns, CAP_NET_ADMIN) to see if you are allowed
>>> to manipulate the network namespace.  So looks like exactly what we
>>> want for that cache.
>>>
>>> Could you double check my understanding of the code?
>>>
>>> I want to be certain that I can't _yet_ start an sunrpc server process
>>> outside of the initial user namespace.  While writing an earlier reply I
>>> realized that I hadn't thought about where sunrpc server processes come
>>> from.
>>>
>>> Reading through the code it looks like we can have nfs mounts outside of
>>> the initial network namespace.
>>
>> We're talking about the server side here, not the client, so I'm not
>> sure what you mean by "nfs mounts".  The nfs server does use various
>> pseudofilesystems ("proc", "nfsd"), and those can be mounted outside the
>> initial network namespace.
>
> Actually I was seeing that nfs clients were starting lockd.  So I was
> just reasoning here that anything that came from a nfs client was
> ultimately in the user namespace of that client, which is ultimately
> limited by the client out.
>
>> The server can receive rpc requests over network interfaces outside the
>> initial network namespace, sure.  The server doesn't perform mounts on
>> behalf of clients, though, it just accesses previously mounted
>> filesystems on clients' behalf.
>
> But nfsd_init_socks only creates sockets in a single network namespace,
> and today we pass only &init_net.
>
>>> But because they are mounts they are
>>> still limited to the initial user namespace.
>>
>> OK, so that's just a limitation on any mount whatsoever for now.  I'm
>> catching on, slowly, thanks!
>
> If you set in struct filesystem .fs_flags = FS_USERNS_MOUNT your
> filesystem can be mounted outside of the initial user namespace.  But
> since that takes extra work and because unprivileged users are allowed
> to create user namespaces and perform the mounts by default it is off.
>
>>> Now looking at the nfs server, seems to be hard coded to only start
>>> in the initial network namespace despite almost having support for
>>> starting in more.
>>
>> Right, Stanislav's got 4 more patches that should finish the job; see
>> http://mid.gmane.org/<20130201125210.3257.46454.stgit@localhost.localdomain>
>> and followups.  That should make it for 3.9, I just need to review
>> them....
>
> Ok that is interesting.
>
> There is an interesting corner case here where an unprivileged user
> can create a user namespace and then can create a network namespace.
> Depending on how we interpret things when Stanislaves patches reach
> there we might have to add:
>
> if (net->user_ns != &init_user_ns)
> 	-EINVAL
>
> Somewhere appropriate.
>
>>> Even more the nfs server is controlled and started through the "nfsd"
>>> filesystem.  Which has to be mounted before you can start the server.
>>> So you can only start the server through a mount in the initial user
>>> namespace.
>>
>> Yes.
>>
>>> lockd is started by either the nfs server or the nfs client.
>>>
>>> There are no other sunrpc servers in the kernel.
>>
>> There are a couple callback services on the NFS client--those should be
>> associated with nfs mounts in some obvious way.  There's a confusing ACL
>> service that's really just an appendage of NFSv2/v3 service.
>>
>> I think we're fine.
>
> Thanks.
>
>>> I think all of that is enough to reasonably claim that you can't have
>>> any sunrpc server processes outside of the initial user namespace.  But
>>> if I am wrong I would to find an appropriate spot to put in a line
>>> that says:
>>> 	 if (current_user_ns() != &init_user)
>>>           	return -ESORRY_CHARLEY;
>>
>> I think you're right.
>>
>> So for now it's safely confined to one user namespace, and I think we
>> understand approximately what to do if we want to support nfsd's in user
>> namespace in the future.  (Mainly, make sure nfsd and proc can be
>> mounted in them and then most things will be determined by the user_ns
>> of the network namespace associated with a given rpc.)
>
> For 3.9 the list of filesystems mountable outside the initial user
> namespace is: mqueuefs, tmpfs, ramfs, devpts, sysfs, and proc.
>
> I am a touch concerned about /proc/fs/nfsd/exports after my patches
> and Stanislavs patches both come in.  As I think that will allow for
> cases where net->user_ns != &init_userns.  But we can cross that bridge
> when we come to it.
>


Hmmm...
Maybe I'm missing the point of user namespaces, but since NFS kernel server
is controlled via NFSd file system write calls, maybe it would be better to add:

.fs_flags = FS_USERNS_MOUNT

to it and add check:

+	if (net->user_ns != current_user_ns())
+		return -EINVAL;

No?


> Eric
>


-- 
Best regards,
Stanislav Kinsbursky

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 22/85] ocfs2: convert between kuids and kgids and DLM locks
  2013-02-13 17:51   ` [PATCH review 22/85] ocfs2: convert between kuids and kgids and DLM locks Eric W. Biederman
@ 2013-02-14  8:34     ` Joel Becker
  0 siblings, 0 replies; 109+ messages in thread
From: Joel Becker @ 2013-02-14  8:34 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Mark Fasheh

On Wed, Feb 13, 2013 at 09:51:11AM -0800, Eric W. Biederman wrote:
> From: "Eric W. Biederman" <ebiederm@xmission.com>
> 
> Convert between uid and gids stored in the on the wire format of dlm
> locks aka struct ocfs2_meta_lvb and kuids and kgids stored in
> inode->i_uid and inode->i_gid.
> 
> Cc: Mark Fasheh <mfasheh@suse.com>
> Cc: Joel Becker <jlbec@evilplan.org>
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>  fs/ocfs2/dlmglue.c |    8 ++++----
>  1 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
> index 4f7795f..f99af1c 100644
> --- a/fs/ocfs2/dlmglue.c
> +++ b/fs/ocfs2/dlmglue.c
> @@ -2045,8 +2045,8 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode)
>  	lvb->lvb_version   = OCFS2_LVB_VERSION;
>  	lvb->lvb_isize	   = cpu_to_be64(i_size_read(inode));
>  	lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters);
> -	lvb->lvb_iuid      = cpu_to_be32(inode->i_uid);
> -	lvb->lvb_igid      = cpu_to_be32(inode->i_gid);
> +	lvb->lvb_iuid      = cpu_to_be32(i_uid_read(inode));
> +	lvb->lvb_igid      = cpu_to_be32(i_gid_read(inode));
>  	lvb->lvb_imode     = cpu_to_be16(inode->i_mode);
>  	lvb->lvb_inlink    = cpu_to_be16(inode->i_nlink);
>  	lvb->lvb_iatime_packed  =
> @@ -2095,8 +2095,8 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
>  	else
>  		inode->i_blocks = ocfs2_inode_sector_count(inode);
>  
> -	inode->i_uid     = be32_to_cpu(lvb->lvb_iuid);
> -	inode->i_gid     = be32_to_cpu(lvb->lvb_igid);
> +	i_uid_write(inode, be32_to_cpu(lvb->lvb_iuid));
> +	i_gid_write(inode, be32_to_cpu(lvb->lvb_igid));
>  	inode->i_mode    = be16_to_cpu(lvb->lvb_imode);
>  	set_nlink(inode, be16_to_cpu(lvb->lvb_inlink));
>  	ocfs2_unpack_timespec(&inode->i_atime,

What does this do if two machines with different user namespaces
communicate.  I think that things go very wrong.  Perhaps right now,
when ocfs2 is tied to init_user_namespace, we're OK.  But as soon as two
systems can be in different namespaces, we are broken.

Joel

> -- 
> 1.7.5.4
> 

-- 

"I think it would be a good idea."  
        - Mahatma Ghandi, when asked what he thought of Western
          civilization

			http://www.jlbec.org/
			jlbec@evilplan.org

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 23/85] ocfs2: Convert uid and gids between in core and on disk inodes
  2013-02-13 17:51   ` [PATCH review 23/85] ocfs2: Convert uid and gids between in core and on disk inodes Eric W. Biederman
@ 2013-02-14  8:35     ` Joel Becker
  2013-02-14  9:10       ` Eric W. Biederman
  0 siblings, 1 reply; 109+ messages in thread
From: Joel Becker @ 2013-02-14  8:35 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Mark Fasheh

This has the same problem with two machines in different userspace
namespaces.  Should this be punted to the sysadmin or helped out in the
filesystem?  Do you define this case as unsupported?

Joel

On Wed, Feb 13, 2013 at 09:51:12AM -0800, Eric W. Biederman wrote:
> From: "Eric W. Biederman" <ebiederm@xmission.com>
> 
> Cc: Mark Fasheh <mfasheh@suse.com>
> Cc: Joel Becker <jlbec@evilplan.org>
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>  fs/ocfs2/inode.c |   12 ++++++------
>  fs/ocfs2/namei.c |    4 ++--
>  2 files changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
> index d89e08a..f87f9bd 100644
> --- a/fs/ocfs2/inode.c
> +++ b/fs/ocfs2/inode.c
> @@ -269,8 +269,8 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
>  	inode->i_generation = le32_to_cpu(fe->i_generation);
>  	inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
>  	inode->i_mode = le16_to_cpu(fe->i_mode);
> -	inode->i_uid = le32_to_cpu(fe->i_uid);
> -	inode->i_gid = le32_to_cpu(fe->i_gid);
> +	i_uid_write(inode, le32_to_cpu(fe->i_uid));
> +	i_gid_write(inode, le32_to_cpu(fe->i_gid));
>  
>  	/* Fast symlinks will have i_size but no allocated clusters. */
>  	if (S_ISLNK(inode->i_mode) && !fe->i_clusters) {
> @@ -1259,8 +1259,8 @@ int ocfs2_mark_inode_dirty(handle_t *handle,
>  
>  	fe->i_size = cpu_to_le64(i_size_read(inode));
>  	ocfs2_set_links_count(fe, inode->i_nlink);
> -	fe->i_uid = cpu_to_le32(inode->i_uid);
> -	fe->i_gid = cpu_to_le32(inode->i_gid);
> +	fe->i_uid = cpu_to_le32(i_uid_read(inode));
> +	fe->i_gid = cpu_to_le32(i_gid_read(inode));
>  	fe->i_mode = cpu_to_le16(inode->i_mode);
>  	fe->i_atime = cpu_to_le64(inode->i_atime.tv_sec);
>  	fe->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
> @@ -1290,8 +1290,8 @@ void ocfs2_refresh_inode(struct inode *inode,
>  	ocfs2_set_inode_flags(inode);
>  	i_size_write(inode, le64_to_cpu(fe->i_size));
>  	set_nlink(inode, ocfs2_read_links_count(fe));
> -	inode->i_uid = le32_to_cpu(fe->i_uid);
> -	inode->i_gid = le32_to_cpu(fe->i_gid);
> +	i_uid_write(inode, le32_to_cpu(fe->i_uid));
> +	i_gid_write(inode, le32_to_cpu(fe->i_gid));
>  	inode->i_mode = le16_to_cpu(fe->i_mode);
>  	if (S_ISLNK(inode->i_mode) && le32_to_cpu(fe->i_clusters) == 0)
>  		inode->i_blocks = 0;
> diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
> index f1fd074..04ee1b5 100644
> --- a/fs/ocfs2/namei.c
> +++ b/fs/ocfs2/namei.c
> @@ -512,8 +512,8 @@ static int __ocfs2_mknod_locked(struct inode *dir,
>  	fe->i_suballoc_loc = cpu_to_le64(suballoc_loc);
>  	fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
>  	fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot);
> -	fe->i_uid = cpu_to_le32(inode->i_uid);
> -	fe->i_gid = cpu_to_le32(inode->i_gid);
> +	fe->i_uid = cpu_to_le32(i_uid_read(inode));
> +	fe->i_gid = cpu_to_le32(i_gid_read(inode));
>  	fe->i_mode = cpu_to_le16(inode->i_mode);
>  	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
>  		fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
> -- 
> 1.7.5.4
> 

-- 

"Sometimes when reading Goethe I have the paralyzing suspicion
 that he is trying to be funny."
         - Guy Davenport

			http://www.jlbec.org/
			jlbec@evilplan.org

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 25/85] ocfs2: Compare kuids and kgids using uid_eq and gid_eq
  2013-02-13 17:51   ` [PATCH review 25/85] ocfs2: Compare kuids and kgids using uid_eq and gid_eq Eric W. Biederman
@ 2013-02-14  8:37     ` Joel Becker
  0 siblings, 0 replies; 109+ messages in thread
From: Joel Becker @ 2013-02-14  8:37 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Mark Fasheh

On Wed, Feb 13, 2013 at 09:51:14AM -0800, Eric W. Biederman wrote:
> From: "Eric W. Biederman" <ebiederm@xmission.com>
> 
> Cc: Mark Fasheh <mfasheh@suse.com>
> Cc: Joel Becker <jlbec@evilplan.org>
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>  fs/ocfs2/file.c         |    8 ++++----
>  fs/ocfs2/refcounttree.c |    2 +-
>  2 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
> index 8ee9332..0a2924a 100644
> --- a/fs/ocfs2/file.c
> +++ b/fs/ocfs2/file.c
> @@ -1175,14 +1175,14 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
>  		}
>  	}
>  
> -	if ((attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
> -	    (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
> +	if ((attr->ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) ||
> +	    (attr->ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) {

Will the code work if built just before this patch?  IOW, does the
original comparison (attr->ia_gid != inode->i_gid) work when the system
is in the init_user_namespace?  If not, then the previous patches are
not leaving a functional filesystem.

Joel

>  		/*
>  		 * Gather pointers to quota structures so that allocation /
>  		 * freeing of quota structures happens here and not inside
>  		 * dquot_transfer() where we have problems with lock ordering
>  		 */
> -		if (attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid
> +		if (attr->ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)
>  		    && OCFS2_HAS_RO_COMPAT_FEATURE(sb,
>  		    OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) {
>  			transfer_to[USRQUOTA] = dqget(sb, make_kqid_uid(attr->ia_uid));
> @@ -1191,7 +1191,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
>  				goto bail_unlock;
>  			}
>  		}
> -		if (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid
> +		if (attr->ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid)
>  		    && OCFS2_HAS_RO_COMPAT_FEATURE(sb,
>  		    OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) {
>  			transfer_to[GRPQUOTA] = dqget(sb, make_kqid_gid(attr->ia_gid));
> diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
> index 30a0550..934a4ac 100644
> --- a/fs/ocfs2/refcounttree.c
> +++ b/fs/ocfs2/refcounttree.c
> @@ -4407,7 +4407,7 @@ static int ocfs2_vfs_reflink(struct dentry *old_dentry, struct inode *dir,
>  	 * rights to do so.
>  	 */
>  	if (preserve) {
> -		if ((current_fsuid() != inode->i_uid) && !capable(CAP_CHOWN))
> +		if (!uid_eq(current_fsuid(), inode->i_uid) && !capable(CAP_CHOWN))
>  			return -EPERM;
>  		if (!in_group_p(inode->i_gid) && !capable(CAP_CHOWN))
>  			return -EPERM;
> -- 
> 1.7.5.4
> 

-- 

"Where are my angels?
 Where's my golden one?
 And where is my hope
 Now that my heroes are gone?"

			http://www.jlbec.org/
			jlbec@evilplan.org

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 26/85] ocfs2: Enable building with user namespaces enabled
  2013-02-13 17:51   ` [PATCH review 26/85] ocfs2: Enable building with user namespaces enabled Eric W. Biederman
@ 2013-02-14  8:38     ` Joel Becker
  0 siblings, 0 replies; 109+ messages in thread
From: Joel Becker @ 2013-02-14  8:38 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Mark Fasheh

On Wed, Feb 13, 2013 at 09:51:15AM -0800, Eric W. Biederman wrote:
> From: "Eric W. Biederman" <ebiederm@xmission.com>
> 
> Now that ocfs2 has been converted to store uids and gids in
> kuid_t and kgid_t and all of the conversions have been added
> to the appropriate places it is safe to allow building and
> using ocfs2 with user namespace support enabled.
> 
> Cc: Mark Fasheh <mfasheh@suse.com>
> Cc: Joel Becker <jlbec@evilplan.org>
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>  init/Kconfig |    1 -
>  1 files changed, 0 insertions(+), 1 deletions(-)
> 
> diff --git a/init/Kconfig b/init/Kconfig
> index f516d52..9cb63c9 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -1076,7 +1076,6 @@ config UIDGID_CONVERTED
>  	depends on NCP_FS = n
>  	depends on NFSD = n
>  	depends on NFS_FS = n
> -	depends on OCFS2_FS = n

Ahh, I can see how this protects the partially applied state.  Sorry
about that.

Joel

>  	depends on XFS_FS = n
>  
>  config UIDGID_STRICT_TYPE_CHECKS
> -- 
> 1.7.5.4
> 

-- 

"People with narrow minds usually have broad tongues."

			http://www.jlbec.org/
			jlbec@evilplan.org

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 52/85] sunrpc: Properly encode kuids and kgids in auth.unix.gid rpc pipe upcalls.
  2013-02-14  7:12                 ` Stanislav Kinsbursky
@ 2013-02-14  8:42                   ` Eric W. Biederman
  0 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-14  8:42 UTC (permalink / raw)
  To: Stanislav Kinsbursky
  Cc: J. Bruce Fields, linux-fsdevel, Linux Containers, linux-kernel,
	Serge E. Hallyn, Trond Myklebust

Stanislav Kinsbursky <skinsbursky@parallels.com> writes:

> 14.02.2013 03:22, Eric W. Biederman пишет:

> Hmmm...
> Maybe I'm missing the point of user namespaces, but since NFS kernel server
> is controlled via NFSd file system write calls, maybe it would be better to add:
>
> .fs_flags = FS_USERNS_MOUNT
>
> to it and add check:
>
> +	if (net->user_ns != current_user_ns())
> +		return -EINVAL;
>
> No?

Not really.  The immediate goal is to just use kuid_t and kgid_t instead
of uid_t and gid_t throughout the kernel.  That ensures someone hasn't
missed a case and is getting a uid in one namespace confused with a uid
in another.  And that is needed to make it safe to enable nfs and nfsd
support when user namespace support is enabled in the kernel.

So at the basic level I have made the assumption that all nfs activity
happens in the initial user namespace and have made conversions to/from
the initial user namespace throughout the nfs and nfsd code.

We can add FS_USERNS_MOUNT when we are ready to support running in
multiple user namespaces.  For now not allowing mounts outside of the
initial user namespace ensures that the nfs client code is always
in the initial user namespace and that the nfs server code is always
dealing with ids in the initial user namespace.

Stanislav even with your pending patches it won't be possible to mount a
nfsd whre net->user_ns != init_userns.  So no bugs will result in the
combination of our patches.  The one case I was worried about was
fs/nfs/exports.  But since that is read-only it creates no problems.


The big things user namespaces allow (besides uid and gid mapping) is a
context where unprivileged users can create containers.  Those
containers can mount and unmount filesystems and have a root user.  But
that root users does not have global uid == 0, nor does that root user
have any global capabilities.  The root user only has capabilities over
objects created in that user namespace.  Which can include network
namespaces etc.




Now all of that said and done when we do start supporting user
namespaces in nfs (something that looks comparitively simple after your
recent work to make nfs and nfsd network namespace aware) I expect the
mount for nfsd and nfs will want to do:
	if (net->user_ns != current_user_ns())
        	return -EINVAL;

I can't see any other cases actually making sense.  If we are in an
ancestor user namespace of net->user_ns we are ok permission wise
but totally we are in a totally confused state with respect to which
permission to talk.  If we are in a descendent user namespace we should
not have the permissions to potentially dangerous things.

Which should make for a very very simple conversion when to get nfs
running in multiple user namespaces for 3.10 as we can just replace
&init_net with net->user_ns everywhere.

Eric

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 23/85] ocfs2: Convert uid and gids between in core and on disk inodes
  2013-02-14  8:35     ` Joel Becker
@ 2013-02-14  9:10       ` Eric W. Biederman
  0 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-14  9:10 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Linux Containers, linux-kernel, Serge E. Hallyn, Mark Fasheh

Joel Becker <jlbec@evilplan.org> writes:

> This has the same problem with two machines in different userspace
> namespaces.  Should this be punted to the sysadmin or helped out in the
> filesystem?  Do you define this case as unsupported?

First I define two machines in the same user namespace as two machines
with synchronized password files.

As today connecting two machines without synchronizing the password
entries is a problem, won't work, and is punted to the sysadmin to make
keep from doing something silly.

At the same time I don't want to make it easy to get confused, or cause
breakage.

With these patches ocfs2 only still only works in the initial user
namespace.  I don't set .fs_flags = FS_USERNS_MOUNT in struct
filesystem.  Which means that while users in other user namespaces can
store files on ocfs2, they can't mount ocfs2.

Eric

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 52/85] sunrpc: Properly encode kuids and kgids in auth.unix.gid rpc pipe upcalls.
  2013-02-13 23:22               ` Eric W. Biederman
  2013-02-14  7:12                 ` Stanislav Kinsbursky
@ 2013-02-15 17:00                 ` J. Bruce Fields
  2013-02-15 18:47                   ` Eric W. Biederman
  1 sibling, 1 reply; 109+ messages in thread
From: J. Bruce Fields @ 2013-02-15 17:00 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Trond Myklebust, Stanislav Kinsbursky

On Wed, Feb 13, 2013 at 03:22:32PM -0800, Eric W. Biederman wrote:
> "J. Bruce Fields" <bfields@fieldses.org> writes:
> 
> > On Wed, Feb 13, 2013 at 02:32:29PM -0800, Eric W. Biederman wrote:
> >> Now looking at the nfs server, seems to be hard coded to only start
> >> in the initial network namespace despite almost having support for
> >> starting in more.
> >
> > Right, Stanislav's got 4 more patches that should finish the job; see
> > http://mid.gmane.org/<20130201125210.3257.46454.stgit@localhost.localdomain>
> > and followups.  That should make it for 3.9, I just need to review
> > them....
> 
> Ok that is interesting.
> 
> There is an interesting corner case here where an unprivileged user
> can create a user namespace and then can create a network namespace.
> Depending on how we interpret things when Stanislaves patches reach
> there we might have to add:
> 
> if (net->user_ns != &init_user_ns)
> 	-EINVAL
> 
> Somewhere appropriate.

I'm assuming that's something that's needed only in kernels that have
*both* Stanislav's patches and yours.

I've committed his patches to

	git://linux-nfs.org/~bfields/linux.git for-3.9

which should also get pulled into next.  Let me know if there's another
patch I should take.

> I am a touch concerned about /proc/fs/nfsd/exports after my patches
> and Stanislavs patches both come in.  As I think that will allow for
> cases where net->user_ns != &init_userns.  But we can cross that bridge
> when we come to it.

OK, let me know of anything I can do to make your life easier....

--b.

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 52/85] sunrpc: Properly encode kuids and kgids in auth.unix.gid rpc pipe upcalls.
  2013-02-15 17:00                 ` J. Bruce Fields
@ 2013-02-15 18:47                   ` Eric W. Biederman
  0 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-02-15 18:47 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Trond Myklebust, Stanislav Kinsbursky

"J. Bruce Fields" <bfields@fieldses.org> writes:

> On Wed, Feb 13, 2013 at 03:22:32PM -0800, Eric W. Biederman wrote:
>
> I've committed his patches to
>
> 	git://linux-nfs.org/~bfields/linux.git for-3.9
>
> which should also get pulled into next.  Let me know if there's another
> patch I should take.

I don't currently see any problems.

My changes are now in:

        git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git for-next

So we will get whatever linux-next testing there is.

>> I am a touch concerned about /proc/fs/nfsd/exports after my patches
>> and Stanislavs patches both come in.  As I think that will allow for
>> cases where net->user_ns != &init_userns.  But we can cross that bridge
>> when we come to it.
>
> OK, let me know of anything I can do to make your life easier....

/proc/fs/nfsd/exports is read-only so it turns out not be be a problem.

That we can not mount nfs or the nfsd control filesystem outside of
init_userns prevents any other problems.  Details are in my conversation
with Stanislav.

Eric

p.s. It would be nice if /proc/fs/nfsd/exports became a symlink to
/proc/net/nfsd/exports so the code didn't have to use current to figure
out how to do the right thing.

p.p.s Full user namespace support probably isn't much more than using
net->user_ns and adding the FS_USERNS_MOUNT flag. 

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 49/85] sunrpc: Update svcgss xdr handle to rpsec_contect cache
  2013-02-13 17:51   ` [PATCH review 49/85] sunrpc: Update svcgss xdr handle to rpsec_contect cache Eric W. Biederman
@ 2013-03-04 14:12     ` J. Bruce Fields
  2013-03-04 17:11       ` Eric W. Biederman
  0 siblings, 1 reply; 109+ messages in thread
From: J. Bruce Fields @ 2013-03-04 14:12 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Trond Myklebust

On Wed, Feb 13, 2013 at 09:51:38AM -0800, Eric W. Biederman wrote:
> From: "Eric W. Biederman" <ebiederm@xmission.com>
> 
> For each received uid call make_kuid and validate the result.
> For each received gid call make_kgid and validate the result.
> 
> Cc: "J. Bruce Fields" <bfields@fieldses.org>
> Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
>  net/sunrpc/auth_gss/svcauth_gss.c |   18 +++++++++++++-----
>  1 files changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
> index 73e9573..ecd1d58 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,
>  {
>  	/* contexthandle expiry [ uid gid N <n gids> mechname ...mechdata... ] */
>  	char *buf = mesg;
> +	int id;
>  	int len, rv;
>  	struct rsc rsci, *rscp = NULL;
>  	time_t expiry;
> @@ -444,7 +445,7 @@ static int rsc_parse(struct cache_detail *cd,
>  		goto out;
>  
>  	/* uid, or NEGATIVE */
> -	rv = get_int(&mesg, &rsci.cred.cr_uid);
> +	rv = get_int(&mesg, &id);
>  	if (rv == -EINVAL)
>  		goto out;
>  	if (rv == -ENOENT)
> @@ -452,8 +453,16 @@ static int rsc_parse(struct cache_detail *cd,
>  	else {
>  		int N, i;
>  
> +		/* uid */
> +		rsci.cred.cr_uid = make_kuid(&init_user_ns, id);
> +		if (!uid_valid(rsci.cred.cr_uid))
> +			goto out;
> +
>  		/* gid */
> -		if (get_int(&mesg, &rsci.cred.cr_gid))
> +		if (get_int(&mesg, &id))
> +			goto out;
> +		rsci.cred.cr_gid = make_kgid(&init_user_ns, id);
> +		if (!gid_valid(rsci.cred.cr_gid))
>  			goto out;

krb5 mounts started failing for me as of this patch (upstream as
683428fae8c73d7d7da0fa2e0b6beb4d8df4e808), and I believe the problem is
these uid/gid_valid checks: if I recall correctly, gssd uses -1 uid/gid
values to indicate "authentication succeeded, but treat this user as
anonymous".  We delay mapping -1 id's to the (configurable-per-export)
anonymous id's till fs/nfsd/auth.c:nfsd_setuser():

        if (uid_eq(new->fsuid, INVALID_UID))
		new->fsuid = exp->ex_anon_uid;
	if (gid_eq(new->fsgid, INVALID_GID))
		new->fsgid = exp->ex_anon_gid;

(We wouldn't be able to do that earlier because we don't know the export
yet.)

Confirmed that the following fixes the regression.

Eric, any objection to removing those checks?

--b.

diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index f7d34e7..59a089d 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -449,15 +449,11 @@ static int rsc_parse(struct cache_detail *cd,
 
 		/* uid */
 		rsci.cred.cr_uid = make_kuid(&init_user_ns, id);
-		if (!uid_valid(rsci.cred.cr_uid))
-			goto out;
 
 		/* gid */
 		if (get_int(&mesg, &id))
 			goto out;
 		rsci.cred.cr_gid = make_kgid(&init_user_ns, id);
-		if (!gid_valid(rsci.cred.cr_gid))
-			goto out;
 
 		/* number of additional gid's */
 		if (get_int(&mesg, &N))

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* Re: [PATCH review 49/85] sunrpc: Update svcgss xdr handle to rpsec_contect cache
  2013-03-04 14:12     ` J. Bruce Fields
@ 2013-03-04 17:11       ` Eric W. Biederman
  2013-03-05 23:10         ` J. Bruce Fields
  0 siblings, 1 reply; 109+ messages in thread
From: Eric W. Biederman @ 2013-03-04 17:11 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Trond Myklebust

"J. Bruce Fields" <bfields@fieldses.org> writes:


> krb5 mounts started failing for me as of this patch (upstream as
> 683428fae8c73d7d7da0fa2e0b6beb4d8df4e808),

Ouch!

>  and I believe the problem is
> these uid/gid_valid checks: if I recall correctly, gssd uses -1 uid/gid
> values to indicate "authentication succeeded, but treat this user as
> anonymous".  We delay mapping -1 id's to the (configurable-per-export)
> anonymous id's till fs/nfsd/auth.c:nfsd_setuser():
>
>         if (uid_eq(new->fsuid, INVALID_UID))
> 		new->fsuid = exp->ex_anon_uid;
> 	if (gid_eq(new->fsgid, INVALID_GID))
> 		new->fsgid = exp->ex_anon_gid;
>
> (We wouldn't be able to do that earlier because we don't know the export
> yet.)
>
> Confirmed that the following fixes the regression.
>
> Eric, any objection to removing those checks?

Not strongly.  As long as we have the uid ang gid valid checks in
there somewhere before we start using these uids and gids much.
This does seems to be the case of using out of range uids and gids
to mean out of range uids and gids.

In the description of my original patch before I split it up, I
noted that one of the small dangers might be that I had added
some possibly unneceessary uid and gid valid checks.  So it seems I had
even considered this slight possibility once and noted that there was a
slight chance we might have to remove a few of these.

It would be nice to have a comment to say that we expect this to happen
so people don't start wondering why there are missing checks on this
path.

There is also a gid_valid check in the secondary uids.  It looks like we
should keep that as we don't have any checks for invalid gids in
nfsd_setuser.  Is that possibly an oversight in nfsd_setuser?

Also looking towards a future in which all of these things don't reside
in the initial user namespace.  Is mapping any out of range uid to
INVALID_UID and then into ex_anon_uid the always the right thing to do?

Or is -1 a very special case in this instance.  In which case we
probably want checks that look like:

        if (-1 == id) {
        	rsci.cred.cr_uid = INVALID_UID;
	} else {
	  	rsci.cred.cr_uid = make_kuid(&init_user_ns, id);
        	if (!uid_valid(rsci.cred.cr_uid))
			goto out;
        }

Eric

> diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
> index f7d34e7..59a089d 100644
> --- a/net/sunrpc/auth_gss/svcauth_gss.c
> +++ b/net/sunrpc/auth_gss/svcauth_gss.c
> @@ -449,15 +449,11 @@ static int rsc_parse(struct cache_detail *cd,
>  
>  		/* uid */
>  		rsci.cred.cr_uid = make_kuid(&init_user_ns, id);
> -		if (!uid_valid(rsci.cred.cr_uid))
> -			goto out;
>  
>  		/* gid */
>  		if (get_int(&mesg, &id))
>  			goto out;
>  		rsci.cred.cr_gid = make_kgid(&init_user_ns, id);
> -		if (!gid_valid(rsci.cred.cr_gid))
> -			goto out;
>  
>  		/* number of additional gid's */
>  		if (get_int(&mesg, &N))

^ permalink raw reply	[flat|nested] 109+ messages in thread

* Re: [PATCH review 49/85] sunrpc: Update svcgss xdr handle to rpsec_contect cache
  2013-03-04 17:11       ` Eric W. Biederman
@ 2013-03-05 23:10         ` J. Bruce Fields
  2013-03-05 23:43           ` Eric W. Biederman
  0 siblings, 1 reply; 109+ messages in thread
From: J. Bruce Fields @ 2013-03-05 23:10 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Trond Myklebust

On Mon, Mar 04, 2013 at 09:11:16AM -0800, Eric W. Biederman wrote:
> "J. Bruce Fields" <bfields@fieldses.org> writes:
> 
> 
> > krb5 mounts started failing for me as of this patch (upstream as
> > 683428fae8c73d7d7da0fa2e0b6beb4d8df4e808),
> 
> Ouch!
> 
> >  and I believe the problem is
> > these uid/gid_valid checks: if I recall correctly, gssd uses -1 uid/gid
> > values to indicate "authentication succeeded, but treat this user as
> > anonymous".  We delay mapping -1 id's to the (configurable-per-export)
> > anonymous id's till fs/nfsd/auth.c:nfsd_setuser():
> >
> >         if (uid_eq(new->fsuid, INVALID_UID))
> > 		new->fsuid = exp->ex_anon_uid;
> > 	if (gid_eq(new->fsgid, INVALID_GID))
> > 		new->fsgid = exp->ex_anon_gid;
> >
> > (We wouldn't be able to do that earlier because we don't know the export
> > yet.)
> >
> > Confirmed that the following fixes the regression.
> >
> > Eric, any objection to removing those checks?
> 
> Not strongly.  As long as we have the uid ang gid valid checks in
> there somewhere before we start using these uids and gids much.
> This does seems to be the case of using out of range uids and gids
> to mean out of range uids and gids.
> 
> In the description of my original patch before I split it up, I
> noted that one of the small dangers might be that I had added
> some possibly unneceessary uid and gid valid checks.  So it seems I had
> even considered this slight possibility once and noted that there was a
> slight chance we might have to remove a few of these.

Ah, I should have seen that and checked that, my bad.

> It would be nice to have a comment to say that we expect this to happen
> so people don't start wondering why there are missing checks on this
> path.

OK--something like the appended?

> There is also a gid_valid check in the secondary uids.  It looks like we
> should keep that as we don't have any checks for invalid gids in
> nfsd_setuser.  Is that possibly an oversight in nfsd_setuser?

Honestly I don't think anyone's thought that through....

But it would seem odd to pass down an "anonymous" supplementary gid--why
not just leave it off the list instead?

(BTW, dumb question: is it legal for userspace to use a uid -1?  And was
it illegal before the user namespace patches?)

> Also looking towards a future in which all of these things don't reside
> in the initial user namespace.  Is mapping any out of range uid to
> INVALID_UID and then into ex_anon_uid the always the right thing to do?
> 
> Or is -1 a very special case in this instance.  In which case we
> probably want checks that look like:

svcgssd should pass down either -1 or a valid uid, so I don't think
we're committed to any particular handling of invalid id's other than
-1--whatever's easiest.

--b.

commit d78f5cd062edb400190521e9540b042b4805875b
Author: J. Bruce Fields <bfields@redhat.com>
Date:   Mon Mar 4 08:44:01 2013 -0500

    nfsd: fix krb5 handling of anonymous principals
    
    krb5 mounts started failing as of
    683428fae8c73d7d7da0fa2e0b6beb4d8df4e808 "sunrpc: Update svcgss xdr
    handle to rpsec_contect cache".
    
    The problem is that mounts are usually done with some host principal
    which isn't normally mapped to any user, in which case svcgssd passes
    down uid -1, which the kernel is then expected to map to the
    export-specific anonymous uid or gid.
    
    The new uid_valid/gid_valid checks were therefore causing that downcall
    to fail.
    
    (Note the regression may not have been seen with older userspace that
    tended to map unknown principals to an anonymous id on their own rather
    than leaving it to the kernel.)
    
    Signed-off-by: J. Bruce Fields <bfields@redhat.com>

diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index f7d34e7..c2ab26f 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -447,17 +447,21 @@ static int rsc_parse(struct cache_detail *cd,
 	else {
 		int N, i;
 
+		/*
+		 * NOTE: we don't check uid_valid() or gid_valid(): instead,
+		 * -1 id's are later mapped to the (export-specific)
+		 * anonymous id by nfsd_setuser.
+		 *
+		 * (But supplementary gid's get no such special
+		 * treatment so are checked for validity here.)
+		 */
 		/* uid */
 		rsci.cred.cr_uid = make_kuid(&init_user_ns, id);
-		if (!uid_valid(rsci.cred.cr_uid))
-			goto out;
 
 		/* gid */
 		if (get_int(&mesg, &id))
 			goto out;
 		rsci.cred.cr_gid = make_kgid(&init_user_ns, id);
-		if (!gid_valid(rsci.cred.cr_gid))
-			goto out;
 
 		/* number of additional gid's */
 		if (get_int(&mesg, &N))

^ permalink raw reply related	[flat|nested] 109+ messages in thread

* Re: [PATCH review 49/85] sunrpc: Update svcgss xdr handle to rpsec_contect cache
  2013-03-05 23:10         ` J. Bruce Fields
@ 2013-03-05 23:43           ` Eric W. Biederman
  0 siblings, 0 replies; 109+ messages in thread
From: Eric W. Biederman @ 2013-03-05 23:43 UTC (permalink / raw)
  To: J. Bruce Fields
  Cc: linux-fsdevel, Linux Containers, linux-kernel, Serge E. Hallyn,
	Trond Myklebust

"J. Bruce Fields" <bfields@fieldses.org> writes:

> On Mon, Mar 04, 2013 at 09:11:16AM -0800, Eric W. Biederman wrote:
>> "J. Bruce Fields" <bfields@fieldses.org> writes:
>> 

>> Not strongly.  As long as we have the uid ang gid valid checks in
>> there somewhere before we start using these uids and gids much.
>> This does seems to be the case of using out of range uids and gids
>> to mean out of range uids and gids.
>> 
>> In the description of my original patch before I split it up, I
>> noted that one of the small dangers might be that I had added
>> some possibly unneceessary uid and gid valid checks.  So it seems I had
>> even considered this slight possibility once and noted that there was a
>> slight chance we might have to remove a few of these.
>
> Ah, I should have seen that and checked that, my bad.

I think that text was lost when I split my nfs patch into all of those
patches so I don't expect  you ever saw that text.

>> It would be nice to have a comment to say that we expect this to happen
>> so people don't start wondering why there are missing checks on this
>> path.
>
> OK--something like the appended?

It looks good to me.

>> There is also a gid_valid check in the secondary uids.  It looks like we
>> should keep that as we don't have any checks for invalid gids in
>> nfsd_setuser.  Is that possibly an oversight in nfsd_setuser?
>
> Honestly I don't think anyone's thought that through....

I try and take these moments of that's weird to spark the thinking of
things through.  Just in case there is something important was
overlooked.

> But it would seem odd to pass down an "anonymous" supplementary gid--why
> not just leave it off the list instead?

True.

> (BTW, dumb question: is it legal for userspace to use a uid -1?  And was
> it illegal before the user namespace patches?)

It is now impossible and thus illegal for userspace to use a uid value
of -1.  Previously to use a uid of -1 you had to jump through hoops as
some system calls would allow it (setuid) and some system calls special
cased the value of -1 (setresuid).  Which mean using a uid value of -1
was while possible but a bad idea because various things would break in
strange ways.

>> Also looking towards a future in which all of these things don't reside
>> in the initial user namespace.  Is mapping any out of range uid to
>> INVALID_UID and then into ex_anon_uid the always the right thing to do?
>> 
>> Or is -1 a very special case in this instance.  In which case we
>> probably want checks that look like:
>
> svcgssd should pass down either -1 or a valid uid, so I don't think
> we're committed to any particular handling of invalid id's other than
> -1--whatever's easiest.

Sounds good.  I won't worry about them in future development then.

> commit d78f5cd062edb400190521e9540b042b4805875b
> Author: J. Bruce Fields <bfields@redhat.com>
> Date:   Mon Mar 4 08:44:01 2013 -0500
>
>     nfsd: fix krb5 handling of anonymous principals
>     
>     krb5 mounts started failing as of
>     683428fae8c73d7d7da0fa2e0b6beb4d8df4e808 "sunrpc: Update svcgss xdr
>     handle to rpsec_contect cache".
>     
>     The problem is that mounts are usually done with some host principal
>     which isn't normally mapped to any user, in which case svcgssd passes
>     down uid -1, which the kernel is then expected to map to the
>     export-specific anonymous uid or gid.
>     
>     The new uid_valid/gid_valid checks were therefore causing that downcall
>     to fail.
>     
>     (Note the regression may not have been seen with older userspace that
>     tended to map unknown principals to an anonymous id on their own rather
>     than leaving it to the kernel.)
>     
>     Signed-off-by: J. Bruce Fields <bfields@redhat.com>

Reviewed-by: "Eric W. Biederman" <ebiederm@xmission.com>

> diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
> index f7d34e7..c2ab26f 100644
> --- a/net/sunrpc/auth_gss/svcauth_gss.c
> +++ b/net/sunrpc/auth_gss/svcauth_gss.c
> @@ -447,17 +447,21 @@ static int rsc_parse(struct cache_detail *cd,
>  	else {
>  		int N, i;
>  
> +		/*
> +		 * NOTE: we don't check uid_valid() or gid_valid(): instead,
> +		 * -1 id's are later mapped to the (export-specific)
> +		 * anonymous id by nfsd_setuser.
> +		 *
> +		 * (But supplementary gid's get no such special
> +		 * treatment so are checked for validity here.)
> +		 */
>  		/* uid */
>  		rsci.cred.cr_uid = make_kuid(&init_user_ns, id);
> -		if (!uid_valid(rsci.cred.cr_uid))
> -			goto out;
>  
>  		/* gid */
>  		if (get_int(&mesg, &id))
>  			goto out;
>  		rsci.cred.cr_gid = make_kgid(&init_user_ns, id);
> -		if (!gid_valid(rsci.cred.cr_gid))
> -			goto out;
>  
>  		/* number of additional gid's */
>  		if (get_int(&mesg, &N))

^ permalink raw reply	[flat|nested] 109+ messages in thread

end of thread, other threads:[~2013-03-05 23:43 UTC | newest]

Thread overview: 109+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <87621w14vs.fsf@xmission.com>
2013-02-13 17:50 ` [PATCH review 01/85] ceph: Only allow mounts in the initial network namespace Eric W. Biederman
2013-02-13 17:50   ` [PATCH review 02/85] ceph: Translate between uid and gids in cap messages and kuids and kgids Eric W. Biederman
2013-02-13 17:50   ` [PATCH review 03/85] ceph: Translate inode uid and gid attributes to/from " Eric W. Biederman
2013-02-13 17:50   ` [PATCH review 04/85] ceph: Convert struct ceph_mds_request to use kuid_t and kgid_t Eric W. Biederman
2013-02-13 17:50   ` [PATCH review 05/85] ceph: Convert kuids and kgids before printing them Eric W. Biederman
2013-02-13 17:50   ` [PATCH review 06/85] ceph: Enable building when user namespaces are enabled Eric W. Biederman
2013-02-13 17:50   ` [PATCH review 07/85] 9p: Add 'u' and 'g' format specifies for kuids and kgids Eric W. Biederman
2013-02-13 17:50   ` [PATCH review 08/85] 9p: Transmit kuid and kgid values Eric W. Biederman
2013-02-13 17:50   ` [PATCH review 09/85] 9p: Modify the stat structures to use kuid_t and kgid_t Eric W. Biederman
2013-02-13 17:50   ` [PATCH review 10/85] 9p: Modify struct 9p_fid to use a kuid_t not a uid_t Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 11/85] 9p: Modify struct v9fs_session_info to use a kuids and kgids Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 12/85] 9p: Modify v9fs_get_fsgid_for_create to return a kgid Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 13/85] 9p: Allow building 9p with user namespaces enabled Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 14/85] afs: Remove unused structure afs_store_status Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 15/85] afs: Only allow mounting afs in the intial network namespace Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 16/85] afs: Support interacting with multiple user namespaces Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 17/85] coda: Restrict coda messages to the initial pid namespace Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 18/85] coda: Restrict coda messages to the initial user namespace Eric W. Biederman
2013-02-13 18:14     ` Jan Harkes
2013-02-13 18:44       ` Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 19/85] coda: Cache permisions in struct coda_inode_info in a kuid_t Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 20/85] coda: Allow coda to be built when user namespace support is enabled Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 21/85] ocfs2: Handle kuids and kgids in acl/xattr conversions Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 22/85] ocfs2: convert between kuids and kgids and DLM locks Eric W. Biederman
2013-02-14  8:34     ` Joel Becker
2013-02-13 17:51   ` [PATCH review 23/85] ocfs2: Convert uid and gids between in core and on disk inodes Eric W. Biederman
2013-02-14  8:35     ` Joel Becker
2013-02-14  9:10       ` Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 24/85] ocfs2: For tracing report the uid and gid values in the initial user namespace Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 25/85] ocfs2: Compare kuids and kgids using uid_eq and gid_eq Eric W. Biederman
2013-02-14  8:37     ` Joel Becker
2013-02-13 17:51   ` [PATCH review 26/85] ocfs2: Enable building with user namespaces enabled Eric W. Biederman
2013-02-14  8:38     ` Joel Becker
2013-02-13 17:51   ` [PATCH review 27/85] gfs2: Remove improper checks in gfs2_set_dqblk Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 28/85] gfs2: Split NO_QUOTA_CHANGE inot NO_UID_QUTOA_CHANGE and NO_GID_QUTOA_CHANGE Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 29/85] gfs2: Report quotas in the caller's user namespace Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 30/85] gfs2: Introduce qd2index Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 31/85] gfs2: Modify struct gfs2_quota_change_host to use struct kqid Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 32/85] gfs2: Modify qdsb_get to take a " Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 33/85] gfs2: Convert gfs2_quota_refresh to take a kqid Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 34/85] gfs2: Store qd_id in struct gfs2_quota_data as a struct kqid Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 35/85] gfs2: Remove the QUOTA_USER and QUOTA_GROUP defines Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 36/85] gfs2: Use kuid_t and kgid_t types where appropriate Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 37/85] gfs2: Use uid_eq and gid_eq " Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 38/85] gfs2: Convert uids and gids between dinodes and vfs inodes Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 39/85] gfs2: Enable building with user namespaces enabled Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 40/85] ncpfs: Support interacting with multiple user namespaces Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 41/85] nfs_common: Update the translation between nfsv3 acls linux posix acls Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 42/85] sunrpc: Use userns friendly constants Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 43/85] sunrpc: Use kuid_t and kgid_t where appropriate Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 44/85] sunrpc: Use uid_eq and gid_eq " Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 45/85] sunrpc: Simplify auth_unix now that everything is a kgid_t Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 46/85] sunrpc: Convert kuids and kgids to uids and gids for printing Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 47/85] sunrpc: Use gid_valid to test for gid != INVALID_GID Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 48/85] sunrpc: Update gss uid to security context mapping Eric W. Biederman
2013-02-13 20:35     ` J. Bruce Fields
2013-02-13 21:17       ` Eric W. Biederman
2013-02-13 21:24         ` J. Bruce Fields
2013-02-13 17:51   ` [PATCH review 49/85] sunrpc: Update svcgss xdr handle to rpsec_contect cache Eric W. Biederman
2013-03-04 14:12     ` J. Bruce Fields
2013-03-04 17:11       ` Eric W. Biederman
2013-03-05 23:10         ` J. Bruce Fields
2013-03-05 23:43           ` Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 50/85] sunrpc: Hash uids by first computing their value in the initial userns Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 51/85] sunrpc: Properly encode kuids and kgids in RPC_AUTH_UNIX credentials Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 52/85] sunrpc: Properly encode kuids and kgids in auth.unix.gid rpc pipe upcalls Eric W. Biederman
2013-02-13 21:05     ` J. Bruce Fields
2013-02-13 21:29       ` Eric W. Biederman
2013-02-13 21:50         ` J. Bruce Fields
2013-02-13 22:32           ` Eric W. Biederman
2013-02-13 22:58             ` J. Bruce Fields
2013-02-13 23:22               ` Eric W. Biederman
2013-02-14  7:12                 ` Stanislav Kinsbursky
2013-02-14  8:42                   ` Eric W. Biederman
2013-02-15 17:00                 ` J. Bruce Fields
2013-02-15 18:47                   ` Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 53/85] sunrpc: Properly decode kuids and kgids in RPC_AUTH_UNIX credentials Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 54/85] nfs: Pass GLOBAL_ROOT_UID and GLOBAL_ROOT_GID to keyring alloc Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 55/85] nfs: Convert struct nfs_fattr to Use kuid_t and kgid_t Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 56/85] nfs: Convert idmap to use kuids and kgids Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 57/85] nfs: Convert nfs2xdr " Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 58/85] nfs: Convert nfs3xdr " Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 59/85] nfs: Convert nfs4xdr " Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 60/85] nfs: kuid and kgid conversions for nfs/inode.c Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 61/85] nfs: Enable building with user namespaces enabled Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 62/85] nfsd: Remove declaration of nonexistent nfs4_acl_permisison Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 63/85] nfsd: idmap use u32 not uid_t as the intermediate type Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 64/85] nfsd: Convert idmap to use kuids and kgids Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 65/85] nfsd: Remove nfsd_luid, nfsd_lgid, nfsd_ruid and nfsd_rgid Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 66/85] nfsd: Convert nfs3xdr to use kuids and kgids Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 67/85] nfsd: Convert nfsxdr " Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 68/85] nfsd: Handle kuids and kgids in the nfs4acl to posix_acl conversion Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 69/85] nfsd: Modify nfsd4_cb_sec to use kuids and kgids Eric W. Biederman
2013-02-13 17:51   ` [PATCH review 70/85] nfsd: Store ex_anon_uid and ex_anon_gid as " Eric W. Biederman
2013-02-13 17:52   ` [PATCH review 71/85] nfsd: Properly compare and initialize " Eric W. Biederman
2013-02-13 17:52   ` [PATCH review 72/85] nfsd: Enable building with user namespaces enabled Eric W. Biederman
2013-02-13 17:52   ` [PATCH review 73/85] cifs: Override unmappable incoming uids and gids Eric W. Biederman
2013-02-13 17:52   ` [PATCH review 74/85] cifs: Use BUILD_BUG_ON to validate uids and gids are the same size Eric W. Biederman
2013-02-13 17:52   ` [PATCH review 75/85] cifs: Pass GLOBAL_ROOT_UID and GLOBAL_ROOT_GID to keyring_alloc Eric W. Biederman
2013-02-13 17:52   ` [PATCH review 76/85] cifs: Use kuids and kgids SID to uid/gid mapping Eric W. Biederman
2013-02-13 17:52   ` [PATCH review 77/85] cifs: Convert from a kuid before printing current_fsuid Eric W. Biederman
2013-02-13 17:52   ` [PATCH review 78/85] cifs: Modify struct cifs_unix_set_info_args to hold a kuid_t and a kgid_t Eric W. Biederman
2013-02-13 17:52   ` [PATCH review 79/85] cifs: Convert struct tcon_link to use a kuid Eric W. Biederman
2013-02-13 17:52   ` [PATCH review 80/85] cifs: Convert struct cifs_fattr to use kuid and kgids Eric W. Biederman
2013-02-13 17:52   ` [PATCH review 81/85] cifs: Convert struct cifsFileInfo to use a kuid Eric W. Biederman
2013-02-13 17:52   ` [PATCH review 82/85] cifs: Modify struct smb_vol to use kuids and kgids Eric W. Biederman
2013-02-13 17:52   ` [PATCH review 83/85] cifs: Convert struct cifs_sb_info " Eric W. Biederman
2013-02-13 17:52   ` [PATCH review 84/85] cifs: Convert struct cifs_ses to use a kuid_t and a kgid_t Eric W. Biederman
2013-02-13 17:52   ` [PATCH review 85/85] cifs: Enable building with user namespaces enabled Eric W. Biederman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).