summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-02-08 07:07:50 -0800
committerEric W. Biederman <ebiederm@xmission.com>2012-05-03 03:29:32 -0700
commit92361636e0153bd0cb22e7dfe3fc6287f6537c66 (patch)
tree8b7d8f91aa528c2bad8ff97c737b2612e414480a
parent5af662030e5db1a5560fd917250d5d688a6be586 (diff)
userns: Store uid and gid types in vfs structures with kuid_t and kgid_t types
The conversion of all of the users is not done yet there are too many to change in one go and leave the code reviewable. For now I change just the header and a few trivial users and rely on CONFIG_UIDGID_STRICT_TYPE_CHECKS not being set to ensure that the code will still compile during the transition. Helper functions i_uid_read, i_uid_write, i_gid_read, i_gid_write are added so that in most cases filesystems can avoid the complexities of multiple user namespaces and can concentrate on moving their raw numeric values into and out of the vfs data structures. Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
-rw-r--r--fs/inode.c6
-rw-r--r--include/linux/fs.h36
2 files changed, 34 insertions, 8 deletions
diff --git a/fs/inode.c b/fs/inode.c
index f0c4ace408e4..deb72f6c2b4f 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -135,8 +135,8 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
inode->i_fop = &empty_fops;
inode->__i_nlink = 1;
inode->i_opflags = 0;
- inode->i_uid = 0;
- inode->i_gid = 0;
+ i_uid_write(inode, 0);
+ i_gid_write(inode, 0);
atomic_set(&inode->i_writecount, 0);
inode->i_size = 0;
inode->i_blocks = 0;
@@ -1732,7 +1732,7 @@ EXPORT_SYMBOL(inode_init_owner);
*/
bool inode_owner_or_capable(const struct inode *inode)
{
- if (current_fsuid() == inode->i_uid)
+ if (uid_eq(current_fsuid(), inode->i_uid))
return true;
if (inode_capable(inode, CAP_FOWNER))
return true;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a6c5efbee0d7..797eb262d9f1 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -402,6 +402,7 @@ struct inodes_stat_t {
#include <linux/atomic.h>
#include <linux/shrinker.h>
#include <linux/migrate_mode.h>
+#include <linux/uidgid.h>
#include <asm/byteorder.h>
@@ -469,8 +470,8 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
struct iattr {
unsigned int ia_valid;
umode_t ia_mode;
- uid_t ia_uid;
- gid_t ia_gid;
+ kuid_t ia_uid;
+ kgid_t ia_gid;
loff_t ia_size;
struct timespec ia_atime;
struct timespec ia_mtime;
@@ -761,8 +762,8 @@ struct posix_acl;
struct inode {
umode_t i_mode;
unsigned short i_opflags;
- uid_t i_uid;
- gid_t i_gid;
+ kuid_t i_uid;
+ kgid_t i_gid;
unsigned int i_flags;
#ifdef CONFIG_FS_POSIX_ACL
@@ -927,6 +928,31 @@ static inline void i_size_write(struct inode *inode, loff_t i_size)
#endif
}
+/* Helper functions so that in most cases filesystems will
+ * not need to deal directly with kuid_t and kgid_t and can
+ * instead deal with the raw numeric values that are stored
+ * in the filesystem.
+ */
+static inline uid_t i_uid_read(const struct inode *inode)
+{
+ return from_kuid(&init_user_ns, inode->i_uid);
+}
+
+static inline gid_t i_gid_read(const struct inode *inode)
+{
+ return from_kgid(&init_user_ns, inode->i_gid);
+}
+
+static inline void i_uid_write(struct inode *inode, uid_t uid)
+{
+ inode->i_uid = make_kuid(&init_user_ns, uid);
+}
+
+static inline void i_gid_write(struct inode *inode, gid_t gid)
+{
+ inode->i_gid = make_kgid(&init_user_ns, gid);
+}
+
static inline unsigned iminor(const struct inode *inode)
{
return MINOR(inode->i_rdev);
@@ -943,7 +969,7 @@ struct fown_struct {
rwlock_t lock; /* protects pid, uid, euid fields */
struct pid *pid; /* pid or -pgrp where SIGIO should be sent */
enum pid_type pid_type; /* Kind of process group SIGIO should be sent to */
- uid_t uid, euid; /* uid/euid of process setting the owner */
+ kuid_t uid, euid; /* uid/euid of process setting the owner */
int signum; /* posix.1b rt signal to be delivered on IO */
};