diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-02 22:11:09 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-02 22:11:09 +0400 |
commit | 437589a74b6a590d175f86cf9f7b2efcee7765e7 (patch) | |
tree | 37bf8635b1356d80ef002b00e84f3faf3d555a63 /include/linux | |
parent | 68d47a137c3bef754923bccf73fb639c9b0bbd5e (diff) | |
parent | 72235465864d84cedb2d9f26f8e1de824ee20339 (diff) | |
download | linux-437589a74b6a590d175f86cf9f7b2efcee7765e7.tar.xz |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull user namespace changes from Eric Biederman:
"This is a mostly modest set of changes to enable basic user namespace
support. This allows the code to code to compile with user namespaces
enabled and removes the assumption there is only the initial user
namespace. Everything is converted except for the most complex of the
filesystems: autofs4, 9p, afs, ceph, cifs, coda, fuse, gfs2, ncpfs,
nfs, ocfs2 and xfs as those patches need a bit more review.
The strategy is to push kuid_t and kgid_t values are far down into
subsystems and filesystems as reasonable. Leaving the make_kuid and
from_kuid operations to happen at the edge of userspace, as the values
come off the disk, and as the values come in from the network.
Letting compile type incompatible compile errors (present when user
namespaces are enabled) guide me to find the issues.
The most tricky areas have been the places where we had an implicit
union of uid and gid values and were storing them in an unsigned int.
Those places were converted into explicit unions. I made certain to
handle those places with simple trivial patches.
Out of that work I discovered we have generic interfaces for storing
quota by projid. I had never heard of the project identifiers before.
Adding full user namespace support for project identifiers accounts
for most of the code size growth in my git tree.
Ultimately there will be work to relax privlige checks from
"capable(FOO)" to "ns_capable(user_ns, FOO)" where it is safe allowing
root in a user names to do those things that today we only forbid to
non-root users because it will confuse suid root applications.
While I was pushing kuid_t and kgid_t changes deep into the audit code
I made a few other cleanups. I capitalized on the fact we process
netlink messages in the context of the message sender. I removed
usage of NETLINK_CRED, and started directly using current->tty.
Some of these patches have also made it into maintainer trees, with no
problems from identical code from different trees showing up in
linux-next.
After reading through all of this code I feel like I might be able to
win a game of kernel trivial pursuit."
Fix up some fairly trivial conflicts in netfilter uid/git logging code.
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: (107 commits)
userns: Convert the ufs filesystem to use kuid/kgid where appropriate
userns: Convert the udf filesystem to use kuid/kgid where appropriate
userns: Convert ubifs to use kuid/kgid
userns: Convert squashfs to use kuid/kgid where appropriate
userns: Convert reiserfs to use kuid and kgid where appropriate
userns: Convert jfs to use kuid/kgid where appropriate
userns: Convert jffs2 to use kuid and kgid where appropriate
userns: Convert hpfs to use kuid and kgid where appropriate
userns: Convert btrfs to use kuid/kgid where appropriate
userns: Convert bfs to use kuid/kgid where appropriate
userns: Convert affs to use kuid/kgid wherwe appropriate
userns: On alpha modify linux_to_osf_stat to use convert from kuids and kgids
userns: On ia64 deal with current_uid and current_gid being kuid and kgid
userns: On ppc convert current_uid from a kuid before printing.
userns: Convert s390 getting uid and gid system calls to use kuid and kgid
userns: Convert s390 hypfs to use kuid and kgid where appropriate
userns: Convert binder ipc to use kuids
userns: Teach security_path_chown to take kuids and kgids
userns: Add user namespace support to IMA
userns: Convert EVM to deal with kuids and kgids in it's hmac computation
...
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/audit.h | 12 | ||||
-rw-r--r-- | include/linux/inet_diag.h | 1 | ||||
-rw-r--r-- | include/linux/init_task.h | 2 | ||||
-rw-r--r-- | include/linux/ipc.h | 9 | ||||
-rw-r--r-- | include/linux/key.h | 9 | ||||
-rw-r--r-- | include/linux/loop.h | 2 | ||||
-rw-r--r-- | include/linux/netlink.h | 1 | ||||
-rw-r--r-- | include/linux/posix_acl.h | 8 | ||||
-rw-r--r-- | include/linux/posix_acl_xattr.h | 18 | ||||
-rw-r--r-- | include/linux/projid.h | 104 | ||||
-rw-r--r-- | include/linux/quota.h | 136 | ||||
-rw-r--r-- | include/linux/quotaops.h | 6 | ||||
-rw-r--r-- | include/linux/sched.h | 2 | ||||
-rw-r--r-- | include/linux/security.h | 6 | ||||
-rw-r--r-- | include/linux/seq_file.h | 14 | ||||
-rw-r--r-- | include/linux/tsacct_kern.h | 8 | ||||
-rw-r--r-- | include/linux/tty.h | 4 | ||||
-rw-r--r-- | include/linux/user_namespace.h | 3 |
18 files changed, 310 insertions, 35 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index 36abf2aa7e68..12367cbadfe1 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -442,6 +442,8 @@ struct audit_krule { struct audit_field { u32 type; u32 val; + kuid_t uid; + kgid_t gid; u32 op; char *lsm_str; void *lsm_rule; @@ -525,7 +527,7 @@ static inline void audit_ptrace(struct task_struct *t) extern unsigned int audit_serial(void); extern int auditsc_get_stamp(struct audit_context *ctx, struct timespec *t, unsigned int *serial); -extern int audit_set_loginuid(uid_t loginuid); +extern int audit_set_loginuid(kuid_t loginuid); #define audit_get_loginuid(t) ((t)->loginuid) #define audit_get_sessionid(t) ((t)->sessionid) extern void audit_log_task_context(struct audit_buffer *ab); @@ -637,7 +639,7 @@ extern int audit_signals; #define audit_core_dumps(i) do { ; } while (0) #define audit_seccomp(i,s,c) do { ; } while (0) #define auditsc_get_stamp(c,t,s) (0) -#define audit_get_loginuid(t) (-1) +#define audit_get_loginuid(t) (INVALID_UID) #define audit_get_sessionid(t) (-1) #define audit_log_task_context(b) do { ; } while (0) #define audit_ipc_obj(i) ((void)0) @@ -700,10 +702,10 @@ extern void audit_log_secctx(struct audit_buffer *ab, u32 secid); extern int audit_update_lsm_rules(void); /* Private API (for audit.c only) */ -extern int audit_filter_user(struct netlink_skb_parms *cb); +extern int audit_filter_user(void); extern int audit_filter_type(int type); -extern int audit_receive_filter(int type, int pid, int uid, int seq, - void *data, size_t datasz, uid_t loginuid, +extern int audit_receive_filter(int type, int pid, int seq, + void *data, size_t datasz, kuid_t loginuid, u32 sessionid, u32 sid); extern int audit_enabled; #else diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h index f1362b5447fc..e788c186ed3a 100644 --- a/include/linux/inet_diag.h +++ b/include/linux/inet_diag.h @@ -159,6 +159,7 @@ struct inet_diag_handler { struct inet_connection_sock; int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, struct sk_buff *skb, struct inet_diag_req_v2 *req, + struct user_namespace *user_ns, u32 pid, u32 seq, u16 nlmsg_flags, const struct nlmsghdr *unlh); void inet_diag_dump_icsk(struct inet_hashinfo *h, struct sk_buff *skb, diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 89f1cb1056f0..6d087c5f57f7 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -92,7 +92,7 @@ extern struct group_info init_groups; #ifdef CONFIG_AUDITSYSCALL #define INIT_IDS \ - .loginuid = -1, \ + .loginuid = INVALID_UID, \ .sessionid = -1, #else #define INIT_IDS diff --git a/include/linux/ipc.h b/include/linux/ipc.h index 30e816148df4..ca833fdc3138 100644 --- a/include/linux/ipc.h +++ b/include/linux/ipc.h @@ -79,6 +79,7 @@ struct ipc_kludge { #ifdef __KERNEL__ #include <linux/spinlock.h> +#include <linux/uidgid.h> #define IPCMNI 32768 /* <= MAX_INT limit for ipc arrays (including sysctl changes) */ @@ -89,10 +90,10 @@ struct kern_ipc_perm int deleted; int id; key_t key; - uid_t uid; - gid_t gid; - uid_t cuid; - gid_t cgid; + kuid_t uid; + kgid_t gid; + kuid_t cuid; + kgid_t cgid; umode_t mode; unsigned long seq; void *security; diff --git a/include/linux/key.h b/include/linux/key.h index cef3b315ba7c..2393b1c040b6 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -24,6 +24,7 @@ #include <linux/atomic.h> #ifdef __KERNEL__ +#include <linux/uidgid.h> /* key handle serial number */ typedef int32_t key_serial_t; @@ -137,8 +138,8 @@ struct key { time_t revoked_at; /* time at which key was revoked */ }; time_t last_used_at; /* last time used for LRU keyring discard */ - uid_t uid; - gid_t gid; + kuid_t uid; + kgid_t gid; key_perm_t perm; /* access permissions */ unsigned short quotalen; /* length added to quota */ unsigned short datalen; /* payload data length @@ -193,7 +194,7 @@ struct key { extern struct key *key_alloc(struct key_type *type, const char *desc, - uid_t uid, gid_t gid, + kuid_t uid, kgid_t gid, const struct cred *cred, key_perm_t perm, unsigned long flags); @@ -262,7 +263,7 @@ extern int key_link(struct key *keyring, extern int key_unlink(struct key *keyring, struct key *key); -extern struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, +extern struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid, const struct cred *cred, unsigned long flags, struct key *dest); diff --git a/include/linux/loop.h b/include/linux/loop.h index 11a41a8f08eb..9635116dd830 100644 --- a/include/linux/loop.h +++ b/include/linux/loop.h @@ -44,7 +44,7 @@ struct loop_device { int lo_encrypt_key_size; struct loop_func_table *lo_encryption; __u32 lo_init[2]; - uid_t lo_key_owner; /* Who set the key */ + kuid_t lo_key_owner; /* Who set the key */ int (*ioctl)(struct loop_device *, int cmd, unsigned long arg); diff --git a/include/linux/netlink.h b/include/linux/netlink.h index f74dd133788f..c9fdde2bc73f 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -165,6 +165,7 @@ struct netlink_skb_parms { struct ucred creds; /* Skb credentials */ __u32 pid; __u32 dst_group; + struct sock *ssk; }; #define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb)) diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 11bad91c4433..7931efe71175 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -36,7 +36,13 @@ struct posix_acl_entry { short e_tag; unsigned short e_perm; - unsigned int e_id; + union { + kuid_t e_uid; + kgid_t e_gid; +#ifndef CONFIG_UIDGID_STRICT_TYPE_CHECKS + unsigned int e_id; +#endif + }; }; struct posix_acl { diff --git a/include/linux/posix_acl_xattr.h b/include/linux/posix_acl_xattr.h index 6e53c34035cd..ad93ad0f1db0 100644 --- a/include/linux/posix_acl_xattr.h +++ b/include/linux/posix_acl_xattr.h @@ -52,7 +52,21 @@ posix_acl_xattr_count(size_t size) return size / sizeof(posix_acl_xattr_entry); } -struct posix_acl *posix_acl_from_xattr(const void *value, size_t size); -int posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size); +#ifdef CONFIG_FS_POSIX_ACL +void posix_acl_fix_xattr_from_user(void *value, size_t size); +void posix_acl_fix_xattr_to_user(void *value, size_t size); +#else +static inline void posix_acl_fix_xattr_from_user(void *value, size_t size) +{ +} +static inline void posix_acl_fix_xattr_to_user(void *value, size_t size) +{ +} +#endif + +struct posix_acl *posix_acl_from_xattr(struct user_namespace *user_ns, + const void *value, size_t size); +int posix_acl_to_xattr(struct user_namespace *user_ns, + const struct posix_acl *acl, void *buffer, size_t size); #endif /* _POSIX_ACL_XATTR_H */ diff --git a/include/linux/projid.h b/include/linux/projid.h new file mode 100644 index 000000000000..36517b95be5c --- /dev/null +++ b/include/linux/projid.h @@ -0,0 +1,104 @@ +#ifndef _LINUX_PROJID_H +#define _LINUX_PROJID_H + +/* + * A set of types for the internal kernel types representing project ids. + * + * The types defined in this header allow distinguishing which project ids in + * the kernel are values used by userspace and which project id values are + * the internal kernel values. With the addition of user namespaces the values + * can be different. Using the type system makes it possible for the compiler + * to detect when we overlook these differences. + * + */ +#include <linux/types.h> + +struct user_namespace; +extern struct user_namespace init_user_ns; + +typedef __kernel_uid32_t projid_t; + +#ifdef CONFIG_UIDGID_STRICT_TYPE_CHECKS + +typedef struct { + projid_t val; +} kprojid_t; + +static inline projid_t __kprojid_val(kprojid_t projid) +{ + return projid.val; +} + +#define KPROJIDT_INIT(value) (kprojid_t){ value } + +#else + +typedef projid_t kprojid_t; + +static inline projid_t __kprojid_val(kprojid_t projid) +{ + return projid; +} + +#define KPROJIDT_INIT(value) ((kprojid_t) value ) + +#endif + +#define INVALID_PROJID KPROJIDT_INIT(-1) +#define OVERFLOW_PROJID 65534 + +static inline bool projid_eq(kprojid_t left, kprojid_t right) +{ + return __kprojid_val(left) == __kprojid_val(right); +} + +static inline bool projid_lt(kprojid_t left, kprojid_t right) +{ + return __kprojid_val(left) < __kprojid_val(right); +} + +static inline bool projid_valid(kprojid_t projid) +{ + return !projid_eq(projid, INVALID_PROJID); +} + +#ifdef CONFIG_USER_NS + +extern kprojid_t make_kprojid(struct user_namespace *from, projid_t projid); + +extern projid_t from_kprojid(struct user_namespace *to, kprojid_t projid); +extern projid_t from_kprojid_munged(struct user_namespace *to, kprojid_t projid); + +static inline bool kprojid_has_mapping(struct user_namespace *ns, kprojid_t projid) +{ + return from_kprojid(ns, projid) != (projid_t)-1; +} + +#else + +static inline kprojid_t make_kprojid(struct user_namespace *from, projid_t projid) +{ + return KPROJIDT_INIT(projid); +} + +static inline projid_t from_kprojid(struct user_namespace *to, kprojid_t kprojid) +{ + return __kprojid_val(kprojid); +} + +static inline projid_t from_kprojid_munged(struct user_namespace *to, kprojid_t kprojid) +{ + projid_t projid = from_kprojid(to, kprojid); + if (projid == (projid_t)-1) + projid = OVERFLOW_PROJID; + return projid; +} + +static inline bool kprojid_has_mapping(struct user_namespace *ns, kprojid_t projid) +{ + return true; +} + +#endif /* CONFIG_USER_NS */ + +#endif /* _LINUX_PROJID_H */ diff --git a/include/linux/quota.h b/include/linux/quota.h index 524ede8a160a..dcd5721e626d 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -181,10 +181,135 @@ enum { #include <linux/dqblk_v2.h> #include <linux/atomic.h> +#include <linux/uidgid.h> +#include <linux/projid.h> + +#undef USRQUOTA +#undef GRPQUOTA +enum quota_type { + USRQUOTA = 0, /* element used for user quotas */ + GRPQUOTA = 1, /* element used for group quotas */ + PRJQUOTA = 2, /* element used for project quotas */ +}; typedef __kernel_uid32_t qid_t; /* Type in which we store ids in memory */ typedef long long qsize_t; /* Type in which we store sizes */ +struct kqid { /* Type in which we store the quota identifier */ + union { + kuid_t uid; + kgid_t gid; + kprojid_t projid; + }; + enum quota_type type; /* USRQUOTA (uid) or GRPQUOTA (gid) or PRJQUOTA (projid) */ +}; + +extern bool qid_eq(struct kqid left, struct kqid right); +extern bool qid_lt(struct kqid left, struct kqid right); +extern qid_t from_kqid(struct user_namespace *to, struct kqid qid); +extern qid_t from_kqid_munged(struct user_namespace *to, struct kqid qid); +extern bool qid_valid(struct kqid qid); + +/** + * make_kqid - Map a user-namespace, type, qid tuple into a kqid. + * @from: User namespace that the qid is in + * @type: The type of quota + * @qid: Quota identifier + * + * Maps a user-namespace, type qid tuple into a kernel internal + * kqid, and returns that kqid. + * + * When there is no mapping defined for the user-namespace, type, + * qid tuple an invalid kqid is returned. Callers are expected to + * test for and handle handle invalid kqids being returned. + * Invalid kqids may be tested for using qid_valid(). + */ +static inline struct kqid make_kqid(struct user_namespace *from, + enum quota_type type, qid_t qid) +{ + struct kqid kqid; + + kqid.type = type; + switch (type) { + case USRQUOTA: + kqid.uid = make_kuid(from, qid); + break; + case GRPQUOTA: + kqid.gid = make_kgid(from, qid); + break; + case PRJQUOTA: + kqid.projid = make_kprojid(from, qid); + break; + default: + BUG(); + } + return kqid; +} + +/** + * make_kqid_invalid - Explicitly make an invalid kqid + * @type: The type of quota identifier + * + * Returns an invalid kqid with the specified type. + */ +static inline struct kqid make_kqid_invalid(enum quota_type type) +{ + struct kqid kqid; + + kqid.type = type; + switch (type) { + case USRQUOTA: + kqid.uid = INVALID_UID; + break; + case GRPQUOTA: + kqid.gid = INVALID_GID; + break; + case PRJQUOTA: + kqid.projid = INVALID_PROJID; + break; + default: + BUG(); + } + return kqid; +} + +/** + * make_kqid_uid - Make a kqid from a kuid + * @uid: The kuid to make the quota identifier from + */ +static inline struct kqid make_kqid_uid(kuid_t uid) +{ + struct kqid kqid; + kqid.type = USRQUOTA; + kqid.uid = uid; + return kqid; +} + +/** + * make_kqid_gid - Make a kqid from a kgid + * @gid: The kgid to make the quota identifier from + */ +static inline struct kqid make_kqid_gid(kgid_t gid) +{ + struct kqid kqid; + kqid.type = GRPQUOTA; + kqid.gid = gid; + return kqid; +} + +/** + * make_kqid_projid - Make a kqid from a projid + * @projid: The kprojid to make the quota identifier from + */ +static inline struct kqid make_kqid_projid(kprojid_t projid) +{ + struct kqid kqid; + kqid.type = PRJQUOTA; + kqid.projid = projid; + return kqid; +} + + extern spinlock_t dq_data_lock; /* Maximal numbers of writes for quota operation (insert/delete/update) @@ -294,10 +419,9 @@ struct dquot { atomic_t dq_count; /* Use count */ wait_queue_head_t dq_wait_unused; /* Wait queue for dquot to become unused */ struct super_block *dq_sb; /* superblock this applies to */ - unsigned int dq_id; /* ID this applies to (uid, gid) */ + struct kqid dq_id; /* ID this applies to (uid, gid, projid) */ loff_t dq_off; /* Offset of dquot on disk */ unsigned long dq_flags; /* See DQ_* */ - short dq_type; /* Type of quota */ struct mem_dqblk dq_dqb; /* Diskquota usage */ }; @@ -336,8 +460,8 @@ struct quotactl_ops { int (*quota_sync)(struct super_block *, int); int (*get_info)(struct super_block *, int, struct if_dqinfo *); int (*set_info)(struct super_block *, int, struct if_dqinfo *); - int (*get_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *); - int (*set_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *); + int (*get_dqblk)(struct super_block *, struct kqid, struct fs_disk_quota *); + int (*set_dqblk)(struct super_block *, struct kqid, struct fs_disk_quota *); int (*get_xstate)(struct super_block *, struct fs_quota_stat *); int (*set_xstate)(struct super_block *, unsigned int, int); }; @@ -386,10 +510,10 @@ static inline unsigned int dquot_generic_flag(unsigned int flags, int type) } #ifdef CONFIG_QUOTA_NETLINK_INTERFACE -extern void quota_send_warning(short type, unsigned int id, dev_t dev, +extern void quota_send_warning(struct kqid qid, dev_t dev, const char warntype); #else -static inline void quota_send_warning(short type, unsigned int id, dev_t dev, +static inline void quota_send_warning(struct kqid qid, dev_t dev, const char warntype) { return; diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index ec6b65feaaba..1c50093ae656 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -44,7 +44,7 @@ void inode_sub_rsv_space(struct inode *inode, qsize_t number); void dquot_initialize(struct inode *inode); void dquot_drop(struct inode *inode); -struct dquot *dqget(struct super_block *sb, unsigned int id, int type); +struct dquot *dqget(struct super_block *sb, struct kqid qid); void dqput(struct dquot *dquot); int dquot_scan_active(struct super_block *sb, int (*fn)(struct dquot *dquot, unsigned long priv), @@ -87,9 +87,9 @@ int dquot_writeback_dquots(struct super_block *sb, int type); int dquot_quota_sync(struct super_block *sb, int type); int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); -int dquot_get_dqblk(struct super_block *sb, int type, qid_t id, +int dquot_get_dqblk(struct super_block *sb, struct kqid id, struct fs_disk_quota *di); -int dquot_set_dqblk(struct super_block *sb, int type, qid_t id, +int dquot_set_dqblk(struct super_block *sb, struct kqid id, struct fs_disk_quota *di); int __dquot_transfer(struct inode *inode, struct dquot **transfer_to); diff --git a/include/linux/sched.h b/include/linux/sched.h index 765dffbb085e..d23ca6245d54 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1414,7 +1414,7 @@ struct task_struct { struct audit_context *audit_context; #ifdef CONFIG_AUDITSYSCALL - uid_t loginuid; + kuid_t loginuid; unsigned int sessionid; #endif struct seccomp seccomp; diff --git a/include/linux/security.h b/include/linux/security.h index d143b8e01954..145accee9236 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1436,7 +1436,7 @@ struct security_operations { int (*path_rename) (struct path *old_dir, struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry); int (*path_chmod) (struct path *path, umode_t mode); - int (*path_chown) (struct path *path, uid_t uid, gid_t gid); + int (*path_chown) (struct path *path, kuid_t uid, kgid_t gid); int (*path_chroot) (struct path *path); #endif @@ -2831,7 +2831,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir, int security_path_rename(struct path *old_dir, struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry); int security_path_chmod(struct path *path, umode_t mode); -int security_path_chown(struct path *path, uid_t uid, gid_t gid); +int security_path_chown(struct path *path, kuid_t uid, kgid_t gid); int security_path_chroot(struct path *path); #else /* CONFIG_SECURITY_PATH */ static inline int security_path_unlink(struct path *dir, struct dentry *dentry) @@ -2887,7 +2887,7 @@ static inline int security_path_chmod(struct path *path, umode_t mode) return 0; } -static inline int security_path_chown(struct path *path, uid_t uid, gid_t gid) +static inline int security_path_chown(struct path *path, kuid_t uid, kgid_t gid) { return 0; } diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index 83c44eefe698..68a04a343cad 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -13,6 +13,7 @@ struct file; struct path; struct inode; struct dentry; +struct user_namespace; struct seq_file { char *buf; @@ -25,6 +26,9 @@ struct seq_file { struct mutex lock; const struct seq_operations *op; int poll_event; +#ifdef CONFIG_USER_NS + struct user_namespace *user_ns; +#endif void *private; }; @@ -128,6 +132,16 @@ int seq_put_decimal_ull(struct seq_file *m, char delimiter, int seq_put_decimal_ll(struct seq_file *m, char delimiter, long long num); +static inline struct user_namespace *seq_user_ns(struct seq_file *seq) +{ +#ifdef CONFIG_USER_NS + return seq->user_ns; +#else + extern struct user_namespace init_user_ns; + return &init_user_ns; +#endif +} + #define SEQ_START_TOKEN ((void *)1) /* * Helpers for iteration over list_head-s in seq_files diff --git a/include/linux/tsacct_kern.h b/include/linux/tsacct_kern.h index 7e50ac795b0b..44893e5ec8f7 100644 --- a/include/linux/tsacct_kern.h +++ b/include/linux/tsacct_kern.h @@ -10,9 +10,13 @@ #include <linux/taskstats.h> #ifdef CONFIG_TASKSTATS -extern void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk); +extern void bacct_add_tsk(struct user_namespace *user_ns, + struct pid_namespace *pid_ns, + struct taskstats *stats, struct task_struct *tsk); #else -static inline void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) +static inline void bacct_add_tsk(struct user_namespace *user_ns, + struct pid_namespace *pid_ns, + struct taskstats *stats, struct task_struct *tsk) {} #endif /* CONFIG_TASKSTATS */ diff --git a/include/linux/tty.h b/include/linux/tty.h index 1509b86825d8..4f6c59a5fb79 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -575,7 +575,7 @@ extern void tty_audit_fork(struct signal_struct *sig); extern void tty_audit_tiocsti(struct tty_struct *tty, char ch); extern void tty_audit_push(struct tty_struct *tty); extern int tty_audit_push_task(struct task_struct *tsk, - uid_t loginuid, u32 sessionid); + kuid_t loginuid, u32 sessionid); #else static inline void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, size_t size) @@ -594,7 +594,7 @@ static inline void tty_audit_push(struct tty_struct *tty) { } static inline int tty_audit_push_task(struct task_struct *tsk, - uid_t loginuid, u32 sessionid) + kuid_t loginuid, u32 sessionid) { return 0; } diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h index 4e72922e5a75..95142cae446a 100644 --- a/include/linux/user_namespace.h +++ b/include/linux/user_namespace.h @@ -20,6 +20,7 @@ struct uid_gid_map { /* 64 bytes -- 1 cache line */ struct user_namespace { struct uid_gid_map uid_map; struct uid_gid_map gid_map; + struct uid_gid_map projid_map; struct kref kref; struct user_namespace *parent; kuid_t owner; @@ -49,8 +50,10 @@ static inline void put_user_ns(struct user_namespace *ns) struct seq_operations; extern struct seq_operations proc_uid_seq_operations; extern struct seq_operations proc_gid_seq_operations; +extern struct seq_operations proc_projid_seq_operations; extern ssize_t proc_uid_map_write(struct file *, const char __user *, size_t, loff_t *); extern ssize_t proc_gid_map_write(struct file *, const char __user *, size_t, loff_t *); +extern ssize_t proc_projid_map_write(struct file *, const char __user *, size_t, loff_t *); #else static inline struct user_namespace *get_user_ns(struct user_namespace *ns) |