aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-23 20:42:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-23 20:42:39 -0400
commit644473e9c60c1ff4f6351fed637a6e5551e3dce7 (patch)
tree10316518bedc735a2c6552886658d69dfd9f1eb0 /include
parentfb827ec68446c83e9e8754fa9b55aed27ecc4661 (diff)
parent4b06a81f1daee668fbd6de85557bfb36dd36078f (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull user namespace enhancements from Eric Biederman: "This is a course correction for the user namespace, so that we can reach an inexpensive, maintainable, and reasonably complete implementation. Highlights: - Config guards make it impossible to enable the user namespace and code that has not been converted to be user namespace safe. - Use of the new kuid_t type ensures the if you somehow get past the config guards the kernel will encounter type errors if you enable user namespaces and attempt to compile in code whose permission checks have not been updated to be user namespace safe. - All uids from child user namespaces are mapped into the initial user namespace before they are processed. Removing the need to add an additional check to see if the user namespace of the compared uids remains the same. - With the user namespaces compiled out the performance is as good or better than it is today. - For most operations absolutely nothing changes performance or operationally with the user namespace enabled. - The worst case performance I could come up with was timing 1 billion cache cold stat operations with the user namespace code enabled. This went from 156s to 164s on my laptop (or 156ns to 164ns per stat operation). - (uid_t)-1 and (gid_t)-1 are reserved as an internal error value. Most uid/gid setting system calls treat these value specially anyway so attempting to use -1 as a uid would likely cause entertaining failures in userspace. - If setuid is called with a uid that can not be mapped setuid fails. I have looked at sendmail, login, ssh and every other program I could think of that would call setuid and they all check for and handle the case where setuid fails. - If stat or a similar system call is called from a context in which we can not map a uid we lie and return overflowuid. The LFS experience suggests not lying and returning an error code might be better, but the historical precedent with uids is different and I can not think of anything that would break by lying about a uid we can't map. - Capabilities are localized to the current user namespace making it safe to give the initial user in a user namespace all capabilities. My git tree covers all of the modifications needed to convert the core kernel and enough changes to make a system bootable to runlevel 1." Fix up trivial conflicts due to nearby independent changes in fs/stat.c * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: (46 commits) userns: Silence silly gcc warning. cred: use correct cred accessor with regards to rcu read lock userns: Convert the move_pages, and migrate_pages permission checks to use uid_eq userns: Convert cgroup permission checks to use uid_eq userns: Convert tmpfs to use kuid and kgid where appropriate userns: Convert sysfs to use kgid/kuid where appropriate userns: Convert sysctl permission checks to use kuid and kgids. userns: Convert proc to use kuid/kgid where appropriate userns: Convert ext4 to user kuid/kgid where appropriate userns: Convert ext3 to use kuid/kgid where appropriate userns: Convert ext2 to use kuid/kgid where appropriate. userns: Convert devpts to use kuid/kgid where appropriate userns: Convert binary formats to use kuid/kgid where appropriate userns: Add negative depends on entries to avoid building code that is userns unsafe userns: signal remove unnecessary map_cred_ns userns: Teach inode_capable to understand inodes whose uids map to other namespaces. userns: Fail exec for suid and sgid binaries with ids outside our user namespace. userns: Convert stat to return values mapped from kuids and kgids userns: Convert user specfied uids and gids in chown into kuids and kgid userns: Use uid_eq gid_eq helpers when comparing kuids and kgids in the vfs ...
Diffstat (limited to 'include')
-rw-r--r--include/linux/capability.h2
-rw-r--r--include/linux/cred.h33
-rw-r--r--include/linux/fs.h42
-rw-r--r--include/linux/pid_namespace.h2
-rw-r--r--include/linux/proc_fs.h4
-rw-r--r--include/linux/quotaops.h4
-rw-r--r--include/linux/sched.h9
-rw-r--r--include/linux/shmem_fs.h4
-rw-r--r--include/linux/stat.h5
-rw-r--r--include/linux/uidgid.h200
-rw-r--r--include/linux/user_namespace.h39
-rw-r--r--include/trace/events/ext3.h4
-rw-r--r--include/trace/events/ext4.h4
13 files changed, 288 insertions, 64 deletions
diff --git a/include/linux/capability.h b/include/linux/capability.h
index c398cff3dab7..68d56effc328 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -377,6 +377,7 @@ struct cpu_vfs_cap_data {
377 377
378#ifdef __KERNEL__ 378#ifdef __KERNEL__
379 379
380struct inode;
380struct dentry; 381struct dentry;
381struct user_namespace; 382struct user_namespace;
382 383
@@ -551,6 +552,7 @@ extern bool has_ns_capability_noaudit(struct task_struct *t,
551extern bool capable(int cap); 552extern bool capable(int cap);
552extern bool ns_capable(struct user_namespace *ns, int cap); 553extern bool ns_capable(struct user_namespace *ns, int cap);
553extern bool nsown_capable(int cap); 554extern bool nsown_capable(int cap);
555extern bool inode_capable(const struct inode *inode, int cap);
554 556
555/* audit system wants to get cap info from files as well */ 557/* audit system wants to get cap info from files as well */
556extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps); 558extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps);
diff --git a/include/linux/cred.h b/include/linux/cred.h
index adadf71a7327..917dc5aeb1d4 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -17,6 +17,7 @@
17#include <linux/key.h> 17#include <linux/key.h>
18#include <linux/selinux.h> 18#include <linux/selinux.h>
19#include <linux/atomic.h> 19#include <linux/atomic.h>
20#include <linux/uidgid.h>
20 21
21struct user_struct; 22struct user_struct;
22struct cred; 23struct cred;
@@ -26,14 +27,14 @@ struct inode;
26 * COW Supplementary groups list 27 * COW Supplementary groups list
27 */ 28 */
28#define NGROUPS_SMALL 32 29#define NGROUPS_SMALL 32
29#define NGROUPS_PER_BLOCK ((unsigned int)(PAGE_SIZE / sizeof(gid_t))) 30#define NGROUPS_PER_BLOCK ((unsigned int)(PAGE_SIZE / sizeof(kgid_t)))
30 31
31struct group_info { 32struct group_info {
32 atomic_t usage; 33 atomic_t usage;
33 int ngroups; 34 int ngroups;
34 int nblocks; 35 int nblocks;
35 gid_t small_block[NGROUPS_SMALL]; 36 kgid_t small_block[NGROUPS_SMALL];
36 gid_t *blocks[0]; 37 kgid_t *blocks[0];
37}; 38};
38 39
39/** 40/**
@@ -66,14 +67,14 @@ extern struct group_info init_groups;
66extern void groups_free(struct group_info *); 67extern void groups_free(struct group_info *);
67extern int set_current_groups(struct group_info *); 68extern int set_current_groups(struct group_info *);
68extern int set_groups(struct cred *, struct group_info *); 69extern int set_groups(struct cred *, struct group_info *);
69extern int groups_search(const struct group_info *, gid_t); 70extern int groups_search(const struct group_info *, kgid_t);
70 71
71/* access the groups "array" with this macro */ 72/* access the groups "array" with this macro */
72#define GROUP_AT(gi, i) \ 73#define GROUP_AT(gi, i) \
73 ((gi)->blocks[(i) / NGROUPS_PER_BLOCK][(i) % NGROUPS_PER_BLOCK]) 74 ((gi)->blocks[(i) / NGROUPS_PER_BLOCK][(i) % NGROUPS_PER_BLOCK])
74 75
75extern int in_group_p(gid_t); 76extern int in_group_p(kgid_t);
76extern int in_egroup_p(gid_t); 77extern int in_egroup_p(kgid_t);
77 78
78/* 79/*
79 * The common credentials for a thread group 80 * The common credentials for a thread group
@@ -122,14 +123,14 @@ struct cred {
122#define CRED_MAGIC 0x43736564 123#define CRED_MAGIC 0x43736564
123#define CRED_MAGIC_DEAD 0x44656144 124#define CRED_MAGIC_DEAD 0x44656144
124#endif 125#endif
125 uid_t uid; /* real UID of the task */ 126 kuid_t uid; /* real UID of the task */
126 gid_t gid; /* real GID of the task */ 127 kgid_t gid; /* real GID of the task */
127 uid_t suid; /* saved UID of the task */ 128 kuid_t suid; /* saved UID of the task */
128 gid_t sgid; /* saved GID of the task */ 129 kgid_t sgid; /* saved GID of the task */
129 uid_t euid; /* effective UID of the task */ 130 kuid_t euid; /* effective UID of the task */
130 gid_t egid; /* effective GID of the task */ 131 kgid_t egid; /* effective GID of the task */
131 uid_t fsuid; /* UID for VFS ops */ 132 kuid_t fsuid; /* UID for VFS ops */
132 gid_t fsgid; /* GID for VFS ops */ 133 kgid_t fsgid; /* GID for VFS ops */
133 unsigned securebits; /* SUID-less security management */ 134 unsigned securebits; /* SUID-less security management */
134 kernel_cap_t cap_inheritable; /* caps our children can inherit */ 135 kernel_cap_t cap_inheritable; /* caps our children can inherit */
135 kernel_cap_t cap_permitted; /* caps we're permitted */ 136 kernel_cap_t cap_permitted; /* caps we're permitted */
@@ -146,7 +147,7 @@ struct cred {
146 void *security; /* subjective LSM security */ 147 void *security; /* subjective LSM security */
147#endif 148#endif
148 struct user_struct *user; /* real user ID subscription */ 149 struct user_struct *user; /* real user ID subscription */
149 struct user_namespace *user_ns; /* cached user->user_ns */ 150 struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */
150 struct group_info *group_info; /* supplementary groups for euid/fsgid */ 151 struct group_info *group_info; /* supplementary groups for euid/fsgid */
151 struct rcu_head rcu; /* RCU deletion hook */ 152 struct rcu_head rcu; /* RCU deletion hook */
152}; 153};
@@ -357,11 +358,11 @@ static inline void put_cred(const struct cred *_cred)
357#define current_user() (current_cred_xxx(user)) 358#define current_user() (current_cred_xxx(user))
358#define current_security() (current_cred_xxx(security)) 359#define current_security() (current_cred_xxx(security))
359 360
361extern struct user_namespace init_user_ns;
360#ifdef CONFIG_USER_NS 362#ifdef CONFIG_USER_NS
361#define current_user_ns() (current_cred_xxx(user_ns)) 363#define current_user_ns() (current_cred_xxx(user_ns))
362#define task_user_ns(task) (task_cred_xxx((task), user_ns)) 364#define task_user_ns(task) (task_cred_xxx((task), user_ns))
363#else 365#else
364extern struct user_namespace init_user_ns;
365#define current_user_ns() (&init_user_ns) 366#define current_user_ns() (&init_user_ns)
366#define task_user_ns(task) (&init_user_ns) 367#define task_user_ns(task) (&init_user_ns)
367#endif 368#endif
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 25c40b9f848a..c0e53372b082 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -402,6 +402,7 @@ struct inodes_stat_t {
402#include <linux/atomic.h> 402#include <linux/atomic.h>
403#include <linux/shrinker.h> 403#include <linux/shrinker.h>
404#include <linux/migrate_mode.h> 404#include <linux/migrate_mode.h>
405#include <linux/uidgid.h>
405 406
406#include <asm/byteorder.h> 407#include <asm/byteorder.h>
407 408
@@ -469,8 +470,8 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
469struct iattr { 470struct iattr {
470 unsigned int ia_valid; 471 unsigned int ia_valid;
471 umode_t ia_mode; 472 umode_t ia_mode;
472 uid_t ia_uid; 473 kuid_t ia_uid;
473 gid_t ia_gid; 474 kgid_t ia_gid;
474 loff_t ia_size; 475 loff_t ia_size;
475 struct timespec ia_atime; 476 struct timespec ia_atime;
476 struct timespec ia_mtime; 477 struct timespec ia_mtime;
@@ -761,8 +762,8 @@ struct posix_acl;
761struct inode { 762struct inode {
762 umode_t i_mode; 763 umode_t i_mode;
763 unsigned short i_opflags; 764 unsigned short i_opflags;
764 uid_t i_uid; 765 kuid_t i_uid;
765 gid_t i_gid; 766 kgid_t i_gid;
766 unsigned int i_flags; 767 unsigned int i_flags;
767 768
768#ifdef CONFIG_FS_POSIX_ACL 769#ifdef CONFIG_FS_POSIX_ACL
@@ -927,6 +928,31 @@ static inline void i_size_write(struct inode *inode, loff_t i_size)
927#endif 928#endif
928} 929}
929 930
931/* Helper functions so that in most cases filesystems will
932 * not need to deal directly with kuid_t and kgid_t and can
933 * instead deal with the raw numeric values that are stored
934 * in the filesystem.
935 */
936static inline uid_t i_uid_read(const struct inode *inode)
937{
938 return from_kuid(&init_user_ns, inode->i_uid);
939}
940
941static inline gid_t i_gid_read(const struct inode *inode)
942{
943 return from_kgid(&init_user_ns, inode->i_gid);
944}
945
946static inline void i_uid_write(struct inode *inode, uid_t uid)
947{
948 inode->i_uid = make_kuid(&init_user_ns, uid);
949}
950
951static inline void i_gid_write(struct inode *inode, gid_t gid)
952{
953 inode->i_gid = make_kgid(&init_user_ns, gid);
954}
955
930static inline unsigned iminor(const struct inode *inode) 956static inline unsigned iminor(const struct inode *inode)
931{ 957{
932 return MINOR(inode->i_rdev); 958 return MINOR(inode->i_rdev);
@@ -943,7 +969,7 @@ struct fown_struct {
943 rwlock_t lock; /* protects pid, uid, euid fields */ 969 rwlock_t lock; /* protects pid, uid, euid fields */
944 struct pid *pid; /* pid or -pgrp where SIGIO should be sent */ 970 struct pid *pid; /* pid or -pgrp where SIGIO should be sent */
945 enum pid_type pid_type; /* Kind of process group SIGIO should be sent to */ 971 enum pid_type pid_type; /* Kind of process group SIGIO should be sent to */
946 uid_t uid, euid; /* uid/euid of process setting the owner */ 972 kuid_t uid, euid; /* uid/euid of process setting the owner */
947 int signum; /* posix.1b rt signal to be delivered on IO */ 973 int signum; /* posix.1b rt signal to be delivered on IO */
948}; 974};
949 975
@@ -1527,12 +1553,6 @@ enum {
1527#define vfs_check_frozen(sb, level) \ 1553#define vfs_check_frozen(sb, level) \
1528 wait_event((sb)->s_wait_unfrozen, ((sb)->s_frozen < (level))) 1554 wait_event((sb)->s_wait_unfrozen, ((sb)->s_frozen < (level)))
1529 1555
1530/*
1531 * until VFS tracks user namespaces for inodes, just make all files
1532 * belong to init_user_ns
1533 */
1534extern struct user_namespace init_user_ns;
1535#define inode_userns(inode) (&init_user_ns)
1536extern bool inode_owner_or_capable(const struct inode *inode); 1556extern bool inode_owner_or_capable(const struct inode *inode);
1537 1557
1538/* not quite ready to be deprecated, but... */ 1558/* not quite ready to be deprecated, but... */
diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h
index b067bd8c49d0..00474b047145 100644
--- a/include/linux/pid_namespace.h
+++ b/include/linux/pid_namespace.h
@@ -31,7 +31,7 @@ struct pid_namespace {
31#ifdef CONFIG_BSD_PROCESS_ACCT 31#ifdef CONFIG_BSD_PROCESS_ACCT
32 struct bsd_acct_struct *bacct; 32 struct bsd_acct_struct *bacct;
33#endif 33#endif
34 gid_t pid_gid; 34 kgid_t pid_gid;
35 int hide_pid; 35 int hide_pid;
36 int reboot; /* group exit code if this pidns was rebooted */ 36 int reboot; /* group exit code if this pidns was rebooted */
37}; 37};
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 85c507306239..3fd2e871ff1b 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -52,8 +52,8 @@ struct proc_dir_entry {
52 unsigned int low_ino; 52 unsigned int low_ino;
53 umode_t mode; 53 umode_t mode;
54 nlink_t nlink; 54 nlink_t nlink;
55 uid_t uid; 55 kuid_t uid;
56 gid_t gid; 56 kgid_t gid;
57 loff_t size; 57 loff_t size;
58 const struct inode_operations *proc_iops; 58 const struct inode_operations *proc_iops;
59 /* 59 /*
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index d93f95e6177c..17b977304a09 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -22,8 +22,8 @@ static inline struct quota_info *sb_dqopt(struct super_block *sb)
22static inline bool is_quota_modification(struct inode *inode, struct iattr *ia) 22static inline bool is_quota_modification(struct inode *inode, struct iattr *ia)
23{ 23{
24 return (ia->ia_valid & ATTR_SIZE && ia->ia_size != inode->i_size) || 24 return (ia->ia_valid & ATTR_SIZE && ia->ia_size != inode->i_size) ||
25 (ia->ia_valid & ATTR_UID && ia->ia_uid != inode->i_uid) || 25 (ia->ia_valid & ATTR_UID && !uid_eq(ia->ia_uid, inode->i_uid)) ||
26 (ia->ia_valid & ATTR_GID && ia->ia_gid != inode->i_gid); 26 (ia->ia_valid & ATTR_GID && !gid_eq(ia->ia_gid, inode->i_gid));
27} 27}
28 28
29#if defined(CONFIG_QUOTA) 29#if defined(CONFIG_QUOTA)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 28fa9d02fd59..5ea8baea9387 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -90,6 +90,7 @@ struct sched_param {
90#include <linux/latencytop.h> 90#include <linux/latencytop.h>
91#include <linux/cred.h> 91#include <linux/cred.h>
92#include <linux/llist.h> 92#include <linux/llist.h>
93#include <linux/uidgid.h>
93 94
94#include <asm/processor.h> 95#include <asm/processor.h>
95 96
@@ -728,8 +729,7 @@ struct user_struct {
728 729
729 /* Hash table maintenance information */ 730 /* Hash table maintenance information */
730 struct hlist_node uidhash_node; 731 struct hlist_node uidhash_node;
731 uid_t uid; 732 kuid_t uid;
732 struct user_namespace *user_ns;
733 733
734#ifdef CONFIG_PERF_EVENTS 734#ifdef CONFIG_PERF_EVENTS
735 atomic_long_t locked_vm; 735 atomic_long_t locked_vm;
@@ -738,7 +738,7 @@ struct user_struct {
738 738
739extern int uids_sysfs_init(void); 739extern int uids_sysfs_init(void);
740 740
741extern struct user_struct *find_user(uid_t); 741extern struct user_struct *find_user(kuid_t);
742 742
743extern struct user_struct root_user; 743extern struct user_struct root_user;
744#define INIT_USER (&root_user) 744#define INIT_USER (&root_user)
@@ -2142,14 +2142,13 @@ extern struct task_struct *find_task_by_pid_ns(pid_t nr,
2142extern void __set_special_pids(struct pid *pid); 2142extern void __set_special_pids(struct pid *pid);
2143 2143
2144/* per-UID process charging. */ 2144/* per-UID process charging. */
2145extern struct user_struct * alloc_uid(struct user_namespace *, uid_t); 2145extern struct user_struct * alloc_uid(kuid_t);
2146static inline struct user_struct *get_uid(struct user_struct *u) 2146static inline struct user_struct *get_uid(struct user_struct *u)
2147{ 2147{
2148 atomic_inc(&u->__count); 2148 atomic_inc(&u->__count);
2149 return u; 2149 return u;
2150} 2150}
2151extern void free_uid(struct user_struct *); 2151extern void free_uid(struct user_struct *);
2152extern void release_uids(struct user_namespace *ns);
2153 2152
2154#include <asm/current.h> 2153#include <asm/current.h>
2155 2154
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index 79ab2555b3b0..bef2cf00b3be 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -28,8 +28,8 @@ struct shmem_sb_info {
28 unsigned long max_inodes; /* How many inodes are allowed */ 28 unsigned long max_inodes; /* How many inodes are allowed */
29 unsigned long free_inodes; /* How many are left for allocation */ 29 unsigned long free_inodes; /* How many are left for allocation */
30 spinlock_t stat_lock; /* Serialize shmem_sb_info changes */ 30 spinlock_t stat_lock; /* Serialize shmem_sb_info changes */
31 uid_t uid; /* Mount uid for root directory */ 31 kuid_t uid; /* Mount uid for root directory */
32 gid_t gid; /* Mount gid for root directory */ 32 kgid_t gid; /* Mount gid for root directory */
33 umode_t mode; /* Mount mode for root directory */ 33 umode_t mode; /* Mount mode for root directory */
34 struct mempolicy *mpol; /* default memory policy for mappings */ 34 struct mempolicy *mpol; /* default memory policy for mappings */
35}; 35};
diff --git a/include/linux/stat.h b/include/linux/stat.h
index 611c398dab72..46132409a3f7 100644
--- a/include/linux/stat.h
+++ b/include/linux/stat.h
@@ -58,14 +58,15 @@
58 58
59#include <linux/types.h> 59#include <linux/types.h>
60#include <linux/time.h> 60#include <linux/time.h>
61#include <linux/uidgid.h>
61 62
62struct kstat { 63struct kstat {
63 u64 ino; 64 u64 ino;
64 dev_t dev; 65 dev_t dev;
65 umode_t mode; 66 umode_t mode;
66 unsigned int nlink; 67 unsigned int nlink;
67 uid_t uid; 68 kuid_t uid;
68 gid_t gid; 69 kgid_t gid;
69 dev_t rdev; 70 dev_t rdev;
70 loff_t size; 71 loff_t size;
71 struct timespec atime; 72 struct timespec atime;
diff --git a/include/linux/uidgid.h b/include/linux/uidgid.h
new file mode 100644
index 000000000000..8e522cbcef29
--- /dev/null
+++ b/include/linux/uidgid.h
@@ -0,0 +1,200 @@
1#ifndef _LINUX_UIDGID_H
2#define _LINUX_UIDGID_H
3
4/*
5 * A set of types for the internal kernel types representing uids and gids.
6 *
7 * The types defined in this header allow distinguishing which uids and gids in
8 * the kernel are values used by userspace and which uid and gid values are
9 * the internal kernel values. With the addition of user namespaces the values
10 * can be different. Using the type system makes it possible for the compiler
11 * to detect when we overlook these differences.
12 *
13 */
14#include <linux/types.h>
15#include <linux/highuid.h>
16
17struct user_namespace;
18extern struct user_namespace init_user_ns;
19
20#ifdef CONFIG_UIDGID_STRICT_TYPE_CHECKS
21
22typedef struct {
23 uid_t val;
24} kuid_t;
25
26
27typedef struct {
28 gid_t val;
29} kgid_t;
30
31#define KUIDT_INIT(value) (kuid_t){ value }
32#define KGIDT_INIT(value) (kgid_t){ value }
33
34static inline uid_t __kuid_val(kuid_t uid)
35{
36 return uid.val;
37}
38
39static inline gid_t __kgid_val(kgid_t gid)
40{
41 return gid.val;
42}
43
44#else
45
46typedef uid_t kuid_t;
47typedef gid_t kgid_t;
48
49static inline uid_t __kuid_val(kuid_t uid)
50{
51 return uid;
52}
53
54static inline gid_t __kgid_val(kgid_t gid)
55{
56 return gid;
57}
58
59#define KUIDT_INIT(value) ((kuid_t) value )
60#define KGIDT_INIT(value) ((kgid_t) value )
61
62#endif
63
64#define GLOBAL_ROOT_UID KUIDT_INIT(0)
65#define GLOBAL_ROOT_GID KGIDT_INIT(0)
66
67#define INVALID_UID KUIDT_INIT(-1)
68#define INVALID_GID KGIDT_INIT(-1)
69
70static inline bool uid_eq(kuid_t left, kuid_t right)
71{
72 return __kuid_val(left) == __kuid_val(right);
73}
74
75static inline bool gid_eq(kgid_t left, kgid_t right)
76{
77 return __kgid_val(left) == __kgid_val(right);
78}
79
80static inline bool uid_gt(kuid_t left, kuid_t right)
81{
82 return __kuid_val(left) > __kuid_val(right);
83}
84
85static inline bool gid_gt(kgid_t left, kgid_t right)
86{
87 return __kgid_val(left) > __kgid_val(right);
88}
89
90static inline bool uid_gte(kuid_t left, kuid_t right)
91{
92 return __kuid_val(left) >= __kuid_val(right);
93}
94
95static inline bool gid_gte(kgid_t left, kgid_t right)
96{
97 return __kgid_val(left) >= __kgid_val(right);
98}
99
100static inline bool uid_lt(kuid_t left, kuid_t right)
101{
102 return __kuid_val(left) < __kuid_val(right);
103}
104
105static inline bool gid_lt(kgid_t left, kgid_t right)
106{
107 return __kgid_val(left) < __kgid_val(right);
108}
109
110static inline bool uid_lte(kuid_t left, kuid_t right)
111{
112 return __kuid_val(left) <= __kuid_val(right);
113}
114
115static inline bool gid_lte(kgid_t left, kgid_t right)
116{
117 return __kgid_val(left) <= __kgid_val(right);
118}
119
120static inline bool uid_valid(kuid_t uid)
121{
122 return !uid_eq(uid, INVALID_UID);
123}
124
125static inline bool gid_valid(kgid_t gid)
126{
127 return !gid_eq(gid, INVALID_GID);
128}
129
130#ifdef CONFIG_USER_NS
131
132extern kuid_t make_kuid(struct user_namespace *from, uid_t uid);
133extern kgid_t make_kgid(struct user_namespace *from, gid_t gid);
134
135extern uid_t from_kuid(struct user_namespace *to, kuid_t uid);
136extern gid_t from_kgid(struct user_namespace *to, kgid_t gid);
137extern uid_t from_kuid_munged(struct user_namespace *to, kuid_t uid);
138extern gid_t from_kgid_munged(struct user_namespace *to, kgid_t gid);
139
140static inline bool kuid_has_mapping(struct user_namespace *ns, kuid_t uid)
141{
142 return from_kuid(ns, uid) != (uid_t) -1;
143}
144
145static inline bool kgid_has_mapping(struct user_namespace *ns, kgid_t gid)
146{
147 return from_kgid(ns, gid) != (gid_t) -1;
148}
149
150#else
151
152static inline kuid_t make_kuid(struct user_namespace *from, uid_t uid)
153{
154 return KUIDT_INIT(uid);
155}
156
157static inline kgid_t make_kgid(struct user_namespace *from, gid_t gid)
158{
159 return KGIDT_INIT(gid);
160}
161
162static inline uid_t from_kuid(struct user_namespace *to, kuid_t kuid)
163{
164 return __kuid_val(kuid);
165}
166
167static inline gid_t from_kgid(struct user_namespace *to, kgid_t kgid)
168{
169 return __kgid_val(kgid);
170}
171
172static inline uid_t from_kuid_munged(struct user_namespace *to, kuid_t kuid)
173{
174 uid_t uid = from_kuid(to, kuid);
175 if (uid == (uid_t)-1)
176 uid = overflowuid;
177 return uid;
178}
179
180static inline gid_t from_kgid_munged(struct user_namespace *to, kgid_t kgid)
181{
182 gid_t gid = from_kgid(to, kgid);
183 if (gid == (gid_t)-1)
184 gid = overflowgid;
185 return gid;
186}
187
188static inline bool kuid_has_mapping(struct user_namespace *ns, kuid_t uid)
189{
190 return true;
191}
192
193static inline bool kgid_has_mapping(struct user_namespace *ns, kgid_t gid)
194{
195 return true;
196}
197
198#endif /* CONFIG_USER_NS */
199
200#endif /* _LINUX_UIDGID_H */
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index faf467944baf..4e72922e5a75 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -6,14 +6,24 @@
6#include <linux/sched.h> 6#include <linux/sched.h>
7#include <linux/err.h> 7#include <linux/err.h>
8 8
9#define UIDHASH_BITS (CONFIG_BASE_SMALL ? 3 : 7) 9#define UID_GID_MAP_MAX_EXTENTS 5
10#define UIDHASH_SZ (1 << UIDHASH_BITS) 10
11struct uid_gid_map { /* 64 bytes -- 1 cache line */
12 u32 nr_extents;
13 struct uid_gid_extent {
14 u32 first;
15 u32 lower_first;
16 u32 count;
17 } extent[UID_GID_MAP_MAX_EXTENTS];
18};
11 19
12struct user_namespace { 20struct user_namespace {
21 struct uid_gid_map uid_map;
22 struct uid_gid_map gid_map;
13 struct kref kref; 23 struct kref kref;
14 struct hlist_head uidhash_table[UIDHASH_SZ]; 24 struct user_namespace *parent;
15 struct user_struct *creator; 25 kuid_t owner;
16 struct work_struct destroyer; 26 kgid_t group;
17}; 27};
18 28
19extern struct user_namespace init_user_ns; 29extern struct user_namespace init_user_ns;
@@ -36,9 +46,11 @@ static inline void put_user_ns(struct user_namespace *ns)
36 kref_put(&ns->kref, free_user_ns); 46 kref_put(&ns->kref, free_user_ns);
37} 47}
38 48
39uid_t user_ns_map_uid(struct user_namespace *to, const struct cred *cred, uid_t uid); 49struct seq_operations;
40gid_t user_ns_map_gid(struct user_namespace *to, const struct cred *cred, gid_t gid); 50extern struct seq_operations proc_uid_seq_operations;
41 51extern struct seq_operations proc_gid_seq_operations;
52extern ssize_t proc_uid_map_write(struct file *, const char __user *, size_t, loff_t *);
53extern ssize_t proc_gid_map_write(struct file *, const char __user *, size_t, loff_t *);
42#else 54#else
43 55
44static inline struct user_namespace *get_user_ns(struct user_namespace *ns) 56static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
@@ -55,17 +67,6 @@ static inline void put_user_ns(struct user_namespace *ns)
55{ 67{
56} 68}
57 69
58static inline uid_t user_ns_map_uid(struct user_namespace *to,
59 const struct cred *cred, uid_t uid)
60{
61 return uid;
62}
63static inline gid_t user_ns_map_gid(struct user_namespace *to,
64 const struct cred *cred, gid_t gid)
65{
66 return gid;
67}
68
69#endif 70#endif
70 71
71#endif /* _LINUX_USER_H */ 72#endif /* _LINUX_USER_H */
diff --git a/include/trace/events/ext3.h b/include/trace/events/ext3.h
index 7b53c0573dc9..15d11a39be47 100644
--- a/include/trace/events/ext3.h
+++ b/include/trace/events/ext3.h
@@ -24,8 +24,8 @@ TRACE_EVENT(ext3_free_inode,
24 __entry->dev = inode->i_sb->s_dev; 24 __entry->dev = inode->i_sb->s_dev;
25 __entry->ino = inode->i_ino; 25 __entry->ino = inode->i_ino;
26 __entry->mode = inode->i_mode; 26 __entry->mode = inode->i_mode;
27 __entry->uid = inode->i_uid; 27 __entry->uid = i_uid_read(inode);
28 __entry->gid = inode->i_gid; 28 __entry->gid = i_gid_read(inode);
29 __entry->blocks = inode->i_blocks; 29 __entry->blocks = inode->i_blocks;
30 ), 30 ),
31 31
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index 319538bf17d2..69d8a69ea831 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -36,8 +36,8 @@ TRACE_EVENT(ext4_free_inode,
36 __entry->dev = inode->i_sb->s_dev; 36 __entry->dev = inode->i_sb->s_dev;
37 __entry->ino = inode->i_ino; 37 __entry->ino = inode->i_ino;
38 __entry->mode = inode->i_mode; 38 __entry->mode = inode->i_mode;
39 __entry->uid = inode->i_uid; 39 __entry->uid = i_uid_read(inode);
40 __entry->gid = inode->i_gid; 40 __entry->gid = i_gid_read(inode);
41 __entry->blocks = inode->i_blocks; 41 __entry->blocks = inode->i_blocks;
42 ), 42 ),
43 43