diff options
245 files changed, 2474 insertions, 1307 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index bc1acdda7a5e..9503a4be40f6 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -278,8 +278,8 @@ linux_to_osf_stat(struct kstat *lstat, struct osf_stat __user *osf_stat) | |||
278 | tmp.st_dev = lstat->dev; | 278 | tmp.st_dev = lstat->dev; |
279 | tmp.st_mode = lstat->mode; | 279 | tmp.st_mode = lstat->mode; |
280 | tmp.st_nlink = lstat->nlink; | 280 | tmp.st_nlink = lstat->nlink; |
281 | tmp.st_uid = lstat->uid; | 281 | tmp.st_uid = from_kuid_munged(current_user_ns(), lstat->uid); |
282 | tmp.st_gid = lstat->gid; | 282 | tmp.st_gid = from_kgid_munged(current_user_ns(), lstat->gid); |
283 | tmp.st_rdev = lstat->rdev; | 283 | tmp.st_rdev = lstat->rdev; |
284 | tmp.st_ldev = lstat->rdev; | 284 | tmp.st_ldev = lstat->rdev; |
285 | tmp.st_size = lstat->size; | 285 | tmp.st_size = lstat->size; |
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index 1c2e89406721..9392e021c93b 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c | |||
@@ -158,7 +158,8 @@ mca_handler_bh(unsigned long paddr, void *iip, unsigned long ipsr) | |||
158 | ia64_mlogbuf_dump(); | 158 | ia64_mlogbuf_dump(); |
159 | printk(KERN_ERR "OS_MCA: process [cpu %d, pid: %d, uid: %d, " | 159 | printk(KERN_ERR "OS_MCA: process [cpu %d, pid: %d, uid: %d, " |
160 | "iip: %p, psr: 0x%lx,paddr: 0x%lx](%s) encounters MCA.\n", | 160 | "iip: %p, psr: 0x%lx,paddr: 0x%lx](%s) encounters MCA.\n", |
161 | raw_smp_processor_id(), current->pid, current_uid(), | 161 | raw_smp_processor_id(), current->pid, |
162 | from_kuid(&init_user_ns, current_uid()), | ||
162 | iip, ipsr, paddr, current->comm); | 163 | iip, ipsr, paddr, current->comm); |
163 | 164 | ||
164 | spin_lock(&mca_bh_lock); | 165 | spin_lock(&mca_bh_lock); |
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 3fa4bc536953..5a5c22245dee 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
@@ -2380,8 +2380,8 @@ static int | |||
2380 | pfm_bad_permissions(struct task_struct *task) | 2380 | pfm_bad_permissions(struct task_struct *task) |
2381 | { | 2381 | { |
2382 | const struct cred *tcred; | 2382 | const struct cred *tcred; |
2383 | uid_t uid = current_uid(); | 2383 | kuid_t uid = current_uid(); |
2384 | gid_t gid = current_gid(); | 2384 | kgid_t gid = current_gid(); |
2385 | int ret; | 2385 | int ret; |
2386 | 2386 | ||
2387 | rcu_read_lock(); | 2387 | rcu_read_lock(); |
@@ -2389,20 +2389,20 @@ pfm_bad_permissions(struct task_struct *task) | |||
2389 | 2389 | ||
2390 | /* inspired by ptrace_attach() */ | 2390 | /* inspired by ptrace_attach() */ |
2391 | DPRINT(("cur: uid=%d gid=%d task: euid=%d suid=%d uid=%d egid=%d sgid=%d\n", | 2391 | DPRINT(("cur: uid=%d gid=%d task: euid=%d suid=%d uid=%d egid=%d sgid=%d\n", |
2392 | uid, | 2392 | from_kuid(&init_user_ns, uid), |
2393 | gid, | 2393 | from_kgid(&init_user_ns, gid), |
2394 | tcred->euid, | 2394 | from_kuid(&init_user_ns, tcred->euid), |
2395 | tcred->suid, | 2395 | from_kuid(&init_user_ns, tcred->suid), |
2396 | tcred->uid, | 2396 | from_kuid(&init_user_ns, tcred->uid), |
2397 | tcred->egid, | 2397 | from_kgid(&init_user_ns, tcred->egid), |
2398 | tcred->sgid)); | 2398 | from_kgid(&init_user_ns, tcred->sgid))); |
2399 | 2399 | ||
2400 | ret = ((uid != tcred->euid) | 2400 | ret = ((!uid_eq(uid, tcred->euid)) |
2401 | || (uid != tcred->suid) | 2401 | || (!uid_eq(uid, tcred->suid)) |
2402 | || (uid != tcred->uid) | 2402 | || (!uid_eq(uid, tcred->uid)) |
2403 | || (gid != tcred->egid) | 2403 | || (!gid_eq(gid, tcred->egid)) |
2404 | || (gid != tcred->sgid) | 2404 | || (!gid_eq(gid, tcred->sgid)) |
2405 | || (gid != tcred->gid)) && !capable(CAP_SYS_PTRACE); | 2405 | || (!gid_eq(gid, tcred->gid))) && !capable(CAP_SYS_PTRACE); |
2406 | 2406 | ||
2407 | rcu_read_unlock(); | 2407 | rcu_read_unlock(); |
2408 | return ret; | 2408 | return ret; |
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index a199be1fe619..37dd79511cbe 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c | |||
@@ -220,7 +220,7 @@ ia64_rt_sigreturn (struct sigscratch *scr) | |||
220 | si.si_errno = 0; | 220 | si.si_errno = 0; |
221 | si.si_code = SI_KERNEL; | 221 | si.si_code = SI_KERNEL; |
222 | si.si_pid = task_pid_vnr(current); | 222 | si.si_pid = task_pid_vnr(current); |
223 | si.si_uid = current_uid(); | 223 | si.si_uid = from_kuid_munged(current_user_ns(), current_uid()); |
224 | si.si_addr = sc; | 224 | si.si_addr = sc; |
225 | force_sig_info(SIGSEGV, &si, current); | 225 | force_sig_info(SIGSEGV, &si, current); |
226 | return retval; | 226 | return retval; |
@@ -317,7 +317,7 @@ force_sigsegv_info (int sig, void __user *addr) | |||
317 | si.si_errno = 0; | 317 | si.si_errno = 0; |
318 | si.si_code = SI_KERNEL; | 318 | si.si_code = SI_KERNEL; |
319 | si.si_pid = task_pid_vnr(current); | 319 | si.si_pid = task_pid_vnr(current); |
320 | si.si_uid = current_uid(); | 320 | si.si_uid = from_kuid_munged(current_user_ns(), current_uid()); |
321 | si.si_addr = addr; | 321 | si.si_addr = addr; |
322 | force_sig_info(SIGSEGV, &si, current); | 322 | force_sig_info(SIGSEGV, &si, current); |
323 | return 0; | 323 | return 0; |
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 08ffcf52a856..e5f028b5794e 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c | |||
@@ -470,7 +470,7 @@ bad_area_nosemaphore: | |||
470 | if (is_exec && (error_code & DSISR_PROTFAULT)) | 470 | if (is_exec && (error_code & DSISR_PROTFAULT)) |
471 | printk_ratelimited(KERN_CRIT "kernel tried to execute NX-protected" | 471 | printk_ratelimited(KERN_CRIT "kernel tried to execute NX-protected" |
472 | " page (%lx) - exploit attempt? (uid: %d)\n", | 472 | " page (%lx) - exploit attempt? (uid: %d)\n", |
473 | address, current_uid()); | 473 | address, from_kuid(&init_user_ns, current_uid())); |
474 | 474 | ||
475 | return SIGSEGV; | 475 | return SIGSEGV; |
476 | 476 | ||
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index 6767b437a103..124ec1a55cc9 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c | |||
@@ -31,8 +31,8 @@ static struct dentry *hypfs_create_update_file(struct super_block *sb, | |||
31 | struct dentry *dir); | 31 | struct dentry *dir); |
32 | 32 | ||
33 | struct hypfs_sb_info { | 33 | struct hypfs_sb_info { |
34 | uid_t uid; /* uid used for files and dirs */ | 34 | kuid_t uid; /* uid used for files and dirs */ |
35 | gid_t gid; /* gid used for files and dirs */ | 35 | kgid_t gid; /* gid used for files and dirs */ |
36 | struct dentry *update_file; /* file to trigger update */ | 36 | struct dentry *update_file; /* file to trigger update */ |
37 | time_t last_update; /* last update time in secs since 1970 */ | 37 | time_t last_update; /* last update time in secs since 1970 */ |
38 | struct mutex lock; /* lock to protect update process */ | 38 | struct mutex lock; /* lock to protect update process */ |
@@ -229,6 +229,8 @@ static int hypfs_parse_options(char *options, struct super_block *sb) | |||
229 | { | 229 | { |
230 | char *str; | 230 | char *str; |
231 | substring_t args[MAX_OPT_ARGS]; | 231 | substring_t args[MAX_OPT_ARGS]; |
232 | kuid_t uid; | ||
233 | kgid_t gid; | ||
232 | 234 | ||
233 | if (!options) | 235 | if (!options) |
234 | return 0; | 236 | return 0; |
@@ -243,12 +245,18 @@ static int hypfs_parse_options(char *options, struct super_block *sb) | |||
243 | case opt_uid: | 245 | case opt_uid: |
244 | if (match_int(&args[0], &option)) | 246 | if (match_int(&args[0], &option)) |
245 | return -EINVAL; | 247 | return -EINVAL; |
246 | hypfs_info->uid = option; | 248 | uid = make_kuid(current_user_ns(), option); |
249 | if (!uid_valid(uid)) | ||
250 | return -EINVAL; | ||
251 | hypfs_info->uid = uid; | ||
247 | break; | 252 | break; |
248 | case opt_gid: | 253 | case opt_gid: |
249 | if (match_int(&args[0], &option)) | 254 | if (match_int(&args[0], &option)) |
250 | return -EINVAL; | 255 | return -EINVAL; |
251 | hypfs_info->gid = option; | 256 | gid = make_kgid(current_user_ns(), option); |
257 | if (!gid_valid(gid)) | ||
258 | return -EINVAL; | ||
259 | hypfs_info->gid = gid; | ||
252 | break; | 260 | break; |
253 | case opt_err: | 261 | case opt_err: |
254 | default: | 262 | default: |
@@ -263,8 +271,8 @@ static int hypfs_show_options(struct seq_file *s, struct dentry *root) | |||
263 | { | 271 | { |
264 | struct hypfs_sb_info *hypfs_info = root->d_sb->s_fs_info; | 272 | struct hypfs_sb_info *hypfs_info = root->d_sb->s_fs_info; |
265 | 273 | ||
266 | seq_printf(s, ",uid=%u", hypfs_info->uid); | 274 | seq_printf(s, ",uid=%u", from_kuid_munged(&init_user_ns, hypfs_info->uid)); |
267 | seq_printf(s, ",gid=%u", hypfs_info->gid); | 275 | seq_printf(s, ",gid=%u", from_kgid_munged(&init_user_ns, hypfs_info->gid)); |
268 | return 0; | 276 | return 0; |
269 | } | 277 | } |
270 | 278 | ||
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index f606d935f495..189963c90c6e 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c | |||
@@ -131,13 +131,19 @@ asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid) | |||
131 | low2highuid(suid)); | 131 | low2highuid(suid)); |
132 | } | 132 | } |
133 | 133 | ||
134 | asmlinkage long sys32_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user *suid) | 134 | asmlinkage long sys32_getresuid16(u16 __user *ruidp, u16 __user *euidp, u16 __user *suidp) |
135 | { | 135 | { |
136 | const struct cred *cred = current_cred(); | ||
136 | int retval; | 137 | int retval; |
138 | u16 ruid, euid, suid; | ||
137 | 139 | ||
138 | if (!(retval = put_user(high2lowuid(current->cred->uid), ruid)) && | 140 | ruid = high2lowuid(from_kuid_munged(cred->user_ns, cred->uid)); |
139 | !(retval = put_user(high2lowuid(current->cred->euid), euid))) | 141 | euid = high2lowuid(from_kuid_munged(cred->user_ns, cred->euid)); |
140 | retval = put_user(high2lowuid(current->cred->suid), suid); | 142 | suid = high2lowuid(from_kuid_munged(cred->user_ns, cred->suid)); |
143 | |||
144 | if (!(retval = put_user(ruid, ruidp)) && | ||
145 | !(retval = put_user(euid, euidp))) | ||
146 | retval = put_user(suid, suidp); | ||
141 | 147 | ||
142 | return retval; | 148 | return retval; |
143 | } | 149 | } |
@@ -148,13 +154,19 @@ asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid) | |||
148 | low2highgid(sgid)); | 154 | low2highgid(sgid)); |
149 | } | 155 | } |
150 | 156 | ||
151 | asmlinkage long sys32_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user *sgid) | 157 | asmlinkage long sys32_getresgid16(u16 __user *rgidp, u16 __user *egidp, u16 __user *sgidp) |
152 | { | 158 | { |
159 | const struct cred *cred = current_cred(); | ||
153 | int retval; | 160 | int retval; |
161 | u16 rgid, egid, sgid; | ||
162 | |||
163 | rgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->gid)); | ||
164 | egid = high2lowgid(from_kgid_munged(cred->user_ns, cred->egid)); | ||
165 | sgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->sgid)); | ||
154 | 166 | ||
155 | if (!(retval = put_user(high2lowgid(current->cred->gid), rgid)) && | 167 | if (!(retval = put_user(rgid, rgidp)) && |
156 | !(retval = put_user(high2lowgid(current->cred->egid), egid))) | 168 | !(retval = put_user(egid, egidp))) |
157 | retval = put_user(high2lowgid(current->cred->sgid), sgid); | 169 | retval = put_user(sgid, sgidp); |
158 | 170 | ||
159 | return retval; | 171 | return retval; |
160 | } | 172 | } |
@@ -258,22 +270,22 @@ asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist) | |||
258 | 270 | ||
259 | asmlinkage long sys32_getuid16(void) | 271 | asmlinkage long sys32_getuid16(void) |
260 | { | 272 | { |
261 | return high2lowuid(current->cred->uid); | 273 | return high2lowuid(from_kuid_munged(current_user_ns(), current_uid())); |
262 | } | 274 | } |
263 | 275 | ||
264 | asmlinkage long sys32_geteuid16(void) | 276 | asmlinkage long sys32_geteuid16(void) |
265 | { | 277 | { |
266 | return high2lowuid(current->cred->euid); | 278 | return high2lowuid(from_kuid_munged(current_user_ns(), current_euid())); |
267 | } | 279 | } |
268 | 280 | ||
269 | asmlinkage long sys32_getgid16(void) | 281 | asmlinkage long sys32_getgid16(void) |
270 | { | 282 | { |
271 | return high2lowgid(current->cred->gid); | 283 | return high2lowgid(from_kgid_munged(current_user_ns(), current_gid())); |
272 | } | 284 | } |
273 | 285 | ||
274 | asmlinkage long sys32_getegid16(void) | 286 | asmlinkage long sys32_getegid16(void) |
275 | { | 287 | { |
276 | return high2lowgid(current->cred->egid); | 288 | return high2lowgid(from_kgid_munged(current_user_ns(), current_egid())); |
277 | } | 289 | } |
278 | 290 | ||
279 | /* | 291 | /* |
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index deb4a456cf83..147d1a4dd269 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c | |||
@@ -309,8 +309,8 @@ static int handle_remove(const char *nodename, struct device *dev) | |||
309 | * before unlinking this node, reset permissions | 309 | * before unlinking this node, reset permissions |
310 | * of possible references like hardlinks | 310 | * of possible references like hardlinks |
311 | */ | 311 | */ |
312 | newattrs.ia_uid = 0; | 312 | newattrs.ia_uid = GLOBAL_ROOT_UID; |
313 | newattrs.ia_gid = 0; | 313 | newattrs.ia_gid = GLOBAL_ROOT_GID; |
314 | newattrs.ia_mode = stat.mode & ~0777; | 314 | newattrs.ia_mode = stat.mode & ~0777; |
315 | newattrs.ia_valid = | 315 | newattrs.ia_valid = |
316 | ATTR_UID|ATTR_GID|ATTR_MODE; | 316 | ATTR_UID|ATTR_GID|ATTR_MODE; |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 3bba65510d23..e9d594fd12cb 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -1038,10 +1038,10 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) | |||
1038 | { | 1038 | { |
1039 | int err; | 1039 | int err; |
1040 | struct loop_func_table *xfer; | 1040 | struct loop_func_table *xfer; |
1041 | uid_t uid = current_uid(); | 1041 | kuid_t uid = current_uid(); |
1042 | 1042 | ||
1043 | if (lo->lo_encrypt_key_size && | 1043 | if (lo->lo_encrypt_key_size && |
1044 | lo->lo_key_owner != uid && | 1044 | !uid_eq(lo->lo_key_owner, uid) && |
1045 | !capable(CAP_SYS_ADMIN)) | 1045 | !capable(CAP_SYS_ADMIN)) |
1046 | return -EPERM; | 1046 | return -EPERM; |
1047 | if (lo->lo_state != Lo_bound) | 1047 | if (lo->lo_state != Lo_bound) |
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c index 3e92b7d3fcd2..fce2000eec31 100644 --- a/drivers/connector/cn_proc.c +++ b/drivers/connector/cn_proc.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/gfp.h> | 30 | #include <linux/gfp.h> |
31 | #include <linux/ptrace.h> | 31 | #include <linux/ptrace.h> |
32 | #include <linux/atomic.h> | 32 | #include <linux/atomic.h> |
33 | #include <linux/pid_namespace.h> | ||
33 | 34 | ||
34 | #include <asm/unaligned.h> | 35 | #include <asm/unaligned.h> |
35 | 36 | ||
@@ -127,11 +128,11 @@ void proc_id_connector(struct task_struct *task, int which_id) | |||
127 | rcu_read_lock(); | 128 | rcu_read_lock(); |
128 | cred = __task_cred(task); | 129 | cred = __task_cred(task); |
129 | if (which_id == PROC_EVENT_UID) { | 130 | if (which_id == PROC_EVENT_UID) { |
130 | ev->event_data.id.r.ruid = cred->uid; | 131 | ev->event_data.id.r.ruid = from_kuid_munged(&init_user_ns, cred->uid); |
131 | ev->event_data.id.e.euid = cred->euid; | 132 | ev->event_data.id.e.euid = from_kuid_munged(&init_user_ns, cred->euid); |
132 | } else if (which_id == PROC_EVENT_GID) { | 133 | } else if (which_id == PROC_EVENT_GID) { |
133 | ev->event_data.id.r.rgid = cred->gid; | 134 | ev->event_data.id.r.rgid = from_kgid_munged(&init_user_ns, cred->gid); |
134 | ev->event_data.id.e.egid = cred->egid; | 135 | ev->event_data.id.e.egid = from_kgid_munged(&init_user_ns, cred->egid); |
135 | } else { | 136 | } else { |
136 | rcu_read_unlock(); | 137 | rcu_read_unlock(); |
137 | return; | 138 | return; |
@@ -303,6 +304,15 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, | |||
303 | if (msg->len != sizeof(*mc_op)) | 304 | if (msg->len != sizeof(*mc_op)) |
304 | return; | 305 | return; |
305 | 306 | ||
307 | /* | ||
308 | * Events are reported with respect to the initial pid | ||
309 | * and user namespaces so ignore requestors from | ||
310 | * other namespaces. | ||
311 | */ | ||
312 | if ((current_user_ns() != &init_user_ns) || | ||
313 | (task_active_pid_ns(current) != &init_pid_ns)) | ||
314 | return; | ||
315 | |||
306 | mc_op = (enum proc_cn_mcast_op *)msg->data; | 316 | mc_op = (enum proc_cn_mcast_op *)msg->data; |
307 | switch (*mc_op) { | 317 | switch (*mc_op) { |
308 | case PROC_CN_MCAST_LISTEN: | 318 | case PROC_CN_MCAST_LISTEN: |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 5062eec673f1..433d2fad1fe6 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -251,7 +251,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
251 | filp->private_data = priv; | 251 | filp->private_data = priv; |
252 | priv->filp = filp; | 252 | priv->filp = filp; |
253 | priv->uid = current_euid(); | 253 | priv->uid = current_euid(); |
254 | priv->pid = task_pid_nr(current); | 254 | priv->pid = get_pid(task_pid(current)); |
255 | priv->minor = idr_find(&drm_minors_idr, minor_id); | 255 | priv->minor = idr_find(&drm_minors_idr, minor_id); |
256 | priv->ioctl_count = 0; | 256 | priv->ioctl_count = 0; |
257 | /* for compatibility root is always authenticated */ | 257 | /* for compatibility root is always authenticated */ |
@@ -524,6 +524,7 @@ int drm_release(struct inode *inode, struct file *filp) | |||
524 | if (drm_core_check_feature(dev, DRIVER_PRIME)) | 524 | if (drm_core_check_feature(dev, DRIVER_PRIME)) |
525 | drm_prime_destroy_file_private(&file_priv->prime); | 525 | drm_prime_destroy_file_private(&file_priv->prime); |
526 | 526 | ||
527 | put_pid(file_priv->pid); | ||
527 | kfree(file_priv); | 528 | kfree(file_priv); |
528 | 529 | ||
529 | /* ======================================================== | 530 | /* ======================================================== |
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c index 8928edbb94c7..eb0af393e6e2 100644 --- a/drivers/gpu/drm/drm_info.c +++ b/drivers/gpu/drm/drm_info.c | |||
@@ -191,8 +191,9 @@ int drm_clients_info(struct seq_file *m, void *data) | |||
191 | seq_printf(m, "%c %3d %5d %5d %10u %10lu\n", | 191 | seq_printf(m, "%c %3d %5d %5d %10u %10lu\n", |
192 | priv->authenticated ? 'y' : 'n', | 192 | priv->authenticated ? 'y' : 'n', |
193 | priv->minor->index, | 193 | priv->minor->index, |
194 | priv->pid, | 194 | pid_vnr(priv->pid), |
195 | priv->uid, priv->magic, priv->ioctl_count); | 195 | from_kuid_munged(seq_user_ns(m), priv->uid), |
196 | priv->magic, priv->ioctl_count); | ||
196 | } | 197 | } |
197 | mutex_unlock(&dev->struct_mutex); | 198 | mutex_unlock(&dev->struct_mutex); |
198 | return 0; | 199 | return 0; |
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 64a62c697313..39a43834cef9 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c | |||
@@ -215,8 +215,8 @@ int drm_getclient(struct drm_device *dev, void *data, | |||
215 | list_for_each_entry(pt, &dev->filelist, lhead) { | 215 | list_for_each_entry(pt, &dev->filelist, lhead) { |
216 | if (i++ >= idx) { | 216 | if (i++ >= idx) { |
217 | client->auth = pt->authenticated; | 217 | client->auth = pt->authenticated; |
218 | client->pid = pt->pid; | 218 | client->pid = pid_vnr(pt->pid); |
219 | client->uid = pt->uid; | 219 | client->uid = from_kuid_munged(current_user_ns(), pt->uid); |
220 | client->magic = pt->magic; | 220 | client->magic = pt->magic; |
221 | client->iocs = pt->ioctl_count; | 221 | client->iocs = pt->ioctl_count; |
222 | mutex_unlock(&dev->struct_mutex); | 222 | mutex_unlock(&dev->struct_mutex); |
diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c index cff8a6c32161..65a2a23f6f8a 100644 --- a/drivers/infiniband/hw/qib/qib_fs.c +++ b/drivers/infiniband/hw/qib/qib_fs.c | |||
@@ -61,8 +61,8 @@ static int qibfs_mknod(struct inode *dir, struct dentry *dentry, | |||
61 | 61 | ||
62 | inode->i_ino = get_next_ino(); | 62 | inode->i_ino = get_next_ino(); |
63 | inode->i_mode = mode; | 63 | inode->i_mode = mode; |
64 | inode->i_uid = 0; | 64 | inode->i_uid = GLOBAL_ROOT_UID; |
65 | inode->i_gid = 0; | 65 | inode->i_gid = GLOBAL_ROOT_GID; |
66 | inode->i_blocks = 0; | 66 | inode->i_blocks = 0; |
67 | inode->i_atime = CURRENT_TIME; | 67 | inode->i_atime = CURRENT_TIME; |
68 | inode->i_mtime = inode->i_atime; | 68 | inode->i_mtime = inode->i_atime; |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 9336b829cc81..0873cdcf39be 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -121,8 +121,8 @@ struct tun_sock; | |||
121 | struct tun_struct { | 121 | struct tun_struct { |
122 | struct tun_file *tfile; | 122 | struct tun_file *tfile; |
123 | unsigned int flags; | 123 | unsigned int flags; |
124 | uid_t owner; | 124 | kuid_t owner; |
125 | gid_t group; | 125 | kgid_t group; |
126 | 126 | ||
127 | struct net_device *dev; | 127 | struct net_device *dev; |
128 | netdev_features_t set_features; | 128 | netdev_features_t set_features; |
@@ -1032,8 +1032,8 @@ static void tun_setup(struct net_device *dev) | |||
1032 | { | 1032 | { |
1033 | struct tun_struct *tun = netdev_priv(dev); | 1033 | struct tun_struct *tun = netdev_priv(dev); |
1034 | 1034 | ||
1035 | tun->owner = -1; | 1035 | tun->owner = INVALID_UID; |
1036 | tun->group = -1; | 1036 | tun->group = INVALID_GID; |
1037 | 1037 | ||
1038 | dev->ethtool_ops = &tun_ethtool_ops; | 1038 | dev->ethtool_ops = &tun_ethtool_ops; |
1039 | dev->destructor = tun_free_netdev; | 1039 | dev->destructor = tun_free_netdev; |
@@ -1156,14 +1156,20 @@ static ssize_t tun_show_owner(struct device *dev, struct device_attribute *attr, | |||
1156 | char *buf) | 1156 | char *buf) |
1157 | { | 1157 | { |
1158 | struct tun_struct *tun = netdev_priv(to_net_dev(dev)); | 1158 | struct tun_struct *tun = netdev_priv(to_net_dev(dev)); |
1159 | return sprintf(buf, "%d\n", tun->owner); | 1159 | return uid_valid(tun->owner)? |
1160 | sprintf(buf, "%u\n", | ||
1161 | from_kuid_munged(current_user_ns(), tun->owner)): | ||
1162 | sprintf(buf, "-1\n"); | ||
1160 | } | 1163 | } |
1161 | 1164 | ||
1162 | static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr, | 1165 | static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr, |
1163 | char *buf) | 1166 | char *buf) |
1164 | { | 1167 | { |
1165 | struct tun_struct *tun = netdev_priv(to_net_dev(dev)); | 1168 | struct tun_struct *tun = netdev_priv(to_net_dev(dev)); |
1166 | return sprintf(buf, "%d\n", tun->group); | 1169 | return gid_valid(tun->group) ? |
1170 | sprintf(buf, "%u\n", | ||
1171 | from_kgid_munged(current_user_ns(), tun->group)): | ||
1172 | sprintf(buf, "-1\n"); | ||
1167 | } | 1173 | } |
1168 | 1174 | ||
1169 | static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL); | 1175 | static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL); |
@@ -1190,8 +1196,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1190 | else | 1196 | else |
1191 | return -EINVAL; | 1197 | return -EINVAL; |
1192 | 1198 | ||
1193 | if (((tun->owner != -1 && cred->euid != tun->owner) || | 1199 | if (((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) || |
1194 | (tun->group != -1 && !in_egroup_p(tun->group))) && | 1200 | (gid_valid(tun->group) && !in_egroup_p(tun->group))) && |
1195 | !capable(CAP_NET_ADMIN)) | 1201 | !capable(CAP_NET_ADMIN)) |
1196 | return -EPERM; | 1202 | return -EPERM; |
1197 | err = security_tun_dev_attach(tun->socket.sk); | 1203 | err = security_tun_dev_attach(tun->socket.sk); |
@@ -1375,6 +1381,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1375 | void __user* argp = (void __user*)arg; | 1381 | void __user* argp = (void __user*)arg; |
1376 | struct sock_fprog fprog; | 1382 | struct sock_fprog fprog; |
1377 | struct ifreq ifr; | 1383 | struct ifreq ifr; |
1384 | kuid_t owner; | ||
1385 | kgid_t group; | ||
1378 | int sndbuf; | 1386 | int sndbuf; |
1379 | int vnet_hdr_sz; | 1387 | int vnet_hdr_sz; |
1380 | int ret; | 1388 | int ret; |
@@ -1448,16 +1456,26 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1448 | 1456 | ||
1449 | case TUNSETOWNER: | 1457 | case TUNSETOWNER: |
1450 | /* Set owner of the device */ | 1458 | /* Set owner of the device */ |
1451 | tun->owner = (uid_t) arg; | 1459 | owner = make_kuid(current_user_ns(), arg); |
1452 | 1460 | if (!uid_valid(owner)) { | |
1453 | tun_debug(KERN_INFO, tun, "owner set to %d\n", tun->owner); | 1461 | ret = -EINVAL; |
1462 | break; | ||
1463 | } | ||
1464 | tun->owner = owner; | ||
1465 | tun_debug(KERN_INFO, tun, "owner set to %d\n", | ||
1466 | from_kuid(&init_user_ns, tun->owner)); | ||
1454 | break; | 1467 | break; |
1455 | 1468 | ||
1456 | case TUNSETGROUP: | 1469 | case TUNSETGROUP: |
1457 | /* Set group of the device */ | 1470 | /* Set group of the device */ |
1458 | tun->group= (gid_t) arg; | 1471 | group = make_kgid(current_user_ns(), arg); |
1459 | 1472 | if (!gid_valid(group)) { | |
1460 | tun_debug(KERN_INFO, tun, "group set to %d\n", tun->group); | 1473 | ret = -EINVAL; |
1474 | break; | ||
1475 | } | ||
1476 | tun->group = group; | ||
1477 | tun_debug(KERN_INFO, tun, "group set to %d\n", | ||
1478 | from_kgid(&init_user_ns, tun->group)); | ||
1461 | break; | 1479 | break; |
1462 | 1480 | ||
1463 | case TUNSETLINK: | 1481 | case TUNSETLINK: |
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index f9f15bb3f03a..c586f78c307f 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -232,8 +232,10 @@ static int adhoc; | |||
232 | 232 | ||
233 | static int probe = 1; | 233 | static int probe = 1; |
234 | 234 | ||
235 | static kuid_t proc_kuid; | ||
235 | static int proc_uid /* = 0 */; | 236 | static int proc_uid /* = 0 */; |
236 | 237 | ||
238 | static kgid_t proc_kgid; | ||
237 | static int proc_gid /* = 0 */; | 239 | static int proc_gid /* = 0 */; |
238 | 240 | ||
239 | static int airo_perm = 0555; | 241 | static int airo_perm = 0555; |
@@ -4499,78 +4501,79 @@ struct proc_data { | |||
4499 | static int setup_proc_entry( struct net_device *dev, | 4501 | static int setup_proc_entry( struct net_device *dev, |
4500 | struct airo_info *apriv ) { | 4502 | struct airo_info *apriv ) { |
4501 | struct proc_dir_entry *entry; | 4503 | struct proc_dir_entry *entry; |
4504 | |||
4502 | /* First setup the device directory */ | 4505 | /* First setup the device directory */ |
4503 | strcpy(apriv->proc_name,dev->name); | 4506 | strcpy(apriv->proc_name,dev->name); |
4504 | apriv->proc_entry = proc_mkdir_mode(apriv->proc_name, airo_perm, | 4507 | apriv->proc_entry = proc_mkdir_mode(apriv->proc_name, airo_perm, |
4505 | airo_entry); | 4508 | airo_entry); |
4506 | if (!apriv->proc_entry) | 4509 | if (!apriv->proc_entry) |
4507 | goto fail; | 4510 | goto fail; |
4508 | apriv->proc_entry->uid = proc_uid; | 4511 | apriv->proc_entry->uid = proc_kuid; |
4509 | apriv->proc_entry->gid = proc_gid; | 4512 | apriv->proc_entry->gid = proc_kgid; |
4510 | 4513 | ||
4511 | /* Setup the StatsDelta */ | 4514 | /* Setup the StatsDelta */ |
4512 | entry = proc_create_data("StatsDelta", S_IRUGO & proc_perm, | 4515 | entry = proc_create_data("StatsDelta", S_IRUGO & proc_perm, |
4513 | apriv->proc_entry, &proc_statsdelta_ops, dev); | 4516 | apriv->proc_entry, &proc_statsdelta_ops, dev); |
4514 | if (!entry) | 4517 | if (!entry) |
4515 | goto fail_stats_delta; | 4518 | goto fail_stats_delta; |
4516 | entry->uid = proc_uid; | 4519 | entry->uid = proc_kuid; |
4517 | entry->gid = proc_gid; | 4520 | entry->gid = proc_kgid; |
4518 | 4521 | ||
4519 | /* Setup the Stats */ | 4522 | /* Setup the Stats */ |
4520 | entry = proc_create_data("Stats", S_IRUGO & proc_perm, | 4523 | entry = proc_create_data("Stats", S_IRUGO & proc_perm, |
4521 | apriv->proc_entry, &proc_stats_ops, dev); | 4524 | apriv->proc_entry, &proc_stats_ops, dev); |
4522 | if (!entry) | 4525 | if (!entry) |
4523 | goto fail_stats; | 4526 | goto fail_stats; |
4524 | entry->uid = proc_uid; | 4527 | entry->uid = proc_kuid; |
4525 | entry->gid = proc_gid; | 4528 | entry->gid = proc_kgid; |
4526 | 4529 | ||
4527 | /* Setup the Status */ | 4530 | /* Setup the Status */ |
4528 | entry = proc_create_data("Status", S_IRUGO & proc_perm, | 4531 | entry = proc_create_data("Status", S_IRUGO & proc_perm, |
4529 | apriv->proc_entry, &proc_status_ops, dev); | 4532 | apriv->proc_entry, &proc_status_ops, dev); |
4530 | if (!entry) | 4533 | if (!entry) |
4531 | goto fail_status; | 4534 | goto fail_status; |
4532 | entry->uid = proc_uid; | 4535 | entry->uid = proc_kuid; |
4533 | entry->gid = proc_gid; | 4536 | entry->gid = proc_kgid; |
4534 | 4537 | ||
4535 | /* Setup the Config */ | 4538 | /* Setup the Config */ |
4536 | entry = proc_create_data("Config", proc_perm, | 4539 | entry = proc_create_data("Config", proc_perm, |
4537 | apriv->proc_entry, &proc_config_ops, dev); | 4540 | apriv->proc_entry, &proc_config_ops, dev); |
4538 | if (!entry) | 4541 | if (!entry) |
4539 | goto fail_config; | 4542 | goto fail_config; |
4540 | entry->uid = proc_uid; | 4543 | entry->uid = proc_kuid; |
4541 | entry->gid = proc_gid; | 4544 | entry->gid = proc_kgid; |
4542 | 4545 | ||
4543 | /* Setup the SSID */ | 4546 | /* Setup the SSID */ |
4544 | entry = proc_create_data("SSID", proc_perm, | 4547 | entry = proc_create_data("SSID", proc_perm, |
4545 | apriv->proc_entry, &proc_SSID_ops, dev); | 4548 | apriv->proc_entry, &proc_SSID_ops, dev); |
4546 | if (!entry) | 4549 | if (!entry) |
4547 | goto fail_ssid; | 4550 | goto fail_ssid; |
4548 | entry->uid = proc_uid; | 4551 | entry->uid = proc_kuid; |
4549 | entry->gid = proc_gid; | 4552 | entry->gid = proc_kgid; |
4550 | 4553 | ||
4551 | /* Setup the APList */ | 4554 | /* Setup the APList */ |
4552 | entry = proc_create_data("APList", proc_perm, | 4555 | entry = proc_create_data("APList", proc_perm, |
4553 | apriv->proc_entry, &proc_APList_ops, dev); | 4556 | apriv->proc_entry, &proc_APList_ops, dev); |
4554 | if (!entry) | 4557 | if (!entry) |
4555 | goto fail_aplist; | 4558 | goto fail_aplist; |
4556 | entry->uid = proc_uid; | 4559 | entry->uid = proc_kuid; |
4557 | entry->gid = proc_gid; | 4560 | entry->gid = proc_kgid; |
4558 | 4561 | ||
4559 | /* Setup the BSSList */ | 4562 | /* Setup the BSSList */ |
4560 | entry = proc_create_data("BSSList", proc_perm, | 4563 | entry = proc_create_data("BSSList", proc_perm, |
4561 | apriv->proc_entry, &proc_BSSList_ops, dev); | 4564 | apriv->proc_entry, &proc_BSSList_ops, dev); |
4562 | if (!entry) | 4565 | if (!entry) |
4563 | goto fail_bsslist; | 4566 | goto fail_bsslist; |
4564 | entry->uid = proc_uid; | 4567 | entry->uid = proc_kuid; |
4565 | entry->gid = proc_gid; | 4568 | entry->gid = proc_kgid; |
4566 | 4569 | ||
4567 | /* Setup the WepKey */ | 4570 | /* Setup the WepKey */ |
4568 | entry = proc_create_data("WepKey", proc_perm, | 4571 | entry = proc_create_data("WepKey", proc_perm, |
4569 | apriv->proc_entry, &proc_wepkey_ops, dev); | 4572 | apriv->proc_entry, &proc_wepkey_ops, dev); |
4570 | if (!entry) | 4573 | if (!entry) |
4571 | goto fail_wepkey; | 4574 | goto fail_wepkey; |
4572 | entry->uid = proc_uid; | 4575 | entry->uid = proc_kuid; |
4573 | entry->gid = proc_gid; | 4576 | entry->gid = proc_kgid; |
4574 | 4577 | ||
4575 | return 0; | 4578 | return 0; |
4576 | 4579 | ||
@@ -5697,11 +5700,16 @@ static int __init airo_init_module( void ) | |||
5697 | { | 5700 | { |
5698 | int i; | 5701 | int i; |
5699 | 5702 | ||
5703 | proc_kuid = make_kuid(&init_user_ns, proc_uid); | ||
5704 | proc_kgid = make_kgid(&init_user_ns, proc_gid); | ||
5705 | if (!uid_valid(proc_kuid) || !gid_valid(proc_kgid)) | ||
5706 | return -EINVAL; | ||
5707 | |||
5700 | airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL); | 5708 | airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL); |
5701 | 5709 | ||
5702 | if (airo_entry) { | 5710 | if (airo_entry) { |
5703 | airo_entry->uid = proc_uid; | 5711 | airo_entry->uid = proc_kuid; |
5704 | airo_entry->gid = proc_gid; | 5712 | airo_entry->gid = proc_kgid; |
5705 | } | 5713 | } |
5706 | 5714 | ||
5707 | for (i = 0; i < 4 && io[i] && irq[i]; i++) { | 5715 | for (i = 0; i < 4 && io[i] && irq[i]; i++) { |
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index a807129c7b5a..b1937ca13575 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c | |||
@@ -47,7 +47,7 @@ static HLIST_HEAD(binder_dead_nodes); | |||
47 | static struct dentry *binder_debugfs_dir_entry_root; | 47 | static struct dentry *binder_debugfs_dir_entry_root; |
48 | static struct dentry *binder_debugfs_dir_entry_proc; | 48 | static struct dentry *binder_debugfs_dir_entry_proc; |
49 | static struct binder_node *binder_context_mgr_node; | 49 | static struct binder_node *binder_context_mgr_node; |
50 | static uid_t binder_context_mgr_uid = -1; | 50 | static kuid_t binder_context_mgr_uid = INVALID_UID; |
51 | static int binder_last_id; | 51 | static int binder_last_id; |
52 | static struct workqueue_struct *binder_deferred_workqueue; | 52 | static struct workqueue_struct *binder_deferred_workqueue; |
53 | 53 | ||
@@ -356,7 +356,7 @@ struct binder_transaction { | |||
356 | unsigned int flags; | 356 | unsigned int flags; |
357 | long priority; | 357 | long priority; |
358 | long saved_priority; | 358 | long saved_priority; |
359 | uid_t sender_euid; | 359 | kuid_t sender_euid; |
360 | }; | 360 | }; |
361 | 361 | ||
362 | static void | 362 | static void |
@@ -2427,7 +2427,7 @@ retry: | |||
2427 | } | 2427 | } |
2428 | tr.code = t->code; | 2428 | tr.code = t->code; |
2429 | tr.flags = t->flags; | 2429 | tr.flags = t->flags; |
2430 | tr.sender_euid = t->sender_euid; | 2430 | tr.sender_euid = from_kuid(current_user_ns(), t->sender_euid); |
2431 | 2431 | ||
2432 | if (t->from) { | 2432 | if (t->from) { |
2433 | struct task_struct *sender = t->from->proc->tsk; | 2433 | struct task_struct *sender = t->from->proc->tsk; |
@@ -2705,12 +2705,12 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
2705 | ret = -EBUSY; | 2705 | ret = -EBUSY; |
2706 | goto err; | 2706 | goto err; |
2707 | } | 2707 | } |
2708 | if (binder_context_mgr_uid != -1) { | 2708 | if (uid_valid(binder_context_mgr_uid)) { |
2709 | if (binder_context_mgr_uid != current->cred->euid) { | 2709 | if (!uid_eq(binder_context_mgr_uid, current->cred->euid)) { |
2710 | pr_err("binder: BINDER_SET_" | 2710 | pr_err("binder: BINDER_SET_" |
2711 | "CONTEXT_MGR bad uid %d != %d\n", | 2711 | "CONTEXT_MGR bad uid %d != %d\n", |
2712 | current->cred->euid, | 2712 | from_kuid(&init_user_ns, current->cred->euid), |
2713 | binder_context_mgr_uid); | 2713 | from_kuid(&init_user_ns, binder_context_mgr_uid)); |
2714 | ret = -EPERM; | 2714 | ret = -EPERM; |
2715 | goto err; | 2715 | goto err; |
2716 | } | 2716 | } |
diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c index 7c5866920622..b0b39b823ccf 100644 --- a/drivers/tty/tty_audit.c +++ b/drivers/tty/tty_audit.c | |||
@@ -61,7 +61,7 @@ static void tty_audit_buf_put(struct tty_audit_buf *buf) | |||
61 | } | 61 | } |
62 | 62 | ||
63 | static void tty_audit_log(const char *description, struct task_struct *tsk, | 63 | static void tty_audit_log(const char *description, struct task_struct *tsk, |
64 | uid_t loginuid, unsigned sessionid, int major, | 64 | kuid_t loginuid, unsigned sessionid, int major, |
65 | int minor, unsigned char *data, size_t size) | 65 | int minor, unsigned char *data, size_t size) |
66 | { | 66 | { |
67 | struct audit_buffer *ab; | 67 | struct audit_buffer *ab; |
@@ -69,11 +69,14 @@ static void tty_audit_log(const char *description, struct task_struct *tsk, | |||
69 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY); | 69 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY); |
70 | if (ab) { | 70 | if (ab) { |
71 | char name[sizeof(tsk->comm)]; | 71 | char name[sizeof(tsk->comm)]; |
72 | uid_t uid = task_uid(tsk); | 72 | kuid_t uid = task_uid(tsk); |
73 | 73 | ||
74 | audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u " | 74 | audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u " |
75 | "major=%d minor=%d comm=", description, | 75 | "major=%d minor=%d comm=", description, |
76 | tsk->pid, uid, loginuid, sessionid, | 76 | tsk->pid, |
77 | from_kuid(&init_user_ns, uid), | ||
78 | from_kuid(&init_user_ns, loginuid), | ||
79 | sessionid, | ||
77 | major, minor); | 80 | major, minor); |
78 | get_task_comm(name, tsk); | 81 | get_task_comm(name, tsk); |
79 | audit_log_untrustedstring(ab, name); | 82 | audit_log_untrustedstring(ab, name); |
@@ -89,7 +92,7 @@ static void tty_audit_log(const char *description, struct task_struct *tsk, | |||
89 | * Generate an audit message from the contents of @buf, which is owned by | 92 | * Generate an audit message from the contents of @buf, which is owned by |
90 | * @tsk with @loginuid. @buf->mutex must be locked. | 93 | * @tsk with @loginuid. @buf->mutex must be locked. |
91 | */ | 94 | */ |
92 | static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid, | 95 | static void tty_audit_buf_push(struct task_struct *tsk, kuid_t loginuid, |
93 | unsigned int sessionid, | 96 | unsigned int sessionid, |
94 | struct tty_audit_buf *buf) | 97 | struct tty_audit_buf *buf) |
95 | { | 98 | { |
@@ -112,7 +115,7 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid, | |||
112 | */ | 115 | */ |
113 | static void tty_audit_buf_push_current(struct tty_audit_buf *buf) | 116 | static void tty_audit_buf_push_current(struct tty_audit_buf *buf) |
114 | { | 117 | { |
115 | uid_t auid = audit_get_loginuid(current); | 118 | kuid_t auid = audit_get_loginuid(current); |
116 | unsigned int sessionid = audit_get_sessionid(current); | 119 | unsigned int sessionid = audit_get_sessionid(current); |
117 | tty_audit_buf_push(current, auid, sessionid, buf); | 120 | tty_audit_buf_push(current, auid, sessionid, buf); |
118 | } | 121 | } |
@@ -179,7 +182,7 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch) | |||
179 | } | 182 | } |
180 | 183 | ||
181 | if (should_audit && audit_enabled) { | 184 | if (should_audit && audit_enabled) { |
182 | uid_t auid; | 185 | kuid_t auid; |
183 | unsigned int sessionid; | 186 | unsigned int sessionid; |
184 | 187 | ||
185 | auid = audit_get_loginuid(current); | 188 | auid = audit_get_loginuid(current); |
@@ -199,7 +202,7 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch) | |||
199 | * reference to the tty audit buffer if available. | 202 | * reference to the tty audit buffer if available. |
200 | * Flush the buffer or return an appropriate error code. | 203 | * Flush the buffer or return an appropriate error code. |
201 | */ | 204 | */ |
202 | int tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid) | 205 | int tty_audit_push_task(struct task_struct *tsk, kuid_t loginuid, u32 sessionid) |
203 | { | 206 | { |
204 | struct tty_audit_buf *buf = ERR_PTR(-EPERM); | 207 | struct tty_audit_buf *buf = ERR_PTR(-EPERM); |
205 | unsigned long flags; | 208 | unsigned long flags; |
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 829aba75a6df..a26c43a151fd 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c | |||
@@ -224,8 +224,8 @@ struct ffs_data { | |||
224 | /* File permissions, written once when fs is mounted */ | 224 | /* File permissions, written once when fs is mounted */ |
225 | struct ffs_file_perms { | 225 | struct ffs_file_perms { |
226 | umode_t mode; | 226 | umode_t mode; |
227 | uid_t uid; | 227 | kuid_t uid; |
228 | gid_t gid; | 228 | kgid_t gid; |
229 | } file_perms; | 229 | } file_perms; |
230 | 230 | ||
231 | /* | 231 | /* |
@@ -1147,10 +1147,19 @@ static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) | |||
1147 | break; | 1147 | break; |
1148 | 1148 | ||
1149 | case 3: | 1149 | case 3: |
1150 | if (!memcmp(opts, "uid", 3)) | 1150 | if (!memcmp(opts, "uid", 3)) { |
1151 | data->perms.uid = value; | 1151 | data->perms.uid = make_kuid(current_user_ns(), value); |
1152 | if (!uid_valid(data->perms.uid)) { | ||
1153 | pr_err("%s: unmapped value: %lu\n", opts, value); | ||
1154 | return -EINVAL; | ||
1155 | } | ||
1156 | } | ||
1152 | else if (!memcmp(opts, "gid", 3)) | 1157 | else if (!memcmp(opts, "gid", 3)) |
1153 | data->perms.gid = value; | 1158 | data->perms.gid = make_kgid(current_user_ns(), value); |
1159 | if (!gid_valid(data->perms.gid)) { | ||
1160 | pr_err("%s: unmapped value: %lu\n", opts, value); | ||
1161 | return -EINVAL; | ||
1162 | } | ||
1154 | else | 1163 | else |
1155 | goto invalid; | 1164 | goto invalid; |
1156 | break; | 1165 | break; |
@@ -1179,8 +1188,8 @@ ffs_fs_mount(struct file_system_type *t, int flags, | |||
1179 | struct ffs_sb_fill_data data = { | 1188 | struct ffs_sb_fill_data data = { |
1180 | .perms = { | 1189 | .perms = { |
1181 | .mode = S_IFREG | 0600, | 1190 | .mode = S_IFREG | 0600, |
1182 | .uid = 0, | 1191 | .uid = GLOBAL_ROOT_UID, |
1183 | .gid = 0 | 1192 | .gid = GLOBAL_ROOT_GID, |
1184 | }, | 1193 | }, |
1185 | .root_mode = S_IFDIR | 0500, | 1194 | .root_mode = S_IFDIR | 0500, |
1186 | }; | 1195 | }; |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 4bb6d53f2de3..76494cabf4e4 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -1985,8 +1985,8 @@ gadgetfs_make_inode (struct super_block *sb, | |||
1985 | if (inode) { | 1985 | if (inode) { |
1986 | inode->i_ino = get_next_ino(); | 1986 | inode->i_ino = get_next_ino(); |
1987 | inode->i_mode = mode; | 1987 | inode->i_mode = mode; |
1988 | inode->i_uid = default_uid; | 1988 | inode->i_uid = make_kuid(&init_user_ns, default_uid); |
1989 | inode->i_gid = default_gid; | 1989 | inode->i_gid = make_kgid(&init_user_ns, default_gid); |
1990 | inode->i_atime = inode->i_mtime = inode->i_ctime | 1990 | inode->i_atime = inode->i_mtime = inode->i_ctime |
1991 | = CURRENT_TIME; | 1991 | = CURRENT_TIME; |
1992 | inode->i_private = data; | 1992 | inode->i_private = data; |
diff --git a/drivers/xen/xenfs/super.c b/drivers/xen/xenfs/super.c index a84b53c01436..459b9ac45cf5 100644 --- a/drivers/xen/xenfs/super.c +++ b/drivers/xen/xenfs/super.c | |||
@@ -30,7 +30,8 @@ static struct inode *xenfs_make_inode(struct super_block *sb, int mode) | |||
30 | 30 | ||
31 | if (ret) { | 31 | if (ret) { |
32 | ret->i_mode = mode; | 32 | ret->i_mode = mode; |
33 | ret->i_uid = ret->i_gid = 0; | 33 | ret->i_uid = GLOBAL_ROOT_UID; |
34 | ret->i_gid = GLOBAL_ROOT_GID; | ||
34 | ret->i_blocks = 0; | 35 | ret->i_blocks = 0; |
35 | ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME; | 36 | ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME; |
36 | } | 37 | } |
diff --git a/fs/9p/acl.c b/fs/9p/acl.c index 9a1d42630751..15b679166201 100644 --- a/fs/9p/acl.c +++ b/fs/9p/acl.c | |||
@@ -37,7 +37,7 @@ static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name) | |||
37 | return ERR_PTR(-ENOMEM); | 37 | return ERR_PTR(-ENOMEM); |
38 | size = v9fs_fid_xattr_get(fid, name, value, size); | 38 | size = v9fs_fid_xattr_get(fid, name, value, size); |
39 | if (size > 0) { | 39 | if (size > 0) { |
40 | acl = posix_acl_from_xattr(value, size); | 40 | acl = posix_acl_from_xattr(&init_user_ns, value, size); |
41 | if (IS_ERR(acl)) | 41 | if (IS_ERR(acl)) |
42 | goto err_out; | 42 | goto err_out; |
43 | } | 43 | } |
@@ -131,7 +131,7 @@ static int v9fs_set_acl(struct dentry *dentry, int type, struct posix_acl *acl) | |||
131 | buffer = kmalloc(size, GFP_KERNEL); | 131 | buffer = kmalloc(size, GFP_KERNEL); |
132 | if (!buffer) | 132 | if (!buffer) |
133 | return -ENOMEM; | 133 | return -ENOMEM; |
134 | retval = posix_acl_to_xattr(acl, buffer, size); | 134 | retval = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); |
135 | if (retval < 0) | 135 | if (retval < 0) |
136 | goto err_free_out; | 136 | goto err_free_out; |
137 | switch (type) { | 137 | switch (type) { |
@@ -251,7 +251,7 @@ static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name, | |||
251 | return PTR_ERR(acl); | 251 | return PTR_ERR(acl); |
252 | if (acl == NULL) | 252 | if (acl == NULL) |
253 | return -ENODATA; | 253 | return -ENODATA; |
254 | error = posix_acl_to_xattr(acl, buffer, size); | 254 | error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); |
255 | posix_acl_release(acl); | 255 | posix_acl_release(acl); |
256 | 256 | ||
257 | return error; | 257 | return error; |
@@ -304,7 +304,7 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name, | |||
304 | return -EPERM; | 304 | return -EPERM; |
305 | if (value) { | 305 | if (value) { |
306 | /* update the cached acl value */ | 306 | /* update the cached acl value */ |
307 | acl = posix_acl_from_xattr(value, size); | 307 | acl = posix_acl_from_xattr(&init_user_ns, value, size); |
308 | if (IS_ERR(acl)) | 308 | if (IS_ERR(acl)) |
309 | return PTR_ERR(acl); | 309 | return PTR_ERR(acl); |
310 | else if (acl) { | 310 | else if (acl) { |
diff --git a/fs/adfs/adfs.h b/fs/adfs/adfs.h index 718ac1f440c6..585adafb0cc2 100644 --- a/fs/adfs/adfs.h +++ b/fs/adfs/adfs.h | |||
@@ -46,8 +46,8 @@ struct adfs_sb_info { | |||
46 | struct adfs_discmap *s_map; /* bh list containing map */ | 46 | struct adfs_discmap *s_map; /* bh list containing map */ |
47 | struct adfs_dir_ops *s_dir; /* directory operations */ | 47 | struct adfs_dir_ops *s_dir; /* directory operations */ |
48 | 48 | ||
49 | uid_t s_uid; /* owner uid */ | 49 | kuid_t s_uid; /* owner uid */ |
50 | gid_t s_gid; /* owner gid */ | 50 | kgid_t s_gid; /* owner gid */ |
51 | umode_t s_owner_mask; /* ADFS owner perm -> unix perm */ | 51 | umode_t s_owner_mask; /* ADFS owner perm -> unix perm */ |
52 | umode_t s_other_mask; /* ADFS other perm -> unix perm */ | 52 | umode_t s_other_mask; /* ADFS other perm -> unix perm */ |
53 | int s_ftsuffix; /* ,xyz hex filetype suffix option */ | 53 | int s_ftsuffix; /* ,xyz hex filetype suffix option */ |
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c index 1dab6a174d6a..e9bad5093a3f 100644 --- a/fs/adfs/inode.c +++ b/fs/adfs/inode.c | |||
@@ -304,8 +304,8 @@ adfs_notify_change(struct dentry *dentry, struct iattr *attr) | |||
304 | * we can't change the UID or GID of any file - | 304 | * we can't change the UID or GID of any file - |
305 | * we have a global UID/GID in the superblock | 305 | * we have a global UID/GID in the superblock |
306 | */ | 306 | */ |
307 | if ((ia_valid & ATTR_UID && attr->ia_uid != ADFS_SB(sb)->s_uid) || | 307 | if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, ADFS_SB(sb)->s_uid)) || |
308 | (ia_valid & ATTR_GID && attr->ia_gid != ADFS_SB(sb)->s_gid)) | 308 | (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, ADFS_SB(sb)->s_gid))) |
309 | error = -EPERM; | 309 | error = -EPERM; |
310 | 310 | ||
311 | if (error) | 311 | if (error) |
diff --git a/fs/adfs/super.c b/fs/adfs/super.c index bdaec92353c2..22a0d7ed5fa1 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/seq_file.h> | 15 | #include <linux/seq_file.h> |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/statfs.h> | 17 | #include <linux/statfs.h> |
18 | #include <linux/user_namespace.h> | ||
18 | #include "adfs.h" | 19 | #include "adfs.h" |
19 | #include "dir_f.h" | 20 | #include "dir_f.h" |
20 | #include "dir_fplus.h" | 21 | #include "dir_fplus.h" |
@@ -130,10 +131,10 @@ static int adfs_show_options(struct seq_file *seq, struct dentry *root) | |||
130 | { | 131 | { |
131 | struct adfs_sb_info *asb = ADFS_SB(root->d_sb); | 132 | struct adfs_sb_info *asb = ADFS_SB(root->d_sb); |
132 | 133 | ||
133 | if (asb->s_uid != 0) | 134 | if (!uid_eq(asb->s_uid, GLOBAL_ROOT_UID)) |
134 | seq_printf(seq, ",uid=%u", asb->s_uid); | 135 | seq_printf(seq, ",uid=%u", from_kuid_munged(&init_user_ns, asb->s_uid)); |
135 | if (asb->s_gid != 0) | 136 | if (!gid_eq(asb->s_gid, GLOBAL_ROOT_GID)) |
136 | seq_printf(seq, ",gid=%u", asb->s_gid); | 137 | seq_printf(seq, ",gid=%u", from_kgid_munged(&init_user_ns, asb->s_gid)); |
137 | if (asb->s_owner_mask != ADFS_DEFAULT_OWNER_MASK) | 138 | if (asb->s_owner_mask != ADFS_DEFAULT_OWNER_MASK) |
138 | seq_printf(seq, ",ownmask=%o", asb->s_owner_mask); | 139 | seq_printf(seq, ",ownmask=%o", asb->s_owner_mask); |
139 | if (asb->s_other_mask != ADFS_DEFAULT_OTHER_MASK) | 140 | if (asb->s_other_mask != ADFS_DEFAULT_OTHER_MASK) |
@@ -175,12 +176,16 @@ static int parse_options(struct super_block *sb, char *options) | |||
175 | case Opt_uid: | 176 | case Opt_uid: |
176 | if (match_int(args, &option)) | 177 | if (match_int(args, &option)) |
177 | return -EINVAL; | 178 | return -EINVAL; |
178 | asb->s_uid = option; | 179 | asb->s_uid = make_kuid(current_user_ns(), option); |
180 | if (!uid_valid(asb->s_uid)) | ||
181 | return -EINVAL; | ||
179 | break; | 182 | break; |
180 | case Opt_gid: | 183 | case Opt_gid: |
181 | if (match_int(args, &option)) | 184 | if (match_int(args, &option)) |
182 | return -EINVAL; | 185 | return -EINVAL; |
183 | asb->s_gid = option; | 186 | asb->s_gid = make_kgid(current_user_ns(), option); |
187 | if (!gid_valid(asb->s_gid)) | ||
188 | return -EINVAL; | ||
184 | break; | 189 | break; |
185 | case Opt_ownmask: | 190 | case Opt_ownmask: |
186 | if (match_octal(args, &option)) | 191 | if (match_octal(args, &option)) |
@@ -369,8 +374,8 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent) | |||
369 | sb->s_fs_info = asb; | 374 | sb->s_fs_info = asb; |
370 | 375 | ||
371 | /* set default options */ | 376 | /* set default options */ |
372 | asb->s_uid = 0; | 377 | asb->s_uid = GLOBAL_ROOT_UID; |
373 | asb->s_gid = 0; | 378 | asb->s_gid = GLOBAL_ROOT_GID; |
374 | asb->s_owner_mask = ADFS_DEFAULT_OWNER_MASK; | 379 | asb->s_owner_mask = ADFS_DEFAULT_OWNER_MASK; |
375 | asb->s_other_mask = ADFS_DEFAULT_OTHER_MASK; | 380 | asb->s_other_mask = ADFS_DEFAULT_OTHER_MASK; |
376 | asb->s_ftsuffix = 0; | 381 | asb->s_ftsuffix = 0; |
diff --git a/fs/affs/affs.h b/fs/affs/affs.h index 6e216419f340..3952121f2f28 100644 --- a/fs/affs/affs.h +++ b/fs/affs/affs.h | |||
@@ -88,8 +88,8 @@ struct affs_sb_info { | |||
88 | u32 s_root_block; /* FFS root block number. */ | 88 | u32 s_root_block; /* FFS root block number. */ |
89 | int s_hashsize; /* Size of hash table. */ | 89 | int s_hashsize; /* Size of hash table. */ |
90 | unsigned long s_flags; /* See below. */ | 90 | unsigned long s_flags; /* See below. */ |
91 | uid_t s_uid; /* uid to override */ | 91 | kuid_t s_uid; /* uid to override */ |
92 | gid_t s_gid; /* gid to override */ | 92 | kgid_t s_gid; /* gid to override */ |
93 | umode_t s_mode; /* mode to override */ | 93 | umode_t s_mode; /* mode to override */ |
94 | struct buffer_head *s_root_bh; /* Cached root block. */ | 94 | struct buffer_head *s_root_bh; /* Cached root block. */ |
95 | struct mutex s_bmlock; /* Protects bitmap access. */ | 95 | struct mutex s_bmlock; /* Protects bitmap access. */ |
diff --git a/fs/affs/inode.c b/fs/affs/inode.c index 8bc4a59f4e7e..15c484268229 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c | |||
@@ -80,17 +80,17 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino) | |||
80 | if (id == 0 || sbi->s_flags & SF_SETUID) | 80 | if (id == 0 || sbi->s_flags & SF_SETUID) |
81 | inode->i_uid = sbi->s_uid; | 81 | inode->i_uid = sbi->s_uid; |
82 | else if (id == 0xFFFF && sbi->s_flags & SF_MUFS) | 82 | else if (id == 0xFFFF && sbi->s_flags & SF_MUFS) |
83 | inode->i_uid = 0; | 83 | i_uid_write(inode, 0); |
84 | else | 84 | else |
85 | inode->i_uid = id; | 85 | i_uid_write(inode, id); |
86 | 86 | ||
87 | id = be16_to_cpu(tail->gid); | 87 | id = be16_to_cpu(tail->gid); |
88 | if (id == 0 || sbi->s_flags & SF_SETGID) | 88 | if (id == 0 || sbi->s_flags & SF_SETGID) |
89 | inode->i_gid = sbi->s_gid; | 89 | inode->i_gid = sbi->s_gid; |
90 | else if (id == 0xFFFF && sbi->s_flags & SF_MUFS) | 90 | else if (id == 0xFFFF && sbi->s_flags & SF_MUFS) |
91 | inode->i_gid = 0; | 91 | i_gid_write(inode, 0); |
92 | else | 92 | else |
93 | inode->i_gid = id; | 93 | i_gid_write(inode, id); |
94 | 94 | ||
95 | switch (be32_to_cpu(tail->stype)) { | 95 | switch (be32_to_cpu(tail->stype)) { |
96 | case ST_ROOT: | 96 | case ST_ROOT: |
@@ -193,13 +193,13 @@ affs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
193 | tail->size = cpu_to_be32(inode->i_size); | 193 | tail->size = cpu_to_be32(inode->i_size); |
194 | secs_to_datestamp(inode->i_mtime.tv_sec,&tail->change); | 194 | secs_to_datestamp(inode->i_mtime.tv_sec,&tail->change); |
195 | if (!(inode->i_ino == AFFS_SB(sb)->s_root_block)) { | 195 | if (!(inode->i_ino == AFFS_SB(sb)->s_root_block)) { |
196 | uid = inode->i_uid; | 196 | uid = i_uid_read(inode); |
197 | gid = inode->i_gid; | 197 | gid = i_gid_read(inode); |
198 | if (AFFS_SB(sb)->s_flags & SF_MUFS) { | 198 | if (AFFS_SB(sb)->s_flags & SF_MUFS) { |
199 | if (inode->i_uid == 0 || inode->i_uid == 0xFFFF) | 199 | if (uid == 0 || uid == 0xFFFF) |
200 | uid = inode->i_uid ^ ~0; | 200 | uid = uid ^ ~0; |
201 | if (inode->i_gid == 0 || inode->i_gid == 0xFFFF) | 201 | if (gid == 0 || gid == 0xFFFF) |
202 | gid = inode->i_gid ^ ~0; | 202 | gid = gid ^ ~0; |
203 | } | 203 | } |
204 | if (!(AFFS_SB(sb)->s_flags & SF_SETUID)) | 204 | if (!(AFFS_SB(sb)->s_flags & SF_SETUID)) |
205 | tail->uid = cpu_to_be16(uid); | 205 | tail->uid = cpu_to_be16(uid); |
diff --git a/fs/affs/super.c b/fs/affs/super.c index 022cecb0757d..1f030825cd3a 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c | |||
@@ -188,7 +188,7 @@ static const match_table_t tokens = { | |||
188 | }; | 188 | }; |
189 | 189 | ||
190 | static int | 190 | static int |
191 | parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s32 *root, | 191 | parse_options(char *options, kuid_t *uid, kgid_t *gid, int *mode, int *reserved, s32 *root, |
192 | int *blocksize, char **prefix, char *volume, unsigned long *mount_opts) | 192 | int *blocksize, char **prefix, char *volume, unsigned long *mount_opts) |
193 | { | 193 | { |
194 | char *p; | 194 | char *p; |
@@ -253,13 +253,17 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s | |||
253 | case Opt_setgid: | 253 | case Opt_setgid: |
254 | if (match_int(&args[0], &option)) | 254 | if (match_int(&args[0], &option)) |
255 | return 0; | 255 | return 0; |
256 | *gid = option; | 256 | *gid = make_kgid(current_user_ns(), option); |
257 | if (!gid_valid(*gid)) | ||
258 | return 0; | ||
257 | *mount_opts |= SF_SETGID; | 259 | *mount_opts |= SF_SETGID; |
258 | break; | 260 | break; |
259 | case Opt_setuid: | 261 | case Opt_setuid: |
260 | if (match_int(&args[0], &option)) | 262 | if (match_int(&args[0], &option)) |
261 | return 0; | 263 | return 0; |
262 | *uid = option; | 264 | *uid = make_kuid(current_user_ns(), option); |
265 | if (!uid_valid(*uid)) | ||
266 | return 0; | ||
263 | *mount_opts |= SF_SETUID; | 267 | *mount_opts |= SF_SETUID; |
264 | break; | 268 | break; |
265 | case Opt_verbose: | 269 | case Opt_verbose: |
@@ -301,8 +305,8 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent) | |||
301 | int num_bm; | 305 | int num_bm; |
302 | int i, j; | 306 | int i, j; |
303 | s32 key; | 307 | s32 key; |
304 | uid_t uid; | 308 | kuid_t uid; |
305 | gid_t gid; | 309 | kgid_t gid; |
306 | int reserved; | 310 | int reserved; |
307 | unsigned long mount_flags; | 311 | unsigned long mount_flags; |
308 | int tmp_flags; /* fix remount prototype... */ | 312 | int tmp_flags; /* fix remount prototype... */ |
@@ -527,8 +531,8 @@ affs_remount(struct super_block *sb, int *flags, char *data) | |||
527 | { | 531 | { |
528 | struct affs_sb_info *sbi = AFFS_SB(sb); | 532 | struct affs_sb_info *sbi = AFFS_SB(sb); |
529 | int blocksize; | 533 | int blocksize; |
530 | uid_t uid; | 534 | kuid_t uid; |
531 | gid_t gid; | 535 | kgid_t gid; |
532 | int mode; | 536 | int mode; |
533 | int reserved; | 537 | int reserved; |
534 | int root_block; | 538 | int root_block; |
diff --git a/fs/befs/befs.h b/fs/befs/befs.h index d9a40abda6b7..b26642839156 100644 --- a/fs/befs/befs.h +++ b/fs/befs/befs.h | |||
@@ -20,8 +20,8 @@ typedef u64 befs_blocknr_t; | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | typedef struct befs_mount_options { | 22 | typedef struct befs_mount_options { |
23 | gid_t gid; | 23 | kgid_t gid; |
24 | uid_t uid; | 24 | kuid_t uid; |
25 | int use_gid; | 25 | int use_gid; |
26 | int use_uid; | 26 | int use_uid; |
27 | int debug; | 27 | int debug; |
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index cf7f3c67c8b7..7f73a692bfd0 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/vfs.h> | 15 | #include <linux/vfs.h> |
16 | #include <linux/parser.h> | 16 | #include <linux/parser.h> |
17 | #include <linux/namei.h> | 17 | #include <linux/namei.h> |
18 | #include <linux/sched.h> | ||
18 | 19 | ||
19 | #include "befs.h" | 20 | #include "befs.h" |
20 | #include "btree.h" | 21 | #include "btree.h" |
@@ -352,9 +353,11 @@ static struct inode *befs_iget(struct super_block *sb, unsigned long ino) | |||
352 | */ | 353 | */ |
353 | 354 | ||
354 | inode->i_uid = befs_sb->mount_opts.use_uid ? | 355 | inode->i_uid = befs_sb->mount_opts.use_uid ? |
355 | befs_sb->mount_opts.uid : (uid_t) fs32_to_cpu(sb, raw_inode->uid); | 356 | befs_sb->mount_opts.uid : |
357 | make_kuid(&init_user_ns, fs32_to_cpu(sb, raw_inode->uid)); | ||
356 | inode->i_gid = befs_sb->mount_opts.use_gid ? | 358 | inode->i_gid = befs_sb->mount_opts.use_gid ? |
357 | befs_sb->mount_opts.gid : (gid_t) fs32_to_cpu(sb, raw_inode->gid); | 359 | befs_sb->mount_opts.gid : |
360 | make_kgid(&init_user_ns, fs32_to_cpu(sb, raw_inode->gid)); | ||
358 | 361 | ||
359 | set_nlink(inode, 1); | 362 | set_nlink(inode, 1); |
360 | 363 | ||
@@ -674,10 +677,12 @@ parse_options(char *options, befs_mount_options * opts) | |||
674 | char *p; | 677 | char *p; |
675 | substring_t args[MAX_OPT_ARGS]; | 678 | substring_t args[MAX_OPT_ARGS]; |
676 | int option; | 679 | int option; |
680 | kuid_t uid; | ||
681 | kgid_t gid; | ||
677 | 682 | ||
678 | /* Initialize options */ | 683 | /* Initialize options */ |
679 | opts->uid = 0; | 684 | opts->uid = GLOBAL_ROOT_UID; |
680 | opts->gid = 0; | 685 | opts->gid = GLOBAL_ROOT_GID; |
681 | opts->use_uid = 0; | 686 | opts->use_uid = 0; |
682 | opts->use_gid = 0; | 687 | opts->use_gid = 0; |
683 | opts->iocharset = NULL; | 688 | opts->iocharset = NULL; |
@@ -696,23 +701,29 @@ parse_options(char *options, befs_mount_options * opts) | |||
696 | case Opt_uid: | 701 | case Opt_uid: |
697 | if (match_int(&args[0], &option)) | 702 | if (match_int(&args[0], &option)) |
698 | return 0; | 703 | return 0; |
699 | if (option < 0) { | 704 | uid = INVALID_UID; |
705 | if (option >= 0) | ||
706 | uid = make_kuid(current_user_ns(), option); | ||
707 | if (!uid_valid(uid)) { | ||
700 | printk(KERN_ERR "BeFS: Invalid uid %d, " | 708 | printk(KERN_ERR "BeFS: Invalid uid %d, " |
701 | "using default\n", option); | 709 | "using default\n", option); |
702 | break; | 710 | break; |
703 | } | 711 | } |
704 | opts->uid = option; | 712 | opts->uid = uid; |
705 | opts->use_uid = 1; | 713 | opts->use_uid = 1; |
706 | break; | 714 | break; |
707 | case Opt_gid: | 715 | case Opt_gid: |
708 | if (match_int(&args[0], &option)) | 716 | if (match_int(&args[0], &option)) |
709 | return 0; | 717 | return 0; |
710 | if (option < 0) { | 718 | gid = INVALID_GID; |
719 | if (option >= 0) | ||
720 | gid = make_kgid(current_user_ns(), option); | ||
721 | if (!gid_valid(gid)) { | ||
711 | printk(KERN_ERR "BeFS: Invalid gid %d, " | 722 | printk(KERN_ERR "BeFS: Invalid gid %d, " |
712 | "using default\n", option); | 723 | "using default\n", option); |
713 | break; | 724 | break; |
714 | } | 725 | } |
715 | opts->gid = option; | 726 | opts->gid = gid; |
716 | opts->use_gid = 1; | 727 | opts->use_gid = 1; |
717 | break; | 728 | break; |
718 | case Opt_charset: | 729 | case Opt_charset: |
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 9870417c26e7..b242beba58ed 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c | |||
@@ -76,8 +76,8 @@ struct inode *bfs_iget(struct super_block *sb, unsigned long ino) | |||
76 | BFS_I(inode)->i_sblock = le32_to_cpu(di->i_sblock); | 76 | BFS_I(inode)->i_sblock = le32_to_cpu(di->i_sblock); |
77 | BFS_I(inode)->i_eblock = le32_to_cpu(di->i_eblock); | 77 | BFS_I(inode)->i_eblock = le32_to_cpu(di->i_eblock); |
78 | BFS_I(inode)->i_dsk_ino = le16_to_cpu(di->i_ino); | 78 | BFS_I(inode)->i_dsk_ino = le16_to_cpu(di->i_ino); |
79 | inode->i_uid = le32_to_cpu(di->i_uid); | 79 | i_uid_write(inode, le32_to_cpu(di->i_uid)); |
80 | inode->i_gid = le32_to_cpu(di->i_gid); | 80 | i_gid_write(inode, le32_to_cpu(di->i_gid)); |
81 | set_nlink(inode, le32_to_cpu(di->i_nlink)); | 81 | set_nlink(inode, le32_to_cpu(di->i_nlink)); |
82 | inode->i_size = BFS_FILESIZE(di); | 82 | inode->i_size = BFS_FILESIZE(di); |
83 | inode->i_blocks = BFS_FILEBLOCKS(di); | 83 | inode->i_blocks = BFS_FILEBLOCKS(di); |
@@ -139,8 +139,8 @@ static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
139 | 139 | ||
140 | di->i_ino = cpu_to_le16(ino); | 140 | di->i_ino = cpu_to_le16(ino); |
141 | di->i_mode = cpu_to_le32(inode->i_mode); | 141 | di->i_mode = cpu_to_le32(inode->i_mode); |
142 | di->i_uid = cpu_to_le32(inode->i_uid); | 142 | di->i_uid = cpu_to_le32(i_uid_read(inode)); |
143 | di->i_gid = cpu_to_le32(inode->i_gid); | 143 | di->i_gid = cpu_to_le32(i_gid_read(inode)); |
144 | di->i_nlink = cpu_to_le32(inode->i_nlink); | 144 | di->i_nlink = cpu_to_le32(inode->i_nlink); |
145 | di->i_atime = cpu_to_le32(inode->i_atime.tv_sec); | 145 | di->i_atime = cpu_to_le32(inode->i_atime.tv_sec); |
146 | di->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec); | 146 | di->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec); |
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 761e2cd8fed1..0c16e3dbfd56 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c | |||
@@ -61,7 +61,7 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type) | |||
61 | size = __btrfs_getxattr(inode, name, value, size); | 61 | size = __btrfs_getxattr(inode, name, value, size); |
62 | } | 62 | } |
63 | if (size > 0) { | 63 | if (size > 0) { |
64 | acl = posix_acl_from_xattr(value, size); | 64 | acl = posix_acl_from_xattr(&init_user_ns, value, size); |
65 | } else if (size == -ENOENT || size == -ENODATA || size == 0) { | 65 | } else if (size == -ENOENT || size == -ENODATA || size == 0) { |
66 | /* FIXME, who returns -ENOENT? I think nobody */ | 66 | /* FIXME, who returns -ENOENT? I think nobody */ |
67 | acl = NULL; | 67 | acl = NULL; |
@@ -91,7 +91,7 @@ static int btrfs_xattr_acl_get(struct dentry *dentry, const char *name, | |||
91 | return PTR_ERR(acl); | 91 | return PTR_ERR(acl); |
92 | if (acl == NULL) | 92 | if (acl == NULL) |
93 | return -ENODATA; | 93 | return -ENODATA; |
94 | ret = posix_acl_to_xattr(acl, value, size); | 94 | ret = posix_acl_to_xattr(&init_user_ns, acl, value, size); |
95 | posix_acl_release(acl); | 95 | posix_acl_release(acl); |
96 | 96 | ||
97 | return ret; | 97 | return ret; |
@@ -141,7 +141,7 @@ static int btrfs_set_acl(struct btrfs_trans_handle *trans, | |||
141 | goto out; | 141 | goto out; |
142 | } | 142 | } |
143 | 143 | ||
144 | ret = posix_acl_to_xattr(acl, value, size); | 144 | ret = posix_acl_to_xattr(&init_user_ns, acl, value, size); |
145 | if (ret < 0) | 145 | if (ret < 0) |
146 | goto out; | 146 | goto out; |
147 | } | 147 | } |
@@ -169,7 +169,7 @@ static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, | |||
169 | return -EOPNOTSUPP; | 169 | return -EOPNOTSUPP; |
170 | 170 | ||
171 | if (value) { | 171 | if (value) { |
172 | acl = posix_acl_from_xattr(value, size); | 172 | acl = posix_acl_from_xattr(&init_user_ns, value, size); |
173 | if (IS_ERR(acl)) | 173 | if (IS_ERR(acl)) |
174 | return PTR_ERR(acl); | 174 | return PTR_ERR(acl); |
175 | 175 | ||
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 07d5eeb1e6f1..52c85e2b95d0 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
@@ -1715,8 +1715,8 @@ static void fill_stack_inode_item(struct btrfs_trans_handle *trans, | |||
1715 | struct btrfs_inode_item *inode_item, | 1715 | struct btrfs_inode_item *inode_item, |
1716 | struct inode *inode) | 1716 | struct inode *inode) |
1717 | { | 1717 | { |
1718 | btrfs_set_stack_inode_uid(inode_item, inode->i_uid); | 1718 | btrfs_set_stack_inode_uid(inode_item, i_uid_read(inode)); |
1719 | btrfs_set_stack_inode_gid(inode_item, inode->i_gid); | 1719 | btrfs_set_stack_inode_gid(inode_item, i_gid_read(inode)); |
1720 | btrfs_set_stack_inode_size(inode_item, BTRFS_I(inode)->disk_i_size); | 1720 | btrfs_set_stack_inode_size(inode_item, BTRFS_I(inode)->disk_i_size); |
1721 | btrfs_set_stack_inode_mode(inode_item, inode->i_mode); | 1721 | btrfs_set_stack_inode_mode(inode_item, inode->i_mode); |
1722 | btrfs_set_stack_inode_nlink(inode_item, inode->i_nlink); | 1722 | btrfs_set_stack_inode_nlink(inode_item, inode->i_nlink); |
@@ -1764,8 +1764,8 @@ int btrfs_fill_inode(struct inode *inode, u32 *rdev) | |||
1764 | 1764 | ||
1765 | inode_item = &delayed_node->inode_item; | 1765 | inode_item = &delayed_node->inode_item; |
1766 | 1766 | ||
1767 | inode->i_uid = btrfs_stack_inode_uid(inode_item); | 1767 | i_uid_write(inode, btrfs_stack_inode_uid(inode_item)); |
1768 | inode->i_gid = btrfs_stack_inode_gid(inode_item); | 1768 | i_gid_write(inode, btrfs_stack_inode_gid(inode_item)); |
1769 | btrfs_i_size_write(inode, btrfs_stack_inode_size(inode_item)); | 1769 | btrfs_i_size_write(inode, btrfs_stack_inode_size(inode_item)); |
1770 | inode->i_mode = btrfs_stack_inode_mode(inode_item); | 1770 | inode->i_mode = btrfs_stack_inode_mode(inode_item); |
1771 | set_nlink(inode, btrfs_stack_inode_nlink(inode_item)); | 1771 | set_nlink(inode, btrfs_stack_inode_nlink(inode_item)); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 316b07a866d2..2a028a58619c 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -2572,8 +2572,8 @@ static void btrfs_read_locked_inode(struct inode *inode) | |||
2572 | struct btrfs_inode_item); | 2572 | struct btrfs_inode_item); |
2573 | inode->i_mode = btrfs_inode_mode(leaf, inode_item); | 2573 | inode->i_mode = btrfs_inode_mode(leaf, inode_item); |
2574 | set_nlink(inode, btrfs_inode_nlink(leaf, inode_item)); | 2574 | set_nlink(inode, btrfs_inode_nlink(leaf, inode_item)); |
2575 | inode->i_uid = btrfs_inode_uid(leaf, inode_item); | 2575 | i_uid_write(inode, btrfs_inode_uid(leaf, inode_item)); |
2576 | inode->i_gid = btrfs_inode_gid(leaf, inode_item); | 2576 | i_gid_write(inode, btrfs_inode_gid(leaf, inode_item)); |
2577 | btrfs_i_size_write(inode, btrfs_inode_size(leaf, inode_item)); | 2577 | btrfs_i_size_write(inode, btrfs_inode_size(leaf, inode_item)); |
2578 | 2578 | ||
2579 | tspec = btrfs_inode_atime(inode_item); | 2579 | tspec = btrfs_inode_atime(inode_item); |
@@ -2651,8 +2651,8 @@ static void fill_inode_item(struct btrfs_trans_handle *trans, | |||
2651 | struct btrfs_inode_item *item, | 2651 | struct btrfs_inode_item *item, |
2652 | struct inode *inode) | 2652 | struct inode *inode) |
2653 | { | 2653 | { |
2654 | btrfs_set_inode_uid(leaf, item, inode->i_uid); | 2654 | btrfs_set_inode_uid(leaf, item, i_uid_read(inode)); |
2655 | btrfs_set_inode_gid(leaf, item, inode->i_gid); | 2655 | btrfs_set_inode_gid(leaf, item, i_gid_read(inode)); |
2656 | btrfs_set_inode_size(leaf, item, BTRFS_I(inode)->disk_i_size); | 2656 | btrfs_set_inode_size(leaf, item, BTRFS_I(inode)->disk_i_size); |
2657 | btrfs_set_inode_mode(leaf, item, inode->i_mode); | 2657 | btrfs_set_inode_mode(leaf, item, inode->i_mode); |
2658 | btrfs_set_inode_nlink(leaf, item, inode->i_nlink); | 2658 | btrfs_set_inode_nlink(leaf, item, inode->i_nlink); |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 9df50fa8a078..27bfce58da3b 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -575,13 +575,13 @@ fail: | |||
575 | */ | 575 | */ |
576 | static inline int btrfs_check_sticky(struct inode *dir, struct inode *inode) | 576 | static inline int btrfs_check_sticky(struct inode *dir, struct inode *inode) |
577 | { | 577 | { |
578 | uid_t fsuid = current_fsuid(); | 578 | kuid_t fsuid = current_fsuid(); |
579 | 579 | ||
580 | if (!(dir->i_mode & S_ISVTX)) | 580 | if (!(dir->i_mode & S_ISVTX)) |
581 | return 0; | 581 | return 0; |
582 | if (inode->i_uid == fsuid) | 582 | if (uid_eq(inode->i_uid, fsuid)) |
583 | return 0; | 583 | return 0; |
584 | if (dir->i_uid == fsuid) | 584 | if (uid_eq(dir->i_uid, fsuid)) |
585 | return 0; | 585 | return 0; |
586 | return !capable(CAP_FOWNER); | 586 | return !capable(CAP_FOWNER); |
587 | } | 587 | } |
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c index 0074362d9f7f..a9d35b0e06cf 100644 --- a/fs/configfs/inode.c +++ b/fs/configfs/inode.c | |||
@@ -79,8 +79,8 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr) | |||
79 | return -ENOMEM; | 79 | return -ENOMEM; |
80 | /* assign default attributes */ | 80 | /* assign default attributes */ |
81 | sd_iattr->ia_mode = sd->s_mode; | 81 | sd_iattr->ia_mode = sd->s_mode; |
82 | sd_iattr->ia_uid = 0; | 82 | sd_iattr->ia_uid = GLOBAL_ROOT_UID; |
83 | sd_iattr->ia_gid = 0; | 83 | sd_iattr->ia_gid = GLOBAL_ROOT_GID; |
84 | sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME; | 84 | sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME; |
85 | sd->s_iattr = sd_iattr; | 85 | sd->s_iattr = sd_iattr; |
86 | } | 86 | } |
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 28cca01ca9c9..c6c3f91ecf06 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c | |||
@@ -90,8 +90,8 @@ static struct inode *get_cramfs_inode(struct super_block *sb, | |||
90 | } | 90 | } |
91 | 91 | ||
92 | inode->i_mode = cramfs_inode->mode; | 92 | inode->i_mode = cramfs_inode->mode; |
93 | inode->i_uid = cramfs_inode->uid; | 93 | i_uid_write(inode, cramfs_inode->uid); |
94 | inode->i_gid = cramfs_inode->gid; | 94 | i_gid_write(inode, cramfs_inode->gid); |
95 | 95 | ||
96 | /* if the lower 2 bits are zero, the inode contains data */ | 96 | /* if the lower 2 bits are zero, the inode contains data */ |
97 | if (!(inode->i_ino & 3)) { | 97 | if (!(inode->i_ino & 3)) { |
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 6393fd61d5c4..b607d92cdf24 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
@@ -128,8 +128,8 @@ static inline int debugfs_positive(struct dentry *dentry) | |||
128 | } | 128 | } |
129 | 129 | ||
130 | struct debugfs_mount_opts { | 130 | struct debugfs_mount_opts { |
131 | uid_t uid; | 131 | kuid_t uid; |
132 | gid_t gid; | 132 | kgid_t gid; |
133 | umode_t mode; | 133 | umode_t mode; |
134 | }; | 134 | }; |
135 | 135 | ||
@@ -156,6 +156,8 @@ static int debugfs_parse_options(char *data, struct debugfs_mount_opts *opts) | |||
156 | substring_t args[MAX_OPT_ARGS]; | 156 | substring_t args[MAX_OPT_ARGS]; |
157 | int option; | 157 | int option; |
158 | int token; | 158 | int token; |
159 | kuid_t uid; | ||
160 | kgid_t gid; | ||
159 | char *p; | 161 | char *p; |
160 | 162 | ||
161 | opts->mode = DEBUGFS_DEFAULT_MODE; | 163 | opts->mode = DEBUGFS_DEFAULT_MODE; |
@@ -169,12 +171,18 @@ static int debugfs_parse_options(char *data, struct debugfs_mount_opts *opts) | |||
169 | case Opt_uid: | 171 | case Opt_uid: |
170 | if (match_int(&args[0], &option)) | 172 | if (match_int(&args[0], &option)) |
171 | return -EINVAL; | 173 | return -EINVAL; |
172 | opts->uid = option; | 174 | uid = make_kuid(current_user_ns(), option); |
175 | if (!uid_valid(uid)) | ||
176 | return -EINVAL; | ||
177 | opts->uid = uid; | ||
173 | break; | 178 | break; |
174 | case Opt_gid: | 179 | case Opt_gid: |
175 | if (match_octal(&args[0], &option)) | 180 | if (match_octal(&args[0], &option)) |
176 | return -EINVAL; | 181 | return -EINVAL; |
177 | opts->gid = option; | 182 | gid = make_kgid(current_user_ns(), option); |
183 | if (!gid_valid(gid)) | ||
184 | return -EINVAL; | ||
185 | opts->gid = gid; | ||
178 | break; | 186 | break; |
179 | case Opt_mode: | 187 | case Opt_mode: |
180 | if (match_octal(&args[0], &option)) | 188 | if (match_octal(&args[0], &option)) |
@@ -226,10 +234,12 @@ static int debugfs_show_options(struct seq_file *m, struct dentry *root) | |||
226 | struct debugfs_fs_info *fsi = root->d_sb->s_fs_info; | 234 | struct debugfs_fs_info *fsi = root->d_sb->s_fs_info; |
227 | struct debugfs_mount_opts *opts = &fsi->mount_opts; | 235 | struct debugfs_mount_opts *opts = &fsi->mount_opts; |
228 | 236 | ||
229 | if (opts->uid != 0) | 237 | if (!uid_eq(opts->uid, GLOBAL_ROOT_UID)) |
230 | seq_printf(m, ",uid=%u", opts->uid); | 238 | seq_printf(m, ",uid=%u", |
231 | if (opts->gid != 0) | 239 | from_kuid_munged(&init_user_ns, opts->uid)); |
232 | seq_printf(m, ",gid=%u", opts->gid); | 240 | if (!gid_eq(opts->gid, GLOBAL_ROOT_GID)) |
241 | seq_printf(m, ",gid=%u", | ||
242 | from_kgid_munged(&init_user_ns, opts->gid)); | ||
233 | if (opts->mode != DEBUGFS_DEFAULT_MODE) | 243 | if (opts->mode != DEBUGFS_DEFAULT_MODE) |
234 | seq_printf(m, ",mode=%o", opts->mode); | 244 | seq_printf(m, ",mode=%o", opts->mode); |
235 | 245 | ||
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 9b627c15010a..24bb043e50d9 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -545,11 +545,12 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags | |||
545 | goto out_free; | 545 | goto out_free; |
546 | } | 546 | } |
547 | 547 | ||
548 | if (check_ruid && path.dentry->d_inode->i_uid != current_uid()) { | 548 | if (check_ruid && !uid_eq(path.dentry->d_inode->i_uid, current_uid())) { |
549 | rc = -EPERM; | 549 | rc = -EPERM; |
550 | printk(KERN_ERR "Mount of device (uid: %d) not owned by " | 550 | printk(KERN_ERR "Mount of device (uid: %d) not owned by " |
551 | "requested user (uid: %d)\n", | 551 | "requested user (uid: %d)\n", |
552 | path.dentry->d_inode->i_uid, current_uid()); | 552 | i_uid_read(path.dentry->d_inode), |
553 | from_kuid(&init_user_ns, current_uid())); | ||
553 | goto out_free; | 554 | goto out_free; |
554 | } | 555 | } |
555 | 556 | ||
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c index b29bb8bfa8d9..5fa2471796c2 100644 --- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c | |||
@@ -33,7 +33,7 @@ static struct hlist_head *ecryptfs_daemon_hash; | |||
33 | struct mutex ecryptfs_daemon_hash_mux; | 33 | struct mutex ecryptfs_daemon_hash_mux; |
34 | static int ecryptfs_hash_bits; | 34 | static int ecryptfs_hash_bits; |
35 | #define ecryptfs_current_euid_hash(uid) \ | 35 | #define ecryptfs_current_euid_hash(uid) \ |
36 | hash_long((unsigned long)current_euid(), ecryptfs_hash_bits) | 36 | hash_long((unsigned long)from_kuid(&init_user_ns, current_euid()), ecryptfs_hash_bits) |
37 | 37 | ||
38 | static u32 ecryptfs_msg_counter; | 38 | static u32 ecryptfs_msg_counter; |
39 | static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; | 39 | static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; |
@@ -121,8 +121,7 @@ int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon) | |||
121 | hlist_for_each_entry(*daemon, elem, | 121 | hlist_for_each_entry(*daemon, elem, |
122 | &ecryptfs_daemon_hash[ecryptfs_current_euid_hash()], | 122 | &ecryptfs_daemon_hash[ecryptfs_current_euid_hash()], |
123 | euid_chain) { | 123 | euid_chain) { |
124 | if ((*daemon)->file->f_cred->euid == current_euid() && | 124 | if (uid_eq((*daemon)->file->f_cred->euid, current_euid())) { |
125 | (*daemon)->file->f_cred->user_ns == current_user_ns()) { | ||
126 | rc = 0; | 125 | rc = 0; |
127 | goto out; | 126 | goto out; |
128 | } | 127 | } |
diff --git a/fs/efs/inode.c b/fs/efs/inode.c index bc84f365d75c..f3913eb2c474 100644 --- a/fs/efs/inode.c +++ b/fs/efs/inode.c | |||
@@ -97,8 +97,8 @@ struct inode *efs_iget(struct super_block *super, unsigned long ino) | |||
97 | 97 | ||
98 | inode->i_mode = be16_to_cpu(efs_inode->di_mode); | 98 | inode->i_mode = be16_to_cpu(efs_inode->di_mode); |
99 | set_nlink(inode, be16_to_cpu(efs_inode->di_nlink)); | 99 | set_nlink(inode, be16_to_cpu(efs_inode->di_nlink)); |
100 | inode->i_uid = (uid_t)be16_to_cpu(efs_inode->di_uid); | 100 | i_uid_write(inode, (uid_t)be16_to_cpu(efs_inode->di_uid)); |
101 | inode->i_gid = (gid_t)be16_to_cpu(efs_inode->di_gid); | 101 | i_gid_write(inode, (gid_t)be16_to_cpu(efs_inode->di_gid)); |
102 | inode->i_size = be32_to_cpu(efs_inode->di_size); | 102 | inode->i_size = be32_to_cpu(efs_inode->di_size); |
103 | inode->i_atime.tv_sec = be32_to_cpu(efs_inode->di_atime); | 103 | inode->i_atime.tv_sec = be32_to_cpu(efs_inode->di_atime); |
104 | inode->i_mtime.tv_sec = be32_to_cpu(efs_inode->di_mtime); | 104 | inode->i_mtime.tv_sec = be32_to_cpu(efs_inode->di_mtime); |
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 1562c27a2fab..b56181047751 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
@@ -1172,8 +1172,8 @@ struct inode *exofs_iget(struct super_block *sb, unsigned long ino) | |||
1172 | 1172 | ||
1173 | /* copy stuff from on-disk struct to in-memory struct */ | 1173 | /* copy stuff from on-disk struct to in-memory struct */ |
1174 | inode->i_mode = le16_to_cpu(fcb.i_mode); | 1174 | inode->i_mode = le16_to_cpu(fcb.i_mode); |
1175 | inode->i_uid = le32_to_cpu(fcb.i_uid); | 1175 | i_uid_write(inode, le32_to_cpu(fcb.i_uid)); |
1176 | inode->i_gid = le32_to_cpu(fcb.i_gid); | 1176 | i_gid_write(inode, le32_to_cpu(fcb.i_gid)); |
1177 | set_nlink(inode, le16_to_cpu(fcb.i_links_count)); | 1177 | set_nlink(inode, le16_to_cpu(fcb.i_links_count)); |
1178 | inode->i_ctime.tv_sec = (signed)le32_to_cpu(fcb.i_ctime); | 1178 | inode->i_ctime.tv_sec = (signed)le32_to_cpu(fcb.i_ctime); |
1179 | inode->i_atime.tv_sec = (signed)le32_to_cpu(fcb.i_atime); | 1179 | inode->i_atime.tv_sec = (signed)le32_to_cpu(fcb.i_atime); |
@@ -1385,8 +1385,8 @@ static int exofs_update_inode(struct inode *inode, int do_sync) | |||
1385 | fcb = &args->fcb; | 1385 | fcb = &args->fcb; |
1386 | 1386 | ||
1387 | fcb->i_mode = cpu_to_le16(inode->i_mode); | 1387 | fcb->i_mode = cpu_to_le16(inode->i_mode); |
1388 | fcb->i_uid = cpu_to_le32(inode->i_uid); | 1388 | fcb->i_uid = cpu_to_le32(i_uid_read(inode)); |
1389 | fcb->i_gid = cpu_to_le32(inode->i_gid); | 1389 | fcb->i_gid = cpu_to_le32(i_gid_read(inode)); |
1390 | fcb->i_links_count = cpu_to_le16(inode->i_nlink); | 1390 | fcb->i_links_count = cpu_to_le16(inode->i_nlink); |
1391 | fcb->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec); | 1391 | fcb->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec); |
1392 | fcb->i_atime = cpu_to_le32(inode->i_atime.tv_sec); | 1392 | fcb->i_atime = cpu_to_le32(inode->i_atime.tv_sec); |
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index 35d6a3cfd9ff..110b6b371a4e 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c | |||
@@ -53,16 +53,23 @@ ext2_acl_from_disk(const void *value, size_t size) | |||
53 | case ACL_OTHER: | 53 | case ACL_OTHER: |
54 | value = (char *)value + | 54 | value = (char *)value + |
55 | sizeof(ext2_acl_entry_short); | 55 | sizeof(ext2_acl_entry_short); |
56 | acl->a_entries[n].e_id = ACL_UNDEFINED_ID; | ||
57 | break; | 56 | break; |
58 | 57 | ||
59 | case ACL_USER: | 58 | case ACL_USER: |
59 | value = (char *)value + sizeof(ext2_acl_entry); | ||
60 | if ((char *)value > end) | ||
61 | goto fail; | ||
62 | acl->a_entries[n].e_uid = | ||
63 | make_kuid(&init_user_ns, | ||
64 | le32_to_cpu(entry->e_id)); | ||
65 | break; | ||
60 | case ACL_GROUP: | 66 | case ACL_GROUP: |
61 | value = (char *)value + sizeof(ext2_acl_entry); | 67 | value = (char *)value + sizeof(ext2_acl_entry); |
62 | if ((char *)value > end) | 68 | if ((char *)value > end) |
63 | goto fail; | 69 | goto fail; |
64 | acl->a_entries[n].e_id = | 70 | acl->a_entries[n].e_gid = |
65 | le32_to_cpu(entry->e_id); | 71 | make_kgid(&init_user_ns, |
72 | le32_to_cpu(entry->e_id)); | ||
66 | break; | 73 | break; |
67 | 74 | ||
68 | default: | 75 | default: |
@@ -96,14 +103,19 @@ ext2_acl_to_disk(const struct posix_acl *acl, size_t *size) | |||
96 | ext_acl->a_version = cpu_to_le32(EXT2_ACL_VERSION); | 103 | ext_acl->a_version = cpu_to_le32(EXT2_ACL_VERSION); |
97 | e = (char *)ext_acl + sizeof(ext2_acl_header); | 104 | e = (char *)ext_acl + sizeof(ext2_acl_header); |
98 | for (n=0; n < acl->a_count; n++) { | 105 | for (n=0; n < acl->a_count; n++) { |
106 | const struct posix_acl_entry *acl_e = &acl->a_entries[n]; | ||
99 | ext2_acl_entry *entry = (ext2_acl_entry *)e; | 107 | ext2_acl_entry *entry = (ext2_acl_entry *)e; |
100 | entry->e_tag = cpu_to_le16(acl->a_entries[n].e_tag); | 108 | entry->e_tag = cpu_to_le16(acl_e->e_tag); |
101 | entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm); | 109 | entry->e_perm = cpu_to_le16(acl_e->e_perm); |
102 | switch(acl->a_entries[n].e_tag) { | 110 | switch(acl_e->e_tag) { |
103 | case ACL_USER: | 111 | case ACL_USER: |
112 | entry->e_id = cpu_to_le32( | ||
113 | from_kuid(&init_user_ns, acl_e->e_uid)); | ||
114 | e += sizeof(ext2_acl_entry); | ||
115 | break; | ||
104 | case ACL_GROUP: | 116 | case ACL_GROUP: |
105 | entry->e_id = | 117 | entry->e_id = cpu_to_le32( |
106 | cpu_to_le32(acl->a_entries[n].e_id); | 118 | from_kgid(&init_user_ns, acl_e->e_gid)); |
107 | e += sizeof(ext2_acl_entry); | 119 | e += sizeof(ext2_acl_entry); |
108 | break; | 120 | break; |
109 | 121 | ||
@@ -350,7 +362,7 @@ ext2_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer, | |||
350 | return PTR_ERR(acl); | 362 | return PTR_ERR(acl); |
351 | if (acl == NULL) | 363 | if (acl == NULL) |
352 | return -ENODATA; | 364 | return -ENODATA; |
353 | error = posix_acl_to_xattr(acl, buffer, size); | 365 | error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); |
354 | posix_acl_release(acl); | 366 | posix_acl_release(acl); |
355 | 367 | ||
356 | return error; | 368 | return error; |
@@ -371,7 +383,7 @@ ext2_xattr_set_acl(struct dentry *dentry, const char *name, const void *value, | |||
371 | return -EPERM; | 383 | return -EPERM; |
372 | 384 | ||
373 | if (value) { | 385 | if (value) { |
374 | acl = posix_acl_from_xattr(value, size); | 386 | acl = posix_acl_from_xattr(&init_user_ns, value, size); |
375 | if (IS_ERR(acl)) | 387 | if (IS_ERR(acl)) |
376 | return PTR_ERR(acl); | 388 | return PTR_ERR(acl); |
377 | else if (acl) { | 389 | else if (acl) { |
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index c76832c8d192..dbb5ad59a7fc 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c | |||
@@ -48,16 +48,23 @@ ext3_acl_from_disk(const void *value, size_t size) | |||
48 | case ACL_OTHER: | 48 | case ACL_OTHER: |
49 | value = (char *)value + | 49 | value = (char *)value + |
50 | sizeof(ext3_acl_entry_short); | 50 | sizeof(ext3_acl_entry_short); |
51 | acl->a_entries[n].e_id = ACL_UNDEFINED_ID; | ||
52 | break; | 51 | break; |
53 | 52 | ||
54 | case ACL_USER: | 53 | case ACL_USER: |
54 | value = (char *)value + sizeof(ext3_acl_entry); | ||
55 | if ((char *)value > end) | ||
56 | goto fail; | ||
57 | acl->a_entries[n].e_uid = | ||
58 | make_kuid(&init_user_ns, | ||
59 | le32_to_cpu(entry->e_id)); | ||
60 | break; | ||
55 | case ACL_GROUP: | 61 | case ACL_GROUP: |
56 | value = (char *)value + sizeof(ext3_acl_entry); | 62 | value = (char *)value + sizeof(ext3_acl_entry); |
57 | if ((char *)value > end) | 63 | if ((char *)value > end) |
58 | goto fail; | 64 | goto fail; |
59 | acl->a_entries[n].e_id = | 65 | acl->a_entries[n].e_gid = |
60 | le32_to_cpu(entry->e_id); | 66 | make_kgid(&init_user_ns, |
67 | le32_to_cpu(entry->e_id)); | ||
61 | break; | 68 | break; |
62 | 69 | ||
63 | default: | 70 | default: |
@@ -91,14 +98,19 @@ ext3_acl_to_disk(const struct posix_acl *acl, size_t *size) | |||
91 | ext_acl->a_version = cpu_to_le32(EXT3_ACL_VERSION); | 98 | ext_acl->a_version = cpu_to_le32(EXT3_ACL_VERSION); |
92 | e = (char *)ext_acl + sizeof(ext3_acl_header); | 99 | e = (char *)ext_acl + sizeof(ext3_acl_header); |
93 | for (n=0; n < acl->a_count; n++) { | 100 | for (n=0; n < acl->a_count; n++) { |
101 | const struct posix_acl_entry *acl_e = &acl->a_entries[n]; | ||
94 | ext3_acl_entry *entry = (ext3_acl_entry *)e; | 102 | ext3_acl_entry *entry = (ext3_acl_entry *)e; |
95 | entry->e_tag = cpu_to_le16(acl->a_entries[n].e_tag); | 103 | entry->e_tag = cpu_to_le16(acl_e->e_tag); |
96 | entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm); | 104 | entry->e_perm = cpu_to_le16(acl_e->e_perm); |
97 | switch(acl->a_entries[n].e_tag) { | 105 | switch(acl_e->e_tag) { |
98 | case ACL_USER: | 106 | case ACL_USER: |
107 | entry->e_id = cpu_to_le32( | ||
108 | from_kuid(&init_user_ns, acl_e->e_uid)); | ||
109 | e += sizeof(ext3_acl_entry); | ||
110 | break; | ||
99 | case ACL_GROUP: | 111 | case ACL_GROUP: |
100 | entry->e_id = | 112 | entry->e_id = cpu_to_le32( |
101 | cpu_to_le32(acl->a_entries[n].e_id); | 113 | from_kgid(&init_user_ns, acl_e->e_gid)); |
102 | e += sizeof(ext3_acl_entry); | 114 | e += sizeof(ext3_acl_entry); |
103 | break; | 115 | break; |
104 | 116 | ||
@@ -369,7 +381,7 @@ ext3_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer, | |||
369 | return PTR_ERR(acl); | 381 | return PTR_ERR(acl); |
370 | if (acl == NULL) | 382 | if (acl == NULL) |
371 | return -ENODATA; | 383 | return -ENODATA; |
372 | error = posix_acl_to_xattr(acl, buffer, size); | 384 | error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); |
373 | posix_acl_release(acl); | 385 | posix_acl_release(acl); |
374 | 386 | ||
375 | return error; | 387 | return error; |
@@ -392,7 +404,7 @@ ext3_xattr_set_acl(struct dentry *dentry, const char *name, const void *value, | |||
392 | return -EPERM; | 404 | return -EPERM; |
393 | 405 | ||
394 | if (value) { | 406 | if (value) { |
395 | acl = posix_acl_from_xattr(value, size); | 407 | acl = posix_acl_from_xattr(&init_user_ns, value, size); |
396 | if (IS_ERR(acl)) | 408 | if (IS_ERR(acl)) |
397 | return PTR_ERR(acl); | 409 | return PTR_ERR(acl); |
398 | else if (acl) { | 410 | else if (acl) { |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 8c892e93d8e7..09b8455bd7eb 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -2803,7 +2803,7 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2803 | 2803 | ||
2804 | static inline struct inode *dquot_to_inode(struct dquot *dquot) | 2804 | static inline struct inode *dquot_to_inode(struct dquot *dquot) |
2805 | { | 2805 | { |
2806 | return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; | 2806 | return sb_dqopt(dquot->dq_sb)->files[dquot->dq_id.type]; |
2807 | } | 2807 | } |
2808 | 2808 | ||
2809 | static int ext3_write_dquot(struct dquot *dquot) | 2809 | static int ext3_write_dquot(struct dquot *dquot) |
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index a5c29bb3b835..d3c5b88fd89f 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c | |||
@@ -55,16 +55,23 @@ ext4_acl_from_disk(const void *value, size_t size) | |||
55 | case ACL_OTHER: | 55 | case ACL_OTHER: |
56 | value = (char *)value + | 56 | value = (char *)value + |
57 | sizeof(ext4_acl_entry_short); | 57 | sizeof(ext4_acl_entry_short); |
58 | acl->a_entries[n].e_id = ACL_UNDEFINED_ID; | ||
59 | break; | 58 | break; |
60 | 59 | ||
61 | case ACL_USER: | 60 | case ACL_USER: |
61 | value = (char *)value + sizeof(ext4_acl_entry); | ||
62 | if ((char *)value > end) | ||
63 | goto fail; | ||
64 | acl->a_entries[n].e_uid = | ||
65 | make_kuid(&init_user_ns, | ||
66 | le32_to_cpu(entry->e_id)); | ||
67 | break; | ||
62 | case ACL_GROUP: | 68 | case ACL_GROUP: |
63 | value = (char *)value + sizeof(ext4_acl_entry); | 69 | value = (char *)value + sizeof(ext4_acl_entry); |
64 | if ((char *)value > end) | 70 | if ((char *)value > end) |
65 | goto fail; | 71 | goto fail; |
66 | acl->a_entries[n].e_id = | 72 | acl->a_entries[n].e_gid = |
67 | le32_to_cpu(entry->e_id); | 73 | make_kgid(&init_user_ns, |
74 | le32_to_cpu(entry->e_id)); | ||
68 | break; | 75 | break; |
69 | 76 | ||
70 | default: | 77 | default: |
@@ -98,13 +105,19 @@ ext4_acl_to_disk(const struct posix_acl *acl, size_t *size) | |||
98 | ext_acl->a_version = cpu_to_le32(EXT4_ACL_VERSION); | 105 | ext_acl->a_version = cpu_to_le32(EXT4_ACL_VERSION); |
99 | e = (char *)ext_acl + sizeof(ext4_acl_header); | 106 | e = (char *)ext_acl + sizeof(ext4_acl_header); |
100 | for (n = 0; n < acl->a_count; n++) { | 107 | for (n = 0; n < acl->a_count; n++) { |
108 | const struct posix_acl_entry *acl_e = &acl->a_entries[n]; | ||
101 | ext4_acl_entry *entry = (ext4_acl_entry *)e; | 109 | ext4_acl_entry *entry = (ext4_acl_entry *)e; |
102 | entry->e_tag = cpu_to_le16(acl->a_entries[n].e_tag); | 110 | entry->e_tag = cpu_to_le16(acl_e->e_tag); |
103 | entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm); | 111 | entry->e_perm = cpu_to_le16(acl_e->e_perm); |
104 | switch (acl->a_entries[n].e_tag) { | 112 | switch (acl_e->e_tag) { |
105 | case ACL_USER: | 113 | case ACL_USER: |
114 | entry->e_id = cpu_to_le32( | ||
115 | from_kuid(&init_user_ns, acl_e->e_uid)); | ||
116 | e += sizeof(ext4_acl_entry); | ||
117 | break; | ||
106 | case ACL_GROUP: | 118 | case ACL_GROUP: |
107 | entry->e_id = cpu_to_le32(acl->a_entries[n].e_id); | 119 | entry->e_id = cpu_to_le32( |
120 | from_kgid(&init_user_ns, acl_e->e_gid)); | ||
108 | e += sizeof(ext4_acl_entry); | 121 | e += sizeof(ext4_acl_entry); |
109 | break; | 122 | break; |
110 | 123 | ||
@@ -374,7 +387,7 @@ ext4_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer, | |||
374 | return PTR_ERR(acl); | 387 | return PTR_ERR(acl); |
375 | if (acl == NULL) | 388 | if (acl == NULL) |
376 | return -ENODATA; | 389 | return -ENODATA; |
377 | error = posix_acl_to_xattr(acl, buffer, size); | 390 | error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); |
378 | posix_acl_release(acl); | 391 | posix_acl_release(acl); |
379 | 392 | ||
380 | return error; | 393 | return error; |
@@ -397,7 +410,7 @@ ext4_xattr_set_acl(struct dentry *dentry, const char *name, const void *value, | |||
397 | return -EPERM; | 410 | return -EPERM; |
398 | 411 | ||
399 | if (value) { | 412 | if (value) { |
400 | acl = posix_acl_from_xattr(value, size); | 413 | acl = posix_acl_from_xattr(&init_user_ns, value, size); |
401 | if (IS_ERR(acl)) | 414 | if (IS_ERR(acl)) |
402 | return PTR_ERR(acl); | 415 | return PTR_ERR(acl); |
403 | else if (acl) { | 416 | else if (acl) { |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index c6e0cb3d1f4a..1f15cc836fbd 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -4791,7 +4791,7 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
4791 | 4791 | ||
4792 | static inline struct inode *dquot_to_inode(struct dquot *dquot) | 4792 | static inline struct inode *dquot_to_inode(struct dquot *dquot) |
4793 | { | 4793 | { |
4794 | return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; | 4794 | return sb_dqopt(dquot->dq_sb)->files[dquot->dq_id.type]; |
4795 | } | 4795 | } |
4796 | 4796 | ||
4797 | static int ext4_write_dquot(struct dquot *dquot) | 4797 | static int ext4_write_dquot(struct dquot *dquot) |
diff --git a/fs/fat/fat.h b/fs/fat/fat.h index 2deeeb86f331..7d8e0dcac5d5 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h | |||
@@ -23,8 +23,8 @@ | |||
23 | #define FAT_ERRORS_RO 3 /* remount r/o on error */ | 23 | #define FAT_ERRORS_RO 3 /* remount r/o on error */ |
24 | 24 | ||
25 | struct fat_mount_options { | 25 | struct fat_mount_options { |
26 | uid_t fs_uid; | 26 | kuid_t fs_uid; |
27 | gid_t fs_gid; | 27 | kgid_t fs_gid; |
28 | unsigned short fs_fmask; | 28 | unsigned short fs_fmask; |
29 | unsigned short fs_dmask; | 29 | unsigned short fs_dmask; |
30 | unsigned short codepage; /* Codepage for shortname conversions */ | 30 | unsigned short codepage; /* Codepage for shortname conversions */ |
diff --git a/fs/fat/file.c b/fs/fat/file.c index e007b8bd8e5e..a62e0ecbe2db 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
@@ -352,7 +352,7 @@ static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode) | |||
352 | { | 352 | { |
353 | umode_t allow_utime = sbi->options.allow_utime; | 353 | umode_t allow_utime = sbi->options.allow_utime; |
354 | 354 | ||
355 | if (current_fsuid() != inode->i_uid) { | 355 | if (!uid_eq(current_fsuid(), inode->i_uid)) { |
356 | if (in_group_p(inode->i_gid)) | 356 | if (in_group_p(inode->i_gid)) |
357 | allow_utime >>= 3; | 357 | allow_utime >>= 3; |
358 | if (allow_utime & MAY_WRITE) | 358 | if (allow_utime & MAY_WRITE) |
@@ -407,9 +407,9 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) | |||
407 | } | 407 | } |
408 | 408 | ||
409 | if (((attr->ia_valid & ATTR_UID) && | 409 | if (((attr->ia_valid & ATTR_UID) && |
410 | (attr->ia_uid != sbi->options.fs_uid)) || | 410 | (!uid_eq(attr->ia_uid, sbi->options.fs_uid))) || |
411 | ((attr->ia_valid & ATTR_GID) && | 411 | ((attr->ia_valid & ATTR_GID) && |
412 | (attr->ia_gid != sbi->options.fs_gid)) || | 412 | (!gid_eq(attr->ia_gid, sbi->options.fs_gid))) || |
413 | ((attr->ia_valid & ATTR_MODE) && | 413 | ((attr->ia_valid & ATTR_MODE) && |
414 | (attr->ia_mode & ~FAT_VALID_MODE))) | 414 | (attr->ia_mode & ~FAT_VALID_MODE))) |
415 | error = -EPERM; | 415 | error = -EPERM; |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 05e897fe9866..47d9eb0be886 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -791,10 +791,12 @@ static int fat_show_options(struct seq_file *m, struct dentry *root) | |||
791 | struct fat_mount_options *opts = &sbi->options; | 791 | struct fat_mount_options *opts = &sbi->options; |
792 | int isvfat = opts->isvfat; | 792 | int isvfat = opts->isvfat; |
793 | 793 | ||
794 | if (opts->fs_uid != 0) | 794 | if (!uid_eq(opts->fs_uid, GLOBAL_ROOT_UID)) |
795 | seq_printf(m, ",uid=%u", opts->fs_uid); | 795 | seq_printf(m, ",uid=%u", |
796 | if (opts->fs_gid != 0) | 796 | from_kuid_munged(&init_user_ns, opts->fs_uid)); |
797 | seq_printf(m, ",gid=%u", opts->fs_gid); | 797 | if (!gid_eq(opts->fs_gid, GLOBAL_ROOT_GID)) |
798 | seq_printf(m, ",gid=%u", | ||
799 | from_kgid_munged(&init_user_ns, opts->fs_gid)); | ||
798 | seq_printf(m, ",fmask=%04o", opts->fs_fmask); | 800 | seq_printf(m, ",fmask=%04o", opts->fs_fmask); |
799 | seq_printf(m, ",dmask=%04o", opts->fs_dmask); | 801 | seq_printf(m, ",dmask=%04o", opts->fs_dmask); |
800 | if (opts->allow_utime) | 802 | if (opts->allow_utime) |
@@ -1037,12 +1039,16 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat, | |||
1037 | case Opt_uid: | 1039 | case Opt_uid: |
1038 | if (match_int(&args[0], &option)) | 1040 | if (match_int(&args[0], &option)) |
1039 | return 0; | 1041 | return 0; |
1040 | opts->fs_uid = option; | 1042 | opts->fs_uid = make_kuid(current_user_ns(), option); |
1043 | if (!uid_valid(opts->fs_uid)) | ||
1044 | return 0; | ||
1041 | break; | 1045 | break; |
1042 | case Opt_gid: | 1046 | case Opt_gid: |
1043 | if (match_int(&args[0], &option)) | 1047 | if (match_int(&args[0], &option)) |
1044 | return 0; | 1048 | return 0; |
1045 | opts->fs_gid = option; | 1049 | opts->fs_gid = make_kgid(current_user_ns(), option); |
1050 | if (!gid_valid(opts->fs_gid)) | ||
1051 | return 0; | ||
1046 | break; | 1052 | break; |
1047 | case Opt_umask: | 1053 | case Opt_umask: |
1048 | if (match_octal(&args[0], &option)) | 1054 | if (match_octal(&args[0], &option)) |
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c index ef67c95f12d4..f47df72cef17 100644 --- a/fs/freevxfs/vxfs_inode.c +++ b/fs/freevxfs/vxfs_inode.c | |||
@@ -224,8 +224,8 @@ vxfs_iinit(struct inode *ip, struct vxfs_inode_info *vip) | |||
224 | { | 224 | { |
225 | 225 | ||
226 | ip->i_mode = vxfs_transmod(vip); | 226 | ip->i_mode = vxfs_transmod(vip); |
227 | ip->i_uid = (uid_t)vip->vii_uid; | 227 | i_uid_write(ip, (uid_t)vip->vii_uid); |
228 | ip->i_gid = (gid_t)vip->vii_gid; | 228 | i_gid_write(ip, (gid_t)vip->vii_gid); |
229 | 229 | ||
230 | set_nlink(ip, vip->vii_nlink); | 230 | set_nlink(ip, vip->vii_nlink); |
231 | ip->i_size = vip->vii_size; | 231 | ip->i_size = vip->vii_size; |
diff --git a/fs/generic_acl.c b/fs/generic_acl.c index d0dddaceac59..b3f3676796d3 100644 --- a/fs/generic_acl.c +++ b/fs/generic_acl.c | |||
@@ -56,7 +56,7 @@ generic_acl_get(struct dentry *dentry, const char *name, void *buffer, | |||
56 | acl = get_cached_acl(dentry->d_inode, type); | 56 | acl = get_cached_acl(dentry->d_inode, type); |
57 | if (!acl) | 57 | if (!acl) |
58 | return -ENODATA; | 58 | return -ENODATA; |
59 | error = posix_acl_to_xattr(acl, buffer, size); | 59 | error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); |
60 | posix_acl_release(acl); | 60 | posix_acl_release(acl); |
61 | 61 | ||
62 | return error; | 62 | return error; |
@@ -77,7 +77,7 @@ generic_acl_set(struct dentry *dentry, const char *name, const void *value, | |||
77 | if (!inode_owner_or_capable(inode)) | 77 | if (!inode_owner_or_capable(inode)) |
78 | return -EPERM; | 78 | return -EPERM; |
79 | if (value) { | 79 | if (value) { |
80 | acl = posix_acl_from_xattr(value, size); | 80 | acl = posix_acl_from_xattr(&init_user_ns, value, size); |
81 | if (IS_ERR(acl)) | 81 | if (IS_ERR(acl)) |
82 | return PTR_ERR(acl); | 82 | return PTR_ERR(acl); |
83 | } | 83 | } |
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index bd4a5892c93c..f850020ad906 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c | |||
@@ -63,7 +63,7 @@ struct posix_acl *gfs2_get_acl(struct inode *inode, int type) | |||
63 | if (len == 0) | 63 | if (len == 0) |
64 | return NULL; | 64 | return NULL; |
65 | 65 | ||
66 | acl = posix_acl_from_xattr(data, len); | 66 | acl = posix_acl_from_xattr(&init_user_ns, data, len); |
67 | kfree(data); | 67 | kfree(data); |
68 | return acl; | 68 | return acl; |
69 | } | 69 | } |
@@ -88,13 +88,13 @@ static int gfs2_acl_set(struct inode *inode, int type, struct posix_acl *acl) | |||
88 | const char *name = gfs2_acl_name(type); | 88 | const char *name = gfs2_acl_name(type); |
89 | 89 | ||
90 | BUG_ON(name == NULL); | 90 | BUG_ON(name == NULL); |
91 | len = posix_acl_to_xattr(acl, NULL, 0); | 91 | len = posix_acl_to_xattr(&init_user_ns, acl, NULL, 0); |
92 | if (len == 0) | 92 | if (len == 0) |
93 | return 0; | 93 | return 0; |
94 | data = kmalloc(len, GFP_NOFS); | 94 | data = kmalloc(len, GFP_NOFS); |
95 | if (data == NULL) | 95 | if (data == NULL) |
96 | return -ENOMEM; | 96 | return -ENOMEM; |
97 | error = posix_acl_to_xattr(acl, data, len); | 97 | error = posix_acl_to_xattr(&init_user_ns, acl, data, len); |
98 | if (error < 0) | 98 | if (error < 0) |
99 | goto out; | 99 | goto out; |
100 | error = __gfs2_xattr_set(inode, name, data, len, 0, GFS2_EATYPE_SYS); | 100 | error = __gfs2_xattr_set(inode, name, data, len, 0, GFS2_EATYPE_SYS); |
@@ -166,12 +166,12 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) | |||
166 | if (error) | 166 | if (error) |
167 | return error; | 167 | return error; |
168 | 168 | ||
169 | len = posix_acl_to_xattr(acl, NULL, 0); | 169 | len = posix_acl_to_xattr(&init_user_ns, acl, NULL, 0); |
170 | data = kmalloc(len, GFP_NOFS); | 170 | data = kmalloc(len, GFP_NOFS); |
171 | error = -ENOMEM; | 171 | error = -ENOMEM; |
172 | if (data == NULL) | 172 | if (data == NULL) |
173 | goto out; | 173 | goto out; |
174 | posix_acl_to_xattr(acl, data, len); | 174 | posix_acl_to_xattr(&init_user_ns, acl, data, len); |
175 | error = gfs2_xattr_acl_chmod(ip, attr, data); | 175 | error = gfs2_xattr_acl_chmod(ip, attr, data); |
176 | kfree(data); | 176 | kfree(data); |
177 | set_cached_acl(&ip->i_inode, ACL_TYPE_ACCESS, acl); | 177 | set_cached_acl(&ip->i_inode, ACL_TYPE_ACCESS, acl); |
@@ -212,7 +212,7 @@ static int gfs2_xattr_system_get(struct dentry *dentry, const char *name, | |||
212 | if (acl == NULL) | 212 | if (acl == NULL) |
213 | return -ENODATA; | 213 | return -ENODATA; |
214 | 214 | ||
215 | error = posix_acl_to_xattr(acl, buffer, size); | 215 | error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); |
216 | posix_acl_release(acl); | 216 | posix_acl_release(acl); |
217 | 217 | ||
218 | return error; | 218 | return error; |
@@ -245,7 +245,7 @@ static int gfs2_xattr_system_set(struct dentry *dentry, const char *name, | |||
245 | if (!value) | 245 | if (!value) |
246 | goto set_acl; | 246 | goto set_acl; |
247 | 247 | ||
248 | acl = posix_acl_from_xattr(value, size); | 248 | acl = posix_acl_from_xattr(&init_user_ns, value, size); |
249 | if (!acl) { | 249 | if (!acl) { |
250 | /* | 250 | /* |
251 | * acl_set_file(3) may request that we set default ACLs with | 251 | * acl_set_file(3) may request that we set default ACLs with |
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 4021deca61ef..40c4b0d42fa8 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -1071,8 +1071,10 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
1071 | 1071 | ||
1072 | if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) { | 1072 | if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) { |
1073 | print_message(qd, "exceeded"); | 1073 | print_message(qd, "exceeded"); |
1074 | quota_send_warning(test_bit(QDF_USER, &qd->qd_flags) ? | 1074 | quota_send_warning(make_kqid(&init_user_ns, |
1075 | USRQUOTA : GRPQUOTA, qd->qd_id, | 1075 | test_bit(QDF_USER, &qd->qd_flags) ? |
1076 | USRQUOTA : GRPQUOTA, | ||
1077 | qd->qd_id), | ||
1076 | sdp->sd_vfs->s_dev, QUOTA_NL_BHARDWARN); | 1078 | sdp->sd_vfs->s_dev, QUOTA_NL_BHARDWARN); |
1077 | 1079 | ||
1078 | error = -EDQUOT; | 1080 | error = -EDQUOT; |
@@ -1082,8 +1084,10 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
1082 | time_after_eq(jiffies, qd->qd_last_warn + | 1084 | time_after_eq(jiffies, qd->qd_last_warn + |
1083 | gfs2_tune_get(sdp, | 1085 | gfs2_tune_get(sdp, |
1084 | gt_quota_warn_period) * HZ)) { | 1086 | gt_quota_warn_period) * HZ)) { |
1085 | quota_send_warning(test_bit(QDF_USER, &qd->qd_flags) ? | 1087 | quota_send_warning(make_kqid(&init_user_ns, |
1086 | USRQUOTA : GRPQUOTA, qd->qd_id, | 1088 | test_bit(QDF_USER, &qd->qd_flags) ? |
1089 | USRQUOTA : GRPQUOTA, | ||
1090 | qd->qd_id), | ||
1087 | sdp->sd_vfs->s_dev, QUOTA_NL_BSOFTWARN); | 1091 | sdp->sd_vfs->s_dev, QUOTA_NL_BSOFTWARN); |
1088 | error = print_message(qd, "warning"); | 1092 | error = print_message(qd, "warning"); |
1089 | qd->qd_last_warn = jiffies; | 1093 | qd->qd_last_warn = jiffies; |
@@ -1470,7 +1474,7 @@ static int gfs2_quota_get_xstate(struct super_block *sb, | |||
1470 | return 0; | 1474 | return 0; |
1471 | } | 1475 | } |
1472 | 1476 | ||
1473 | static int gfs2_get_dqblk(struct super_block *sb, int type, qid_t id, | 1477 | static int gfs2_get_dqblk(struct super_block *sb, struct kqid qid, |
1474 | struct fs_disk_quota *fdq) | 1478 | struct fs_disk_quota *fdq) |
1475 | { | 1479 | { |
1476 | struct gfs2_sbd *sdp = sb->s_fs_info; | 1480 | struct gfs2_sbd *sdp = sb->s_fs_info; |
@@ -1478,20 +1482,21 @@ static int gfs2_get_dqblk(struct super_block *sb, int type, qid_t id, | |||
1478 | struct gfs2_quota_data *qd; | 1482 | struct gfs2_quota_data *qd; |
1479 | struct gfs2_holder q_gh; | 1483 | struct gfs2_holder q_gh; |
1480 | int error; | 1484 | int error; |
1485 | int type; | ||
1481 | 1486 | ||
1482 | memset(fdq, 0, sizeof(struct fs_disk_quota)); | 1487 | memset(fdq, 0, sizeof(struct fs_disk_quota)); |
1483 | 1488 | ||
1484 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | 1489 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) |
1485 | return -ESRCH; /* Crazy XFS error code */ | 1490 | return -ESRCH; /* Crazy XFS error code */ |
1486 | 1491 | ||
1487 | if (type == USRQUOTA) | 1492 | if (qid.type == USRQUOTA) |
1488 | type = QUOTA_USER; | 1493 | type = QUOTA_USER; |
1489 | else if (type == GRPQUOTA) | 1494 | else if (qid.type == GRPQUOTA) |
1490 | type = QUOTA_GROUP; | 1495 | type = QUOTA_GROUP; |
1491 | else | 1496 | else |
1492 | return -EINVAL; | 1497 | return -EINVAL; |
1493 | 1498 | ||
1494 | error = qd_get(sdp, type, id, &qd); | 1499 | error = qd_get(sdp, type, from_kqid(&init_user_ns, qid), &qd); |
1495 | if (error) | 1500 | if (error) |
1496 | return error; | 1501 | return error; |
1497 | error = do_glock(qd, FORCE, &q_gh); | 1502 | error = do_glock(qd, FORCE, &q_gh); |
@@ -1501,7 +1506,7 @@ static int gfs2_get_dqblk(struct super_block *sb, int type, qid_t id, | |||
1501 | qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lvb; | 1506 | qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lvb; |
1502 | fdq->d_version = FS_DQUOT_VERSION; | 1507 | fdq->d_version = FS_DQUOT_VERSION; |
1503 | fdq->d_flags = (type == QUOTA_USER) ? FS_USER_QUOTA : FS_GROUP_QUOTA; | 1508 | fdq->d_flags = (type == QUOTA_USER) ? FS_USER_QUOTA : FS_GROUP_QUOTA; |
1504 | fdq->d_id = id; | 1509 | fdq->d_id = from_kqid(&init_user_ns, qid); |
1505 | fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit) << sdp->sd_fsb2bb_shift; | 1510 | fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit) << sdp->sd_fsb2bb_shift; |
1506 | fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn) << sdp->sd_fsb2bb_shift; | 1511 | fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn) << sdp->sd_fsb2bb_shift; |
1507 | fdq->d_bcount = be64_to_cpu(qlvb->qb_value) << sdp->sd_fsb2bb_shift; | 1512 | fdq->d_bcount = be64_to_cpu(qlvb->qb_value) << sdp->sd_fsb2bb_shift; |
@@ -1515,7 +1520,7 @@ out: | |||
1515 | /* GFS2 only supports a subset of the XFS fields */ | 1520 | /* GFS2 only supports a subset of the XFS fields */ |
1516 | #define GFS2_FIELDMASK (FS_DQ_BSOFT|FS_DQ_BHARD|FS_DQ_BCOUNT) | 1521 | #define GFS2_FIELDMASK (FS_DQ_BSOFT|FS_DQ_BHARD|FS_DQ_BCOUNT) |
1517 | 1522 | ||
1518 | static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id, | 1523 | static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid, |
1519 | struct fs_disk_quota *fdq) | 1524 | struct fs_disk_quota *fdq) |
1520 | { | 1525 | { |
1521 | struct gfs2_sbd *sdp = sb->s_fs_info; | 1526 | struct gfs2_sbd *sdp = sb->s_fs_info; |
@@ -1527,11 +1532,12 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id, | |||
1527 | int alloc_required; | 1532 | int alloc_required; |
1528 | loff_t offset; | 1533 | loff_t offset; |
1529 | int error; | 1534 | int error; |
1535 | int type; | ||
1530 | 1536 | ||
1531 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | 1537 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) |
1532 | return -ESRCH; /* Crazy XFS error code */ | 1538 | return -ESRCH; /* Crazy XFS error code */ |
1533 | 1539 | ||
1534 | switch(type) { | 1540 | switch(qid.type) { |
1535 | case USRQUOTA: | 1541 | case USRQUOTA: |
1536 | type = QUOTA_USER; | 1542 | type = QUOTA_USER; |
1537 | if (fdq->d_flags != FS_USER_QUOTA) | 1543 | if (fdq->d_flags != FS_USER_QUOTA) |
@@ -1548,10 +1554,10 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id, | |||
1548 | 1554 | ||
1549 | if (fdq->d_fieldmask & ~GFS2_FIELDMASK) | 1555 | if (fdq->d_fieldmask & ~GFS2_FIELDMASK) |
1550 | return -EINVAL; | 1556 | return -EINVAL; |
1551 | if (fdq->d_id != id) | 1557 | if (fdq->d_id != from_kqid(&init_user_ns, qid)) |
1552 | return -EINVAL; | 1558 | return -EINVAL; |
1553 | 1559 | ||
1554 | error = qd_get(sdp, type, id, &qd); | 1560 | error = qd_get(sdp, type, from_kqid(&init_user_ns, qid), &qd); |
1555 | if (error) | 1561 | if (error) |
1556 | return error; | 1562 | return error; |
1557 | 1563 | ||
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h index 8275175acf6e..693df9fe52b2 100644 --- a/fs/hfs/hfs_fs.h +++ b/fs/hfs/hfs_fs.h | |||
@@ -134,8 +134,8 @@ struct hfs_sb_info { | |||
134 | permissions on all files */ | 134 | permissions on all files */ |
135 | umode_t s_dir_umask; /* The umask applied to the | 135 | umode_t s_dir_umask; /* The umask applied to the |
136 | permissions on all dirs */ | 136 | permissions on all dirs */ |
137 | uid_t s_uid; /* The uid of all files */ | 137 | kuid_t s_uid; /* The uid of all files */ |
138 | gid_t s_gid; /* The gid of all files */ | 138 | kgid_t s_gid; /* The gid of all files */ |
139 | 139 | ||
140 | int session, part; | 140 | int session, part; |
141 | struct nls_table *nls_io, *nls_disk; | 141 | struct nls_table *nls_io, *nls_disk; |
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index 553909395270..0b35903219bc 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c | |||
@@ -594,9 +594,9 @@ int hfs_inode_setattr(struct dentry *dentry, struct iattr * attr) | |||
594 | 594 | ||
595 | /* no uig/gid changes and limit which mode bits can be set */ | 595 | /* no uig/gid changes and limit which mode bits can be set */ |
596 | if (((attr->ia_valid & ATTR_UID) && | 596 | if (((attr->ia_valid & ATTR_UID) && |
597 | (attr->ia_uid != hsb->s_uid)) || | 597 | (!uid_eq(attr->ia_uid, hsb->s_uid))) || |
598 | ((attr->ia_valid & ATTR_GID) && | 598 | ((attr->ia_valid & ATTR_GID) && |
599 | (attr->ia_gid != hsb->s_gid)) || | 599 | (!gid_eq(attr->ia_gid, hsb->s_gid))) || |
600 | ((attr->ia_valid & ATTR_MODE) && | 600 | ((attr->ia_valid & ATTR_MODE) && |
601 | ((S_ISDIR(inode->i_mode) && | 601 | ((S_ISDIR(inode->i_mode) && |
602 | (attr->ia_mode != inode->i_mode)) || | 602 | (attr->ia_mode != inode->i_mode)) || |
diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 4eb873e0c07b..0b63d135a092 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c | |||
@@ -138,7 +138,9 @@ static int hfs_show_options(struct seq_file *seq, struct dentry *root) | |||
138 | seq_printf(seq, ",creator=%.4s", (char *)&sbi->s_creator); | 138 | seq_printf(seq, ",creator=%.4s", (char *)&sbi->s_creator); |
139 | if (sbi->s_type != cpu_to_be32(0x3f3f3f3f)) | 139 | if (sbi->s_type != cpu_to_be32(0x3f3f3f3f)) |
140 | seq_printf(seq, ",type=%.4s", (char *)&sbi->s_type); | 140 | seq_printf(seq, ",type=%.4s", (char *)&sbi->s_type); |
141 | seq_printf(seq, ",uid=%u,gid=%u", sbi->s_uid, sbi->s_gid); | 141 | seq_printf(seq, ",uid=%u,gid=%u", |
142 | from_kuid_munged(&init_user_ns, sbi->s_uid), | ||
143 | from_kgid_munged(&init_user_ns, sbi->s_gid)); | ||
142 | if (sbi->s_file_umask != 0133) | 144 | if (sbi->s_file_umask != 0133) |
143 | seq_printf(seq, ",file_umask=%o", sbi->s_file_umask); | 145 | seq_printf(seq, ",file_umask=%o", sbi->s_file_umask); |
144 | if (sbi->s_dir_umask != 0022) | 146 | if (sbi->s_dir_umask != 0022) |
@@ -254,14 +256,22 @@ static int parse_options(char *options, struct hfs_sb_info *hsb) | |||
254 | printk(KERN_ERR "hfs: uid requires an argument\n"); | 256 | printk(KERN_ERR "hfs: uid requires an argument\n"); |
255 | return 0; | 257 | return 0; |
256 | } | 258 | } |
257 | hsb->s_uid = (uid_t)tmp; | 259 | hsb->s_uid = make_kuid(current_user_ns(), (uid_t)tmp); |
260 | if (!uid_valid(hsb->s_uid)) { | ||
261 | printk(KERN_ERR "hfs: invalid uid %d\n", tmp); | ||
262 | return 0; | ||
263 | } | ||
258 | break; | 264 | break; |
259 | case opt_gid: | 265 | case opt_gid: |
260 | if (match_int(&args[0], &tmp)) { | 266 | if (match_int(&args[0], &tmp)) { |
261 | printk(KERN_ERR "hfs: gid requires an argument\n"); | 267 | printk(KERN_ERR "hfs: gid requires an argument\n"); |
262 | return 0; | 268 | return 0; |
263 | } | 269 | } |
264 | hsb->s_gid = (gid_t)tmp; | 270 | hsb->s_gid = make_kgid(current_user_ns(), (gid_t)tmp); |
271 | if (!gid_valid(hsb->s_gid)) { | ||
272 | printk(KERN_ERR "hfs: invalid gid %d\n", tmp); | ||
273 | return 0; | ||
274 | } | ||
265 | break; | 275 | break; |
266 | case opt_umask: | 276 | case opt_umask: |
267 | if (match_octal(&args[0], &tmp)) { | 277 | if (match_octal(&args[0], &tmp)) { |
diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c index ec2a9c23f0c9..798d9c4c5e71 100644 --- a/fs/hfsplus/catalog.c +++ b/fs/hfsplus/catalog.c | |||
@@ -80,8 +80,8 @@ void hfsplus_cat_set_perms(struct inode *inode, struct hfsplus_perm *perms) | |||
80 | 80 | ||
81 | perms->userflags = HFSPLUS_I(inode)->userflags; | 81 | perms->userflags = HFSPLUS_I(inode)->userflags; |
82 | perms->mode = cpu_to_be16(inode->i_mode); | 82 | perms->mode = cpu_to_be16(inode->i_mode); |
83 | perms->owner = cpu_to_be32(inode->i_uid); | 83 | perms->owner = cpu_to_be32(i_uid_read(inode)); |
84 | perms->group = cpu_to_be32(inode->i_gid); | 84 | perms->group = cpu_to_be32(i_gid_read(inode)); |
85 | 85 | ||
86 | if (S_ISREG(inode->i_mode)) | 86 | if (S_ISREG(inode->i_mode)) |
87 | perms->dev = cpu_to_be32(inode->i_nlink); | 87 | perms->dev = cpu_to_be32(inode->i_nlink); |
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 558dbb463a4e..c571de224b15 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h | |||
@@ -149,8 +149,8 @@ struct hfsplus_sb_info { | |||
149 | u32 type; | 149 | u32 type; |
150 | 150 | ||
151 | umode_t umask; | 151 | umode_t umask; |
152 | uid_t uid; | 152 | kuid_t uid; |
153 | gid_t gid; | 153 | kgid_t gid; |
154 | 154 | ||
155 | int part, session; | 155 | int part, session; |
156 | unsigned long flags; | 156 | unsigned long flags; |
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 3d8b4a675ba0..2172aa5976f5 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c | |||
@@ -233,12 +233,12 @@ static void hfsplus_get_perms(struct inode *inode, | |||
233 | 233 | ||
234 | mode = be16_to_cpu(perms->mode); | 234 | mode = be16_to_cpu(perms->mode); |
235 | 235 | ||
236 | inode->i_uid = be32_to_cpu(perms->owner); | 236 | i_uid_write(inode, be32_to_cpu(perms->owner)); |
237 | if (!inode->i_uid && !mode) | 237 | if (!i_uid_read(inode) && !mode) |
238 | inode->i_uid = sbi->uid; | 238 | inode->i_uid = sbi->uid; |
239 | 239 | ||
240 | inode->i_gid = be32_to_cpu(perms->group); | 240 | i_gid_write(inode, be32_to_cpu(perms->group)); |
241 | if (!inode->i_gid && !mode) | 241 | if (!i_gid_read(inode) && !mode) |
242 | inode->i_gid = sbi->gid; | 242 | inode->i_gid = sbi->gid; |
243 | 243 | ||
244 | if (dir) { | 244 | if (dir) { |
diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c index 06fa5618600c..ed257c671615 100644 --- a/fs/hfsplus/options.c +++ b/fs/hfsplus/options.c | |||
@@ -135,14 +135,22 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi) | |||
135 | printk(KERN_ERR "hfs: uid requires an argument\n"); | 135 | printk(KERN_ERR "hfs: uid requires an argument\n"); |
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
138 | sbi->uid = (uid_t)tmp; | 138 | sbi->uid = make_kuid(current_user_ns(), (uid_t)tmp); |
139 | if (!uid_valid(sbi->uid)) { | ||
140 | printk(KERN_ERR "hfs: invalid uid specified\n"); | ||
141 | return 0; | ||
142 | } | ||
139 | break; | 143 | break; |
140 | case opt_gid: | 144 | case opt_gid: |
141 | if (match_int(&args[0], &tmp)) { | 145 | if (match_int(&args[0], &tmp)) { |
142 | printk(KERN_ERR "hfs: gid requires an argument\n"); | 146 | printk(KERN_ERR "hfs: gid requires an argument\n"); |
143 | return 0; | 147 | return 0; |
144 | } | 148 | } |
145 | sbi->gid = (gid_t)tmp; | 149 | sbi->gid = make_kgid(current_user_ns(), (gid_t)tmp); |
150 | if (!gid_valid(sbi->gid)) { | ||
151 | printk(KERN_ERR "hfs: invalid gid specified\n"); | ||
152 | return 0; | ||
153 | } | ||
146 | break; | 154 | break; |
147 | case opt_part: | 155 | case opt_part: |
148 | if (match_int(&args[0], &sbi->part)) { | 156 | if (match_int(&args[0], &sbi->part)) { |
@@ -215,7 +223,8 @@ int hfsplus_show_options(struct seq_file *seq, struct dentry *root) | |||
215 | if (sbi->type != HFSPLUS_DEF_CR_TYPE) | 223 | if (sbi->type != HFSPLUS_DEF_CR_TYPE) |
216 | seq_printf(seq, ",type=%.4s", (char *)&sbi->type); | 224 | seq_printf(seq, ",type=%.4s", (char *)&sbi->type); |
217 | seq_printf(seq, ",umask=%o,uid=%u,gid=%u", sbi->umask, | 225 | seq_printf(seq, ",umask=%o,uid=%u,gid=%u", sbi->umask, |
218 | sbi->uid, sbi->gid); | 226 | from_kuid_munged(&init_user_ns, sbi->uid), |
227 | from_kgid_munged(&init_user_ns, sbi->gid)); | ||
219 | if (sbi->part >= 0) | 228 | if (sbi->part >= 0) |
220 | seq_printf(seq, ",part=%u", sbi->part); | 229 | seq_printf(seq, ",part=%u", sbi->part); |
221 | if (sbi->session >= 0) | 230 | if (sbi->session >= 0) |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 124146543aa7..6c9f3a9d5e21 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -542,8 +542,8 @@ static int read_name(struct inode *ino, char *name) | |||
542 | ino->i_ino = st.ino; | 542 | ino->i_ino = st.ino; |
543 | ino->i_mode = st.mode; | 543 | ino->i_mode = st.mode; |
544 | set_nlink(ino, st.nlink); | 544 | set_nlink(ino, st.nlink); |
545 | ino->i_uid = st.uid; | 545 | i_uid_write(ino, st.uid); |
546 | ino->i_gid = st.gid; | 546 | i_gid_write(ino, st.gid); |
547 | ino->i_atime = st.atime; | 547 | ino->i_atime = st.atime; |
548 | ino->i_mtime = st.mtime; | 548 | ino->i_mtime = st.mtime; |
549 | ino->i_ctime = st.ctime; | 549 | ino->i_ctime = st.ctime; |
@@ -808,11 +808,11 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
808 | } | 808 | } |
809 | if (attr->ia_valid & ATTR_UID) { | 809 | if (attr->ia_valid & ATTR_UID) { |
810 | attrs.ia_valid |= HOSTFS_ATTR_UID; | 810 | attrs.ia_valid |= HOSTFS_ATTR_UID; |
811 | attrs.ia_uid = attr->ia_uid; | 811 | attrs.ia_uid = from_kuid(&init_user_ns, attr->ia_uid); |
812 | } | 812 | } |
813 | if (attr->ia_valid & ATTR_GID) { | 813 | if (attr->ia_valid & ATTR_GID) { |
814 | attrs.ia_valid |= HOSTFS_ATTR_GID; | 814 | attrs.ia_valid |= HOSTFS_ATTR_GID; |
815 | attrs.ia_gid = attr->ia_gid; | 815 | attrs.ia_gid = from_kgid(&init_user_ns, attr->ia_gid); |
816 | } | 816 | } |
817 | if (attr->ia_valid & ATTR_SIZE) { | 817 | if (attr->ia_valid & ATTR_SIZE) { |
818 | attrs.ia_valid |= HOSTFS_ATTR_SIZE; | 818 | attrs.ia_valid |= HOSTFS_ATTR_SIZE; |
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index ac1ead194db5..7102aaecc244 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h | |||
@@ -63,8 +63,8 @@ struct hpfs_sb_info { | |||
63 | unsigned sb_dmap; /* sector number of dnode bit map */ | 63 | unsigned sb_dmap; /* sector number of dnode bit map */ |
64 | unsigned sb_n_free; /* free blocks for statfs, or -1 */ | 64 | unsigned sb_n_free; /* free blocks for statfs, or -1 */ |
65 | unsigned sb_n_free_dnodes; /* free dnodes for statfs, or -1 */ | 65 | unsigned sb_n_free_dnodes; /* free dnodes for statfs, or -1 */ |
66 | uid_t sb_uid; /* uid from mount options */ | 66 | kuid_t sb_uid; /* uid from mount options */ |
67 | gid_t sb_gid; /* gid from mount options */ | 67 | kgid_t sb_gid; /* gid from mount options */ |
68 | umode_t sb_mode; /* mode from mount options */ | 68 | umode_t sb_mode; /* mode from mount options */ |
69 | unsigned sb_eas : 2; /* eas: 0-ignore, 1-ro, 2-rw */ | 69 | unsigned sb_eas : 2; /* eas: 0-ignore, 1-ro, 2-rw */ |
70 | unsigned sb_err : 2; /* on errs: 0-cont, 1-ro, 2-panic */ | 70 | unsigned sb_err : 2; /* on errs: 0-cont, 1-ro, 2-panic */ |
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index ed671e0ea784..804a9a842cbc 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c | |||
@@ -7,6 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
10 | #include <linux/user_namespace.h> | ||
10 | #include "hpfs_fn.h" | 11 | #include "hpfs_fn.h" |
11 | 12 | ||
12 | void hpfs_init_inode(struct inode *i) | 13 | void hpfs_init_inode(struct inode *i) |
@@ -60,14 +61,14 @@ void hpfs_read_inode(struct inode *i) | |||
60 | if (hpfs_sb(i->i_sb)->sb_eas) { | 61 | if (hpfs_sb(i->i_sb)->sb_eas) { |
61 | if ((ea = hpfs_get_ea(i->i_sb, fnode, "UID", &ea_size))) { | 62 | if ((ea = hpfs_get_ea(i->i_sb, fnode, "UID", &ea_size))) { |
62 | if (ea_size == 2) { | 63 | if (ea_size == 2) { |
63 | i->i_uid = le16_to_cpu(*(__le16*)ea); | 64 | i_uid_write(i, le16_to_cpu(*(__le16*)ea)); |
64 | hpfs_inode->i_ea_uid = 1; | 65 | hpfs_inode->i_ea_uid = 1; |
65 | } | 66 | } |
66 | kfree(ea); | 67 | kfree(ea); |
67 | } | 68 | } |
68 | if ((ea = hpfs_get_ea(i->i_sb, fnode, "GID", &ea_size))) { | 69 | if ((ea = hpfs_get_ea(i->i_sb, fnode, "GID", &ea_size))) { |
69 | if (ea_size == 2) { | 70 | if (ea_size == 2) { |
70 | i->i_gid = le16_to_cpu(*(__le16*)ea); | 71 | i_gid_write(i, le16_to_cpu(*(__le16*)ea)); |
71 | hpfs_inode->i_ea_gid = 1; | 72 | hpfs_inode->i_ea_gid = 1; |
72 | } | 73 | } |
73 | kfree(ea); | 74 | kfree(ea); |
@@ -149,13 +150,13 @@ static void hpfs_write_inode_ea(struct inode *i, struct fnode *fnode) | |||
149 | hpfs_error(i->i_sb, "fnode %08x has some unknown HPFS386 stuctures", i->i_ino); | 150 | hpfs_error(i->i_sb, "fnode %08x has some unknown HPFS386 stuctures", i->i_ino); |
150 | } else*/ if (hpfs_sb(i->i_sb)->sb_eas >= 2) { | 151 | } else*/ if (hpfs_sb(i->i_sb)->sb_eas >= 2) { |
151 | __le32 ea; | 152 | __le32 ea; |
152 | if ((i->i_uid != hpfs_sb(i->i_sb)->sb_uid) || hpfs_inode->i_ea_uid) { | 153 | if (!uid_eq(i->i_uid, hpfs_sb(i->i_sb)->sb_uid) || hpfs_inode->i_ea_uid) { |
153 | ea = cpu_to_le32(i->i_uid); | 154 | ea = cpu_to_le32(i_uid_read(i)); |
154 | hpfs_set_ea(i, fnode, "UID", (char*)&ea, 2); | 155 | hpfs_set_ea(i, fnode, "UID", (char*)&ea, 2); |
155 | hpfs_inode->i_ea_uid = 1; | 156 | hpfs_inode->i_ea_uid = 1; |
156 | } | 157 | } |
157 | if ((i->i_gid != hpfs_sb(i->i_sb)->sb_gid) || hpfs_inode->i_ea_gid) { | 158 | if (!gid_eq(i->i_gid, hpfs_sb(i->i_sb)->sb_gid) || hpfs_inode->i_ea_gid) { |
158 | ea = cpu_to_le32(i->i_gid); | 159 | ea = cpu_to_le32(i_gid_read(i)); |
159 | hpfs_set_ea(i, fnode, "GID", (char *)&ea, 2); | 160 | hpfs_set_ea(i, fnode, "GID", (char *)&ea, 2); |
160 | hpfs_inode->i_ea_gid = 1; | 161 | hpfs_inode->i_ea_gid = 1; |
161 | } | 162 | } |
@@ -261,9 +262,11 @@ int hpfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
261 | hpfs_lock(inode->i_sb); | 262 | hpfs_lock(inode->i_sb); |
262 | if (inode->i_ino == hpfs_sb(inode->i_sb)->sb_root) | 263 | if (inode->i_ino == hpfs_sb(inode->i_sb)->sb_root) |
263 | goto out_unlock; | 264 | goto out_unlock; |
264 | if ((attr->ia_valid & ATTR_UID) && attr->ia_uid >= 0x10000) | 265 | if ((attr->ia_valid & ATTR_UID) && |
266 | from_kuid(&init_user_ns, attr->ia_uid) >= 0x10000) | ||
265 | goto out_unlock; | 267 | goto out_unlock; |
266 | if ((attr->ia_valid & ATTR_GID) && attr->ia_gid >= 0x10000) | 268 | if ((attr->ia_valid & ATTR_GID) && |
269 | from_kgid(&init_user_ns, attr->ia_gid) >= 0x10000) | ||
267 | goto out_unlock; | 270 | goto out_unlock; |
268 | if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size) | 271 | if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size) |
269 | goto out_unlock; | 272 | goto out_unlock; |
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index bc9082482f68..345713d2f8f3 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c | |||
@@ -91,8 +91,8 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
91 | inc_nlink(dir); | 91 | inc_nlink(dir); |
92 | insert_inode_hash(result); | 92 | insert_inode_hash(result); |
93 | 93 | ||
94 | if (result->i_uid != current_fsuid() || | 94 | if (!uid_eq(result->i_uid, current_fsuid()) || |
95 | result->i_gid != current_fsgid() || | 95 | !gid_eq(result->i_gid, current_fsgid()) || |
96 | result->i_mode != (mode | S_IFDIR)) { | 96 | result->i_mode != (mode | S_IFDIR)) { |
97 | result->i_uid = current_fsuid(); | 97 | result->i_uid = current_fsuid(); |
98 | result->i_gid = current_fsgid(); | 98 | result->i_gid = current_fsgid(); |
@@ -179,8 +179,8 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, b | |||
179 | 179 | ||
180 | insert_inode_hash(result); | 180 | insert_inode_hash(result); |
181 | 181 | ||
182 | if (result->i_uid != current_fsuid() || | 182 | if (!uid_eq(result->i_uid, current_fsuid()) || |
183 | result->i_gid != current_fsgid() || | 183 | !gid_eq(result->i_gid, current_fsgid()) || |
184 | result->i_mode != (mode | S_IFREG)) { | 184 | result->i_mode != (mode | S_IFREG)) { |
185 | result->i_uid = current_fsuid(); | 185 | result->i_uid = current_fsuid(); |
186 | result->i_gid = current_fsgid(); | 186 | result->i_gid = current_fsgid(); |
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index 706a12c083ea..a152783602d9 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c | |||
@@ -251,7 +251,7 @@ static const match_table_t tokens = { | |||
251 | {Opt_err, NULL}, | 251 | {Opt_err, NULL}, |
252 | }; | 252 | }; |
253 | 253 | ||
254 | static int parse_opts(char *opts, uid_t *uid, gid_t *gid, umode_t *umask, | 254 | static int parse_opts(char *opts, kuid_t *uid, kgid_t *gid, umode_t *umask, |
255 | int *lowercase, int *eas, int *chk, int *errs, | 255 | int *lowercase, int *eas, int *chk, int *errs, |
256 | int *chkdsk, int *timeshift) | 256 | int *chkdsk, int *timeshift) |
257 | { | 257 | { |
@@ -276,12 +276,16 @@ static int parse_opts(char *opts, uid_t *uid, gid_t *gid, umode_t *umask, | |||
276 | case Opt_uid: | 276 | case Opt_uid: |
277 | if (match_int(args, &option)) | 277 | if (match_int(args, &option)) |
278 | return 0; | 278 | return 0; |
279 | *uid = option; | 279 | *uid = make_kuid(current_user_ns(), option); |
280 | if (!uid_valid(*uid)) | ||
281 | return 0; | ||
280 | break; | 282 | break; |
281 | case Opt_gid: | 283 | case Opt_gid: |
282 | if (match_int(args, &option)) | 284 | if (match_int(args, &option)) |
283 | return 0; | 285 | return 0; |
284 | *gid = option; | 286 | *gid = make_kgid(current_user_ns(), option); |
287 | if (!gid_valid(*gid)) | ||
288 | return 0; | ||
285 | break; | 289 | break; |
286 | case Opt_umask: | 290 | case Opt_umask: |
287 | if (match_octal(args, &option)) | 291 | if (match_octal(args, &option)) |
@@ -378,8 +382,8 @@ HPFS filesystem options:\n\ | |||
378 | 382 | ||
379 | static int hpfs_remount_fs(struct super_block *s, int *flags, char *data) | 383 | static int hpfs_remount_fs(struct super_block *s, int *flags, char *data) |
380 | { | 384 | { |
381 | uid_t uid; | 385 | kuid_t uid; |
382 | gid_t gid; | 386 | kgid_t gid; |
383 | umode_t umask; | 387 | umode_t umask; |
384 | int lowercase, eas, chk, errs, chkdsk, timeshift; | 388 | int lowercase, eas, chk, errs, chkdsk, timeshift; |
385 | int o; | 389 | int o; |
@@ -455,8 +459,8 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) | |||
455 | struct hpfs_sb_info *sbi; | 459 | struct hpfs_sb_info *sbi; |
456 | struct inode *root; | 460 | struct inode *root; |
457 | 461 | ||
458 | uid_t uid; | 462 | kuid_t uid; |
459 | gid_t gid; | 463 | kgid_t gid; |
460 | umode_t umask; | 464 | umode_t umask; |
461 | int lowercase, eas, chk, errs, chkdsk, timeshift; | 465 | int lowercase, eas, chk, errs, chkdsk, timeshift; |
462 | 466 | ||
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 8349a899912e..6e572c4fbf68 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -42,8 +42,8 @@ static const struct inode_operations hugetlbfs_dir_inode_operations; | |||
42 | static const struct inode_operations hugetlbfs_inode_operations; | 42 | static const struct inode_operations hugetlbfs_inode_operations; |
43 | 43 | ||
44 | struct hugetlbfs_config { | 44 | struct hugetlbfs_config { |
45 | uid_t uid; | 45 | kuid_t uid; |
46 | gid_t gid; | 46 | kgid_t gid; |
47 | umode_t mode; | 47 | umode_t mode; |
48 | long nr_blocks; | 48 | long nr_blocks; |
49 | long nr_inodes; | 49 | long nr_inodes; |
@@ -785,13 +785,17 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig) | |||
785 | case Opt_uid: | 785 | case Opt_uid: |
786 | if (match_int(&args[0], &option)) | 786 | if (match_int(&args[0], &option)) |
787 | goto bad_val; | 787 | goto bad_val; |
788 | pconfig->uid = option; | 788 | pconfig->uid = make_kuid(current_user_ns(), option); |
789 | if (!uid_valid(pconfig->uid)) | ||
790 | goto bad_val; | ||
789 | break; | 791 | break; |
790 | 792 | ||
791 | case Opt_gid: | 793 | case Opt_gid: |
792 | if (match_int(&args[0], &option)) | 794 | if (match_int(&args[0], &option)) |
793 | goto bad_val; | 795 | goto bad_val; |
794 | pconfig->gid = option; | 796 | pconfig->gid = make_kgid(current_user_ns(), option); |
797 | if (!gid_valid(pconfig->gid)) | ||
798 | goto bad_val; | ||
795 | break; | 799 | break; |
796 | 800 | ||
797 | case Opt_mode: | 801 | case Opt_mode: |
@@ -924,7 +928,9 @@ static struct vfsmount *hugetlbfs_vfsmount; | |||
924 | 928 | ||
925 | static int can_do_hugetlb_shm(void) | 929 | static int can_do_hugetlb_shm(void) |
926 | { | 930 | { |
927 | return capable(CAP_IPC_LOCK) || in_group_p(sysctl_hugetlb_shm_group); | 931 | kgid_t shm_group; |
932 | shm_group = make_kgid(&init_user_ns, sysctl_hugetlb_shm_group); | ||
933 | return capable(CAP_IPC_LOCK) || in_group_p(shm_group); | ||
928 | } | 934 | } |
929 | 935 | ||
930 | struct file *hugetlb_file_setup(const char *name, unsigned long addr, | 936 | struct file *hugetlb_file_setup(const char *name, unsigned long addr, |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 29037c365ba4..a7d8e6cc5e0c 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/cdrom.h> | 21 | #include <linux/cdrom.h> |
22 | #include <linux/parser.h> | 22 | #include <linux/parser.h> |
23 | #include <linux/mpage.h> | 23 | #include <linux/mpage.h> |
24 | #include <linux/user_namespace.h> | ||
24 | 25 | ||
25 | #include "isofs.h" | 26 | #include "isofs.h" |
26 | #include "zisofs.h" | 27 | #include "zisofs.h" |
@@ -171,8 +172,8 @@ struct iso9660_options{ | |||
171 | unsigned int blocksize; | 172 | unsigned int blocksize; |
172 | umode_t fmode; | 173 | umode_t fmode; |
173 | umode_t dmode; | 174 | umode_t dmode; |
174 | gid_t gid; | 175 | kgid_t gid; |
175 | uid_t uid; | 176 | kuid_t uid; |
176 | char *iocharset; | 177 | char *iocharset; |
177 | /* LVE */ | 178 | /* LVE */ |
178 | s32 session; | 179 | s32 session; |
@@ -383,8 +384,8 @@ static int parse_options(char *options, struct iso9660_options *popt) | |||
383 | popt->fmode = popt->dmode = ISOFS_INVALID_MODE; | 384 | popt->fmode = popt->dmode = ISOFS_INVALID_MODE; |
384 | popt->uid_set = 0; | 385 | popt->uid_set = 0; |
385 | popt->gid_set = 0; | 386 | popt->gid_set = 0; |
386 | popt->gid = 0; | 387 | popt->gid = GLOBAL_ROOT_GID; |
387 | popt->uid = 0; | 388 | popt->uid = GLOBAL_ROOT_UID; |
388 | popt->iocharset = NULL; | 389 | popt->iocharset = NULL; |
389 | popt->utf8 = 0; | 390 | popt->utf8 = 0; |
390 | popt->overriderockperm = 0; | 391 | popt->overriderockperm = 0; |
@@ -460,13 +461,17 @@ static int parse_options(char *options, struct iso9660_options *popt) | |||
460 | case Opt_uid: | 461 | case Opt_uid: |
461 | if (match_int(&args[0], &option)) | 462 | if (match_int(&args[0], &option)) |
462 | return 0; | 463 | return 0; |
463 | popt->uid = option; | 464 | popt->uid = make_kuid(current_user_ns(), option); |
465 | if (!uid_valid(popt->uid)) | ||
466 | return 0; | ||
464 | popt->uid_set = 1; | 467 | popt->uid_set = 1; |
465 | break; | 468 | break; |
466 | case Opt_gid: | 469 | case Opt_gid: |
467 | if (match_int(&args[0], &option)) | 470 | if (match_int(&args[0], &option)) |
468 | return 0; | 471 | return 0; |
469 | popt->gid = option; | 472 | popt->gid = make_kgid(current_user_ns(), option); |
473 | if (!gid_valid(popt->gid)) | ||
474 | return 0; | ||
470 | popt->gid_set = 1; | 475 | popt->gid_set = 1; |
471 | break; | 476 | break; |
472 | case Opt_mode: | 477 | case Opt_mode: |
diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h index 3620ad1ea9bc..99167238518d 100644 --- a/fs/isofs/isofs.h +++ b/fs/isofs/isofs.h | |||
@@ -52,8 +52,8 @@ struct isofs_sb_info { | |||
52 | 52 | ||
53 | umode_t s_fmode; | 53 | umode_t s_fmode; |
54 | umode_t s_dmode; | 54 | umode_t s_dmode; |
55 | gid_t s_gid; | 55 | kgid_t s_gid; |
56 | uid_t s_uid; | 56 | kuid_t s_uid; |
57 | struct nls_table *s_nls_iocharset; /* Native language support table */ | 57 | struct nls_table *s_nls_iocharset; /* Native language support table */ |
58 | }; | 58 | }; |
59 | 59 | ||
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index 70e79d0c756a..c0bf42472e40 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c | |||
@@ -364,8 +364,8 @@ repeat: | |||
364 | case SIG('P', 'X'): | 364 | case SIG('P', 'X'): |
365 | inode->i_mode = isonum_733(rr->u.PX.mode); | 365 | inode->i_mode = isonum_733(rr->u.PX.mode); |
366 | set_nlink(inode, isonum_733(rr->u.PX.n_links)); | 366 | set_nlink(inode, isonum_733(rr->u.PX.n_links)); |
367 | inode->i_uid = isonum_733(rr->u.PX.uid); | 367 | i_uid_write(inode, isonum_733(rr->u.PX.uid)); |
368 | inode->i_gid = isonum_733(rr->u.PX.gid); | 368 | i_gid_write(inode, isonum_733(rr->u.PX.gid)); |
369 | break; | 369 | break; |
370 | case SIG('P', 'N'): | 370 | case SIG('P', 'N'): |
371 | { | 371 | { |
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 922f146e4235..223283c30111 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c | |||
@@ -94,15 +94,23 @@ static struct posix_acl *jffs2_acl_from_medium(void *value, size_t size) | |||
94 | case ACL_MASK: | 94 | case ACL_MASK: |
95 | case ACL_OTHER: | 95 | case ACL_OTHER: |
96 | value += sizeof(struct jffs2_acl_entry_short); | 96 | value += sizeof(struct jffs2_acl_entry_short); |
97 | acl->a_entries[i].e_id = ACL_UNDEFINED_ID; | ||
98 | break; | 97 | break; |
99 | 98 | ||
100 | case ACL_USER: | 99 | case ACL_USER: |
100 | value += sizeof(struct jffs2_acl_entry); | ||
101 | if (value > end) | ||
102 | goto fail; | ||
103 | acl->a_entries[i].e_uid = | ||
104 | make_kuid(&init_user_ns, | ||
105 | je32_to_cpu(entry->e_id)); | ||
106 | break; | ||
101 | case ACL_GROUP: | 107 | case ACL_GROUP: |
102 | value += sizeof(struct jffs2_acl_entry); | 108 | value += sizeof(struct jffs2_acl_entry); |
103 | if (value > end) | 109 | if (value > end) |
104 | goto fail; | 110 | goto fail; |
105 | acl->a_entries[i].e_id = je32_to_cpu(entry->e_id); | 111 | acl->a_entries[i].e_gid = |
112 | make_kgid(&init_user_ns, | ||
113 | je32_to_cpu(entry->e_id)); | ||
106 | break; | 114 | break; |
107 | 115 | ||
108 | default: | 116 | default: |
@@ -131,13 +139,19 @@ static void *jffs2_acl_to_medium(const struct posix_acl *acl, size_t *size) | |||
131 | header->a_version = cpu_to_je32(JFFS2_ACL_VERSION); | 139 | header->a_version = cpu_to_je32(JFFS2_ACL_VERSION); |
132 | e = header + 1; | 140 | e = header + 1; |
133 | for (i=0; i < acl->a_count; i++) { | 141 | for (i=0; i < acl->a_count; i++) { |
142 | const struct posix_acl_entry *acl_e = &acl->a_entries[i]; | ||
134 | entry = e; | 143 | entry = e; |
135 | entry->e_tag = cpu_to_je16(acl->a_entries[i].e_tag); | 144 | entry->e_tag = cpu_to_je16(acl_e->e_tag); |
136 | entry->e_perm = cpu_to_je16(acl->a_entries[i].e_perm); | 145 | entry->e_perm = cpu_to_je16(acl_e->e_perm); |
137 | switch(acl->a_entries[i].e_tag) { | 146 | switch(acl_e->e_tag) { |
138 | case ACL_USER: | 147 | case ACL_USER: |
148 | entry->e_id = cpu_to_je32( | ||
149 | from_kuid(&init_user_ns, acl_e->e_uid)); | ||
150 | e += sizeof(struct jffs2_acl_entry); | ||
151 | break; | ||
139 | case ACL_GROUP: | 152 | case ACL_GROUP: |
140 | entry->e_id = cpu_to_je32(acl->a_entries[i].e_id); | 153 | entry->e_id = cpu_to_je32( |
154 | from_kgid(&init_user_ns, acl_e->e_gid)); | ||
141 | e += sizeof(struct jffs2_acl_entry); | 155 | e += sizeof(struct jffs2_acl_entry); |
142 | break; | 156 | break; |
143 | 157 | ||
@@ -363,7 +377,7 @@ static int jffs2_acl_getxattr(struct dentry *dentry, const char *name, | |||
363 | return PTR_ERR(acl); | 377 | return PTR_ERR(acl); |
364 | if (!acl) | 378 | if (!acl) |
365 | return -ENODATA; | 379 | return -ENODATA; |
366 | rc = posix_acl_to_xattr(acl, buffer, size); | 380 | rc = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); |
367 | posix_acl_release(acl); | 381 | posix_acl_release(acl); |
368 | 382 | ||
369 | return rc; | 383 | return rc; |
@@ -381,7 +395,7 @@ static int jffs2_acl_setxattr(struct dentry *dentry, const char *name, | |||
381 | return -EPERM; | 395 | return -EPERM; |
382 | 396 | ||
383 | if (value) { | 397 | if (value) { |
384 | acl = posix_acl_from_xattr(value, size); | 398 | acl = posix_acl_from_xattr(&init_user_ns, value, size); |
385 | if (IS_ERR(acl)) | 399 | if (IS_ERR(acl)) |
386 | return PTR_ERR(acl); | 400 | return PTR_ERR(acl); |
387 | if (acl) { | 401 | if (acl) { |
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index db3889ba8818..60ef3fb707ff 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c | |||
@@ -175,8 +175,8 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, | |||
175 | ri.ino = cpu_to_je32(f->inocache->ino); | 175 | ri.ino = cpu_to_je32(f->inocache->ino); |
176 | ri.version = cpu_to_je32(++f->highest_version); | 176 | ri.version = cpu_to_je32(++f->highest_version); |
177 | ri.mode = cpu_to_jemode(inode->i_mode); | 177 | ri.mode = cpu_to_jemode(inode->i_mode); |
178 | ri.uid = cpu_to_je16(inode->i_uid); | 178 | ri.uid = cpu_to_je16(i_uid_read(inode)); |
179 | ri.gid = cpu_to_je16(inode->i_gid); | 179 | ri.gid = cpu_to_je16(i_gid_read(inode)); |
180 | ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs)); | 180 | ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs)); |
181 | ri.atime = ri.ctime = ri.mtime = cpu_to_je32(get_seconds()); | 181 | ri.atime = ri.ctime = ri.mtime = cpu_to_je32(get_seconds()); |
182 | ri.offset = cpu_to_je32(inode->i_size); | 182 | ri.offset = cpu_to_je32(inode->i_size); |
@@ -283,8 +283,8 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping, | |||
283 | /* Set the fields that the generic jffs2_write_inode_range() code can't find */ | 283 | /* Set the fields that the generic jffs2_write_inode_range() code can't find */ |
284 | ri->ino = cpu_to_je32(inode->i_ino); | 284 | ri->ino = cpu_to_je32(inode->i_ino); |
285 | ri->mode = cpu_to_jemode(inode->i_mode); | 285 | ri->mode = cpu_to_jemode(inode->i_mode); |
286 | ri->uid = cpu_to_je16(inode->i_uid); | 286 | ri->uid = cpu_to_je16(i_uid_read(inode)); |
287 | ri->gid = cpu_to_je16(inode->i_gid); | 287 | ri->gid = cpu_to_je16(i_gid_read(inode)); |
288 | ri->isize = cpu_to_je32((uint32_t)inode->i_size); | 288 | ri->isize = cpu_to_je32((uint32_t)inode->i_size); |
289 | ri->atime = ri->ctime = ri->mtime = cpu_to_je32(get_seconds()); | 289 | ri->atime = ri->ctime = ri->mtime = cpu_to_je32(get_seconds()); |
290 | 290 | ||
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 3d3092eda811..fe3c0527545f 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c | |||
@@ -99,8 +99,10 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) | |||
99 | ri->ino = cpu_to_je32(inode->i_ino); | 99 | ri->ino = cpu_to_je32(inode->i_ino); |
100 | ri->version = cpu_to_je32(++f->highest_version); | 100 | ri->version = cpu_to_je32(++f->highest_version); |
101 | 101 | ||
102 | ri->uid = cpu_to_je16((ivalid & ATTR_UID)?iattr->ia_uid:inode->i_uid); | 102 | ri->uid = cpu_to_je16((ivalid & ATTR_UID)? |
103 | ri->gid = cpu_to_je16((ivalid & ATTR_GID)?iattr->ia_gid:inode->i_gid); | 103 | from_kuid(&init_user_ns, iattr->ia_uid):i_uid_read(inode)); |
104 | ri->gid = cpu_to_je16((ivalid & ATTR_GID)? | ||
105 | from_kgid(&init_user_ns, iattr->ia_gid):i_gid_read(inode)); | ||
104 | 106 | ||
105 | if (ivalid & ATTR_MODE) | 107 | if (ivalid & ATTR_MODE) |
106 | ri->mode = cpu_to_jemode(iattr->ia_mode); | 108 | ri->mode = cpu_to_jemode(iattr->ia_mode); |
@@ -147,8 +149,8 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) | |||
147 | inode->i_ctime = ITIME(je32_to_cpu(ri->ctime)); | 149 | inode->i_ctime = ITIME(je32_to_cpu(ri->ctime)); |
148 | inode->i_mtime = ITIME(je32_to_cpu(ri->mtime)); | 150 | inode->i_mtime = ITIME(je32_to_cpu(ri->mtime)); |
149 | inode->i_mode = jemode_to_cpu(ri->mode); | 151 | inode->i_mode = jemode_to_cpu(ri->mode); |
150 | inode->i_uid = je16_to_cpu(ri->uid); | 152 | i_uid_write(inode, je16_to_cpu(ri->uid)); |
151 | inode->i_gid = je16_to_cpu(ri->gid); | 153 | i_gid_write(inode, je16_to_cpu(ri->gid)); |
152 | 154 | ||
153 | 155 | ||
154 | old_metadata = f->metadata; | 156 | old_metadata = f->metadata; |
@@ -276,8 +278,8 @@ struct inode *jffs2_iget(struct super_block *sb, unsigned long ino) | |||
276 | return ERR_PTR(ret); | 278 | return ERR_PTR(ret); |
277 | } | 279 | } |
278 | inode->i_mode = jemode_to_cpu(latest_node.mode); | 280 | inode->i_mode = jemode_to_cpu(latest_node.mode); |
279 | inode->i_uid = je16_to_cpu(latest_node.uid); | 281 | i_uid_write(inode, je16_to_cpu(latest_node.uid)); |
280 | inode->i_gid = je16_to_cpu(latest_node.gid); | 282 | i_gid_write(inode, je16_to_cpu(latest_node.gid)); |
281 | inode->i_size = je32_to_cpu(latest_node.isize); | 283 | inode->i_size = je32_to_cpu(latest_node.isize); |
282 | inode->i_atime = ITIME(je32_to_cpu(latest_node.atime)); | 284 | inode->i_atime = ITIME(je32_to_cpu(latest_node.atime)); |
283 | inode->i_mtime = ITIME(je32_to_cpu(latest_node.mtime)); | 285 | inode->i_mtime = ITIME(je32_to_cpu(latest_node.mtime)); |
@@ -440,14 +442,14 @@ struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, struct jffs2_r | |||
440 | 442 | ||
441 | memset(ri, 0, sizeof(*ri)); | 443 | memset(ri, 0, sizeof(*ri)); |
442 | /* Set OS-specific defaults for new inodes */ | 444 | /* Set OS-specific defaults for new inodes */ |
443 | ri->uid = cpu_to_je16(current_fsuid()); | 445 | ri->uid = cpu_to_je16(from_kuid(&init_user_ns, current_fsuid())); |
444 | 446 | ||
445 | if (dir_i->i_mode & S_ISGID) { | 447 | if (dir_i->i_mode & S_ISGID) { |
446 | ri->gid = cpu_to_je16(dir_i->i_gid); | 448 | ri->gid = cpu_to_je16(i_gid_read(dir_i)); |
447 | if (S_ISDIR(mode)) | 449 | if (S_ISDIR(mode)) |
448 | mode |= S_ISGID; | 450 | mode |= S_ISGID; |
449 | } else { | 451 | } else { |
450 | ri->gid = cpu_to_je16(current_fsgid()); | 452 | ri->gid = cpu_to_je16(from_kgid(&init_user_ns, current_fsgid())); |
451 | } | 453 | } |
452 | 454 | ||
453 | /* POSIX ACLs have to be processed now, at least partly. | 455 | /* POSIX ACLs have to be processed now, at least partly. |
@@ -467,8 +469,8 @@ struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, struct jffs2_r | |||
467 | set_nlink(inode, 1); | 469 | set_nlink(inode, 1); |
468 | inode->i_ino = je32_to_cpu(ri->ino); | 470 | inode->i_ino = je32_to_cpu(ri->ino); |
469 | inode->i_mode = jemode_to_cpu(ri->mode); | 471 | inode->i_mode = jemode_to_cpu(ri->mode); |
470 | inode->i_gid = je16_to_cpu(ri->gid); | 472 | i_gid_write(inode, je16_to_cpu(ri->gid)); |
471 | inode->i_uid = je16_to_cpu(ri->uid); | 473 | i_uid_write(inode, je16_to_cpu(ri->uid)); |
472 | inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; | 474 | inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; |
473 | ri->atime = ri->mtime = ri->ctime = cpu_to_je32(I_SEC(inode->i_mtime)); | 475 | ri->atime = ri->mtime = ri->ctime = cpu_to_je32(I_SEC(inode->i_mtime)); |
474 | 476 | ||
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index bcd983d7e7f9..d200a9b8fd5e 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h | |||
@@ -27,8 +27,8 @@ struct kvec; | |||
27 | 27 | ||
28 | #define JFFS2_F_I_SIZE(f) (OFNI_EDONI_2SFFJ(f)->i_size) | 28 | #define JFFS2_F_I_SIZE(f) (OFNI_EDONI_2SFFJ(f)->i_size) |
29 | #define JFFS2_F_I_MODE(f) (OFNI_EDONI_2SFFJ(f)->i_mode) | 29 | #define JFFS2_F_I_MODE(f) (OFNI_EDONI_2SFFJ(f)->i_mode) |
30 | #define JFFS2_F_I_UID(f) (OFNI_EDONI_2SFFJ(f)->i_uid) | 30 | #define JFFS2_F_I_UID(f) (i_uid_read(OFNI_EDONI_2SFFJ(f))) |
31 | #define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid) | 31 | #define JFFS2_F_I_GID(f) (i_gid_read(OFNI_EDONI_2SFFJ(f))) |
32 | #define JFFS2_F_I_RDEV(f) (OFNI_EDONI_2SFFJ(f)->i_rdev) | 32 | #define JFFS2_F_I_RDEV(f) (OFNI_EDONI_2SFFJ(f)->i_rdev) |
33 | 33 | ||
34 | #define ITIME(sec) ((struct timespec){sec, 0}) | 34 | #define ITIME(sec) ((struct timespec){sec, 0}) |
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index 45559dc3ea2f..d254d6d35995 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c | |||
@@ -64,7 +64,7 @@ struct posix_acl *jfs_get_acl(struct inode *inode, int type) | |||
64 | else | 64 | else |
65 | acl = ERR_PTR(size); | 65 | acl = ERR_PTR(size); |
66 | } else { | 66 | } else { |
67 | acl = posix_acl_from_xattr(value, size); | 67 | acl = posix_acl_from_xattr(&init_user_ns, value, size); |
68 | } | 68 | } |
69 | kfree(value); | 69 | kfree(value); |
70 | if (!IS_ERR(acl)) | 70 | if (!IS_ERR(acl)) |
@@ -100,7 +100,7 @@ static int jfs_set_acl(tid_t tid, struct inode *inode, int type, | |||
100 | value = kmalloc(size, GFP_KERNEL); | 100 | value = kmalloc(size, GFP_KERNEL); |
101 | if (!value) | 101 | if (!value) |
102 | return -ENOMEM; | 102 | return -ENOMEM; |
103 | rc = posix_acl_to_xattr(acl, value, size); | 103 | rc = posix_acl_to_xattr(&init_user_ns, acl, value, size); |
104 | if (rc < 0) | 104 | if (rc < 0) |
105 | goto out; | 105 | goto out; |
106 | } | 106 | } |
diff --git a/fs/jfs/file.c b/fs/jfs/file.c index 844f9460cb11..9d3afd157f99 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c | |||
@@ -108,8 +108,8 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
108 | 108 | ||
109 | if (is_quota_modification(inode, iattr)) | 109 | if (is_quota_modification(inode, iattr)) |
110 | dquot_initialize(inode); | 110 | dquot_initialize(inode); |
111 | if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || | 111 | if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) || |
112 | (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { | 112 | (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) { |
113 | rc = dquot_transfer(inode, iattr); | 113 | rc = dquot_transfer(inode, iattr); |
114 | if (rc) | 114 | if (rc) |
115 | return rc; | 115 | return rc; |
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index 1b6f15f191b3..6ba4006e011b 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c | |||
@@ -3078,15 +3078,15 @@ static int copy_from_dinode(struct dinode * dip, struct inode *ip) | |||
3078 | } | 3078 | } |
3079 | set_nlink(ip, le32_to_cpu(dip->di_nlink)); | 3079 | set_nlink(ip, le32_to_cpu(dip->di_nlink)); |
3080 | 3080 | ||
3081 | jfs_ip->saved_uid = le32_to_cpu(dip->di_uid); | 3081 | jfs_ip->saved_uid = make_kuid(&init_user_ns, le32_to_cpu(dip->di_uid)); |
3082 | if (sbi->uid == -1) | 3082 | if (!uid_valid(sbi->uid)) |
3083 | ip->i_uid = jfs_ip->saved_uid; | 3083 | ip->i_uid = jfs_ip->saved_uid; |
3084 | else { | 3084 | else { |
3085 | ip->i_uid = sbi->uid; | 3085 | ip->i_uid = sbi->uid; |
3086 | } | 3086 | } |
3087 | 3087 | ||
3088 | jfs_ip->saved_gid = le32_to_cpu(dip->di_gid); | 3088 | jfs_ip->saved_gid = make_kgid(&init_user_ns, le32_to_cpu(dip->di_gid)); |
3089 | if (sbi->gid == -1) | 3089 | if (!gid_valid(sbi->gid)) |
3090 | ip->i_gid = jfs_ip->saved_gid; | 3090 | ip->i_gid = jfs_ip->saved_gid; |
3091 | else { | 3091 | else { |
3092 | ip->i_gid = sbi->gid; | 3092 | ip->i_gid = sbi->gid; |
@@ -3150,14 +3150,16 @@ static void copy_to_dinode(struct dinode * dip, struct inode *ip) | |||
3150 | dip->di_size = cpu_to_le64(ip->i_size); | 3150 | dip->di_size = cpu_to_le64(ip->i_size); |
3151 | dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks)); | 3151 | dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks)); |
3152 | dip->di_nlink = cpu_to_le32(ip->i_nlink); | 3152 | dip->di_nlink = cpu_to_le32(ip->i_nlink); |
3153 | if (sbi->uid == -1) | 3153 | if (!uid_valid(sbi->uid)) |
3154 | dip->di_uid = cpu_to_le32(ip->i_uid); | 3154 | dip->di_uid = cpu_to_le32(i_uid_read(ip)); |
3155 | else | 3155 | else |
3156 | dip->di_uid = cpu_to_le32(jfs_ip->saved_uid); | 3156 | dip->di_uid =cpu_to_le32(from_kuid(&init_user_ns, |
3157 | if (sbi->gid == -1) | 3157 | jfs_ip->saved_uid)); |
3158 | dip->di_gid = cpu_to_le32(ip->i_gid); | 3158 | if (!gid_valid(sbi->gid)) |
3159 | dip->di_gid = cpu_to_le32(i_gid_read(ip)); | ||
3159 | else | 3160 | else |
3160 | dip->di_gid = cpu_to_le32(jfs_ip->saved_gid); | 3161 | dip->di_gid = cpu_to_le32(from_kgid(&init_user_ns, |
3162 | jfs_ip->saved_gid)); | ||
3161 | jfs_get_inode_flags(jfs_ip); | 3163 | jfs_get_inode_flags(jfs_ip); |
3162 | /* | 3164 | /* |
3163 | * mode2 is only needed for storing the higher order bits. | 3165 | * mode2 is only needed for storing the higher order bits. |
diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h index 584a4a1a6e81..680605d7bf15 100644 --- a/fs/jfs/jfs_incore.h +++ b/fs/jfs/jfs_incore.h | |||
@@ -38,8 +38,8 @@ | |||
38 | struct jfs_inode_info { | 38 | struct jfs_inode_info { |
39 | int fileset; /* fileset number (always 16)*/ | 39 | int fileset; /* fileset number (always 16)*/ |
40 | uint mode2; /* jfs-specific mode */ | 40 | uint mode2; /* jfs-specific mode */ |
41 | uint saved_uid; /* saved for uid mount option */ | 41 | kuid_t saved_uid; /* saved for uid mount option */ |
42 | uint saved_gid; /* saved for gid mount option */ | 42 | kgid_t saved_gid; /* saved for gid mount option */ |
43 | pxd_t ixpxd; /* inode extent descriptor */ | 43 | pxd_t ixpxd; /* inode extent descriptor */ |
44 | dxd_t acl; /* dxd describing acl */ | 44 | dxd_t acl; /* dxd describing acl */ |
45 | dxd_t ea; /* dxd describing ea */ | 45 | dxd_t ea; /* dxd describing ea */ |
@@ -192,8 +192,8 @@ struct jfs_sb_info { | |||
192 | uint state; /* mount/recovery state */ | 192 | uint state; /* mount/recovery state */ |
193 | unsigned long flag; /* mount time flags */ | 193 | unsigned long flag; /* mount time flags */ |
194 | uint p_state; /* state prior to going no integrity */ | 194 | uint p_state; /* state prior to going no integrity */ |
195 | uint uid; /* uid to override on-disk uid */ | 195 | kuid_t uid; /* uid to override on-disk uid */ |
196 | uint gid; /* gid to override on-disk gid */ | 196 | kgid_t gid; /* gid to override on-disk gid */ |
197 | uint umask; /* umask to override on-disk umask */ | 197 | uint umask; /* umask to override on-disk umask */ |
198 | }; | 198 | }; |
199 | 199 | ||
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index c55c7452d285..706692f24033 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
@@ -321,13 +321,19 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, | |||
321 | case Opt_uid: | 321 | case Opt_uid: |
322 | { | 322 | { |
323 | char *uid = args[0].from; | 323 | char *uid = args[0].from; |
324 | sbi->uid = simple_strtoul(uid, &uid, 0); | 324 | uid_t val = simple_strtoul(uid, &uid, 0); |
325 | sbi->uid = make_kuid(current_user_ns(), val); | ||
326 | if (!uid_valid(sbi->uid)) | ||
327 | goto cleanup; | ||
325 | break; | 328 | break; |
326 | } | 329 | } |
327 | case Opt_gid: | 330 | case Opt_gid: |
328 | { | 331 | { |
329 | char *gid = args[0].from; | 332 | char *gid = args[0].from; |
330 | sbi->gid = simple_strtoul(gid, &gid, 0); | 333 | gid_t val = simple_strtoul(gid, &gid, 0); |
334 | sbi->gid = make_kgid(current_user_ns(), val); | ||
335 | if (!gid_valid(sbi->gid)) | ||
336 | goto cleanup; | ||
331 | break; | 337 | break; |
332 | } | 338 | } |
333 | case Opt_umask: | 339 | case Opt_umask: |
@@ -443,7 +449,9 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) | |||
443 | sb->s_fs_info = sbi; | 449 | sb->s_fs_info = sbi; |
444 | sb->s_max_links = JFS_LINK_MAX; | 450 | sb->s_max_links = JFS_LINK_MAX; |
445 | sbi->sb = sb; | 451 | sbi->sb = sb; |
446 | sbi->uid = sbi->gid = sbi->umask = -1; | 452 | sbi->uid = INVALID_UID; |
453 | sbi->gid = INVALID_GID; | ||
454 | sbi->umask = -1; | ||
447 | 455 | ||
448 | /* initialize the mount flag and determine the default error handler */ | 456 | /* initialize the mount flag and determine the default error handler */ |
449 | flag = JFS_ERR_REMOUNT_RO; | 457 | flag = JFS_ERR_REMOUNT_RO; |
@@ -617,10 +625,10 @@ static int jfs_show_options(struct seq_file *seq, struct dentry *root) | |||
617 | { | 625 | { |
618 | struct jfs_sb_info *sbi = JFS_SBI(root->d_sb); | 626 | struct jfs_sb_info *sbi = JFS_SBI(root->d_sb); |
619 | 627 | ||
620 | if (sbi->uid != -1) | 628 | if (uid_valid(sbi->uid)) |
621 | seq_printf(seq, ",uid=%d", sbi->uid); | 629 | seq_printf(seq, ",uid=%d", from_kuid(&init_user_ns, sbi->uid)); |
622 | if (sbi->gid != -1) | 630 | if (gid_valid(sbi->gid)) |
623 | seq_printf(seq, ",gid=%d", sbi->gid); | 631 | seq_printf(seq, ",gid=%d", from_kgid(&init_user_ns, sbi->gid)); |
624 | if (sbi->umask != -1) | 632 | if (sbi->umask != -1) |
625 | seq_printf(seq, ",umask=%03o", sbi->umask); | 633 | seq_printf(seq, ",umask=%03o", sbi->umask); |
626 | if (sbi->flag & JFS_NOINTEGRITY) | 634 | if (sbi->flag & JFS_NOINTEGRITY) |
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index 26683e15b3ac..42d67f9757bf 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c | |||
@@ -685,7 +685,7 @@ static int can_set_system_xattr(struct inode *inode, const char *name, | |||
685 | * POSIX_ACL_XATTR_ACCESS is tied to i_mode | 685 | * POSIX_ACL_XATTR_ACCESS is tied to i_mode |
686 | */ | 686 | */ |
687 | if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) { | 687 | if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) { |
688 | acl = posix_acl_from_xattr(value, value_len); | 688 | acl = posix_acl_from_xattr(&init_user_ns, value, value_len); |
689 | if (IS_ERR(acl)) { | 689 | if (IS_ERR(acl)) { |
690 | rc = PTR_ERR(acl); | 690 | rc = PTR_ERR(acl); |
691 | printk(KERN_ERR "posix_acl_from_xattr returned %d\n", | 691 | printk(KERN_ERR "posix_acl_from_xattr returned %d\n", |
@@ -710,7 +710,7 @@ static int can_set_system_xattr(struct inode *inode, const char *name, | |||
710 | 710 | ||
711 | return 0; | 711 | return 0; |
712 | } else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) { | 712 | } else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) { |
713 | acl = posix_acl_from_xattr(value, value_len); | 713 | acl = posix_acl_from_xattr(&init_user_ns, value, value_len); |
714 | if (IS_ERR(acl)) { | 714 | if (IS_ERR(acl)) { |
715 | rc = PTR_ERR(acl); | 715 | rc = PTR_ERR(acl); |
716 | printk(KERN_ERR "posix_acl_from_xattr returned %d\n", | 716 | printk(KERN_ERR "posix_acl_from_xattr returned %d\n", |
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c index 6984562738d3..bda39085309f 100644 --- a/fs/logfs/inode.c +++ b/fs/logfs/inode.c | |||
@@ -208,8 +208,8 @@ static void logfs_init_inode(struct super_block *sb, struct inode *inode) | |||
208 | li->li_height = 0; | 208 | li->li_height = 0; |
209 | li->li_used_bytes = 0; | 209 | li->li_used_bytes = 0; |
210 | li->li_block = NULL; | 210 | li->li_block = NULL; |
211 | inode->i_uid = 0; | 211 | i_uid_write(inode, 0); |
212 | inode->i_gid = 0; | 212 | i_gid_write(inode, 0); |
213 | inode->i_size = 0; | 213 | inode->i_size = 0; |
214 | inode->i_blocks = 0; | 214 | inode->i_blocks = 0; |
215 | inode->i_ctime = CURRENT_TIME; | 215 | inode->i_ctime = CURRENT_TIME; |
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index 5be0abef603d..e1a3b6bf6324 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c | |||
@@ -119,8 +119,8 @@ static void logfs_disk_to_inode(struct logfs_disk_inode *di, struct inode*inode) | |||
119 | inode->i_mode = be16_to_cpu(di->di_mode); | 119 | inode->i_mode = be16_to_cpu(di->di_mode); |
120 | li->li_height = di->di_height; | 120 | li->li_height = di->di_height; |
121 | li->li_flags = be32_to_cpu(di->di_flags); | 121 | li->li_flags = be32_to_cpu(di->di_flags); |
122 | inode->i_uid = be32_to_cpu(di->di_uid); | 122 | i_uid_write(inode, be32_to_cpu(di->di_uid)); |
123 | inode->i_gid = be32_to_cpu(di->di_gid); | 123 | i_gid_write(inode, be32_to_cpu(di->di_gid)); |
124 | inode->i_size = be64_to_cpu(di->di_size); | 124 | inode->i_size = be64_to_cpu(di->di_size); |
125 | logfs_set_blocks(inode, be64_to_cpu(di->di_used_bytes)); | 125 | logfs_set_blocks(inode, be64_to_cpu(di->di_used_bytes)); |
126 | inode->i_atime = be64_to_timespec(di->di_atime); | 126 | inode->i_atime = be64_to_timespec(di->di_atime); |
@@ -156,8 +156,8 @@ static void logfs_inode_to_disk(struct inode *inode, struct logfs_disk_inode*di) | |||
156 | di->di_height = li->li_height; | 156 | di->di_height = li->li_height; |
157 | di->di_pad = 0; | 157 | di->di_pad = 0; |
158 | di->di_flags = cpu_to_be32(li->li_flags); | 158 | di->di_flags = cpu_to_be32(li->li_flags); |
159 | di->di_uid = cpu_to_be32(inode->i_uid); | 159 | di->di_uid = cpu_to_be32(i_uid_read(inode)); |
160 | di->di_gid = cpu_to_be32(inode->i_gid); | 160 | di->di_gid = cpu_to_be32(i_gid_read(inode)); |
161 | di->di_size = cpu_to_be64(i_size_read(inode)); | 161 | di->di_size = cpu_to_be64(i_size_read(inode)); |
162 | di->di_used_bytes = cpu_to_be64(li->li_used_bytes); | 162 | di->di_used_bytes = cpu_to_be64(li->li_used_bytes); |
163 | di->di_atime = timespec_to_be64(inode->i_atime); | 163 | di->di_atime = timespec_to_be64(inode->i_atime); |
diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 2a503ad020d5..d0e42c678923 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c | |||
@@ -460,8 +460,8 @@ static struct inode *V1_minix_iget(struct inode *inode) | |||
460 | return ERR_PTR(-EIO); | 460 | return ERR_PTR(-EIO); |
461 | } | 461 | } |
462 | inode->i_mode = raw_inode->i_mode; | 462 | inode->i_mode = raw_inode->i_mode; |
463 | inode->i_uid = (uid_t)raw_inode->i_uid; | 463 | i_uid_write(inode, raw_inode->i_uid); |
464 | inode->i_gid = (gid_t)raw_inode->i_gid; | 464 | i_gid_write(inode, raw_inode->i_gid); |
465 | set_nlink(inode, raw_inode->i_nlinks); | 465 | set_nlink(inode, raw_inode->i_nlinks); |
466 | inode->i_size = raw_inode->i_size; | 466 | inode->i_size = raw_inode->i_size; |
467 | inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec = raw_inode->i_time; | 467 | inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec = raw_inode->i_time; |
@@ -493,8 +493,8 @@ static struct inode *V2_minix_iget(struct inode *inode) | |||
493 | return ERR_PTR(-EIO); | 493 | return ERR_PTR(-EIO); |
494 | } | 494 | } |
495 | inode->i_mode = raw_inode->i_mode; | 495 | inode->i_mode = raw_inode->i_mode; |
496 | inode->i_uid = (uid_t)raw_inode->i_uid; | 496 | i_uid_write(inode, raw_inode->i_uid); |
497 | inode->i_gid = (gid_t)raw_inode->i_gid; | 497 | i_gid_write(inode, raw_inode->i_gid); |
498 | set_nlink(inode, raw_inode->i_nlinks); | 498 | set_nlink(inode, raw_inode->i_nlinks); |
499 | inode->i_size = raw_inode->i_size; | 499 | inode->i_size = raw_inode->i_size; |
500 | inode->i_mtime.tv_sec = raw_inode->i_mtime; | 500 | inode->i_mtime.tv_sec = raw_inode->i_mtime; |
@@ -545,8 +545,8 @@ static struct buffer_head * V1_minix_update_inode(struct inode * inode) | |||
545 | if (!raw_inode) | 545 | if (!raw_inode) |
546 | return NULL; | 546 | return NULL; |
547 | raw_inode->i_mode = inode->i_mode; | 547 | raw_inode->i_mode = inode->i_mode; |
548 | raw_inode->i_uid = fs_high2lowuid(inode->i_uid); | 548 | raw_inode->i_uid = fs_high2lowuid(i_uid_read(inode)); |
549 | raw_inode->i_gid = fs_high2lowgid(inode->i_gid); | 549 | raw_inode->i_gid = fs_high2lowgid(i_gid_read(inode)); |
550 | raw_inode->i_nlinks = inode->i_nlink; | 550 | raw_inode->i_nlinks = inode->i_nlink; |
551 | raw_inode->i_size = inode->i_size; | 551 | raw_inode->i_size = inode->i_size; |
552 | raw_inode->i_time = inode->i_mtime.tv_sec; | 552 | raw_inode->i_time = inode->i_mtime.tv_sec; |
@@ -572,8 +572,8 @@ static struct buffer_head * V2_minix_update_inode(struct inode * inode) | |||
572 | if (!raw_inode) | 572 | if (!raw_inode) |
573 | return NULL; | 573 | return NULL; |
574 | raw_inode->i_mode = inode->i_mode; | 574 | raw_inode->i_mode = inode->i_mode; |
575 | raw_inode->i_uid = fs_high2lowuid(inode->i_uid); | 575 | raw_inode->i_uid = fs_high2lowuid(i_uid_read(inode)); |
576 | raw_inode->i_gid = fs_high2lowgid(inode->i_gid); | 576 | raw_inode->i_gid = fs_high2lowgid(i_gid_read(inode)); |
577 | raw_inode->i_nlinks = inode->i_nlink; | 577 | raw_inode->i_nlinks = inode->i_nlink; |
578 | raw_inode->i_size = inode->i_size; | 578 | raw_inode->i_size = inode->i_size; |
579 | raw_inode->i_mtime = inode->i_mtime.tv_sec; | 579 | raw_inode->i_mtime = inode->i_mtime.tv_sec; |
diff --git a/fs/namei.c b/fs/namei.c index dd1ed1b8e98e..a856e7f7b6e3 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -680,7 +680,7 @@ static inline int may_follow_link(struct path *link, struct nameidata *nd) | |||
680 | 680 | ||
681 | /* Allowed if owner and follower match. */ | 681 | /* Allowed if owner and follower match. */ |
682 | inode = link->dentry->d_inode; | 682 | inode = link->dentry->d_inode; |
683 | if (current_cred()->fsuid == inode->i_uid) | 683 | if (uid_eq(current_cred()->fsuid, inode->i_uid)) |
684 | return 0; | 684 | return 0; |
685 | 685 | ||
686 | /* Allowed if parent directory not sticky and world-writable. */ | 686 | /* Allowed if parent directory not sticky and world-writable. */ |
@@ -689,7 +689,7 @@ static inline int may_follow_link(struct path *link, struct nameidata *nd) | |||
689 | return 0; | 689 | return 0; |
690 | 690 | ||
691 | /* Allowed if parent directory and link owner match. */ | 691 | /* Allowed if parent directory and link owner match. */ |
692 | if (parent->i_uid == inode->i_uid) | 692 | if (uid_eq(parent->i_uid, inode->i_uid)) |
693 | return 0; | 693 | return 0; |
694 | 694 | ||
695 | path_put_conditional(link, nd); | 695 | path_put_conditional(link, nd); |
@@ -759,7 +759,7 @@ static int may_linkat(struct path *link) | |||
759 | /* Source inode owner (or CAP_FOWNER) can hardlink all they like, | 759 | /* Source inode owner (or CAP_FOWNER) can hardlink all they like, |
760 | * otherwise, it must be a safe source. | 760 | * otherwise, it must be a safe source. |
761 | */ | 761 | */ |
762 | if (cred->fsuid == inode->i_uid || safe_hardlink_source(inode) || | 762 | if (uid_eq(cred->fsuid, inode->i_uid) || safe_hardlink_source(inode) || |
763 | capable(CAP_FOWNER)) | 763 | capable(CAP_FOWNER)) |
764 | return 0; | 764 | return 0; |
765 | 765 | ||
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index e4498dc351a8..4a1aafba6a20 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c | |||
@@ -70,7 +70,7 @@ ssize_t nfs3_getxattr(struct dentry *dentry, const char *name, | |||
70 | if (type == ACL_TYPE_ACCESS && acl->a_count == 0) | 70 | if (type == ACL_TYPE_ACCESS && acl->a_count == 0) |
71 | error = -ENODATA; | 71 | error = -ENODATA; |
72 | else | 72 | else |
73 | error = posix_acl_to_xattr(acl, buffer, size); | 73 | error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); |
74 | posix_acl_release(acl); | 74 | posix_acl_release(acl); |
75 | } else | 75 | } else |
76 | error = -ENODATA; | 76 | error = -ENODATA; |
@@ -92,7 +92,7 @@ int nfs3_setxattr(struct dentry *dentry, const char *name, | |||
92 | else | 92 | else |
93 | return -EOPNOTSUPP; | 93 | return -EOPNOTSUPP; |
94 | 94 | ||
95 | acl = posix_acl_from_xattr(value, size); | 95 | acl = posix_acl_from_xattr(&init_user_ns, value, size); |
96 | if (IS_ERR(acl)) | 96 | if (IS_ERR(acl)) |
97 | return PTR_ERR(acl); | 97 | return PTR_ERR(acl); |
98 | error = nfs3_proc_setacl(inode, type, acl); | 98 | error = nfs3_proc_setacl(inode, type, acl); |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index a9269f142cc4..3f67b8e12251 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -480,7 +480,7 @@ set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key) | |||
480 | if (buf == NULL) | 480 | if (buf == NULL) |
481 | goto out; | 481 | goto out; |
482 | 482 | ||
483 | len = posix_acl_to_xattr(pacl, buf, buflen); | 483 | len = posix_acl_to_xattr(&init_user_ns, pacl, buf, buflen); |
484 | if (len < 0) { | 484 | if (len < 0) { |
485 | error = len; | 485 | error = len; |
486 | goto out; | 486 | goto out; |
@@ -549,7 +549,7 @@ _get_posix_acl(struct dentry *dentry, char *key) | |||
549 | if (buflen <= 0) | 549 | if (buflen <= 0) |
550 | return ERR_PTR(buflen); | 550 | return ERR_PTR(buflen); |
551 | 551 | ||
552 | pacl = posix_acl_from_xattr(buf, buflen); | 552 | pacl = posix_acl_from_xattr(&init_user_ns, buf, buflen); |
553 | kfree(buf); | 553 | kfree(buf); |
554 | return pacl; | 554 | return pacl; |
555 | } | 555 | } |
@@ -2264,7 +2264,7 @@ nfsd_get_posix_acl(struct svc_fh *fhp, int type) | |||
2264 | if (size < 0) | 2264 | if (size < 0) |
2265 | return ERR_PTR(size); | 2265 | return ERR_PTR(size); |
2266 | 2266 | ||
2267 | acl = posix_acl_from_xattr(value, size); | 2267 | acl = posix_acl_from_xattr(&init_user_ns, value, size); |
2268 | kfree(value); | 2268 | kfree(value); |
2269 | return acl; | 2269 | return acl; |
2270 | } | 2270 | } |
@@ -2297,7 +2297,7 @@ nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl) | |||
2297 | value = kmalloc(size, GFP_KERNEL); | 2297 | value = kmalloc(size, GFP_KERNEL); |
2298 | if (!value) | 2298 | if (!value) |
2299 | return -ENOMEM; | 2299 | return -ENOMEM; |
2300 | error = posix_acl_to_xattr(acl, value, size); | 2300 | error = posix_acl_to_xattr(&init_user_ns, acl, value, size); |
2301 | if (error < 0) | 2301 | if (error < 0) |
2302 | goto getout; | 2302 | goto getout; |
2303 | size = error; | 2303 | size = error; |
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 6e2c3db976b2..4d31d2cca7fd 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
@@ -401,8 +401,8 @@ int nilfs_read_inode_common(struct inode *inode, | |||
401 | int err; | 401 | int err; |
402 | 402 | ||
403 | inode->i_mode = le16_to_cpu(raw_inode->i_mode); | 403 | inode->i_mode = le16_to_cpu(raw_inode->i_mode); |
404 | inode->i_uid = (uid_t)le32_to_cpu(raw_inode->i_uid); | 404 | i_uid_write(inode, le32_to_cpu(raw_inode->i_uid)); |
405 | inode->i_gid = (gid_t)le32_to_cpu(raw_inode->i_gid); | 405 | i_gid_write(inode, le32_to_cpu(raw_inode->i_gid)); |
406 | set_nlink(inode, le16_to_cpu(raw_inode->i_links_count)); | 406 | set_nlink(inode, le16_to_cpu(raw_inode->i_links_count)); |
407 | inode->i_size = le64_to_cpu(raw_inode->i_size); | 407 | inode->i_size = le64_to_cpu(raw_inode->i_size); |
408 | inode->i_atime.tv_sec = le64_to_cpu(raw_inode->i_mtime); | 408 | inode->i_atime.tv_sec = le64_to_cpu(raw_inode->i_mtime); |
@@ -590,8 +590,8 @@ void nilfs_write_inode_common(struct inode *inode, | |||
590 | struct nilfs_inode_info *ii = NILFS_I(inode); | 590 | struct nilfs_inode_info *ii = NILFS_I(inode); |
591 | 591 | ||
592 | raw_inode->i_mode = cpu_to_le16(inode->i_mode); | 592 | raw_inode->i_mode = cpu_to_le16(inode->i_mode); |
593 | raw_inode->i_uid = cpu_to_le32(inode->i_uid); | 593 | raw_inode->i_uid = cpu_to_le32(i_uid_read(inode)); |
594 | raw_inode->i_gid = cpu_to_le32(inode->i_gid); | 594 | raw_inode->i_gid = cpu_to_le32(i_gid_read(inode)); |
595 | raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); | 595 | raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); |
596 | raw_inode->i_size = cpu_to_le64(inode->i_size); | 596 | raw_inode->i_size = cpu_to_le64(inode->i_size); |
597 | raw_inode->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec); | 597 | raw_inode->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec); |
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index c6dbd3db6ca8..1d27331e6fc9 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c | |||
@@ -2124,7 +2124,8 @@ int ntfs_read_inode_mount(struct inode *vi) | |||
2124 | * ntfs_read_inode() will have set up the default ones. | 2124 | * ntfs_read_inode() will have set up the default ones. |
2125 | */ | 2125 | */ |
2126 | /* Set uid and gid to root. */ | 2126 | /* Set uid and gid to root. */ |
2127 | vi->i_uid = vi->i_gid = 0; | 2127 | vi->i_uid = GLOBAL_ROOT_UID; |
2128 | vi->i_gid = GLOBAL_ROOT_GID; | ||
2128 | /* Regular file. No access for anyone. */ | 2129 | /* Regular file. No access for anyone. */ |
2129 | vi->i_mode = S_IFREG; | 2130 | vi->i_mode = S_IFREG; |
2130 | /* No VFS initiated operations allowed for $MFT. */ | 2131 | /* No VFS initiated operations allowed for $MFT. */ |
@@ -2312,8 +2313,8 @@ int ntfs_show_options(struct seq_file *sf, struct dentry *root) | |||
2312 | ntfs_volume *vol = NTFS_SB(root->d_sb); | 2313 | ntfs_volume *vol = NTFS_SB(root->d_sb); |
2313 | int i; | 2314 | int i; |
2314 | 2315 | ||
2315 | seq_printf(sf, ",uid=%i", vol->uid); | 2316 | seq_printf(sf, ",uid=%i", from_kuid_munged(&init_user_ns, vol->uid)); |
2316 | seq_printf(sf, ",gid=%i", vol->gid); | 2317 | seq_printf(sf, ",gid=%i", from_kgid_munged(&init_user_ns, vol->gid)); |
2317 | if (vol->fmask == vol->dmask) | 2318 | if (vol->fmask == vol->dmask) |
2318 | seq_printf(sf, ",umask=0%o", vol->fmask); | 2319 | seq_printf(sf, ",umask=0%o", vol->fmask); |
2319 | else { | 2320 | else { |
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 2bc149d6a784..da01c165067d 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c | |||
@@ -102,8 +102,8 @@ static bool parse_options(ntfs_volume *vol, char *opt) | |||
102 | char *p, *v, *ov; | 102 | char *p, *v, *ov; |
103 | static char *utf8 = "utf8"; | 103 | static char *utf8 = "utf8"; |
104 | int errors = 0, sloppy = 0; | 104 | int errors = 0, sloppy = 0; |
105 | uid_t uid = (uid_t)-1; | 105 | kuid_t uid = INVALID_UID; |
106 | gid_t gid = (gid_t)-1; | 106 | kgid_t gid = INVALID_GID; |
107 | umode_t fmask = (umode_t)-1, dmask = (umode_t)-1; | 107 | umode_t fmask = (umode_t)-1, dmask = (umode_t)-1; |
108 | int mft_zone_multiplier = -1, on_errors = -1; | 108 | int mft_zone_multiplier = -1, on_errors = -1; |
109 | int show_sys_files = -1, case_sensitive = -1, disable_sparse = -1; | 109 | int show_sys_files = -1, case_sensitive = -1, disable_sparse = -1; |
@@ -128,6 +128,30 @@ static bool parse_options(ntfs_volume *vol, char *opt) | |||
128 | if (*v) \ | 128 | if (*v) \ |
129 | goto needs_val; \ | 129 | goto needs_val; \ |
130 | } | 130 | } |
131 | #define NTFS_GETOPT_UID(option, variable) \ | ||
132 | if (!strcmp(p, option)) { \ | ||
133 | uid_t uid_value; \ | ||
134 | if (!v || !*v) \ | ||
135 | goto needs_arg; \ | ||
136 | uid_value = simple_strtoul(ov = v, &v, 0); \ | ||
137 | if (*v) \ | ||
138 | goto needs_val; \ | ||
139 | variable = make_kuid(current_user_ns(), uid_value); \ | ||
140 | if (!uid_valid(variable)) \ | ||
141 | goto needs_val; \ | ||
142 | } | ||
143 | #define NTFS_GETOPT_GID(option, variable) \ | ||
144 | if (!strcmp(p, option)) { \ | ||
145 | gid_t gid_value; \ | ||
146 | if (!v || !*v) \ | ||
147 | goto needs_arg; \ | ||
148 | gid_value = simple_strtoul(ov = v, &v, 0); \ | ||
149 | if (*v) \ | ||
150 | goto needs_val; \ | ||
151 | variable = make_kgid(current_user_ns(), gid_value); \ | ||
152 | if (!gid_valid(variable)) \ | ||
153 | goto needs_val; \ | ||
154 | } | ||
131 | #define NTFS_GETOPT_OCTAL(option, variable) \ | 155 | #define NTFS_GETOPT_OCTAL(option, variable) \ |
132 | if (!strcmp(p, option)) { \ | 156 | if (!strcmp(p, option)) { \ |
133 | if (!v || !*v) \ | 157 | if (!v || !*v) \ |
@@ -165,8 +189,8 @@ static bool parse_options(ntfs_volume *vol, char *opt) | |||
165 | while ((p = strsep(&opt, ","))) { | 189 | while ((p = strsep(&opt, ","))) { |
166 | if ((v = strchr(p, '='))) | 190 | if ((v = strchr(p, '='))) |
167 | *v++ = 0; | 191 | *v++ = 0; |
168 | NTFS_GETOPT("uid", uid) | 192 | NTFS_GETOPT_UID("uid", uid) |
169 | else NTFS_GETOPT("gid", gid) | 193 | else NTFS_GETOPT_GID("gid", gid) |
170 | else NTFS_GETOPT_OCTAL("umask", fmask = dmask) | 194 | else NTFS_GETOPT_OCTAL("umask", fmask = dmask) |
171 | else NTFS_GETOPT_OCTAL("fmask", fmask) | 195 | else NTFS_GETOPT_OCTAL("fmask", fmask) |
172 | else NTFS_GETOPT_OCTAL("dmask", dmask) | 196 | else NTFS_GETOPT_OCTAL("dmask", dmask) |
@@ -283,9 +307,9 @@ no_mount_options: | |||
283 | vol->on_errors = on_errors; | 307 | vol->on_errors = on_errors; |
284 | if (!vol->on_errors || vol->on_errors == ON_ERRORS_RECOVER) | 308 | if (!vol->on_errors || vol->on_errors == ON_ERRORS_RECOVER) |
285 | vol->on_errors |= ON_ERRORS_CONTINUE; | 309 | vol->on_errors |= ON_ERRORS_CONTINUE; |
286 | if (uid != (uid_t)-1) | 310 | if (uid_valid(uid)) |
287 | vol->uid = uid; | 311 | vol->uid = uid; |
288 | if (gid != (gid_t)-1) | 312 | if (gid_valid(gid)) |
289 | vol->gid = gid; | 313 | vol->gid = gid; |
290 | if (fmask != (umode_t)-1) | 314 | if (fmask != (umode_t)-1) |
291 | vol->fmask = fmask; | 315 | vol->fmask = fmask; |
@@ -1023,7 +1047,8 @@ static bool load_and_init_mft_mirror(ntfs_volume *vol) | |||
1023 | * ntfs_read_inode() will have set up the default ones. | 1047 | * ntfs_read_inode() will have set up the default ones. |
1024 | */ | 1048 | */ |
1025 | /* Set uid and gid to root. */ | 1049 | /* Set uid and gid to root. */ |
1026 | tmp_ino->i_uid = tmp_ino->i_gid = 0; | 1050 | tmp_ino->i_uid = GLOBAL_ROOT_UID; |
1051 | tmp_ino->i_gid = GLOBAL_ROOT_GID; | ||
1027 | /* Regular file. No access for anyone. */ | 1052 | /* Regular file. No access for anyone. */ |
1028 | tmp_ino->i_mode = S_IFREG; | 1053 | tmp_ino->i_mode = S_IFREG; |
1029 | /* No VFS initiated operations allowed for $MFTMirr. */ | 1054 | /* No VFS initiated operations allowed for $MFTMirr. */ |
diff --git a/fs/ntfs/volume.h b/fs/ntfs/volume.h index 15e3ba8d521a..4f579b02bc76 100644 --- a/fs/ntfs/volume.h +++ b/fs/ntfs/volume.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define _LINUX_NTFS_VOLUME_H | 25 | #define _LINUX_NTFS_VOLUME_H |
26 | 26 | ||
27 | #include <linux/rwsem.h> | 27 | #include <linux/rwsem.h> |
28 | #include <linux/uidgid.h> | ||
28 | 29 | ||
29 | #include "types.h" | 30 | #include "types.h" |
30 | #include "layout.h" | 31 | #include "layout.h" |
@@ -46,8 +47,8 @@ typedef struct { | |||
46 | sized blocks on the device. */ | 47 | sized blocks on the device. */ |
47 | /* Configuration provided by user at mount time. */ | 48 | /* Configuration provided by user at mount time. */ |
48 | unsigned long flags; /* Miscellaneous flags, see below. */ | 49 | unsigned long flags; /* Miscellaneous flags, see below. */ |
49 | uid_t uid; /* uid that files will be mounted as. */ | 50 | kuid_t uid; /* uid that files will be mounted as. */ |
50 | gid_t gid; /* gid that files will be mounted as. */ | 51 | kgid_t gid; /* gid that files will be mounted as. */ |
51 | umode_t fmask; /* The mask for file permissions. */ | 52 | umode_t fmask; /* The mask for file permissions. */ |
52 | umode_t dmask; /* The mask for directory | 53 | umode_t dmask; /* The mask for directory |
53 | permissions. */ | 54 | permissions. */ |
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index a7219075b4de..260b16281fc3 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c | |||
@@ -452,7 +452,7 @@ static int ocfs2_xattr_get_acl(struct dentry *dentry, const char *name, | |||
452 | return PTR_ERR(acl); | 452 | return PTR_ERR(acl); |
453 | if (acl == NULL) | 453 | if (acl == NULL) |
454 | return -ENODATA; | 454 | return -ENODATA; |
455 | ret = posix_acl_to_xattr(acl, buffer, size); | 455 | ret = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); |
456 | posix_acl_release(acl); | 456 | posix_acl_release(acl); |
457 | 457 | ||
458 | return ret; | 458 | return ret; |
@@ -475,7 +475,7 @@ static int ocfs2_xattr_set_acl(struct dentry *dentry, const char *name, | |||
475 | return -EPERM; | 475 | return -EPERM; |
476 | 476 | ||
477 | if (value) { | 477 | if (value) { |
478 | acl = posix_acl_from_xattr(value, size); | 478 | acl = posix_acl_from_xattr(&init_user_ns, value, size); |
479 | if (IS_ERR(acl)) | 479 | if (IS_ERR(acl)) |
480 | return PTR_ERR(acl); | 480 | return PTR_ERR(acl); |
481 | else if (acl) { | 481 | else if (acl) { |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 46a1f6d75104..5a4ee77cec51 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1184,8 +1184,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
1184 | if (attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid | 1184 | if (attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid |
1185 | && OCFS2_HAS_RO_COMPAT_FEATURE(sb, | 1185 | && OCFS2_HAS_RO_COMPAT_FEATURE(sb, |
1186 | OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) { | 1186 | OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) { |
1187 | transfer_to[USRQUOTA] = dqget(sb, attr->ia_uid, | 1187 | transfer_to[USRQUOTA] = dqget(sb, make_kqid_uid(attr->ia_uid)); |
1188 | USRQUOTA); | ||
1189 | if (!transfer_to[USRQUOTA]) { | 1188 | if (!transfer_to[USRQUOTA]) { |
1190 | status = -ESRCH; | 1189 | status = -ESRCH; |
1191 | goto bail_unlock; | 1190 | goto bail_unlock; |
@@ -1194,8 +1193,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
1194 | if (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid | 1193 | if (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid |
1195 | && OCFS2_HAS_RO_COMPAT_FEATURE(sb, | 1194 | && OCFS2_HAS_RO_COMPAT_FEATURE(sb, |
1196 | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) { | 1195 | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) { |
1197 | transfer_to[GRPQUOTA] = dqget(sb, attr->ia_gid, | 1196 | transfer_to[GRPQUOTA] = dqget(sb, make_kqid_gid(attr->ia_gid)); |
1198 | GRPQUOTA); | ||
1199 | if (!transfer_to[GRPQUOTA]) { | 1197 | if (!transfer_to[GRPQUOTA]) { |
1200 | status = -ESRCH; | 1198 | status = -ESRCH; |
1201 | goto bail_unlock; | 1199 | goto bail_unlock; |
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index 0a86e302655f..332a281f217e 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c | |||
@@ -95,7 +95,7 @@ static void ocfs2_global_mem2diskdqb(void *dp, struct dquot *dquot) | |||
95 | struct ocfs2_global_disk_dqblk *d = dp; | 95 | struct ocfs2_global_disk_dqblk *d = dp; |
96 | struct mem_dqblk *m = &dquot->dq_dqb; | 96 | struct mem_dqblk *m = &dquot->dq_dqb; |
97 | 97 | ||
98 | d->dqb_id = cpu_to_le32(dquot->dq_id); | 98 | d->dqb_id = cpu_to_le32(from_kqid(&init_user_ns, dquot->dq_id)); |
99 | d->dqb_use_count = cpu_to_le32(OCFS2_DQUOT(dquot)->dq_use_count); | 99 | d->dqb_use_count = cpu_to_le32(OCFS2_DQUOT(dquot)->dq_use_count); |
100 | d->dqb_ihardlimit = cpu_to_le64(m->dqb_ihardlimit); | 100 | d->dqb_ihardlimit = cpu_to_le64(m->dqb_ihardlimit); |
101 | d->dqb_isoftlimit = cpu_to_le64(m->dqb_isoftlimit); | 101 | d->dqb_isoftlimit = cpu_to_le64(m->dqb_isoftlimit); |
@@ -112,11 +112,14 @@ static int ocfs2_global_is_id(void *dp, struct dquot *dquot) | |||
112 | { | 112 | { |
113 | struct ocfs2_global_disk_dqblk *d = dp; | 113 | struct ocfs2_global_disk_dqblk *d = dp; |
114 | struct ocfs2_mem_dqinfo *oinfo = | 114 | struct ocfs2_mem_dqinfo *oinfo = |
115 | sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv; | 115 | sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv; |
116 | 116 | ||
117 | if (qtree_entry_unused(&oinfo->dqi_gi, dp)) | 117 | if (qtree_entry_unused(&oinfo->dqi_gi, dp)) |
118 | return 0; | 118 | return 0; |
119 | return le32_to_cpu(d->dqb_id) == dquot->dq_id; | 119 | |
120 | return qid_eq(make_kqid(&init_user_ns, dquot->dq_id.type, | ||
121 | le32_to_cpu(d->dqb_id)), | ||
122 | dquot->dq_id); | ||
120 | } | 123 | } |
121 | 124 | ||
122 | struct qtree_fmt_operations ocfs2_global_ops = { | 125 | struct qtree_fmt_operations ocfs2_global_ops = { |
@@ -475,7 +478,7 @@ int __ocfs2_sync_dquot(struct dquot *dquot, int freeing) | |||
475 | { | 478 | { |
476 | int err, err2; | 479 | int err, err2; |
477 | struct super_block *sb = dquot->dq_sb; | 480 | struct super_block *sb = dquot->dq_sb; |
478 | int type = dquot->dq_type; | 481 | int type = dquot->dq_id.type; |
479 | struct ocfs2_mem_dqinfo *info = sb_dqinfo(sb, type)->dqi_priv; | 482 | struct ocfs2_mem_dqinfo *info = sb_dqinfo(sb, type)->dqi_priv; |
480 | struct ocfs2_global_disk_dqblk dqblk; | 483 | struct ocfs2_global_disk_dqblk dqblk; |
481 | s64 spacechange, inodechange; | 484 | s64 spacechange, inodechange; |
@@ -504,7 +507,8 @@ int __ocfs2_sync_dquot(struct dquot *dquot, int freeing) | |||
504 | olditime = dquot->dq_dqb.dqb_itime; | 507 | olditime = dquot->dq_dqb.dqb_itime; |
505 | oldbtime = dquot->dq_dqb.dqb_btime; | 508 | oldbtime = dquot->dq_dqb.dqb_btime; |
506 | ocfs2_global_disk2memdqb(dquot, &dqblk); | 509 | ocfs2_global_disk2memdqb(dquot, &dqblk); |
507 | trace_ocfs2_sync_dquot(dquot->dq_id, dquot->dq_dqb.dqb_curspace, | 510 | trace_ocfs2_sync_dquot(from_kqid(&init_user_ns, dquot->dq_id), |
511 | dquot->dq_dqb.dqb_curspace, | ||
508 | (long long)spacechange, | 512 | (long long)spacechange, |
509 | dquot->dq_dqb.dqb_curinodes, | 513 | dquot->dq_dqb.dqb_curinodes, |
510 | (long long)inodechange); | 514 | (long long)inodechange); |
@@ -555,8 +559,8 @@ int __ocfs2_sync_dquot(struct dquot *dquot, int freeing) | |||
555 | err = ocfs2_qinfo_lock(info, freeing); | 559 | err = ocfs2_qinfo_lock(info, freeing); |
556 | if (err < 0) { | 560 | if (err < 0) { |
557 | mlog(ML_ERROR, "Failed to lock quota info, losing quota write" | 561 | mlog(ML_ERROR, "Failed to lock quota info, losing quota write" |
558 | " (type=%d, id=%u)\n", dquot->dq_type, | 562 | " (type=%d, id=%u)\n", dquot->dq_id.type, |
559 | (unsigned)dquot->dq_id); | 563 | (unsigned)from_kqid(&init_user_ns, dquot->dq_id)); |
560 | goto out; | 564 | goto out; |
561 | } | 565 | } |
562 | if (freeing) | 566 | if (freeing) |
@@ -591,9 +595,10 @@ static int ocfs2_sync_dquot_helper(struct dquot *dquot, unsigned long type) | |||
591 | struct ocfs2_super *osb = OCFS2_SB(sb); | 595 | struct ocfs2_super *osb = OCFS2_SB(sb); |
592 | int status = 0; | 596 | int status = 0; |
593 | 597 | ||
594 | trace_ocfs2_sync_dquot_helper(dquot->dq_id, dquot->dq_type, | 598 | trace_ocfs2_sync_dquot_helper(from_kqid(&init_user_ns, dquot->dq_id), |
599 | dquot->dq_id.type, | ||
595 | type, sb->s_id); | 600 | type, sb->s_id); |
596 | if (type != dquot->dq_type) | 601 | if (type != dquot->dq_id.type) |
597 | goto out; | 602 | goto out; |
598 | status = ocfs2_lock_global_qf(oinfo, 1); | 603 | status = ocfs2_lock_global_qf(oinfo, 1); |
599 | if (status < 0) | 604 | if (status < 0) |
@@ -643,7 +648,8 @@ static int ocfs2_write_dquot(struct dquot *dquot) | |||
643 | struct ocfs2_super *osb = OCFS2_SB(dquot->dq_sb); | 648 | struct ocfs2_super *osb = OCFS2_SB(dquot->dq_sb); |
644 | int status = 0; | 649 | int status = 0; |
645 | 650 | ||
646 | trace_ocfs2_write_dquot(dquot->dq_id, dquot->dq_type); | 651 | trace_ocfs2_write_dquot(from_kqid(&init_user_ns, dquot->dq_id), |
652 | dquot->dq_id.type); | ||
647 | 653 | ||
648 | handle = ocfs2_start_trans(osb, OCFS2_QWRITE_CREDITS); | 654 | handle = ocfs2_start_trans(osb, OCFS2_QWRITE_CREDITS); |
649 | if (IS_ERR(handle)) { | 655 | if (IS_ERR(handle)) { |
@@ -677,11 +683,12 @@ static int ocfs2_release_dquot(struct dquot *dquot) | |||
677 | { | 683 | { |
678 | handle_t *handle; | 684 | handle_t *handle; |
679 | struct ocfs2_mem_dqinfo *oinfo = | 685 | struct ocfs2_mem_dqinfo *oinfo = |
680 | sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv; | 686 | sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv; |
681 | struct ocfs2_super *osb = OCFS2_SB(dquot->dq_sb); | 687 | struct ocfs2_super *osb = OCFS2_SB(dquot->dq_sb); |
682 | int status = 0; | 688 | int status = 0; |
683 | 689 | ||
684 | trace_ocfs2_release_dquot(dquot->dq_id, dquot->dq_type); | 690 | trace_ocfs2_release_dquot(from_kqid(&init_user_ns, dquot->dq_id), |
691 | dquot->dq_id.type); | ||
685 | 692 | ||
686 | mutex_lock(&dquot->dq_lock); | 693 | mutex_lock(&dquot->dq_lock); |
687 | /* Check whether we are not racing with some other dqget() */ | 694 | /* Check whether we are not racing with some other dqget() */ |
@@ -691,7 +698,7 @@ static int ocfs2_release_dquot(struct dquot *dquot) | |||
691 | if (status < 0) | 698 | if (status < 0) |
692 | goto out; | 699 | goto out; |
693 | handle = ocfs2_start_trans(osb, | 700 | handle = ocfs2_start_trans(osb, |
694 | ocfs2_calc_qdel_credits(dquot->dq_sb, dquot->dq_type)); | 701 | ocfs2_calc_qdel_credits(dquot->dq_sb, dquot->dq_id.type)); |
695 | if (IS_ERR(handle)) { | 702 | if (IS_ERR(handle)) { |
696 | status = PTR_ERR(handle); | 703 | status = PTR_ERR(handle); |
697 | mlog_errno(status); | 704 | mlog_errno(status); |
@@ -733,13 +740,14 @@ static int ocfs2_acquire_dquot(struct dquot *dquot) | |||
733 | int ex = 0; | 740 | int ex = 0; |
734 | struct super_block *sb = dquot->dq_sb; | 741 | struct super_block *sb = dquot->dq_sb; |
735 | struct ocfs2_super *osb = OCFS2_SB(sb); | 742 | struct ocfs2_super *osb = OCFS2_SB(sb); |
736 | int type = dquot->dq_type; | 743 | int type = dquot->dq_id.type; |
737 | struct ocfs2_mem_dqinfo *info = sb_dqinfo(sb, type)->dqi_priv; | 744 | struct ocfs2_mem_dqinfo *info = sb_dqinfo(sb, type)->dqi_priv; |
738 | struct inode *gqinode = info->dqi_gqinode; | 745 | struct inode *gqinode = info->dqi_gqinode; |
739 | int need_alloc = ocfs2_global_qinit_alloc(sb, type); | 746 | int need_alloc = ocfs2_global_qinit_alloc(sb, type); |
740 | handle_t *handle; | 747 | handle_t *handle; |
741 | 748 | ||
742 | trace_ocfs2_acquire_dquot(dquot->dq_id, type); | 749 | trace_ocfs2_acquire_dquot(from_kqid(&init_user_ns, dquot->dq_id), |
750 | type); | ||
743 | mutex_lock(&dquot->dq_lock); | 751 | mutex_lock(&dquot->dq_lock); |
744 | /* | 752 | /* |
745 | * We need an exclusive lock, because we're going to update use count | 753 | * We need an exclusive lock, because we're going to update use count |
@@ -821,12 +829,13 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot) | |||
821 | int sync = 0; | 829 | int sync = 0; |
822 | int status; | 830 | int status; |
823 | struct super_block *sb = dquot->dq_sb; | 831 | struct super_block *sb = dquot->dq_sb; |
824 | int type = dquot->dq_type; | 832 | int type = dquot->dq_id.type; |
825 | struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv; | 833 | struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv; |
826 | handle_t *handle; | 834 | handle_t *handle; |
827 | struct ocfs2_super *osb = OCFS2_SB(sb); | 835 | struct ocfs2_super *osb = OCFS2_SB(sb); |
828 | 836 | ||
829 | trace_ocfs2_mark_dquot_dirty(dquot->dq_id, type); | 837 | trace_ocfs2_mark_dquot_dirty(from_kqid(&init_user_ns, dquot->dq_id), |
838 | type); | ||
830 | 839 | ||
831 | /* In case user set some limits, sync dquot immediately to global | 840 | /* In case user set some limits, sync dquot immediately to global |
832 | * quota file so that information propagates quicker */ | 841 | * quota file so that information propagates quicker */ |
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c index f100bf70a906..27fe7ee4874c 100644 --- a/fs/ocfs2/quota_local.c +++ b/fs/ocfs2/quota_local.c | |||
@@ -501,7 +501,9 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode, | |||
501 | } | 501 | } |
502 | dqblk = (struct ocfs2_local_disk_dqblk *)(qbh->b_data + | 502 | dqblk = (struct ocfs2_local_disk_dqblk *)(qbh->b_data + |
503 | ol_dqblk_block_off(sb, chunk, bit)); | 503 | ol_dqblk_block_off(sb, chunk, bit)); |
504 | dquot = dqget(sb, le64_to_cpu(dqblk->dqb_id), type); | 504 | dquot = dqget(sb, |
505 | make_kqid(&init_user_ns, type, | ||
506 | le64_to_cpu(dqblk->dqb_id))); | ||
505 | if (!dquot) { | 507 | if (!dquot) { |
506 | status = -EIO; | 508 | status = -EIO; |
507 | mlog(ML_ERROR, "Failed to get quota structure " | 509 | mlog(ML_ERROR, "Failed to get quota structure " |
@@ -881,7 +883,8 @@ static void olq_set_dquot(struct buffer_head *bh, void *private) | |||
881 | dqblk = (struct ocfs2_local_disk_dqblk *)(bh->b_data | 883 | dqblk = (struct ocfs2_local_disk_dqblk *)(bh->b_data |
882 | + ol_dqblk_block_offset(sb, od->dq_local_off)); | 884 | + ol_dqblk_block_offset(sb, od->dq_local_off)); |
883 | 885 | ||
884 | dqblk->dqb_id = cpu_to_le64(od->dq_dquot.dq_id); | 886 | dqblk->dqb_id = cpu_to_le64(from_kqid(&init_user_ns, |
887 | od->dq_dquot.dq_id)); | ||
885 | spin_lock(&dq_data_lock); | 888 | spin_lock(&dq_data_lock); |
886 | dqblk->dqb_spacemod = cpu_to_le64(od->dq_dquot.dq_dqb.dqb_curspace - | 889 | dqblk->dqb_spacemod = cpu_to_le64(od->dq_dquot.dq_dqb.dqb_curspace - |
887 | od->dq_origspace); | 890 | od->dq_origspace); |
@@ -891,7 +894,7 @@ static void olq_set_dquot(struct buffer_head *bh, void *private) | |||
891 | trace_olq_set_dquot( | 894 | trace_olq_set_dquot( |
892 | (unsigned long long)le64_to_cpu(dqblk->dqb_spacemod), | 895 | (unsigned long long)le64_to_cpu(dqblk->dqb_spacemod), |
893 | (unsigned long long)le64_to_cpu(dqblk->dqb_inodemod), | 896 | (unsigned long long)le64_to_cpu(dqblk->dqb_inodemod), |
894 | od->dq_dquot.dq_id); | 897 | from_kqid(&init_user_ns, od->dq_dquot.dq_id)); |
895 | } | 898 | } |
896 | 899 | ||
897 | /* Write dquot to local quota file */ | 900 | /* Write dquot to local quota file */ |
@@ -900,7 +903,7 @@ int ocfs2_local_write_dquot(struct dquot *dquot) | |||
900 | struct super_block *sb = dquot->dq_sb; | 903 | struct super_block *sb = dquot->dq_sb; |
901 | struct ocfs2_dquot *od = OCFS2_DQUOT(dquot); | 904 | struct ocfs2_dquot *od = OCFS2_DQUOT(dquot); |
902 | struct buffer_head *bh; | 905 | struct buffer_head *bh; |
903 | struct inode *lqinode = sb_dqopt(sb)->files[dquot->dq_type]; | 906 | struct inode *lqinode = sb_dqopt(sb)->files[dquot->dq_id.type]; |
904 | int status; | 907 | int status; |
905 | 908 | ||
906 | status = ocfs2_read_quota_phys_block(lqinode, od->dq_local_phys_blk, | 909 | status = ocfs2_read_quota_phys_block(lqinode, od->dq_local_phys_blk, |
@@ -1221,7 +1224,7 @@ static void olq_alloc_dquot(struct buffer_head *bh, void *private) | |||
1221 | int ocfs2_create_local_dquot(struct dquot *dquot) | 1224 | int ocfs2_create_local_dquot(struct dquot *dquot) |
1222 | { | 1225 | { |
1223 | struct super_block *sb = dquot->dq_sb; | 1226 | struct super_block *sb = dquot->dq_sb; |
1224 | int type = dquot->dq_type; | 1227 | int type = dquot->dq_id.type; |
1225 | struct inode *lqinode = sb_dqopt(sb)->files[type]; | 1228 | struct inode *lqinode = sb_dqopt(sb)->files[type]; |
1226 | struct ocfs2_quota_chunk *chunk; | 1229 | struct ocfs2_quota_chunk *chunk; |
1227 | struct ocfs2_dquot *od = OCFS2_DQUOT(dquot); | 1230 | struct ocfs2_dquot *od = OCFS2_DQUOT(dquot); |
@@ -1275,7 +1278,7 @@ out: | |||
1275 | int ocfs2_local_release_dquot(handle_t *handle, struct dquot *dquot) | 1278 | int ocfs2_local_release_dquot(handle_t *handle, struct dquot *dquot) |
1276 | { | 1279 | { |
1277 | int status; | 1280 | int status; |
1278 | int type = dquot->dq_type; | 1281 | int type = dquot->dq_id.type; |
1279 | struct ocfs2_dquot *od = OCFS2_DQUOT(dquot); | 1282 | struct ocfs2_dquot *od = OCFS2_DQUOT(dquot); |
1280 | struct super_block *sb = dquot->dq_sb; | 1283 | struct super_block *sb = dquot->dq_sb; |
1281 | struct ocfs2_local_disk_chunk *dchunk; | 1284 | struct ocfs2_local_disk_chunk *dchunk; |
diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c index e6213b3725d1..25d715c7c87a 100644 --- a/fs/omfs/inode.c +++ b/fs/omfs/inode.c | |||
@@ -391,12 +391,16 @@ static int parse_options(char *options, struct omfs_sb_info *sbi) | |||
391 | case Opt_uid: | 391 | case Opt_uid: |
392 | if (match_int(&args[0], &option)) | 392 | if (match_int(&args[0], &option)) |
393 | return 0; | 393 | return 0; |
394 | sbi->s_uid = option; | 394 | sbi->s_uid = make_kuid(current_user_ns(), option); |
395 | if (!uid_valid(sbi->s_uid)) | ||
396 | return 0; | ||
395 | break; | 397 | break; |
396 | case Opt_gid: | 398 | case Opt_gid: |
397 | if (match_int(&args[0], &option)) | 399 | if (match_int(&args[0], &option)) |
398 | return 0; | 400 | return 0; |
399 | sbi->s_gid = option; | 401 | sbi->s_gid = make_kgid(current_user_ns(), option); |
402 | if (!gid_valid(sbi->s_gid)) | ||
403 | return 0; | ||
400 | break; | 404 | break; |
401 | case Opt_umask: | 405 | case Opt_umask: |
402 | if (match_octal(&args[0], &option)) | 406 | if (match_octal(&args[0], &option)) |
diff --git a/fs/omfs/omfs.h b/fs/omfs/omfs.h index 8941f12c6b01..f0f8bc75e609 100644 --- a/fs/omfs/omfs.h +++ b/fs/omfs/omfs.h | |||
@@ -19,8 +19,8 @@ struct omfs_sb_info { | |||
19 | unsigned long **s_imap; | 19 | unsigned long **s_imap; |
20 | int s_imap_size; | 20 | int s_imap_size; |
21 | struct mutex s_bitmap_lock; | 21 | struct mutex s_bitmap_lock; |
22 | int s_uid; | 22 | kuid_t s_uid; |
23 | int s_gid; | 23 | kgid_t s_gid; |
24 | int s_dmask; | 24 | int s_dmask; |
25 | int s_fmask; | 25 | int s_fmask; |
26 | }; | 26 | }; |
@@ -534,7 +534,7 @@ static int chown_common(struct path *path, uid_t user, gid_t group) | |||
534 | newattrs.ia_valid |= | 534 | newattrs.ia_valid |= |
535 | ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; | 535 | ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; |
536 | mutex_lock(&inode->i_mutex); | 536 | mutex_lock(&inode->i_mutex); |
537 | error = security_path_chown(path, user, group); | 537 | error = security_path_chown(path, uid, gid); |
538 | if (!error) | 538 | if (!error) |
539 | error = notify_change(path->dentry, &newattrs); | 539 | error = notify_change(path->dentry, &newattrs); |
540 | mutex_unlock(&inode->i_mutex); | 540 | mutex_unlock(&inode->i_mutex); |
diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 5e325a42e33d..8bd2135b7f82 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c | |||
@@ -78,7 +78,8 @@ posix_acl_valid(const struct posix_acl *acl) | |||
78 | { | 78 | { |
79 | const struct posix_acl_entry *pa, *pe; | 79 | const struct posix_acl_entry *pa, *pe; |
80 | int state = ACL_USER_OBJ; | 80 | int state = ACL_USER_OBJ; |
81 | unsigned int id = 0; /* keep gcc happy */ | 81 | kuid_t prev_uid = INVALID_UID; |
82 | kgid_t prev_gid = INVALID_GID; | ||
82 | int needs_mask = 0; | 83 | int needs_mask = 0; |
83 | 84 | ||
84 | FOREACH_ACL_ENTRY(pa, acl, pe) { | 85 | FOREACH_ACL_ENTRY(pa, acl, pe) { |
@@ -87,7 +88,6 @@ posix_acl_valid(const struct posix_acl *acl) | |||
87 | switch (pa->e_tag) { | 88 | switch (pa->e_tag) { |
88 | case ACL_USER_OBJ: | 89 | case ACL_USER_OBJ: |
89 | if (state == ACL_USER_OBJ) { | 90 | if (state == ACL_USER_OBJ) { |
90 | id = 0; | ||
91 | state = ACL_USER; | 91 | state = ACL_USER; |
92 | break; | 92 | break; |
93 | } | 93 | } |
@@ -96,16 +96,17 @@ posix_acl_valid(const struct posix_acl *acl) | |||
96 | case ACL_USER: | 96 | case ACL_USER: |
97 | if (state != ACL_USER) | 97 | if (state != ACL_USER) |
98 | return -EINVAL; | 98 | return -EINVAL; |
99 | if (pa->e_id == ACL_UNDEFINED_ID || | 99 | if (!uid_valid(pa->e_uid)) |
100 | pa->e_id < id) | ||
101 | return -EINVAL; | 100 | return -EINVAL; |
102 | id = pa->e_id + 1; | 101 | if (uid_valid(prev_uid) && |
102 | uid_lte(pa->e_uid, prev_uid)) | ||
103 | return -EINVAL; | ||
104 | prev_uid = pa->e_uid; | ||
103 | needs_mask = 1; | 105 | needs_mask = 1; |
104 | break; | 106 | break; |
105 | 107 | ||
106 | case ACL_GROUP_OBJ: | 108 | case ACL_GROUP_OBJ: |
107 | if (state == ACL_USER) { | 109 | if (state == ACL_USER) { |
108 | id = 0; | ||
109 | state = ACL_GROUP; | 110 | state = ACL_GROUP; |
110 | break; | 111 | break; |
111 | } | 112 | } |
@@ -114,10 +115,12 @@ posix_acl_valid(const struct posix_acl *acl) | |||
114 | case ACL_GROUP: | 115 | case ACL_GROUP: |
115 | if (state != ACL_GROUP) | 116 | if (state != ACL_GROUP) |
116 | return -EINVAL; | 117 | return -EINVAL; |
117 | if (pa->e_id == ACL_UNDEFINED_ID || | 118 | if (!gid_valid(pa->e_gid)) |
118 | pa->e_id < id) | 119 | return -EINVAL; |
120 | if (gid_valid(prev_gid) && | ||
121 | gid_lte(pa->e_gid, prev_gid)) | ||
119 | return -EINVAL; | 122 | return -EINVAL; |
120 | id = pa->e_id + 1; | 123 | prev_gid = pa->e_gid; |
121 | needs_mask = 1; | 124 | needs_mask = 1; |
122 | break; | 125 | break; |
123 | 126 | ||
@@ -195,15 +198,12 @@ posix_acl_from_mode(umode_t mode, gfp_t flags) | |||
195 | return ERR_PTR(-ENOMEM); | 198 | return ERR_PTR(-ENOMEM); |
196 | 199 | ||
197 | acl->a_entries[0].e_tag = ACL_USER_OBJ; | 200 | acl->a_entries[0].e_tag = ACL_USER_OBJ; |
198 | acl->a_entries[0].e_id = ACL_UNDEFINED_ID; | ||
199 | acl->a_entries[0].e_perm = (mode & S_IRWXU) >> 6; | 201 | acl->a_entries[0].e_perm = (mode & S_IRWXU) >> 6; |
200 | 202 | ||
201 | acl->a_entries[1].e_tag = ACL_GROUP_OBJ; | 203 | acl->a_entries[1].e_tag = ACL_GROUP_OBJ; |
202 | acl->a_entries[1].e_id = ACL_UNDEFINED_ID; | ||
203 | acl->a_entries[1].e_perm = (mode & S_IRWXG) >> 3; | 204 | acl->a_entries[1].e_perm = (mode & S_IRWXG) >> 3; |
204 | 205 | ||
205 | acl->a_entries[2].e_tag = ACL_OTHER; | 206 | acl->a_entries[2].e_tag = ACL_OTHER; |
206 | acl->a_entries[2].e_id = ACL_UNDEFINED_ID; | ||
207 | acl->a_entries[2].e_perm = (mode & S_IRWXO); | 207 | acl->a_entries[2].e_perm = (mode & S_IRWXO); |
208 | return acl; | 208 | return acl; |
209 | } | 209 | } |
@@ -224,11 +224,11 @@ posix_acl_permission(struct inode *inode, const struct posix_acl *acl, int want) | |||
224 | switch(pa->e_tag) { | 224 | switch(pa->e_tag) { |
225 | case ACL_USER_OBJ: | 225 | case ACL_USER_OBJ: |
226 | /* (May have been checked already) */ | 226 | /* (May have been checked already) */ |
227 | if (inode->i_uid == current_fsuid()) | 227 | if (uid_eq(inode->i_uid, current_fsuid())) |
228 | goto check_perm; | 228 | goto check_perm; |
229 | break; | 229 | break; |
230 | case ACL_USER: | 230 | case ACL_USER: |
231 | if (pa->e_id == current_fsuid()) | 231 | if (uid_eq(pa->e_uid, current_fsuid())) |
232 | goto mask; | 232 | goto mask; |
233 | break; | 233 | break; |
234 | case ACL_GROUP_OBJ: | 234 | case ACL_GROUP_OBJ: |
@@ -239,7 +239,7 @@ posix_acl_permission(struct inode *inode, const struct posix_acl *acl, int want) | |||
239 | } | 239 | } |
240 | break; | 240 | break; |
241 | case ACL_GROUP: | 241 | case ACL_GROUP: |
242 | if (in_group_p(pa->e_id)) { | 242 | if (in_group_p(pa->e_gid)) { |
243 | found = 1; | 243 | found = 1; |
244 | if ((pa->e_perm & want) == want) | 244 | if ((pa->e_perm & want) == want) |
245 | goto mask; | 245 | goto mask; |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 1b6c84cbdb73..acd1960c28a2 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1089,7 +1089,8 @@ static ssize_t proc_loginuid_read(struct file * file, char __user * buf, | |||
1089 | if (!task) | 1089 | if (!task) |
1090 | return -ESRCH; | 1090 | return -ESRCH; |
1091 | length = scnprintf(tmpbuf, TMPBUFLEN, "%u", | 1091 | length = scnprintf(tmpbuf, TMPBUFLEN, "%u", |
1092 | audit_get_loginuid(task)); | 1092 | from_kuid(file->f_cred->user_ns, |
1093 | audit_get_loginuid(task))); | ||
1093 | put_task_struct(task); | 1094 | put_task_struct(task); |
1094 | return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); | 1095 | return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); |
1095 | } | 1096 | } |
@@ -1101,6 +1102,7 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf, | |||
1101 | char *page, *tmp; | 1102 | char *page, *tmp; |
1102 | ssize_t length; | 1103 | ssize_t length; |
1103 | uid_t loginuid; | 1104 | uid_t loginuid; |
1105 | kuid_t kloginuid; | ||
1104 | 1106 | ||
1105 | rcu_read_lock(); | 1107 | rcu_read_lock(); |
1106 | if (current != pid_task(proc_pid(inode), PIDTYPE_PID)) { | 1108 | if (current != pid_task(proc_pid(inode), PIDTYPE_PID)) { |
@@ -1130,7 +1132,13 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf, | |||
1130 | goto out_free_page; | 1132 | goto out_free_page; |
1131 | 1133 | ||
1132 | } | 1134 | } |
1133 | length = audit_set_loginuid(loginuid); | 1135 | kloginuid = make_kuid(file->f_cred->user_ns, loginuid); |
1136 | if (!uid_valid(kloginuid)) { | ||
1137 | length = -EINVAL; | ||
1138 | goto out_free_page; | ||
1139 | } | ||
1140 | |||
1141 | length = audit_set_loginuid(kloginuid); | ||
1134 | if (likely(length == 0)) | 1142 | if (likely(length == 0)) |
1135 | length = count; | 1143 | length = count; |
1136 | 1144 | ||
@@ -2983,6 +2991,11 @@ static int proc_gid_map_open(struct inode *inode, struct file *file) | |||
2983 | return proc_id_map_open(inode, file, &proc_gid_seq_operations); | 2991 | return proc_id_map_open(inode, file, &proc_gid_seq_operations); |
2984 | } | 2992 | } |
2985 | 2993 | ||
2994 | static int proc_projid_map_open(struct inode *inode, struct file *file) | ||
2995 | { | ||
2996 | return proc_id_map_open(inode, file, &proc_projid_seq_operations); | ||
2997 | } | ||
2998 | |||
2986 | static const struct file_operations proc_uid_map_operations = { | 2999 | static const struct file_operations proc_uid_map_operations = { |
2987 | .open = proc_uid_map_open, | 3000 | .open = proc_uid_map_open, |
2988 | .write = proc_uid_map_write, | 3001 | .write = proc_uid_map_write, |
@@ -2998,6 +3011,14 @@ static const struct file_operations proc_gid_map_operations = { | |||
2998 | .llseek = seq_lseek, | 3011 | .llseek = seq_lseek, |
2999 | .release = proc_id_map_release, | 3012 | .release = proc_id_map_release, |
3000 | }; | 3013 | }; |
3014 | |||
3015 | static const struct file_operations proc_projid_map_operations = { | ||
3016 | .open = proc_projid_map_open, | ||
3017 | .write = proc_projid_map_write, | ||
3018 | .read = seq_read, | ||
3019 | .llseek = seq_lseek, | ||
3020 | .release = proc_id_map_release, | ||
3021 | }; | ||
3001 | #endif /* CONFIG_USER_NS */ | 3022 | #endif /* CONFIG_USER_NS */ |
3002 | 3023 | ||
3003 | static int proc_pid_personality(struct seq_file *m, struct pid_namespace *ns, | 3024 | static int proc_pid_personality(struct seq_file *m, struct pid_namespace *ns, |
@@ -3105,6 +3126,7 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
3105 | #ifdef CONFIG_USER_NS | 3126 | #ifdef CONFIG_USER_NS |
3106 | REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), | 3127 | REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), |
3107 | REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), | 3128 | REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), |
3129 | REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations), | ||
3108 | #endif | 3130 | #endif |
3109 | }; | 3131 | }; |
3110 | 3132 | ||
@@ -3468,6 +3490,7 @@ static const struct pid_entry tid_base_stuff[] = { | |||
3468 | #ifdef CONFIG_USER_NS | 3490 | #ifdef CONFIG_USER_NS |
3469 | REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), | 3491 | REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations), |
3470 | REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), | 3492 | REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), |
3493 | REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations), | ||
3471 | #endif | 3494 | #endif |
3472 | }; | 3495 | }; |
3473 | 3496 | ||
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index 552e994e3aa1..5c3c7b02e17b 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c | |||
@@ -312,8 +312,8 @@ struct inode *qnx4_iget(struct super_block *sb, unsigned long ino) | |||
312 | (ino % QNX4_INODES_PER_BLOCK); | 312 | (ino % QNX4_INODES_PER_BLOCK); |
313 | 313 | ||
314 | inode->i_mode = le16_to_cpu(raw_inode->di_mode); | 314 | inode->i_mode = le16_to_cpu(raw_inode->di_mode); |
315 | inode->i_uid = (uid_t)le16_to_cpu(raw_inode->di_uid); | 315 | i_uid_write(inode, (uid_t)le16_to_cpu(raw_inode->di_uid)); |
316 | inode->i_gid = (gid_t)le16_to_cpu(raw_inode->di_gid); | 316 | i_gid_write(inode, (gid_t)le16_to_cpu(raw_inode->di_gid)); |
317 | set_nlink(inode, le16_to_cpu(raw_inode->di_nlink)); | 317 | set_nlink(inode, le16_to_cpu(raw_inode->di_nlink)); |
318 | inode->i_size = le32_to_cpu(raw_inode->di_size); | 318 | inode->i_size = le32_to_cpu(raw_inode->di_size); |
319 | inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->di_mtime); | 319 | inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->di_mtime); |
diff --git a/fs/qnx6/inode.c b/fs/qnx6/inode.c index 2049c814bda4..f4eef0b5e7b5 100644 --- a/fs/qnx6/inode.c +++ b/fs/qnx6/inode.c | |||
@@ -574,8 +574,8 @@ struct inode *qnx6_iget(struct super_block *sb, unsigned ino) | |||
574 | raw_inode = ((struct qnx6_inode_entry *)page_address(page)) + offs; | 574 | raw_inode = ((struct qnx6_inode_entry *)page_address(page)) + offs; |
575 | 575 | ||
576 | inode->i_mode = fs16_to_cpu(sbi, raw_inode->di_mode); | 576 | inode->i_mode = fs16_to_cpu(sbi, raw_inode->di_mode); |
577 | inode->i_uid = (uid_t)fs32_to_cpu(sbi, raw_inode->di_uid); | 577 | i_uid_write(inode, (uid_t)fs32_to_cpu(sbi, raw_inode->di_uid)); |
578 | inode->i_gid = (gid_t)fs32_to_cpu(sbi, raw_inode->di_gid); | 578 | i_gid_write(inode, (gid_t)fs32_to_cpu(sbi, raw_inode->di_gid)); |
579 | inode->i_size = fs64_to_cpu(sbi, raw_inode->di_size); | 579 | inode->i_size = fs64_to_cpu(sbi, raw_inode->di_size); |
580 | inode->i_mtime.tv_sec = fs32_to_cpu(sbi, raw_inode->di_mtime); | 580 | inode->i_mtime.tv_sec = fs32_to_cpu(sbi, raw_inode->di_mtime); |
581 | inode->i_mtime.tv_nsec = 0; | 581 | inode->i_mtime.tv_nsec = 0; |
diff --git a/fs/quota/Makefile b/fs/quota/Makefile index 5f9e9e276af0..c66c37cdaa39 100644 --- a/fs/quota/Makefile +++ b/fs/quota/Makefile | |||
@@ -2,6 +2,6 @@ obj-$(CONFIG_QUOTA) += dquot.o | |||
2 | obj-$(CONFIG_QFMT_V1) += quota_v1.o | 2 | obj-$(CONFIG_QFMT_V1) += quota_v1.o |
3 | obj-$(CONFIG_QFMT_V2) += quota_v2.o | 3 | obj-$(CONFIG_QFMT_V2) += quota_v2.o |
4 | obj-$(CONFIG_QUOTA_TREE) += quota_tree.o | 4 | obj-$(CONFIG_QUOTA_TREE) += quota_tree.o |
5 | obj-$(CONFIG_QUOTACTL) += quota.o | 5 | obj-$(CONFIG_QUOTACTL) += quota.o kqid.o |
6 | obj-$(CONFIG_QUOTACTL_COMPAT) += compat.o | 6 | obj-$(CONFIG_QUOTACTL_COMPAT) += compat.o |
7 | obj-$(CONFIG_QUOTA_NETLINK_INTERFACE) += netlink.o | 7 | obj-$(CONFIG_QUOTA_NETLINK_INTERFACE) += netlink.o |
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index c495a3055e2a..557a9c20a215 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -253,8 +253,10 @@ static qsize_t inode_get_rsv_space(struct inode *inode); | |||
253 | static void __dquot_initialize(struct inode *inode, int type); | 253 | static void __dquot_initialize(struct inode *inode, int type); |
254 | 254 | ||
255 | static inline unsigned int | 255 | static inline unsigned int |
256 | hashfn(const struct super_block *sb, unsigned int id, int type) | 256 | hashfn(const struct super_block *sb, struct kqid qid) |
257 | { | 257 | { |
258 | unsigned int id = from_kqid(&init_user_ns, qid); | ||
259 | int type = qid.type; | ||
258 | unsigned long tmp; | 260 | unsigned long tmp; |
259 | 261 | ||
260 | tmp = (((unsigned long)sb>>L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type); | 262 | tmp = (((unsigned long)sb>>L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type); |
@@ -267,7 +269,7 @@ hashfn(const struct super_block *sb, unsigned int id, int type) | |||
267 | static inline void insert_dquot_hash(struct dquot *dquot) | 269 | static inline void insert_dquot_hash(struct dquot *dquot) |
268 | { | 270 | { |
269 | struct hlist_head *head; | 271 | struct hlist_head *head; |
270 | head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type); | 272 | head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id); |
271 | hlist_add_head(&dquot->dq_hash, head); | 273 | hlist_add_head(&dquot->dq_hash, head); |
272 | } | 274 | } |
273 | 275 | ||
@@ -277,15 +279,14 @@ static inline void remove_dquot_hash(struct dquot *dquot) | |||
277 | } | 279 | } |
278 | 280 | ||
279 | static struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, | 281 | static struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, |
280 | unsigned int id, int type) | 282 | struct kqid qid) |
281 | { | 283 | { |
282 | struct hlist_node *node; | 284 | struct hlist_node *node; |
283 | struct dquot *dquot; | 285 | struct dquot *dquot; |
284 | 286 | ||
285 | hlist_for_each (node, dquot_hash+hashent) { | 287 | hlist_for_each (node, dquot_hash+hashent) { |
286 | dquot = hlist_entry(node, struct dquot, dq_hash); | 288 | dquot = hlist_entry(node, struct dquot, dq_hash); |
287 | if (dquot->dq_sb == sb && dquot->dq_id == id && | 289 | if (dquot->dq_sb == sb && qid_eq(dquot->dq_id, qid)) |
288 | dquot->dq_type == type) | ||
289 | return dquot; | 290 | return dquot; |
290 | } | 291 | } |
291 | return NULL; | 292 | return NULL; |
@@ -351,7 +352,7 @@ int dquot_mark_dquot_dirty(struct dquot *dquot) | |||
351 | spin_lock(&dq_list_lock); | 352 | spin_lock(&dq_list_lock); |
352 | if (!test_and_set_bit(DQ_MOD_B, &dquot->dq_flags)) { | 353 | if (!test_and_set_bit(DQ_MOD_B, &dquot->dq_flags)) { |
353 | list_add(&dquot->dq_dirty, &sb_dqopt(dquot->dq_sb)-> | 354 | list_add(&dquot->dq_dirty, &sb_dqopt(dquot->dq_sb)-> |
354 | info[dquot->dq_type].dqi_dirty_list); | 355 | info[dquot->dq_id.type].dqi_dirty_list); |
355 | ret = 0; | 356 | ret = 0; |
356 | } | 357 | } |
357 | spin_unlock(&dq_list_lock); | 358 | spin_unlock(&dq_list_lock); |
@@ -410,17 +411,17 @@ int dquot_acquire(struct dquot *dquot) | |||
410 | mutex_lock(&dquot->dq_lock); | 411 | mutex_lock(&dquot->dq_lock); |
411 | mutex_lock(&dqopt->dqio_mutex); | 412 | mutex_lock(&dqopt->dqio_mutex); |
412 | if (!test_bit(DQ_READ_B, &dquot->dq_flags)) | 413 | if (!test_bit(DQ_READ_B, &dquot->dq_flags)) |
413 | ret = dqopt->ops[dquot->dq_type]->read_dqblk(dquot); | 414 | ret = dqopt->ops[dquot->dq_id.type]->read_dqblk(dquot); |
414 | if (ret < 0) | 415 | if (ret < 0) |
415 | goto out_iolock; | 416 | goto out_iolock; |
416 | set_bit(DQ_READ_B, &dquot->dq_flags); | 417 | set_bit(DQ_READ_B, &dquot->dq_flags); |
417 | /* Instantiate dquot if needed */ | 418 | /* Instantiate dquot if needed */ |
418 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) { | 419 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) { |
419 | ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); | 420 | ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot); |
420 | /* Write the info if needed */ | 421 | /* Write the info if needed */ |
421 | if (info_dirty(&dqopt->info[dquot->dq_type])) { | 422 | if (info_dirty(&dqopt->info[dquot->dq_id.type])) { |
422 | ret2 = dqopt->ops[dquot->dq_type]->write_file_info( | 423 | ret2 = dqopt->ops[dquot->dq_id.type]->write_file_info( |
423 | dquot->dq_sb, dquot->dq_type); | 424 | dquot->dq_sb, dquot->dq_id.type); |
424 | } | 425 | } |
425 | if (ret < 0) | 426 | if (ret < 0) |
426 | goto out_iolock; | 427 | goto out_iolock; |
@@ -455,7 +456,7 @@ int dquot_commit(struct dquot *dquot) | |||
455 | /* Inactive dquot can be only if there was error during read/init | 456 | /* Inactive dquot can be only if there was error during read/init |
456 | * => we have better not writing it */ | 457 | * => we have better not writing it */ |
457 | if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) | 458 | if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) |
458 | ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); | 459 | ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot); |
459 | else | 460 | else |
460 | ret = -EIO; | 461 | ret = -EIO; |
461 | out_sem: | 462 | out_sem: |
@@ -477,12 +478,12 @@ int dquot_release(struct dquot *dquot) | |||
477 | if (atomic_read(&dquot->dq_count) > 1) | 478 | if (atomic_read(&dquot->dq_count) > 1) |
478 | goto out_dqlock; | 479 | goto out_dqlock; |
479 | mutex_lock(&dqopt->dqio_mutex); | 480 | mutex_lock(&dqopt->dqio_mutex); |
480 | if (dqopt->ops[dquot->dq_type]->release_dqblk) { | 481 | if (dqopt->ops[dquot->dq_id.type]->release_dqblk) { |
481 | ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot); | 482 | ret = dqopt->ops[dquot->dq_id.type]->release_dqblk(dquot); |
482 | /* Write the info */ | 483 | /* Write the info */ |
483 | if (info_dirty(&dqopt->info[dquot->dq_type])) { | 484 | if (info_dirty(&dqopt->info[dquot->dq_id.type])) { |
484 | ret2 = dqopt->ops[dquot->dq_type]->write_file_info( | 485 | ret2 = dqopt->ops[dquot->dq_id.type]->write_file_info( |
485 | dquot->dq_sb, dquot->dq_type); | 486 | dquot->dq_sb, dquot->dq_id.type); |
486 | } | 487 | } |
487 | if (ret >= 0) | 488 | if (ret >= 0) |
488 | ret = ret2; | 489 | ret = ret2; |
@@ -521,7 +522,7 @@ restart: | |||
521 | list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) { | 522 | list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) { |
522 | if (dquot->dq_sb != sb) | 523 | if (dquot->dq_sb != sb) |
523 | continue; | 524 | continue; |
524 | if (dquot->dq_type != type) | 525 | if (dquot->dq_id.type != type) |
525 | continue; | 526 | continue; |
526 | /* Wait for dquot users */ | 527 | /* Wait for dquot users */ |
527 | if (atomic_read(&dquot->dq_count)) { | 528 | if (atomic_read(&dquot->dq_count)) { |
@@ -741,7 +742,8 @@ void dqput(struct dquot *dquot) | |||
741 | #ifdef CONFIG_QUOTA_DEBUG | 742 | #ifdef CONFIG_QUOTA_DEBUG |
742 | if (!atomic_read(&dquot->dq_count)) { | 743 | if (!atomic_read(&dquot->dq_count)) { |
743 | quota_error(dquot->dq_sb, "trying to free free dquot of %s %d", | 744 | quota_error(dquot->dq_sb, "trying to free free dquot of %s %d", |
744 | quotatypes[dquot->dq_type], dquot->dq_id); | 745 | quotatypes[dquot->dq_id.type], |
746 | from_kqid(&init_user_ns, dquot->dq_id)); | ||
745 | BUG(); | 747 | BUG(); |
746 | } | 748 | } |
747 | #endif | 749 | #endif |
@@ -752,7 +754,7 @@ we_slept: | |||
752 | /* We have more than one user... nothing to do */ | 754 | /* We have more than one user... nothing to do */ |
753 | atomic_dec(&dquot->dq_count); | 755 | atomic_dec(&dquot->dq_count); |
754 | /* Releasing dquot during quotaoff phase? */ | 756 | /* Releasing dquot during quotaoff phase? */ |
755 | if (!sb_has_quota_active(dquot->dq_sb, dquot->dq_type) && | 757 | if (!sb_has_quota_active(dquot->dq_sb, dquot->dq_id.type) && |
756 | atomic_read(&dquot->dq_count) == 1) | 758 | atomic_read(&dquot->dq_count) == 1) |
757 | wake_up(&dquot->dq_wait_unused); | 759 | wake_up(&dquot->dq_wait_unused); |
758 | spin_unlock(&dq_list_lock); | 760 | spin_unlock(&dq_list_lock); |
@@ -815,7 +817,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) | |||
815 | INIT_LIST_HEAD(&dquot->dq_dirty); | 817 | INIT_LIST_HEAD(&dquot->dq_dirty); |
816 | init_waitqueue_head(&dquot->dq_wait_unused); | 818 | init_waitqueue_head(&dquot->dq_wait_unused); |
817 | dquot->dq_sb = sb; | 819 | dquot->dq_sb = sb; |
818 | dquot->dq_type = type; | 820 | dquot->dq_id = make_kqid_invalid(type); |
819 | atomic_set(&dquot->dq_count, 1); | 821 | atomic_set(&dquot->dq_count, 1); |
820 | 822 | ||
821 | return dquot; | 823 | return dquot; |
@@ -829,35 +831,35 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) | |||
829 | * a) checking for quota flags under dq_list_lock and | 831 | * a) checking for quota flags under dq_list_lock and |
830 | * b) getting a reference to dquot before we release dq_list_lock | 832 | * b) getting a reference to dquot before we release dq_list_lock |
831 | */ | 833 | */ |
832 | struct dquot *dqget(struct super_block *sb, unsigned int id, int type) | 834 | struct dquot *dqget(struct super_block *sb, struct kqid qid) |
833 | { | 835 | { |
834 | unsigned int hashent = hashfn(sb, id, type); | 836 | unsigned int hashent = hashfn(sb, qid); |
835 | struct dquot *dquot = NULL, *empty = NULL; | 837 | struct dquot *dquot = NULL, *empty = NULL; |
836 | 838 | ||
837 | if (!sb_has_quota_active(sb, type)) | 839 | if (!sb_has_quota_active(sb, qid.type)) |
838 | return NULL; | 840 | return NULL; |
839 | we_slept: | 841 | we_slept: |
840 | spin_lock(&dq_list_lock); | 842 | spin_lock(&dq_list_lock); |
841 | spin_lock(&dq_state_lock); | 843 | spin_lock(&dq_state_lock); |
842 | if (!sb_has_quota_active(sb, type)) { | 844 | if (!sb_has_quota_active(sb, qid.type)) { |
843 | spin_unlock(&dq_state_lock); | 845 | spin_unlock(&dq_state_lock); |
844 | spin_unlock(&dq_list_lock); | 846 | spin_unlock(&dq_list_lock); |
845 | goto out; | 847 | goto out; |
846 | } | 848 | } |
847 | spin_unlock(&dq_state_lock); | 849 | spin_unlock(&dq_state_lock); |
848 | 850 | ||
849 | dquot = find_dquot(hashent, sb, id, type); | 851 | dquot = find_dquot(hashent, sb, qid); |
850 | if (!dquot) { | 852 | if (!dquot) { |
851 | if (!empty) { | 853 | if (!empty) { |
852 | spin_unlock(&dq_list_lock); | 854 | spin_unlock(&dq_list_lock); |
853 | empty = get_empty_dquot(sb, type); | 855 | empty = get_empty_dquot(sb, qid.type); |
854 | if (!empty) | 856 | if (!empty) |
855 | schedule(); /* Try to wait for a moment... */ | 857 | schedule(); /* Try to wait for a moment... */ |
856 | goto we_slept; | 858 | goto we_slept; |
857 | } | 859 | } |
858 | dquot = empty; | 860 | dquot = empty; |
859 | empty = NULL; | 861 | empty = NULL; |
860 | dquot->dq_id = id; | 862 | dquot->dq_id = qid; |
861 | /* all dquots go on the inuse_list */ | 863 | /* all dquots go on the inuse_list */ |
862 | put_inuse(dquot); | 864 | put_inuse(dquot); |
863 | /* hash it first so it can be found */ | 865 | /* hash it first so it can be found */ |
@@ -1129,8 +1131,7 @@ static void dquot_decr_space(struct dquot *dquot, qsize_t number) | |||
1129 | 1131 | ||
1130 | struct dquot_warn { | 1132 | struct dquot_warn { |
1131 | struct super_block *w_sb; | 1133 | struct super_block *w_sb; |
1132 | qid_t w_dq_id; | 1134 | struct kqid w_dq_id; |
1133 | short w_dq_type; | ||
1134 | short w_type; | 1135 | short w_type; |
1135 | }; | 1136 | }; |
1136 | 1137 | ||
@@ -1154,11 +1155,11 @@ static int need_print_warning(struct dquot_warn *warn) | |||
1154 | if (!flag_print_warnings) | 1155 | if (!flag_print_warnings) |
1155 | return 0; | 1156 | return 0; |
1156 | 1157 | ||
1157 | switch (warn->w_dq_type) { | 1158 | switch (warn->w_dq_id.type) { |
1158 | case USRQUOTA: | 1159 | case USRQUOTA: |
1159 | return current_fsuid() == warn->w_dq_id; | 1160 | return uid_eq(current_fsuid(), warn->w_dq_id.uid); |
1160 | case GRPQUOTA: | 1161 | case GRPQUOTA: |
1161 | return in_group_p(warn->w_dq_id); | 1162 | return in_group_p(warn->w_dq_id.gid); |
1162 | } | 1163 | } |
1163 | return 0; | 1164 | return 0; |
1164 | } | 1165 | } |
@@ -1184,7 +1185,7 @@ static void print_warning(struct dquot_warn *warn) | |||
1184 | tty_write_message(tty, ": warning, "); | 1185 | tty_write_message(tty, ": warning, "); |
1185 | else | 1186 | else |
1186 | tty_write_message(tty, ": write failed, "); | 1187 | tty_write_message(tty, ": write failed, "); |
1187 | tty_write_message(tty, quotatypes[warn->w_dq_type]); | 1188 | tty_write_message(tty, quotatypes[warn->w_dq_id.type]); |
1188 | switch (warntype) { | 1189 | switch (warntype) { |
1189 | case QUOTA_NL_IHARDWARN: | 1190 | case QUOTA_NL_IHARDWARN: |
1190 | msg = " file limit reached.\r\n"; | 1191 | msg = " file limit reached.\r\n"; |
@@ -1218,7 +1219,6 @@ static void prepare_warning(struct dquot_warn *warn, struct dquot *dquot, | |||
1218 | warn->w_type = warntype; | 1219 | warn->w_type = warntype; |
1219 | warn->w_sb = dquot->dq_sb; | 1220 | warn->w_sb = dquot->dq_sb; |
1220 | warn->w_dq_id = dquot->dq_id; | 1221 | warn->w_dq_id = dquot->dq_id; |
1221 | warn->w_dq_type = dquot->dq_type; | ||
1222 | } | 1222 | } |
1223 | 1223 | ||
1224 | /* | 1224 | /* |
@@ -1236,14 +1236,14 @@ static void flush_warnings(struct dquot_warn *warn) | |||
1236 | #ifdef CONFIG_PRINT_QUOTA_WARNING | 1236 | #ifdef CONFIG_PRINT_QUOTA_WARNING |
1237 | print_warning(&warn[i]); | 1237 | print_warning(&warn[i]); |
1238 | #endif | 1238 | #endif |
1239 | quota_send_warning(warn[i].w_dq_type, warn[i].w_dq_id, | 1239 | quota_send_warning(warn[i].w_dq_id, |
1240 | warn[i].w_sb->s_dev, warn[i].w_type); | 1240 | warn[i].w_sb->s_dev, warn[i].w_type); |
1241 | } | 1241 | } |
1242 | } | 1242 | } |
1243 | 1243 | ||
1244 | static int ignore_hardlimit(struct dquot *dquot) | 1244 | static int ignore_hardlimit(struct dquot *dquot) |
1245 | { | 1245 | { |
1246 | struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type]; | 1246 | struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type]; |
1247 | 1247 | ||
1248 | return capable(CAP_SYS_RESOURCE) && | 1248 | return capable(CAP_SYS_RESOURCE) && |
1249 | (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD || | 1249 | (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD || |
@@ -1256,7 +1256,7 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, | |||
1256 | { | 1256 | { |
1257 | qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes; | 1257 | qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes; |
1258 | 1258 | ||
1259 | if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) || | 1259 | if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_id.type) || |
1260 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) | 1260 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) |
1261 | return 0; | 1261 | return 0; |
1262 | 1262 | ||
@@ -1281,7 +1281,7 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, | |||
1281 | dquot->dq_dqb.dqb_itime == 0) { | 1281 | dquot->dq_dqb.dqb_itime == 0) { |
1282 | prepare_warning(warn, dquot, QUOTA_NL_ISOFTWARN); | 1282 | prepare_warning(warn, dquot, QUOTA_NL_ISOFTWARN); |
1283 | dquot->dq_dqb.dqb_itime = get_seconds() + | 1283 | dquot->dq_dqb.dqb_itime = get_seconds() + |
1284 | sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace; | 1284 | sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type].dqi_igrace; |
1285 | } | 1285 | } |
1286 | 1286 | ||
1287 | return 0; | 1287 | return 0; |
@@ -1294,7 +1294,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, | |||
1294 | qsize_t tspace; | 1294 | qsize_t tspace; |
1295 | struct super_block *sb = dquot->dq_sb; | 1295 | struct super_block *sb = dquot->dq_sb; |
1296 | 1296 | ||
1297 | if (!sb_has_quota_limits_enabled(sb, dquot->dq_type) || | 1297 | if (!sb_has_quota_limits_enabled(sb, dquot->dq_id.type) || |
1298 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) | 1298 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) |
1299 | return 0; | 1299 | return 0; |
1300 | 1300 | ||
@@ -1325,7 +1325,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, | |||
1325 | if (!prealloc) { | 1325 | if (!prealloc) { |
1326 | prepare_warning(warn, dquot, QUOTA_NL_BSOFTWARN); | 1326 | prepare_warning(warn, dquot, QUOTA_NL_BSOFTWARN); |
1327 | dquot->dq_dqb.dqb_btime = get_seconds() + | 1327 | dquot->dq_dqb.dqb_btime = get_seconds() + |
1328 | sb_dqopt(sb)->info[dquot->dq_type].dqi_bgrace; | 1328 | sb_dqopt(sb)->info[dquot->dq_id.type].dqi_bgrace; |
1329 | } | 1329 | } |
1330 | else | 1330 | else |
1331 | /* | 1331 | /* |
@@ -1344,7 +1344,7 @@ static int info_idq_free(struct dquot *dquot, qsize_t inodes) | |||
1344 | 1344 | ||
1345 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || | 1345 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || |
1346 | dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit || | 1346 | dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit || |
1347 | !sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type)) | 1347 | !sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_id.type)) |
1348 | return QUOTA_NL_NOWARN; | 1348 | return QUOTA_NL_NOWARN; |
1349 | 1349 | ||
1350 | newinodes = dquot->dq_dqb.dqb_curinodes - inodes; | 1350 | newinodes = dquot->dq_dqb.dqb_curinodes - inodes; |
@@ -1390,7 +1390,6 @@ static int dquot_active(const struct inode *inode) | |||
1390 | */ | 1390 | */ |
1391 | static void __dquot_initialize(struct inode *inode, int type) | 1391 | static void __dquot_initialize(struct inode *inode, int type) |
1392 | { | 1392 | { |
1393 | unsigned int id = 0; | ||
1394 | int cnt; | 1393 | int cnt; |
1395 | struct dquot *got[MAXQUOTAS]; | 1394 | struct dquot *got[MAXQUOTAS]; |
1396 | struct super_block *sb = inode->i_sb; | 1395 | struct super_block *sb = inode->i_sb; |
@@ -1403,18 +1402,19 @@ static void __dquot_initialize(struct inode *inode, int type) | |||
1403 | 1402 | ||
1404 | /* First get references to structures we might need. */ | 1403 | /* First get references to structures we might need. */ |
1405 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1404 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1405 | struct kqid qid; | ||
1406 | got[cnt] = NULL; | 1406 | got[cnt] = NULL; |
1407 | if (type != -1 && cnt != type) | 1407 | if (type != -1 && cnt != type) |
1408 | continue; | 1408 | continue; |
1409 | switch (cnt) { | 1409 | switch (cnt) { |
1410 | case USRQUOTA: | 1410 | case USRQUOTA: |
1411 | id = inode->i_uid; | 1411 | qid = make_kqid_uid(inode->i_uid); |
1412 | break; | 1412 | break; |
1413 | case GRPQUOTA: | 1413 | case GRPQUOTA: |
1414 | id = inode->i_gid; | 1414 | qid = make_kqid_gid(inode->i_gid); |
1415 | break; | 1415 | break; |
1416 | } | 1416 | } |
1417 | got[cnt] = dqget(sb, id, cnt); | 1417 | got[cnt] = dqget(sb, qid); |
1418 | } | 1418 | } |
1419 | 1419 | ||
1420 | down_write(&sb_dqopt(sb)->dqptr_sem); | 1420 | down_write(&sb_dqopt(sb)->dqptr_sem); |
@@ -1897,10 +1897,10 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) | |||
1897 | if (!dquot_active(inode)) | 1897 | if (!dquot_active(inode)) |
1898 | return 0; | 1898 | return 0; |
1899 | 1899 | ||
1900 | if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) | 1900 | if (iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) |
1901 | transfer_to[USRQUOTA] = dqget(sb, iattr->ia_uid, USRQUOTA); | 1901 | transfer_to[USRQUOTA] = dqget(sb, make_kqid_uid(iattr->ia_uid)); |
1902 | if (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) | 1902 | if (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid)) |
1903 | transfer_to[GRPQUOTA] = dqget(sb, iattr->ia_gid, GRPQUOTA); | 1903 | transfer_to[GRPQUOTA] = dqget(sb, make_kqid_gid(iattr->ia_gid)); |
1904 | 1904 | ||
1905 | ret = __dquot_transfer(inode, transfer_to); | 1905 | ret = __dquot_transfer(inode, transfer_to); |
1906 | dqput_all(transfer_to); | 1906 | dqput_all(transfer_to); |
@@ -2360,9 +2360,9 @@ static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di) | |||
2360 | 2360 | ||
2361 | memset(di, 0, sizeof(*di)); | 2361 | memset(di, 0, sizeof(*di)); |
2362 | di->d_version = FS_DQUOT_VERSION; | 2362 | di->d_version = FS_DQUOT_VERSION; |
2363 | di->d_flags = dquot->dq_type == USRQUOTA ? | 2363 | di->d_flags = dquot->dq_id.type == USRQUOTA ? |
2364 | FS_USER_QUOTA : FS_GROUP_QUOTA; | 2364 | FS_USER_QUOTA : FS_GROUP_QUOTA; |
2365 | di->d_id = dquot->dq_id; | 2365 | di->d_id = from_kqid_munged(current_user_ns(), dquot->dq_id); |
2366 | 2366 | ||
2367 | spin_lock(&dq_data_lock); | 2367 | spin_lock(&dq_data_lock); |
2368 | di->d_blk_hardlimit = stoqb(dm->dqb_bhardlimit); | 2368 | di->d_blk_hardlimit = stoqb(dm->dqb_bhardlimit); |
@@ -2376,12 +2376,12 @@ static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di) | |||
2376 | spin_unlock(&dq_data_lock); | 2376 | spin_unlock(&dq_data_lock); |
2377 | } | 2377 | } |
2378 | 2378 | ||
2379 | int dquot_get_dqblk(struct super_block *sb, int type, qid_t id, | 2379 | int dquot_get_dqblk(struct super_block *sb, struct kqid qid, |
2380 | struct fs_disk_quota *di) | 2380 | struct fs_disk_quota *di) |
2381 | { | 2381 | { |
2382 | struct dquot *dquot; | 2382 | struct dquot *dquot; |
2383 | 2383 | ||
2384 | dquot = dqget(sb, id, type); | 2384 | dquot = dqget(sb, qid); |
2385 | if (!dquot) | 2385 | if (!dquot) |
2386 | return -ESRCH; | 2386 | return -ESRCH; |
2387 | do_get_dqblk(dquot, di); | 2387 | do_get_dqblk(dquot, di); |
@@ -2401,7 +2401,7 @@ static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di) | |||
2401 | { | 2401 | { |
2402 | struct mem_dqblk *dm = &dquot->dq_dqb; | 2402 | struct mem_dqblk *dm = &dquot->dq_dqb; |
2403 | int check_blim = 0, check_ilim = 0; | 2403 | int check_blim = 0, check_ilim = 0; |
2404 | struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type]; | 2404 | struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type]; |
2405 | 2405 | ||
2406 | if (di->d_fieldmask & ~VFS_FS_DQ_MASK) | 2406 | if (di->d_fieldmask & ~VFS_FS_DQ_MASK) |
2407 | return -EINVAL; | 2407 | return -EINVAL; |
@@ -2488,13 +2488,13 @@ static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di) | |||
2488 | return 0; | 2488 | return 0; |
2489 | } | 2489 | } |
2490 | 2490 | ||
2491 | int dquot_set_dqblk(struct super_block *sb, int type, qid_t id, | 2491 | int dquot_set_dqblk(struct super_block *sb, struct kqid qid, |
2492 | struct fs_disk_quota *di) | 2492 | struct fs_disk_quota *di) |
2493 | { | 2493 | { |
2494 | struct dquot *dquot; | 2494 | struct dquot *dquot; |
2495 | int rc; | 2495 | int rc; |
2496 | 2496 | ||
2497 | dquot = dqget(sb, id, type); | 2497 | dquot = dqget(sb, qid); |
2498 | if (!dquot) { | 2498 | if (!dquot) { |
2499 | rc = -ESRCH; | 2499 | rc = -ESRCH; |
2500 | goto out; | 2500 | goto out; |
diff --git a/fs/quota/kqid.c b/fs/quota/kqid.c new file mode 100644 index 000000000000..2f97b0e2c501 --- /dev/null +++ b/fs/quota/kqid.c | |||
@@ -0,0 +1,132 @@ | |||
1 | #include <linux/fs.h> | ||
2 | #include <linux/quota.h> | ||
3 | #include <linux/export.h> | ||
4 | |||
5 | /** | ||
6 | * qid_eq - Test to see if to kquid values are the same | ||
7 | * @left: A qid value | ||
8 | * @right: Another quid value | ||
9 | * | ||
10 | * Return true if the two qid values are equal and false otherwise. | ||
11 | */ | ||
12 | bool qid_eq(struct kqid left, struct kqid right) | ||
13 | { | ||
14 | if (left.type != right.type) | ||
15 | return false; | ||
16 | switch(left.type) { | ||
17 | case USRQUOTA: | ||
18 | return uid_eq(left.uid, right.uid); | ||
19 | case GRPQUOTA: | ||
20 | return gid_eq(left.gid, right.gid); | ||
21 | case PRJQUOTA: | ||
22 | return projid_eq(left.projid, right.projid); | ||
23 | default: | ||
24 | BUG(); | ||
25 | } | ||
26 | } | ||
27 | EXPORT_SYMBOL(qid_eq); | ||
28 | |||
29 | /** | ||
30 | * qid_lt - Test to see if one qid value is less than another | ||
31 | * @left: The possibly lesser qid value | ||
32 | * @right: The possibly greater qid value | ||
33 | * | ||
34 | * Return true if left is less than right and false otherwise. | ||
35 | */ | ||
36 | bool qid_lt(struct kqid left, struct kqid right) | ||
37 | { | ||
38 | if (left.type < right.type) | ||
39 | return true; | ||
40 | if (left.type > right.type) | ||
41 | return false; | ||
42 | switch (left.type) { | ||
43 | case USRQUOTA: | ||
44 | return uid_lt(left.uid, right.uid); | ||
45 | case GRPQUOTA: | ||
46 | return gid_lt(left.gid, right.gid); | ||
47 | case PRJQUOTA: | ||
48 | return projid_lt(left.projid, right.projid); | ||
49 | default: | ||
50 | BUG(); | ||
51 | } | ||
52 | } | ||
53 | EXPORT_SYMBOL(qid_lt); | ||
54 | |||
55 | /** | ||
56 | * from_kqid - Create a qid from a kqid user-namespace pair. | ||
57 | * @targ: The user namespace we want a qid in. | ||
58 | * @kuid: The kernel internal quota identifier to start with. | ||
59 | * | ||
60 | * Map @kqid into the user-namespace specified by @targ and | ||
61 | * return the resulting qid. | ||
62 | * | ||
63 | * There is always a mapping into the initial user_namespace. | ||
64 | * | ||
65 | * If @kqid has no mapping in @targ (qid_t)-1 is returned. | ||
66 | */ | ||
67 | qid_t from_kqid(struct user_namespace *targ, struct kqid kqid) | ||
68 | { | ||
69 | switch (kqid.type) { | ||
70 | case USRQUOTA: | ||
71 | return from_kuid(targ, kqid.uid); | ||
72 | case GRPQUOTA: | ||
73 | return from_kgid(targ, kqid.gid); | ||
74 | case PRJQUOTA: | ||
75 | return from_kprojid(targ, kqid.projid); | ||
76 | default: | ||
77 | BUG(); | ||
78 | } | ||
79 | } | ||
80 | EXPORT_SYMBOL(from_kqid); | ||
81 | |||
82 | /** | ||
83 | * from_kqid_munged - Create a qid from a kqid user-namespace pair. | ||
84 | * @targ: The user namespace we want a qid in. | ||
85 | * @kqid: The kernel internal quota identifier to start with. | ||
86 | * | ||
87 | * Map @kqid into the user-namespace specified by @targ and | ||
88 | * return the resulting qid. | ||
89 | * | ||
90 | * There is always a mapping into the initial user_namespace. | ||
91 | * | ||
92 | * Unlike from_kqid from_kqid_munged never fails and always | ||
93 | * returns a valid projid. This makes from_kqid_munged | ||
94 | * appropriate for use in places where failing to provide | ||
95 | * a qid_t is not a good option. | ||
96 | * | ||
97 | * If @kqid has no mapping in @targ the kqid.type specific | ||
98 | * overflow identifier is returned. | ||
99 | */ | ||
100 | qid_t from_kqid_munged(struct user_namespace *targ, struct kqid kqid) | ||
101 | { | ||
102 | switch (kqid.type) { | ||
103 | case USRQUOTA: | ||
104 | return from_kuid_munged(targ, kqid.uid); | ||
105 | case GRPQUOTA: | ||
106 | return from_kgid_munged(targ, kqid.gid); | ||
107 | case PRJQUOTA: | ||
108 | return from_kprojid_munged(targ, kqid.projid); | ||
109 | default: | ||
110 | BUG(); | ||
111 | } | ||
112 | } | ||
113 | EXPORT_SYMBOL(from_kqid_munged); | ||
114 | |||
115 | /** | ||
116 | * qid_valid - Report if a valid value is stored in a kqid. | ||
117 | * @qid: The kernel internal quota identifier to test. | ||
118 | */ | ||
119 | bool qid_valid(struct kqid qid) | ||
120 | { | ||
121 | switch (qid.type) { | ||
122 | case USRQUOTA: | ||
123 | return uid_valid(qid.uid); | ||
124 | case GRPQUOTA: | ||
125 | return gid_valid(qid.gid); | ||
126 | case PRJQUOTA: | ||
127 | return projid_valid(qid.projid); | ||
128 | default: | ||
129 | BUG(); | ||
130 | } | ||
131 | } | ||
132 | EXPORT_SYMBOL(qid_valid); | ||
diff --git a/fs/quota/netlink.c b/fs/quota/netlink.c index d67908b407d9..16e8abb7709b 100644 --- a/fs/quota/netlink.c +++ b/fs/quota/netlink.c | |||
@@ -30,7 +30,7 @@ static struct genl_family quota_genl_family = { | |||
30 | * | 30 | * |
31 | */ | 31 | */ |
32 | 32 | ||
33 | void quota_send_warning(short type, unsigned int id, dev_t dev, | 33 | void quota_send_warning(struct kqid qid, dev_t dev, |
34 | const char warntype) | 34 | const char warntype) |
35 | { | 35 | { |
36 | static atomic_t seq; | 36 | static atomic_t seq; |
@@ -56,10 +56,11 @@ void quota_send_warning(short type, unsigned int id, dev_t dev, | |||
56 | "VFS: Cannot store netlink header in quota warning.\n"); | 56 | "VFS: Cannot store netlink header in quota warning.\n"); |
57 | goto err_out; | 57 | goto err_out; |
58 | } | 58 | } |
59 | ret = nla_put_u32(skb, QUOTA_NL_A_QTYPE, type); | 59 | ret = nla_put_u32(skb, QUOTA_NL_A_QTYPE, qid.type); |
60 | if (ret) | 60 | if (ret) |
61 | goto attr_err_out; | 61 | goto attr_err_out; |
62 | ret = nla_put_u64(skb, QUOTA_NL_A_EXCESS_ID, id); | 62 | ret = nla_put_u64(skb, QUOTA_NL_A_EXCESS_ID, |
63 | from_kqid_munged(&init_user_ns, qid)); | ||
63 | if (ret) | 64 | if (ret) |
64 | goto attr_err_out; | 65 | goto attr_err_out; |
65 | ret = nla_put_u32(skb, QUOTA_NL_A_WARNING, warntype); | 66 | ret = nla_put_u32(skb, QUOTA_NL_A_WARNING, warntype); |
@@ -71,7 +72,8 @@ void quota_send_warning(short type, unsigned int id, dev_t dev, | |||
71 | ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MINOR, MINOR(dev)); | 72 | ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MINOR, MINOR(dev)); |
72 | if (ret) | 73 | if (ret) |
73 | goto attr_err_out; | 74 | goto attr_err_out; |
74 | ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current_uid()); | 75 | ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, |
76 | from_kuid_munged(&init_user_ns, current_uid())); | ||
75 | if (ret) | 77 | if (ret) |
76 | goto attr_err_out; | 78 | goto attr_err_out; |
77 | genlmsg_end(skb, msg_head); | 79 | genlmsg_end(skb, msg_head); |
diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 6f155788cbc6..ff0135d6bc51 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c | |||
@@ -32,8 +32,8 @@ static int check_quotactl_permission(struct super_block *sb, int type, int cmd, | |||
32 | /* allow to query information for dquots we "own" */ | 32 | /* allow to query information for dquots we "own" */ |
33 | case Q_GETQUOTA: | 33 | case Q_GETQUOTA: |
34 | case Q_XGETQUOTA: | 34 | case Q_XGETQUOTA: |
35 | if ((type == USRQUOTA && current_euid() == id) || | 35 | if ((type == USRQUOTA && uid_eq(current_euid(), make_kuid(current_user_ns(), id))) || |
36 | (type == GRPQUOTA && in_egroup_p(id))) | 36 | (type == GRPQUOTA && in_egroup_p(make_kgid(current_user_ns(), id)))) |
37 | break; | 37 | break; |
38 | /*FALLTHROUGH*/ | 38 | /*FALLTHROUGH*/ |
39 | default: | 39 | default: |
@@ -130,13 +130,17 @@ static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src) | |||
130 | static int quota_getquota(struct super_block *sb, int type, qid_t id, | 130 | static int quota_getquota(struct super_block *sb, int type, qid_t id, |
131 | void __user *addr) | 131 | void __user *addr) |
132 | { | 132 | { |
133 | struct kqid qid; | ||
133 | struct fs_disk_quota fdq; | 134 | struct fs_disk_quota fdq; |
134 | struct if_dqblk idq; | 135 | struct if_dqblk idq; |
135 | int ret; | 136 | int ret; |
136 | 137 | ||
137 | if (!sb->s_qcop->get_dqblk) | 138 | if (!sb->s_qcop->get_dqblk) |
138 | return -ENOSYS; | 139 | return -ENOSYS; |
139 | ret = sb->s_qcop->get_dqblk(sb, type, id, &fdq); | 140 | qid = make_kqid(current_user_ns(), type, id); |
141 | if (!qid_valid(qid)) | ||
142 | return -EINVAL; | ||
143 | ret = sb->s_qcop->get_dqblk(sb, qid, &fdq); | ||
140 | if (ret) | 144 | if (ret) |
141 | return ret; | 145 | return ret; |
142 | copy_to_if_dqblk(&idq, &fdq); | 146 | copy_to_if_dqblk(&idq, &fdq); |
@@ -176,13 +180,17 @@ static int quota_setquota(struct super_block *sb, int type, qid_t id, | |||
176 | { | 180 | { |
177 | struct fs_disk_quota fdq; | 181 | struct fs_disk_quota fdq; |
178 | struct if_dqblk idq; | 182 | struct if_dqblk idq; |
183 | struct kqid qid; | ||
179 | 184 | ||
180 | if (copy_from_user(&idq, addr, sizeof(idq))) | 185 | if (copy_from_user(&idq, addr, sizeof(idq))) |
181 | return -EFAULT; | 186 | return -EFAULT; |
182 | if (!sb->s_qcop->set_dqblk) | 187 | if (!sb->s_qcop->set_dqblk) |
183 | return -ENOSYS; | 188 | return -ENOSYS; |
189 | qid = make_kqid(current_user_ns(), type, id); | ||
190 | if (!qid_valid(qid)) | ||
191 | return -EINVAL; | ||
184 | copy_from_if_dqblk(&fdq, &idq); | 192 | copy_from_if_dqblk(&fdq, &idq); |
185 | return sb->s_qcop->set_dqblk(sb, type, id, &fdq); | 193 | return sb->s_qcop->set_dqblk(sb, qid, &fdq); |
186 | } | 194 | } |
187 | 195 | ||
188 | static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr) | 196 | static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr) |
@@ -213,23 +221,31 @@ static int quota_setxquota(struct super_block *sb, int type, qid_t id, | |||
213 | void __user *addr) | 221 | void __user *addr) |
214 | { | 222 | { |
215 | struct fs_disk_quota fdq; | 223 | struct fs_disk_quota fdq; |
224 | struct kqid qid; | ||
216 | 225 | ||
217 | if (copy_from_user(&fdq, addr, sizeof(fdq))) | 226 | if (copy_from_user(&fdq, addr, sizeof(fdq))) |
218 | return -EFAULT; | 227 | return -EFAULT; |
219 | if (!sb->s_qcop->set_dqblk) | 228 | if (!sb->s_qcop->set_dqblk) |
220 | return -ENOSYS; | 229 | return -ENOSYS; |
221 | return sb->s_qcop->set_dqblk(sb, type, id, &fdq); | 230 | qid = make_kqid(current_user_ns(), type, id); |
231 | if (!qid_valid(qid)) | ||
232 | return -EINVAL; | ||
233 | return sb->s_qcop->set_dqblk(sb, qid, &fdq); | ||
222 | } | 234 | } |
223 | 235 | ||
224 | static int quota_getxquota(struct super_block *sb, int type, qid_t id, | 236 | static int quota_getxquota(struct super_block *sb, int type, qid_t id, |
225 | void __user *addr) | 237 | void __user *addr) |
226 | { | 238 | { |
227 | struct fs_disk_quota fdq; | 239 | struct fs_disk_quota fdq; |
240 | struct kqid qid; | ||
228 | int ret; | 241 | int ret; |
229 | 242 | ||
230 | if (!sb->s_qcop->get_dqblk) | 243 | if (!sb->s_qcop->get_dqblk) |
231 | return -ENOSYS; | 244 | return -ENOSYS; |
232 | ret = sb->s_qcop->get_dqblk(sb, type, id, &fdq); | 245 | qid = make_kqid(current_user_ns(), type, id); |
246 | if (!qid_valid(qid)) | ||
247 | return -EINVAL; | ||
248 | ret = sb->s_qcop->get_dqblk(sb, qid, &fdq); | ||
233 | if (!ret && copy_to_user(addr, &fdq, sizeof(fdq))) | 249 | if (!ret && copy_to_user(addr, &fdq, sizeof(fdq))) |
234 | return -EFAULT; | 250 | return -EFAULT; |
235 | return ret; | 251 | return ret; |
diff --git a/fs/quota/quota_tree.c b/fs/quota/quota_tree.c index e41c1becf096..d65877fbe8f4 100644 --- a/fs/quota/quota_tree.c +++ b/fs/quota/quota_tree.c | |||
@@ -22,9 +22,10 @@ MODULE_LICENSE("GPL"); | |||
22 | 22 | ||
23 | #define __QUOTA_QT_PARANOIA | 23 | #define __QUOTA_QT_PARANOIA |
24 | 24 | ||
25 | static int get_index(struct qtree_mem_dqinfo *info, qid_t id, int depth) | 25 | static int get_index(struct qtree_mem_dqinfo *info, struct kqid qid, int depth) |
26 | { | 26 | { |
27 | unsigned int epb = info->dqi_usable_bs >> 2; | 27 | unsigned int epb = info->dqi_usable_bs >> 2; |
28 | qid_t id = from_kqid(&init_user_ns, qid); | ||
28 | 29 | ||
29 | depth = info->dqi_qtree_depth - depth - 1; | 30 | depth = info->dqi_qtree_depth - depth - 1; |
30 | while (depth--) | 31 | while (depth--) |
@@ -244,7 +245,7 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info, | |||
244 | /* This is enough as the block is already zeroed and the entry | 245 | /* This is enough as the block is already zeroed and the entry |
245 | * list is empty... */ | 246 | * list is empty... */ |
246 | info->dqi_free_entry = blk; | 247 | info->dqi_free_entry = blk; |
247 | mark_info_dirty(dquot->dq_sb, dquot->dq_type); | 248 | mark_info_dirty(dquot->dq_sb, dquot->dq_id.type); |
248 | } | 249 | } |
249 | /* Block will be full? */ | 250 | /* Block will be full? */ |
250 | if (le16_to_cpu(dh->dqdh_entries) + 1 >= qtree_dqstr_in_blk(info)) { | 251 | if (le16_to_cpu(dh->dqdh_entries) + 1 >= qtree_dqstr_in_blk(info)) { |
@@ -357,7 +358,7 @@ static inline int dq_insert_tree(struct qtree_mem_dqinfo *info, | |||
357 | */ | 358 | */ |
358 | int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) | 359 | int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) |
359 | { | 360 | { |
360 | int type = dquot->dq_type; | 361 | int type = dquot->dq_id.type; |
361 | struct super_block *sb = dquot->dq_sb; | 362 | struct super_block *sb = dquot->dq_sb; |
362 | ssize_t ret; | 363 | ssize_t ret; |
363 | char *ddquot = getdqbuf(info->dqi_entry_size); | 364 | char *ddquot = getdqbuf(info->dqi_entry_size); |
@@ -538,8 +539,9 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info, | |||
538 | ddquot += info->dqi_entry_size; | 539 | ddquot += info->dqi_entry_size; |
539 | } | 540 | } |
540 | if (i == qtree_dqstr_in_blk(info)) { | 541 | if (i == qtree_dqstr_in_blk(info)) { |
541 | quota_error(dquot->dq_sb, "Quota for id %u referenced " | 542 | quota_error(dquot->dq_sb, |
542 | "but not present", dquot->dq_id); | 543 | "Quota for id %u referenced but not present", |
544 | from_kqid(&init_user_ns, dquot->dq_id)); | ||
543 | ret = -EIO; | 545 | ret = -EIO; |
544 | goto out_buf; | 546 | goto out_buf; |
545 | } else { | 547 | } else { |
@@ -589,7 +591,7 @@ static inline loff_t find_dqentry(struct qtree_mem_dqinfo *info, | |||
589 | 591 | ||
590 | int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) | 592 | int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) |
591 | { | 593 | { |
592 | int type = dquot->dq_type; | 594 | int type = dquot->dq_id.type; |
593 | struct super_block *sb = dquot->dq_sb; | 595 | struct super_block *sb = dquot->dq_sb; |
594 | loff_t offset; | 596 | loff_t offset; |
595 | char *ddquot; | 597 | char *ddquot; |
@@ -607,8 +609,10 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) | |||
607 | offset = find_dqentry(info, dquot); | 609 | offset = find_dqentry(info, dquot); |
608 | if (offset <= 0) { /* Entry not present? */ | 610 | if (offset <= 0) { /* Entry not present? */ |
609 | if (offset < 0) | 611 | if (offset < 0) |
610 | quota_error(sb, "Can't read quota structure " | 612 | quota_error(sb,"Can't read quota structure " |
611 | "for id %u", dquot->dq_id); | 613 | "for id %u", |
614 | from_kqid(&init_user_ns, | ||
615 | dquot->dq_id)); | ||
612 | dquot->dq_off = 0; | 616 | dquot->dq_off = 0; |
613 | set_bit(DQ_FAKE_B, &dquot->dq_flags); | 617 | set_bit(DQ_FAKE_B, &dquot->dq_flags); |
614 | memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk)); | 618 | memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk)); |
@@ -626,7 +630,7 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) | |||
626 | if (ret >= 0) | 630 | if (ret >= 0) |
627 | ret = -EIO; | 631 | ret = -EIO; |
628 | quota_error(sb, "Error while reading quota structure for id %u", | 632 | quota_error(sb, "Error while reading quota structure for id %u", |
629 | dquot->dq_id); | 633 | from_kqid(&init_user_ns, dquot->dq_id)); |
630 | set_bit(DQ_FAKE_B, &dquot->dq_flags); | 634 | set_bit(DQ_FAKE_B, &dquot->dq_flags); |
631 | memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk)); | 635 | memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk)); |
632 | kfree(ddquot); | 636 | kfree(ddquot); |
diff --git a/fs/quota/quota_v1.c b/fs/quota/quota_v1.c index 34b37a67bb16..469c6848b322 100644 --- a/fs/quota/quota_v1.c +++ b/fs/quota/quota_v1.c | |||
@@ -54,7 +54,7 @@ static void v1_mem2disk_dqblk(struct v1_disk_dqblk *d, struct mem_dqblk *m) | |||
54 | 54 | ||
55 | static int v1_read_dqblk(struct dquot *dquot) | 55 | static int v1_read_dqblk(struct dquot *dquot) |
56 | { | 56 | { |
57 | int type = dquot->dq_type; | 57 | int type = dquot->dq_id.type; |
58 | struct v1_disk_dqblk dqblk; | 58 | struct v1_disk_dqblk dqblk; |
59 | 59 | ||
60 | if (!sb_dqopt(dquot->dq_sb)->files[type]) | 60 | if (!sb_dqopt(dquot->dq_sb)->files[type]) |
@@ -63,7 +63,8 @@ static int v1_read_dqblk(struct dquot *dquot) | |||
63 | /* Set structure to 0s in case read fails/is after end of file */ | 63 | /* Set structure to 0s in case read fails/is after end of file */ |
64 | memset(&dqblk, 0, sizeof(struct v1_disk_dqblk)); | 64 | memset(&dqblk, 0, sizeof(struct v1_disk_dqblk)); |
65 | dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, (char *)&dqblk, | 65 | dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, (char *)&dqblk, |
66 | sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id)); | 66 | sizeof(struct v1_disk_dqblk), |
67 | v1_dqoff(from_kqid(&init_user_ns, dquot->dq_id))); | ||
67 | 68 | ||
68 | v1_disk2mem_dqblk(&dquot->dq_dqb, &dqblk); | 69 | v1_disk2mem_dqblk(&dquot->dq_dqb, &dqblk); |
69 | if (dquot->dq_dqb.dqb_bhardlimit == 0 && | 70 | if (dquot->dq_dqb.dqb_bhardlimit == 0 && |
@@ -78,12 +79,13 @@ static int v1_read_dqblk(struct dquot *dquot) | |||
78 | 79 | ||
79 | static int v1_commit_dqblk(struct dquot *dquot) | 80 | static int v1_commit_dqblk(struct dquot *dquot) |
80 | { | 81 | { |
81 | short type = dquot->dq_type; | 82 | short type = dquot->dq_id.type; |
82 | ssize_t ret; | 83 | ssize_t ret; |
83 | struct v1_disk_dqblk dqblk; | 84 | struct v1_disk_dqblk dqblk; |
84 | 85 | ||
85 | v1_mem2disk_dqblk(&dqblk, &dquot->dq_dqb); | 86 | v1_mem2disk_dqblk(&dqblk, &dquot->dq_dqb); |
86 | if (dquot->dq_id == 0) { | 87 | if (((type == USRQUOTA) && uid_eq(dquot->dq_id.uid, GLOBAL_ROOT_UID)) || |
88 | ((type == GRPQUOTA) && gid_eq(dquot->dq_id.gid, GLOBAL_ROOT_GID))) { | ||
87 | dqblk.dqb_btime = | 89 | dqblk.dqb_btime = |
88 | sb_dqopt(dquot->dq_sb)->info[type].dqi_bgrace; | 90 | sb_dqopt(dquot->dq_sb)->info[type].dqi_bgrace; |
89 | dqblk.dqb_itime = | 91 | dqblk.dqb_itime = |
@@ -93,7 +95,7 @@ static int v1_commit_dqblk(struct dquot *dquot) | |||
93 | if (sb_dqopt(dquot->dq_sb)->files[type]) | 95 | if (sb_dqopt(dquot->dq_sb)->files[type]) |
94 | ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type, | 96 | ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type, |
95 | (char *)&dqblk, sizeof(struct v1_disk_dqblk), | 97 | (char *)&dqblk, sizeof(struct v1_disk_dqblk), |
96 | v1_dqoff(dquot->dq_id)); | 98 | v1_dqoff(from_kqid(&init_user_ns, dquot->dq_id))); |
97 | if (ret != sizeof(struct v1_disk_dqblk)) { | 99 | if (ret != sizeof(struct v1_disk_dqblk)) { |
98 | quota_error(dquot->dq_sb, "dquota write failed"); | 100 | quota_error(dquot->dq_sb, "dquota write failed"); |
99 | if (ret >= 0) | 101 | if (ret >= 0) |
diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c index f1ab3604db5a..02751ec695c5 100644 --- a/fs/quota/quota_v2.c +++ b/fs/quota/quota_v2.c | |||
@@ -196,7 +196,7 @@ static void v2r0_mem2diskdqb(void *dp, struct dquot *dquot) | |||
196 | struct v2r0_disk_dqblk *d = dp; | 196 | struct v2r0_disk_dqblk *d = dp; |
197 | struct mem_dqblk *m = &dquot->dq_dqb; | 197 | struct mem_dqblk *m = &dquot->dq_dqb; |
198 | struct qtree_mem_dqinfo *info = | 198 | struct qtree_mem_dqinfo *info = |
199 | sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv; | 199 | sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv; |
200 | 200 | ||
201 | d->dqb_ihardlimit = cpu_to_le32(m->dqb_ihardlimit); | 201 | d->dqb_ihardlimit = cpu_to_le32(m->dqb_ihardlimit); |
202 | d->dqb_isoftlimit = cpu_to_le32(m->dqb_isoftlimit); | 202 | d->dqb_isoftlimit = cpu_to_le32(m->dqb_isoftlimit); |
@@ -206,7 +206,7 @@ static void v2r0_mem2diskdqb(void *dp, struct dquot *dquot) | |||
206 | d->dqb_bsoftlimit = cpu_to_le32(v2_stoqb(m->dqb_bsoftlimit)); | 206 | d->dqb_bsoftlimit = cpu_to_le32(v2_stoqb(m->dqb_bsoftlimit)); |
207 | d->dqb_curspace = cpu_to_le64(m->dqb_curspace); | 207 | d->dqb_curspace = cpu_to_le64(m->dqb_curspace); |
208 | d->dqb_btime = cpu_to_le64(m->dqb_btime); | 208 | d->dqb_btime = cpu_to_le64(m->dqb_btime); |
209 | d->dqb_id = cpu_to_le32(dquot->dq_id); | 209 | d->dqb_id = cpu_to_le32(from_kqid(&init_user_ns, dquot->dq_id)); |
210 | if (qtree_entry_unused(info, dp)) | 210 | if (qtree_entry_unused(info, dp)) |
211 | d->dqb_itime = cpu_to_le64(1); | 211 | d->dqb_itime = cpu_to_le64(1); |
212 | } | 212 | } |
@@ -215,11 +215,13 @@ static int v2r0_is_id(void *dp, struct dquot *dquot) | |||
215 | { | 215 | { |
216 | struct v2r0_disk_dqblk *d = dp; | 216 | struct v2r0_disk_dqblk *d = dp; |
217 | struct qtree_mem_dqinfo *info = | 217 | struct qtree_mem_dqinfo *info = |
218 | sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv; | 218 | sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv; |
219 | 219 | ||
220 | if (qtree_entry_unused(info, dp)) | 220 | if (qtree_entry_unused(info, dp)) |
221 | return 0; | 221 | return 0; |
222 | return le32_to_cpu(d->dqb_id) == dquot->dq_id; | 222 | return qid_eq(make_kqid(&init_user_ns, dquot->dq_id.type, |
223 | le32_to_cpu(d->dqb_id)), | ||
224 | dquot->dq_id); | ||
223 | } | 225 | } |
224 | 226 | ||
225 | static void v2r1_disk2memdqb(struct dquot *dquot, void *dp) | 227 | static void v2r1_disk2memdqb(struct dquot *dquot, void *dp) |
@@ -247,7 +249,7 @@ static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot) | |||
247 | struct v2r1_disk_dqblk *d = dp; | 249 | struct v2r1_disk_dqblk *d = dp; |
248 | struct mem_dqblk *m = &dquot->dq_dqb; | 250 | struct mem_dqblk *m = &dquot->dq_dqb; |
249 | struct qtree_mem_dqinfo *info = | 251 | struct qtree_mem_dqinfo *info = |
250 | sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv; | 252 | sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv; |
251 | 253 | ||
252 | d->dqb_ihardlimit = cpu_to_le64(m->dqb_ihardlimit); | 254 | d->dqb_ihardlimit = cpu_to_le64(m->dqb_ihardlimit); |
253 | d->dqb_isoftlimit = cpu_to_le64(m->dqb_isoftlimit); | 255 | d->dqb_isoftlimit = cpu_to_le64(m->dqb_isoftlimit); |
@@ -257,7 +259,7 @@ static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot) | |||
257 | d->dqb_bsoftlimit = cpu_to_le64(v2_stoqb(m->dqb_bsoftlimit)); | 259 | d->dqb_bsoftlimit = cpu_to_le64(v2_stoqb(m->dqb_bsoftlimit)); |
258 | d->dqb_curspace = cpu_to_le64(m->dqb_curspace); | 260 | d->dqb_curspace = cpu_to_le64(m->dqb_curspace); |
259 | d->dqb_btime = cpu_to_le64(m->dqb_btime); | 261 | d->dqb_btime = cpu_to_le64(m->dqb_btime); |
260 | d->dqb_id = cpu_to_le32(dquot->dq_id); | 262 | d->dqb_id = cpu_to_le32(from_kqid(&init_user_ns, dquot->dq_id)); |
261 | if (qtree_entry_unused(info, dp)) | 263 | if (qtree_entry_unused(info, dp)) |
262 | d->dqb_itime = cpu_to_le64(1); | 264 | d->dqb_itime = cpu_to_le64(1); |
263 | } | 265 | } |
@@ -266,26 +268,28 @@ static int v2r1_is_id(void *dp, struct dquot *dquot) | |||
266 | { | 268 | { |
267 | struct v2r1_disk_dqblk *d = dp; | 269 | struct v2r1_disk_dqblk *d = dp; |
268 | struct qtree_mem_dqinfo *info = | 270 | struct qtree_mem_dqinfo *info = |
269 | sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv; | 271 | sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv; |
270 | 272 | ||
271 | if (qtree_entry_unused(info, dp)) | 273 | if (qtree_entry_unused(info, dp)) |
272 | return 0; | 274 | return 0; |
273 | return le32_to_cpu(d->dqb_id) == dquot->dq_id; | 275 | return qid_eq(make_kqid(&init_user_ns, dquot->dq_id.type, |
276 | le32_to_cpu(d->dqb_id)), | ||
277 | dquot->dq_id); | ||
274 | } | 278 | } |
275 | 279 | ||
276 | static int v2_read_dquot(struct dquot *dquot) | 280 | static int v2_read_dquot(struct dquot *dquot) |
277 | { | 281 | { |
278 | return qtree_read_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv, dquot); | 282 | return qtree_read_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, dquot); |
279 | } | 283 | } |
280 | 284 | ||
281 | static int v2_write_dquot(struct dquot *dquot) | 285 | static int v2_write_dquot(struct dquot *dquot) |
282 | { | 286 | { |
283 | return qtree_write_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv, dquot); | 287 | return qtree_write_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, dquot); |
284 | } | 288 | } |
285 | 289 | ||
286 | static int v2_release_dquot(struct dquot *dquot) | 290 | static int v2_release_dquot(struct dquot *dquot) |
287 | { | 291 | { |
288 | return qtree_release_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv, dquot); | 292 | return qtree_release_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, dquot); |
289 | } | 293 | } |
290 | 294 | ||
291 | static int v2_free_file_info(struct super_block *sb, int type) | 295 | static int v2_free_file_info(struct super_block *sb, int type) |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 855da58db145..46485557cdc6 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -1155,8 +1155,8 @@ static void init_inode(struct inode *inode, struct treepath *path) | |||
1155 | set_inode_sd_version(inode, STAT_DATA_V1); | 1155 | set_inode_sd_version(inode, STAT_DATA_V1); |
1156 | inode->i_mode = sd_v1_mode(sd); | 1156 | inode->i_mode = sd_v1_mode(sd); |
1157 | set_nlink(inode, sd_v1_nlink(sd)); | 1157 | set_nlink(inode, sd_v1_nlink(sd)); |
1158 | inode->i_uid = sd_v1_uid(sd); | 1158 | i_uid_write(inode, sd_v1_uid(sd)); |
1159 | inode->i_gid = sd_v1_gid(sd); | 1159 | i_gid_write(inode, sd_v1_gid(sd)); |
1160 | inode->i_size = sd_v1_size(sd); | 1160 | inode->i_size = sd_v1_size(sd); |
1161 | inode->i_atime.tv_sec = sd_v1_atime(sd); | 1161 | inode->i_atime.tv_sec = sd_v1_atime(sd); |
1162 | inode->i_mtime.tv_sec = sd_v1_mtime(sd); | 1162 | inode->i_mtime.tv_sec = sd_v1_mtime(sd); |
@@ -1200,9 +1200,9 @@ static void init_inode(struct inode *inode, struct treepath *path) | |||
1200 | 1200 | ||
1201 | inode->i_mode = sd_v2_mode(sd); | 1201 | inode->i_mode = sd_v2_mode(sd); |
1202 | set_nlink(inode, sd_v2_nlink(sd)); | 1202 | set_nlink(inode, sd_v2_nlink(sd)); |
1203 | inode->i_uid = sd_v2_uid(sd); | 1203 | i_uid_write(inode, sd_v2_uid(sd)); |
1204 | inode->i_size = sd_v2_size(sd); | 1204 | inode->i_size = sd_v2_size(sd); |
1205 | inode->i_gid = sd_v2_gid(sd); | 1205 | i_gid_write(inode, sd_v2_gid(sd)); |
1206 | inode->i_mtime.tv_sec = sd_v2_mtime(sd); | 1206 | inode->i_mtime.tv_sec = sd_v2_mtime(sd); |
1207 | inode->i_atime.tv_sec = sd_v2_atime(sd); | 1207 | inode->i_atime.tv_sec = sd_v2_atime(sd); |
1208 | inode->i_ctime.tv_sec = sd_v2_ctime(sd); | 1208 | inode->i_ctime.tv_sec = sd_v2_ctime(sd); |
@@ -1258,9 +1258,9 @@ static void inode2sd(void *sd, struct inode *inode, loff_t size) | |||
1258 | 1258 | ||
1259 | set_sd_v2_mode(sd_v2, inode->i_mode); | 1259 | set_sd_v2_mode(sd_v2, inode->i_mode); |
1260 | set_sd_v2_nlink(sd_v2, inode->i_nlink); | 1260 | set_sd_v2_nlink(sd_v2, inode->i_nlink); |
1261 | set_sd_v2_uid(sd_v2, inode->i_uid); | 1261 | set_sd_v2_uid(sd_v2, i_uid_read(inode)); |
1262 | set_sd_v2_size(sd_v2, size); | 1262 | set_sd_v2_size(sd_v2, size); |
1263 | set_sd_v2_gid(sd_v2, inode->i_gid); | 1263 | set_sd_v2_gid(sd_v2, i_gid_read(inode)); |
1264 | set_sd_v2_mtime(sd_v2, inode->i_mtime.tv_sec); | 1264 | set_sd_v2_mtime(sd_v2, inode->i_mtime.tv_sec); |
1265 | set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec); | 1265 | set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec); |
1266 | set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec); | 1266 | set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec); |
@@ -1280,8 +1280,8 @@ static void inode2sd_v1(void *sd, struct inode *inode, loff_t size) | |||
1280 | struct stat_data_v1 *sd_v1 = (struct stat_data_v1 *)sd; | 1280 | struct stat_data_v1 *sd_v1 = (struct stat_data_v1 *)sd; |
1281 | 1281 | ||
1282 | set_sd_v1_mode(sd_v1, inode->i_mode); | 1282 | set_sd_v1_mode(sd_v1, inode->i_mode); |
1283 | set_sd_v1_uid(sd_v1, inode->i_uid); | 1283 | set_sd_v1_uid(sd_v1, i_uid_read(inode)); |
1284 | set_sd_v1_gid(sd_v1, inode->i_gid); | 1284 | set_sd_v1_gid(sd_v1, i_gid_read(inode)); |
1285 | set_sd_v1_nlink(sd_v1, inode->i_nlink); | 1285 | set_sd_v1_nlink(sd_v1, inode->i_nlink); |
1286 | set_sd_v1_size(sd_v1, size); | 1286 | set_sd_v1_size(sd_v1, size); |
1287 | set_sd_v1_atime(sd_v1, inode->i_atime.tv_sec); | 1287 | set_sd_v1_atime(sd_v1, inode->i_atime.tv_sec); |
@@ -1869,7 +1869,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1869 | goto out_bad_inode; | 1869 | goto out_bad_inode; |
1870 | } | 1870 | } |
1871 | if (old_format_only(sb)) { | 1871 | if (old_format_only(sb)) { |
1872 | if (inode->i_uid & ~0xffff || inode->i_gid & ~0xffff) { | 1872 | if (i_uid_read(inode) & ~0xffff || i_gid_read(inode) & ~0xffff) { |
1873 | pathrelse(&path_to_key); | 1873 | pathrelse(&path_to_key); |
1874 | /* i_uid or i_gid is too big to be stored in stat data v3.5 */ | 1874 | /* i_uid or i_gid is too big to be stored in stat data v3.5 */ |
1875 | err = -EINVAL; | 1875 | err = -EINVAL; |
@@ -3140,16 +3140,16 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3140 | } | 3140 | } |
3141 | } | 3141 | } |
3142 | 3142 | ||
3143 | if ((((attr->ia_valid & ATTR_UID) && (attr->ia_uid & ~0xffff)) || | 3143 | if ((((attr->ia_valid & ATTR_UID) && (from_kuid(&init_user_ns, attr->ia_uid) & ~0xffff)) || |
3144 | ((attr->ia_valid & ATTR_GID) && (attr->ia_gid & ~0xffff))) && | 3144 | ((attr->ia_valid & ATTR_GID) && (from_kgid(&init_user_ns, attr->ia_gid) & ~0xffff))) && |
3145 | (get_inode_sd_version(inode) == STAT_DATA_V1)) { | 3145 | (get_inode_sd_version(inode) == STAT_DATA_V1)) { |
3146 | /* stat data of format v3.5 has 16 bit uid and gid */ | 3146 | /* stat data of format v3.5 has 16 bit uid and gid */ |
3147 | error = -EINVAL; | 3147 | error = -EINVAL; |
3148 | goto out; | 3148 | goto out; |
3149 | } | 3149 | } |
3150 | 3150 | ||
3151 | if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || | 3151 | if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) || |
3152 | (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { | 3152 | (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) { |
3153 | struct reiserfs_transaction_handle th; | 3153 | struct reiserfs_transaction_handle th; |
3154 | int jbegin_count = | 3154 | int jbegin_count = |
3155 | 2 * | 3155 | 2 * |
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index 44474f9b990d..d7c01ef64eda 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c | |||
@@ -30,7 +30,7 @@ posix_acl_set(struct dentry *dentry, const char *name, const void *value, | |||
30 | return -EPERM; | 30 | return -EPERM; |
31 | 31 | ||
32 | if (value) { | 32 | if (value) { |
33 | acl = posix_acl_from_xattr(value, size); | 33 | acl = posix_acl_from_xattr(&init_user_ns, value, size); |
34 | if (IS_ERR(acl)) { | 34 | if (IS_ERR(acl)) { |
35 | return PTR_ERR(acl); | 35 | return PTR_ERR(acl); |
36 | } else if (acl) { | 36 | } else if (acl) { |
@@ -77,7 +77,7 @@ posix_acl_get(struct dentry *dentry, const char *name, void *buffer, | |||
77 | return PTR_ERR(acl); | 77 | return PTR_ERR(acl); |
78 | if (acl == NULL) | 78 | if (acl == NULL) |
79 | return -ENODATA; | 79 | return -ENODATA; |
80 | error = posix_acl_to_xattr(acl, buffer, size); | 80 | error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); |
81 | posix_acl_release(acl); | 81 | posix_acl_release(acl); |
82 | 82 | ||
83 | return error; | 83 | return error; |
@@ -121,15 +121,23 @@ static struct posix_acl *posix_acl_from_disk(const void *value, size_t size) | |||
121 | case ACL_OTHER: | 121 | case ACL_OTHER: |
122 | value = (char *)value + | 122 | value = (char *)value + |
123 | sizeof(reiserfs_acl_entry_short); | 123 | sizeof(reiserfs_acl_entry_short); |
124 | acl->a_entries[n].e_id = ACL_UNDEFINED_ID; | ||
125 | break; | 124 | break; |
126 | 125 | ||
127 | case ACL_USER: | 126 | case ACL_USER: |
127 | value = (char *)value + sizeof(reiserfs_acl_entry); | ||
128 | if ((char *)value > end) | ||
129 | goto fail; | ||
130 | acl->a_entries[n].e_uid = | ||
131 | make_kuid(&init_user_ns, | ||
132 | le32_to_cpu(entry->e_id)); | ||
133 | break; | ||
128 | case ACL_GROUP: | 134 | case ACL_GROUP: |
129 | value = (char *)value + sizeof(reiserfs_acl_entry); | 135 | value = (char *)value + sizeof(reiserfs_acl_entry); |
130 | if ((char *)value > end) | 136 | if ((char *)value > end) |
131 | goto fail; | 137 | goto fail; |
132 | acl->a_entries[n].e_id = le32_to_cpu(entry->e_id); | 138 | acl->a_entries[n].e_gid = |
139 | make_kgid(&init_user_ns, | ||
140 | le32_to_cpu(entry->e_id)); | ||
133 | break; | 141 | break; |
134 | 142 | ||
135 | default: | 143 | default: |
@@ -164,13 +172,19 @@ static void *posix_acl_to_disk(const struct posix_acl *acl, size_t * size) | |||
164 | ext_acl->a_version = cpu_to_le32(REISERFS_ACL_VERSION); | 172 | ext_acl->a_version = cpu_to_le32(REISERFS_ACL_VERSION); |
165 | e = (char *)ext_acl + sizeof(reiserfs_acl_header); | 173 | e = (char *)ext_acl + sizeof(reiserfs_acl_header); |
166 | for (n = 0; n < acl->a_count; n++) { | 174 | for (n = 0; n < acl->a_count; n++) { |
175 | const struct posix_acl_entry *acl_e = &acl->a_entries[n]; | ||
167 | reiserfs_acl_entry *entry = (reiserfs_acl_entry *) e; | 176 | reiserfs_acl_entry *entry = (reiserfs_acl_entry *) e; |
168 | entry->e_tag = cpu_to_le16(acl->a_entries[n].e_tag); | 177 | entry->e_tag = cpu_to_le16(acl->a_entries[n].e_tag); |
169 | entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm); | 178 | entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm); |
170 | switch (acl->a_entries[n].e_tag) { | 179 | switch (acl->a_entries[n].e_tag) { |
171 | case ACL_USER: | 180 | case ACL_USER: |
181 | entry->e_id = cpu_to_le32( | ||
182 | from_kuid(&init_user_ns, acl_e->e_uid)); | ||
183 | e += sizeof(reiserfs_acl_entry); | ||
184 | break; | ||
172 | case ACL_GROUP: | 185 | case ACL_GROUP: |
173 | entry->e_id = cpu_to_le32(acl->a_entries[n].e_id); | 186 | entry->e_id = cpu_to_le32( |
187 | from_kgid(&init_user_ns, acl_e->e_gid)); | ||
174 | e += sizeof(reiserfs_acl_entry); | 188 | e += sizeof(reiserfs_acl_entry); |
175 | break; | 189 | break; |
176 | 190 | ||
diff --git a/fs/seq_file.c b/fs/seq_file.c index 14cf9de1dbe1..99dffab4c4e4 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/export.h> | 9 | #include <linux/export.h> |
10 | #include <linux/seq_file.h> | 10 | #include <linux/seq_file.h> |
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/cred.h> | ||
12 | 13 | ||
13 | #include <asm/uaccess.h> | 14 | #include <asm/uaccess.h> |
14 | #include <asm/page.h> | 15 | #include <asm/page.h> |
@@ -56,6 +57,9 @@ int seq_open(struct file *file, const struct seq_operations *op) | |||
56 | memset(p, 0, sizeof(*p)); | 57 | memset(p, 0, sizeof(*p)); |
57 | mutex_init(&p->lock); | 58 | mutex_init(&p->lock); |
58 | p->op = op; | 59 | p->op = op; |
60 | #ifdef CONFIG_USER_NS | ||
61 | p->user_ns = file->f_cred->user_ns; | ||
62 | #endif | ||
59 | 63 | ||
60 | /* | 64 | /* |
61 | * Wrappers around seq_open(e.g. swaps_open) need to be | 65 | * Wrappers around seq_open(e.g. swaps_open) need to be |
diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c index 81afbccfa843..a1ce5ce60632 100644 --- a/fs/squashfs/inode.c +++ b/fs/squashfs/inode.c | |||
@@ -56,16 +56,20 @@ | |||
56 | static int squashfs_new_inode(struct super_block *sb, struct inode *inode, | 56 | static int squashfs_new_inode(struct super_block *sb, struct inode *inode, |
57 | struct squashfs_base_inode *sqsh_ino) | 57 | struct squashfs_base_inode *sqsh_ino) |
58 | { | 58 | { |
59 | uid_t i_uid; | ||
60 | gid_t i_gid; | ||
59 | int err; | 61 | int err; |
60 | 62 | ||
61 | err = squashfs_get_id(sb, le16_to_cpu(sqsh_ino->uid), &inode->i_uid); | 63 | err = squashfs_get_id(sb, le16_to_cpu(sqsh_ino->uid), &i_uid); |
62 | if (err) | 64 | if (err) |
63 | return err; | 65 | return err; |
64 | 66 | ||
65 | err = squashfs_get_id(sb, le16_to_cpu(sqsh_ino->guid), &inode->i_gid); | 67 | err = squashfs_get_id(sb, le16_to_cpu(sqsh_ino->guid), &i_gid); |
66 | if (err) | 68 | if (err) |
67 | return err; | 69 | return err; |
68 | 70 | ||
71 | i_uid_write(inode, i_uid); | ||
72 | i_gid_write(inode, i_gid); | ||
69 | inode->i_ino = le32_to_cpu(sqsh_ino->inode_number); | 73 | inode->i_ino = le32_to_cpu(sqsh_ino->inode_number); |
70 | inode->i_mtime.tv_sec = le32_to_cpu(sqsh_ino->mtime); | 74 | inode->i_mtime.tv_sec = le32_to_cpu(sqsh_ino->mtime); |
71 | inode->i_atime.tv_sec = inode->i_mtime.tv_sec; | 75 | inode->i_atime.tv_sec = inode->i_mtime.tv_sec; |
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index 80e1e2b18df1..b23ab736685d 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c | |||
@@ -202,8 +202,8 @@ struct inode *sysv_iget(struct super_block *sb, unsigned int ino) | |||
202 | } | 202 | } |
203 | /* SystemV FS: kludge permissions if ino==SYSV_ROOT_INO ?? */ | 203 | /* SystemV FS: kludge permissions if ino==SYSV_ROOT_INO ?? */ |
204 | inode->i_mode = fs16_to_cpu(sbi, raw_inode->i_mode); | 204 | inode->i_mode = fs16_to_cpu(sbi, raw_inode->i_mode); |
205 | inode->i_uid = (uid_t)fs16_to_cpu(sbi, raw_inode->i_uid); | 205 | i_uid_write(inode, (uid_t)fs16_to_cpu(sbi, raw_inode->i_uid)); |
206 | inode->i_gid = (gid_t)fs16_to_cpu(sbi, raw_inode->i_gid); | 206 | i_gid_write(inode, (gid_t)fs16_to_cpu(sbi, raw_inode->i_gid)); |
207 | set_nlink(inode, fs16_to_cpu(sbi, raw_inode->i_nlink)); | 207 | set_nlink(inode, fs16_to_cpu(sbi, raw_inode->i_nlink)); |
208 | inode->i_size = fs32_to_cpu(sbi, raw_inode->i_size); | 208 | inode->i_size = fs32_to_cpu(sbi, raw_inode->i_size); |
209 | inode->i_atime.tv_sec = fs32_to_cpu(sbi, raw_inode->i_atime); | 209 | inode->i_atime.tv_sec = fs32_to_cpu(sbi, raw_inode->i_atime); |
@@ -256,8 +256,8 @@ static int __sysv_write_inode(struct inode *inode, int wait) | |||
256 | } | 256 | } |
257 | 257 | ||
258 | raw_inode->i_mode = cpu_to_fs16(sbi, inode->i_mode); | 258 | raw_inode->i_mode = cpu_to_fs16(sbi, inode->i_mode); |
259 | raw_inode->i_uid = cpu_to_fs16(sbi, fs_high2lowuid(inode->i_uid)); | 259 | raw_inode->i_uid = cpu_to_fs16(sbi, fs_high2lowuid(i_uid_read(inode))); |
260 | raw_inode->i_gid = cpu_to_fs16(sbi, fs_high2lowgid(inode->i_gid)); | 260 | raw_inode->i_gid = cpu_to_fs16(sbi, fs_high2lowgid(i_gid_read(inode))); |
261 | raw_inode->i_nlink = cpu_to_fs16(sbi, inode->i_nlink); | 261 | raw_inode->i_nlink = cpu_to_fs16(sbi, inode->i_nlink); |
262 | raw_inode->i_size = cpu_to_fs32(sbi, inode->i_size); | 262 | raw_inode->i_size = cpu_to_fs32(sbi, inode->i_size); |
263 | raw_inode->i_atime = cpu_to_fs32(sbi, inode->i_atime.tv_sec); | 263 | raw_inode->i_atime = cpu_to_fs32(sbi, inode->i_atime.tv_sec); |
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c index bc4f94b28706..969489e478bc 100644 --- a/fs/ubifs/budget.c +++ b/fs/ubifs/budget.c | |||
@@ -272,8 +272,8 @@ long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs) | |||
272 | */ | 272 | */ |
273 | static int can_use_rp(struct ubifs_info *c) | 273 | static int can_use_rp(struct ubifs_info *c) |
274 | { | 274 | { |
275 | if (current_fsuid() == c->rp_uid || capable(CAP_SYS_RESOURCE) || | 275 | if (uid_eq(current_fsuid(), c->rp_uid) || capable(CAP_SYS_RESOURCE) || |
276 | (c->rp_gid != 0 && in_group_p(c->rp_gid))) | 276 | (!gid_eq(c->rp_gid, GLOBAL_ROOT_GID) && in_group_p(c->rp_gid))) |
277 | return 1; | 277 | return 1; |
278 | return 0; | 278 | return 0; |
279 | } | 279 | } |
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index bb3167257aab..340d1afc1302 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c | |||
@@ -243,8 +243,8 @@ void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode) | |||
243 | printk(KERN_ERR "\tsize %llu\n", | 243 | printk(KERN_ERR "\tsize %llu\n", |
244 | (unsigned long long)i_size_read(inode)); | 244 | (unsigned long long)i_size_read(inode)); |
245 | printk(KERN_ERR "\tnlink %u\n", inode->i_nlink); | 245 | printk(KERN_ERR "\tnlink %u\n", inode->i_nlink); |
246 | printk(KERN_ERR "\tuid %u\n", (unsigned int)inode->i_uid); | 246 | printk(KERN_ERR "\tuid %u\n", (unsigned int)i_uid_read(inode)); |
247 | printk(KERN_ERR "\tgid %u\n", (unsigned int)inode->i_gid); | 247 | printk(KERN_ERR "\tgid %u\n", (unsigned int)i_gid_read(inode)); |
248 | printk(KERN_ERR "\tatime %u.%u\n", | 248 | printk(KERN_ERR "\tatime %u.%u\n", |
249 | (unsigned int)inode->i_atime.tv_sec, | 249 | (unsigned int)inode->i_atime.tv_sec, |
250 | (unsigned int)inode->i_atime.tv_nsec); | 250 | (unsigned int)inode->i_atime.tv_nsec); |
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index 12c0f154ca83..afaad07f3b29 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c | |||
@@ -469,8 +469,8 @@ static void pack_inode(struct ubifs_info *c, struct ubifs_ino_node *ino, | |||
469 | ino->ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec); | 469 | ino->ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec); |
470 | ino->mtime_sec = cpu_to_le64(inode->i_mtime.tv_sec); | 470 | ino->mtime_sec = cpu_to_le64(inode->i_mtime.tv_sec); |
471 | ino->mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec); | 471 | ino->mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec); |
472 | ino->uid = cpu_to_le32(inode->i_uid); | 472 | ino->uid = cpu_to_le32(i_uid_read(inode)); |
473 | ino->gid = cpu_to_le32(inode->i_gid); | 473 | ino->gid = cpu_to_le32(i_gid_read(inode)); |
474 | ino->mode = cpu_to_le32(inode->i_mode); | 474 | ino->mode = cpu_to_le32(inode->i_mode); |
475 | ino->flags = cpu_to_le32(ui->flags); | 475 | ino->flags = cpu_to_le32(ui->flags); |
476 | ino->size = cpu_to_le64(ui->ui_size); | 476 | ino->size = cpu_to_le64(ui->ui_size); |
diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c index 15e2fc5aa60b..52c21f4190f6 100644 --- a/fs/ubifs/sb.c +++ b/fs/ubifs/sb.c | |||
@@ -611,8 +611,8 @@ int ubifs_read_superblock(struct ubifs_info *c) | |||
611 | c->fanout = le32_to_cpu(sup->fanout); | 611 | c->fanout = le32_to_cpu(sup->fanout); |
612 | c->lsave_cnt = le32_to_cpu(sup->lsave_cnt); | 612 | c->lsave_cnt = le32_to_cpu(sup->lsave_cnt); |
613 | c->rp_size = le64_to_cpu(sup->rp_size); | 613 | c->rp_size = le64_to_cpu(sup->rp_size); |
614 | c->rp_uid = le32_to_cpu(sup->rp_uid); | 614 | c->rp_uid = make_kuid(&init_user_ns, le32_to_cpu(sup->rp_uid)); |
615 | c->rp_gid = le32_to_cpu(sup->rp_gid); | 615 | c->rp_gid = make_kgid(&init_user_ns, le32_to_cpu(sup->rp_gid)); |
616 | sup_flags = le32_to_cpu(sup->flags); | 616 | sup_flags = le32_to_cpu(sup->flags); |
617 | if (!c->mount_opts.override_compr) | 617 | if (!c->mount_opts.override_compr) |
618 | c->default_compr = le16_to_cpu(sup->default_compr); | 618 | c->default_compr = le16_to_cpu(sup->default_compr); |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 71a197f0f93d..681f3a942444 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -130,8 +130,8 @@ struct inode *ubifs_iget(struct super_block *sb, unsigned long inum) | |||
130 | 130 | ||
131 | inode->i_flags |= (S_NOCMTIME | S_NOATIME); | 131 | inode->i_flags |= (S_NOCMTIME | S_NOATIME); |
132 | set_nlink(inode, le32_to_cpu(ino->nlink)); | 132 | set_nlink(inode, le32_to_cpu(ino->nlink)); |
133 | inode->i_uid = le32_to_cpu(ino->uid); | 133 | i_uid_write(inode, le32_to_cpu(ino->uid)); |
134 | inode->i_gid = le32_to_cpu(ino->gid); | 134 | i_gid_write(inode, le32_to_cpu(ino->gid)); |
135 | inode->i_atime.tv_sec = (int64_t)le64_to_cpu(ino->atime_sec); | 135 | inode->i_atime.tv_sec = (int64_t)le64_to_cpu(ino->atime_sec); |
136 | inode->i_atime.tv_nsec = le32_to_cpu(ino->atime_nsec); | 136 | inode->i_atime.tv_nsec = le32_to_cpu(ino->atime_nsec); |
137 | inode->i_mtime.tv_sec = (int64_t)le64_to_cpu(ino->mtime_sec); | 137 | inode->i_mtime.tv_sec = (int64_t)le64_to_cpu(ino->mtime_sec); |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 1e5a08623d11..64f2367c2f4c 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -1426,8 +1426,8 @@ struct ubifs_info { | |||
1426 | 1426 | ||
1427 | long long rp_size; | 1427 | long long rp_size; |
1428 | long long report_rp_size; | 1428 | long long report_rp_size; |
1429 | uid_t rp_uid; | 1429 | kuid_t rp_uid; |
1430 | gid_t rp_gid; | 1430 | kgid_t rp_gid; |
1431 | 1431 | ||
1432 | /* The below fields are used only during mounting and re-mounting */ | 1432 | /* The below fields are used only during mounting and re-mounting */ |
1433 | unsigned int empty:1; | 1433 | unsigned int empty:1; |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index aa233469b3c1..287ef9f587b7 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -1312,14 +1312,14 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1312 | } | 1312 | } |
1313 | 1313 | ||
1314 | read_lock(&sbi->s_cred_lock); | 1314 | read_lock(&sbi->s_cred_lock); |
1315 | inode->i_uid = le32_to_cpu(fe->uid); | 1315 | i_uid_write(inode, le32_to_cpu(fe->uid)); |
1316 | if (inode->i_uid == -1 || | 1316 | if (!uid_valid(inode->i_uid) || |
1317 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_IGNORE) || | 1317 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_IGNORE) || |
1318 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_SET)) | 1318 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_SET)) |
1319 | inode->i_uid = UDF_SB(inode->i_sb)->s_uid; | 1319 | inode->i_uid = UDF_SB(inode->i_sb)->s_uid; |
1320 | 1320 | ||
1321 | inode->i_gid = le32_to_cpu(fe->gid); | 1321 | i_gid_write(inode, le32_to_cpu(fe->gid)); |
1322 | if (inode->i_gid == -1 || | 1322 | if (!gid_valid(inode->i_gid) || |
1323 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_IGNORE) || | 1323 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_IGNORE) || |
1324 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET)) | 1324 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET)) |
1325 | inode->i_gid = UDF_SB(inode->i_sb)->s_gid; | 1325 | inode->i_gid = UDF_SB(inode->i_sb)->s_gid; |
@@ -1542,12 +1542,12 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1542 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET)) | 1542 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET)) |
1543 | fe->uid = cpu_to_le32(-1); | 1543 | fe->uid = cpu_to_le32(-1); |
1544 | else | 1544 | else |
1545 | fe->uid = cpu_to_le32(inode->i_uid); | 1545 | fe->uid = cpu_to_le32(i_uid_read(inode)); |
1546 | 1546 | ||
1547 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET)) | 1547 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET)) |
1548 | fe->gid = cpu_to_le32(-1); | 1548 | fe->gid = cpu_to_le32(-1); |
1549 | else | 1549 | else |
1550 | fe->gid = cpu_to_le32(inode->i_gid); | 1550 | fe->gid = cpu_to_le32(i_gid_read(inode)); |
1551 | 1551 | ||
1552 | udfperms = ((inode->i_mode & S_IRWXO)) | | 1552 | udfperms = ((inode->i_mode & S_IRWXO)) | |
1553 | ((inode->i_mode & S_IRWXG) << 2) | | 1553 | ((inode->i_mode & S_IRWXG) << 2) | |
diff --git a/fs/udf/super.c b/fs/udf/super.c index 18fc038a438d..862741dddf27 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -199,8 +199,8 @@ struct udf_options { | |||
199 | unsigned int rootdir; | 199 | unsigned int rootdir; |
200 | unsigned int flags; | 200 | unsigned int flags; |
201 | umode_t umask; | 201 | umode_t umask; |
202 | gid_t gid; | 202 | kgid_t gid; |
203 | uid_t uid; | 203 | kuid_t uid; |
204 | umode_t fmode; | 204 | umode_t fmode; |
205 | umode_t dmode; | 205 | umode_t dmode; |
206 | struct nls_table *nls_map; | 206 | struct nls_table *nls_map; |
@@ -335,9 +335,9 @@ static int udf_show_options(struct seq_file *seq, struct dentry *root) | |||
335 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_IGNORE)) | 335 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_IGNORE)) |
336 | seq_puts(seq, ",gid=ignore"); | 336 | seq_puts(seq, ",gid=ignore"); |
337 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_SET)) | 337 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_SET)) |
338 | seq_printf(seq, ",uid=%u", sbi->s_uid); | 338 | seq_printf(seq, ",uid=%u", from_kuid(&init_user_ns, sbi->s_uid)); |
339 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_SET)) | 339 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_SET)) |
340 | seq_printf(seq, ",gid=%u", sbi->s_gid); | 340 | seq_printf(seq, ",gid=%u", from_kgid(&init_user_ns, sbi->s_gid)); |
341 | if (sbi->s_umask != 0) | 341 | if (sbi->s_umask != 0) |
342 | seq_printf(seq, ",umask=%ho", sbi->s_umask); | 342 | seq_printf(seq, ",umask=%ho", sbi->s_umask); |
343 | if (sbi->s_fmode != UDF_INVALID_MODE) | 343 | if (sbi->s_fmode != UDF_INVALID_MODE) |
@@ -516,13 +516,17 @@ static int udf_parse_options(char *options, struct udf_options *uopt, | |||
516 | case Opt_gid: | 516 | case Opt_gid: |
517 | if (match_int(args, &option)) | 517 | if (match_int(args, &option)) |
518 | return 0; | 518 | return 0; |
519 | uopt->gid = option; | 519 | uopt->gid = make_kgid(current_user_ns(), option); |
520 | if (!gid_valid(uopt->gid)) | ||
521 | return 0; | ||
520 | uopt->flags |= (1 << UDF_FLAG_GID_SET); | 522 | uopt->flags |= (1 << UDF_FLAG_GID_SET); |
521 | break; | 523 | break; |
522 | case Opt_uid: | 524 | case Opt_uid: |
523 | if (match_int(args, &option)) | 525 | if (match_int(args, &option)) |
524 | return 0; | 526 | return 0; |
525 | uopt->uid = option; | 527 | uopt->uid = make_kuid(current_user_ns(), option); |
528 | if (!uid_valid(uopt->uid)) | ||
529 | return 0; | ||
526 | uopt->flags |= (1 << UDF_FLAG_UID_SET); | 530 | uopt->flags |= (1 << UDF_FLAG_UID_SET); |
527 | break; | 531 | break; |
528 | case Opt_umask: | 532 | case Opt_umask: |
@@ -1934,8 +1938,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1934 | struct udf_sb_info *sbi; | 1938 | struct udf_sb_info *sbi; |
1935 | 1939 | ||
1936 | uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT); | 1940 | uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT); |
1937 | uopt.uid = -1; | 1941 | uopt.uid = INVALID_UID; |
1938 | uopt.gid = -1; | 1942 | uopt.gid = INVALID_GID; |
1939 | uopt.umask = 0; | 1943 | uopt.umask = 0; |
1940 | uopt.fmode = UDF_INVALID_MODE; | 1944 | uopt.fmode = UDF_INVALID_MODE; |
1941 | uopt.dmode = UDF_INVALID_MODE; | 1945 | uopt.dmode = UDF_INVALID_MODE; |
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index 42ad69ac9576..5f027227f085 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h | |||
@@ -128,8 +128,8 @@ struct udf_sb_info { | |||
128 | 128 | ||
129 | /* Default permissions */ | 129 | /* Default permissions */ |
130 | umode_t s_umask; | 130 | umode_t s_umask; |
131 | gid_t s_gid; | 131 | kgid_t s_gid; |
132 | uid_t s_uid; | 132 | kuid_t s_uid; |
133 | umode_t s_fmode; | 133 | umode_t s_fmode; |
134 | umode_t s_dmode; | 134 | umode_t s_dmode; |
135 | /* Lock protecting consistency of above permission settings */ | 135 | /* Lock protecting consistency of above permission settings */ |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index dd7c89d8a1c1..eb6d0b7dc879 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -597,8 +597,8 @@ static int ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode) | |||
597 | /* | 597 | /* |
598 | * Linux now has 32-bit uid and gid, so we can support EFT. | 598 | * Linux now has 32-bit uid and gid, so we can support EFT. |
599 | */ | 599 | */ |
600 | inode->i_uid = ufs_get_inode_uid(sb, ufs_inode); | 600 | i_uid_write(inode, ufs_get_inode_uid(sb, ufs_inode)); |
601 | inode->i_gid = ufs_get_inode_gid(sb, ufs_inode); | 601 | i_gid_write(inode, ufs_get_inode_gid(sb, ufs_inode)); |
602 | 602 | ||
603 | inode->i_size = fs64_to_cpu(sb, ufs_inode->ui_size); | 603 | inode->i_size = fs64_to_cpu(sb, ufs_inode->ui_size); |
604 | inode->i_atime.tv_sec = fs32_to_cpu(sb, ufs_inode->ui_atime.tv_sec); | 604 | inode->i_atime.tv_sec = fs32_to_cpu(sb, ufs_inode->ui_atime.tv_sec); |
@@ -645,8 +645,8 @@ static int ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode) | |||
645 | /* | 645 | /* |
646 | * Linux now has 32-bit uid and gid, so we can support EFT. | 646 | * Linux now has 32-bit uid and gid, so we can support EFT. |
647 | */ | 647 | */ |
648 | inode->i_uid = fs32_to_cpu(sb, ufs2_inode->ui_uid); | 648 | i_uid_write(inode, fs32_to_cpu(sb, ufs2_inode->ui_uid)); |
649 | inode->i_gid = fs32_to_cpu(sb, ufs2_inode->ui_gid); | 649 | i_gid_write(inode, fs32_to_cpu(sb, ufs2_inode->ui_gid)); |
650 | 650 | ||
651 | inode->i_size = fs64_to_cpu(sb, ufs2_inode->ui_size); | 651 | inode->i_size = fs64_to_cpu(sb, ufs2_inode->ui_size); |
652 | inode->i_atime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_atime); | 652 | inode->i_atime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_atime); |
@@ -745,8 +745,8 @@ static void ufs1_update_inode(struct inode *inode, struct ufs_inode *ufs_inode) | |||
745 | ufs_inode->ui_mode = cpu_to_fs16(sb, inode->i_mode); | 745 | ufs_inode->ui_mode = cpu_to_fs16(sb, inode->i_mode); |
746 | ufs_inode->ui_nlink = cpu_to_fs16(sb, inode->i_nlink); | 746 | ufs_inode->ui_nlink = cpu_to_fs16(sb, inode->i_nlink); |
747 | 747 | ||
748 | ufs_set_inode_uid(sb, ufs_inode, inode->i_uid); | 748 | ufs_set_inode_uid(sb, ufs_inode, i_uid_read(inode)); |
749 | ufs_set_inode_gid(sb, ufs_inode, inode->i_gid); | 749 | ufs_set_inode_gid(sb, ufs_inode, i_gid_read(inode)); |
750 | 750 | ||
751 | ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size); | 751 | ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size); |
752 | ufs_inode->ui_atime.tv_sec = cpu_to_fs32(sb, inode->i_atime.tv_sec); | 752 | ufs_inode->ui_atime.tv_sec = cpu_to_fs32(sb, inode->i_atime.tv_sec); |
@@ -789,8 +789,8 @@ static void ufs2_update_inode(struct inode *inode, struct ufs2_inode *ufs_inode) | |||
789 | ufs_inode->ui_mode = cpu_to_fs16(sb, inode->i_mode); | 789 | ufs_inode->ui_mode = cpu_to_fs16(sb, inode->i_mode); |
790 | ufs_inode->ui_nlink = cpu_to_fs16(sb, inode->i_nlink); | 790 | ufs_inode->ui_nlink = cpu_to_fs16(sb, inode->i_nlink); |
791 | 791 | ||
792 | ufs_inode->ui_uid = cpu_to_fs32(sb, inode->i_uid); | 792 | ufs_inode->ui_uid = cpu_to_fs32(sb, i_uid_read(inode)); |
793 | ufs_inode->ui_gid = cpu_to_fs32(sb, inode->i_gid); | 793 | ufs_inode->ui_gid = cpu_to_fs32(sb, i_gid_read(inode)); |
794 | 794 | ||
795 | ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size); | 795 | ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size); |
796 | ufs_inode->ui_atime = cpu_to_fs64(sb, inode->i_atime.tv_sec); | 796 | ufs_inode->ui_atime = cpu_to_fs64(sb, inode->i_atime.tv_sec); |
diff --git a/fs/xattr.c b/fs/xattr.c index 014f11321fd9..f7f7f09b0b41 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/fsnotify.h> | 20 | #include <linux/fsnotify.h> |
21 | #include <linux/audit.h> | 21 | #include <linux/audit.h> |
22 | #include <linux/vmalloc.h> | 22 | #include <linux/vmalloc.h> |
23 | #include <linux/posix_acl_xattr.h> | ||
23 | 24 | ||
24 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
25 | 26 | ||
@@ -347,6 +348,9 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value, | |||
347 | error = -EFAULT; | 348 | error = -EFAULT; |
348 | goto out; | 349 | goto out; |
349 | } | 350 | } |
351 | if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || | ||
352 | (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) | ||
353 | posix_acl_fix_xattr_from_user(kvalue, size); | ||
350 | } | 354 | } |
351 | 355 | ||
352 | error = vfs_setxattr(d, kname, kvalue, size, flags); | 356 | error = vfs_setxattr(d, kname, kvalue, size, flags); |
@@ -450,6 +454,9 @@ getxattr(struct dentry *d, const char __user *name, void __user *value, | |||
450 | 454 | ||
451 | error = vfs_getxattr(d, kname, kvalue, size); | 455 | error = vfs_getxattr(d, kname, kvalue, size); |
452 | if (error > 0) { | 456 | if (error > 0) { |
457 | if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || | ||
458 | (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) | ||
459 | posix_acl_fix_xattr_to_user(kvalue, size); | ||
453 | if (size && copy_to_user(value, kvalue, error)) | 460 | if (size && copy_to_user(value, kvalue, error)) |
454 | error = -EFAULT; | 461 | error = -EFAULT; |
455 | } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) { | 462 | } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) { |
diff --git a/fs/xattr_acl.c b/fs/xattr_acl.c index 69d06b07b169..11efd830b5f5 100644 --- a/fs/xattr_acl.c +++ b/fs/xattr_acl.c | |||
@@ -9,13 +9,72 @@ | |||
9 | #include <linux/fs.h> | 9 | #include <linux/fs.h> |
10 | #include <linux/posix_acl_xattr.h> | 10 | #include <linux/posix_acl_xattr.h> |
11 | #include <linux/gfp.h> | 11 | #include <linux/gfp.h> |
12 | #include <linux/user_namespace.h> | ||
12 | 13 | ||
14 | /* | ||
15 | * Fix up the uids and gids in posix acl extended attributes in place. | ||
16 | */ | ||
17 | static void posix_acl_fix_xattr_userns( | ||
18 | struct user_namespace *to, struct user_namespace *from, | ||
19 | void *value, size_t size) | ||
20 | { | ||
21 | posix_acl_xattr_header *header = (posix_acl_xattr_header *)value; | ||
22 | posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end; | ||
23 | int count; | ||
24 | kuid_t uid; | ||
25 | kgid_t gid; | ||
26 | |||
27 | if (!value) | ||
28 | return; | ||
29 | if (size < sizeof(posix_acl_xattr_header)) | ||
30 | return; | ||
31 | if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION)) | ||
32 | return; | ||
33 | |||
34 | count = posix_acl_xattr_count(size); | ||
35 | if (count < 0) | ||
36 | return; | ||
37 | if (count == 0) | ||
38 | return; | ||
39 | |||
40 | for (end = entry + count; entry != end; entry++) { | ||
41 | switch(le16_to_cpu(entry->e_tag)) { | ||
42 | case ACL_USER: | ||
43 | uid = make_kuid(from, le32_to_cpu(entry->e_id)); | ||
44 | entry->e_id = cpu_to_le32(from_kuid(to, uid)); | ||
45 | break; | ||
46 | case ACL_GROUP: | ||
47 | gid = make_kgid(from, le32_to_cpu(entry->e_id)); | ||
48 | entry->e_id = cpu_to_le32(from_kuid(to, uid)); | ||
49 | break; | ||
50 | default: | ||
51 | break; | ||
52 | } | ||
53 | } | ||
54 | } | ||
55 | |||
56 | void posix_acl_fix_xattr_from_user(void *value, size_t size) | ||
57 | { | ||
58 | struct user_namespace *user_ns = current_user_ns(); | ||
59 | if (user_ns == &init_user_ns) | ||
60 | return; | ||
61 | posix_acl_fix_xattr_userns(&init_user_ns, user_ns, value, size); | ||
62 | } | ||
63 | |||
64 | void posix_acl_fix_xattr_to_user(void *value, size_t size) | ||
65 | { | ||
66 | struct user_namespace *user_ns = current_user_ns(); | ||
67 | if (user_ns == &init_user_ns) | ||
68 | return; | ||
69 | posix_acl_fix_xattr_userns(user_ns, &init_user_ns, value, size); | ||
70 | } | ||
13 | 71 | ||
14 | /* | 72 | /* |
15 | * Convert from extended attribute to in-memory representation. | 73 | * Convert from extended attribute to in-memory representation. |
16 | */ | 74 | */ |
17 | struct posix_acl * | 75 | struct posix_acl * |
18 | posix_acl_from_xattr(const void *value, size_t size) | 76 | posix_acl_from_xattr(struct user_namespace *user_ns, |
77 | const void *value, size_t size) | ||
19 | { | 78 | { |
20 | posix_acl_xattr_header *header = (posix_acl_xattr_header *)value; | 79 | posix_acl_xattr_header *header = (posix_acl_xattr_header *)value; |
21 | posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end; | 80 | posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end; |
@@ -50,12 +109,21 @@ posix_acl_from_xattr(const void *value, size_t size) | |||
50 | case ACL_GROUP_OBJ: | 109 | case ACL_GROUP_OBJ: |
51 | case ACL_MASK: | 110 | case ACL_MASK: |
52 | case ACL_OTHER: | 111 | case ACL_OTHER: |
53 | acl_e->e_id = ACL_UNDEFINED_ID; | ||
54 | break; | 112 | break; |
55 | 113 | ||
56 | case ACL_USER: | 114 | case ACL_USER: |
115 | acl_e->e_uid = | ||
116 | make_kuid(user_ns, | ||
117 | le32_to_cpu(entry->e_id)); | ||
118 | if (!uid_valid(acl_e->e_uid)) | ||
119 | goto fail; | ||
120 | break; | ||
57 | case ACL_GROUP: | 121 | case ACL_GROUP: |
58 | acl_e->e_id = le32_to_cpu(entry->e_id); | 122 | acl_e->e_gid = |
123 | make_kgid(user_ns, | ||
124 | le32_to_cpu(entry->e_id)); | ||
125 | if (!gid_valid(acl_e->e_gid)) | ||
126 | goto fail; | ||
59 | break; | 127 | break; |
60 | 128 | ||
61 | default: | 129 | default: |
@@ -74,7 +142,8 @@ EXPORT_SYMBOL (posix_acl_from_xattr); | |||
74 | * Convert from in-memory to extended attribute representation. | 142 | * Convert from in-memory to extended attribute representation. |
75 | */ | 143 | */ |
76 | int | 144 | int |
77 | posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size) | 145 | posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl, |
146 | void *buffer, size_t size) | ||
78 | { | 147 | { |
79 | posix_acl_xattr_header *ext_acl = (posix_acl_xattr_header *)buffer; | 148 | posix_acl_xattr_header *ext_acl = (posix_acl_xattr_header *)buffer; |
80 | posix_acl_xattr_entry *ext_entry = ext_acl->a_entries; | 149 | posix_acl_xattr_entry *ext_entry = ext_acl->a_entries; |
@@ -89,9 +158,22 @@ posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size) | |||
89 | ext_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION); | 158 | ext_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION); |
90 | 159 | ||
91 | for (n=0; n < acl->a_count; n++, ext_entry++) { | 160 | for (n=0; n < acl->a_count; n++, ext_entry++) { |
92 | ext_entry->e_tag = cpu_to_le16(acl->a_entries[n].e_tag); | 161 | const struct posix_acl_entry *acl_e = &acl->a_entries[n]; |
93 | ext_entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm); | 162 | ext_entry->e_tag = cpu_to_le16(acl_e->e_tag); |
94 | ext_entry->e_id = cpu_to_le32(acl->a_entries[n].e_id); | 163 | ext_entry->e_perm = cpu_to_le16(acl_e->e_perm); |
164 | switch(acl_e->e_tag) { | ||
165 | case ACL_USER: | ||
166 | ext_entry->e_id = | ||
167 | cpu_to_le32(from_kuid(user_ns, acl_e->e_uid)); | ||
168 | break; | ||
169 | case ACL_GROUP: | ||
170 | ext_entry->e_id = | ||
171 | cpu_to_le32(from_kgid(user_ns, acl_e->e_gid)); | ||
172 | break; | ||
173 | default: | ||
174 | ext_entry->e_id = cpu_to_le32(ACL_UNDEFINED_ID); | ||
175 | break; | ||
176 | } | ||
95 | } | 177 | } |
96 | return real_size; | 178 | return real_size; |
97 | } | 179 | } |
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index ac702a6eab9b..1d32f1d52763 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c | |||
@@ -337,7 +337,7 @@ xfs_xattr_acl_get(struct dentry *dentry, const char *name, | |||
337 | if (acl == NULL) | 337 | if (acl == NULL) |
338 | return -ENODATA; | 338 | return -ENODATA; |
339 | 339 | ||
340 | error = posix_acl_to_xattr(acl, value, size); | 340 | error = posix_acl_to_xattr(&init_user_ns, acl, value, size); |
341 | posix_acl_release(acl); | 341 | posix_acl_release(acl); |
342 | 342 | ||
343 | return error; | 343 | return error; |
@@ -361,7 +361,7 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name, | |||
361 | if (!value) | 361 | if (!value) |
362 | goto set_acl; | 362 | goto set_acl; |
363 | 363 | ||
364 | acl = posix_acl_from_xattr(value, size); | 364 | acl = posix_acl_from_xattr(&init_user_ns, value, size); |
365 | if (!acl) { | 365 | if (!acl) { |
366 | /* | 366 | /* |
367 | * acl_set_file(3) may request that we set default ACLs with | 367 | * acl_set_file(3) may request that we set default ACLs with |
diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c index fed504fc2999..71926d630527 100644 --- a/fs/xfs/xfs_quotaops.c +++ b/fs/xfs/xfs_quotaops.c | |||
@@ -97,8 +97,7 @@ xfs_fs_set_xstate( | |||
97 | STATIC int | 97 | STATIC int |
98 | xfs_fs_get_dqblk( | 98 | xfs_fs_get_dqblk( |
99 | struct super_block *sb, | 99 | struct super_block *sb, |
100 | int type, | 100 | struct kqid qid, |
101 | qid_t id, | ||
102 | struct fs_disk_quota *fdq) | 101 | struct fs_disk_quota *fdq) |
103 | { | 102 | { |
104 | struct xfs_mount *mp = XFS_M(sb); | 103 | struct xfs_mount *mp = XFS_M(sb); |
@@ -108,14 +107,14 @@ xfs_fs_get_dqblk( | |||
108 | if (!XFS_IS_QUOTA_ON(mp)) | 107 | if (!XFS_IS_QUOTA_ON(mp)) |
109 | return -ESRCH; | 108 | return -ESRCH; |
110 | 109 | ||
111 | return -xfs_qm_scall_getquota(mp, id, xfs_quota_type(type), fdq); | 110 | return -xfs_qm_scall_getquota(mp, from_kqid(&init_user_ns, qid), |
111 | xfs_quota_type(qid.type), fdq); | ||
112 | } | 112 | } |
113 | 113 | ||
114 | STATIC int | 114 | STATIC int |
115 | xfs_fs_set_dqblk( | 115 | xfs_fs_set_dqblk( |
116 | struct super_block *sb, | 116 | struct super_block *sb, |
117 | int type, | 117 | struct kqid qid, |
118 | qid_t id, | ||
119 | struct fs_disk_quota *fdq) | 118 | struct fs_disk_quota *fdq) |
120 | { | 119 | { |
121 | struct xfs_mount *mp = XFS_M(sb); | 120 | struct xfs_mount *mp = XFS_M(sb); |
@@ -127,7 +126,8 @@ xfs_fs_set_dqblk( | |||
127 | if (!XFS_IS_QUOTA_ON(mp)) | 126 | if (!XFS_IS_QUOTA_ON(mp)) |
128 | return -ESRCH; | 127 | return -ESRCH; |
129 | 128 | ||
130 | return -xfs_qm_scall_setqlim(mp, id, xfs_quota_type(type), fdq); | 129 | return -xfs_qm_scall_setqlim(mp, from_kqid(&init_user_ns, qid), |
130 | xfs_quota_type(qid.type), fdq); | ||
131 | } | 131 | } |
132 | 132 | ||
133 | const struct quotactl_ops xfs_quotactl_operations = { | 133 | const struct quotactl_ops xfs_quotactl_operations = { |
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index bcb60542fcf1..0c7fa54f309e 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c | |||
@@ -578,9 +578,11 @@ xfs_quota_warn( | |||
578 | /* no warnings for project quotas - we just return ENOSPC later */ | 578 | /* no warnings for project quotas - we just return ENOSPC later */ |
579 | if (dqp->dq_flags & XFS_DQ_PROJ) | 579 | if (dqp->dq_flags & XFS_DQ_PROJ) |
580 | return; | 580 | return; |
581 | quota_send_warning((dqp->dq_flags & XFS_DQ_USER) ? USRQUOTA : GRPQUOTA, | 581 | quota_send_warning(make_kqid(&init_user_ns, |
582 | be32_to_cpu(dqp->q_core.d_id), mp->m_super->s_dev, | 582 | (dqp->dq_flags & XFS_DQ_USER) ? |
583 | type); | 583 | USRQUOTA : GRPQUOTA, |
584 | be32_to_cpu(dqp->q_core.d_id)), | ||
585 | mp->m_super->s_dev, type); | ||
584 | } | 586 | } |
585 | 587 | ||
586 | /* | 588 | /* |
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index d6b67bb9075f..9bc5c6a1d52c 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -426,8 +426,8 @@ struct drm_prime_file_private { | |||
426 | /** File private data */ | 426 | /** File private data */ |
427 | struct drm_file { | 427 | struct drm_file { |
428 | int authenticated; | 428 | int authenticated; |
429 | pid_t pid; | 429 | struct pid *pid; |
430 | uid_t uid; | 430 | kuid_t uid; |
431 | drm_magic_t magic; | 431 | drm_magic_t magic; |
432 | unsigned long ioctl_count; | 432 | unsigned long ioctl_count; |
433 | struct list_head lhead; | 433 | struct list_head lhead; |
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 { | |||
442 | struct audit_field { | 442 | struct audit_field { |
443 | u32 type; | 443 | u32 type; |
444 | u32 val; | 444 | u32 val; |
445 | kuid_t uid; | ||
446 | kgid_t gid; | ||
445 | u32 op; | 447 | u32 op; |
446 | char *lsm_str; | 448 | char *lsm_str; |
447 | void *lsm_rule; | 449 | void *lsm_rule; |
@@ -525,7 +527,7 @@ static inline void audit_ptrace(struct task_struct *t) | |||
525 | extern unsigned int audit_serial(void); | 527 | extern unsigned int audit_serial(void); |
526 | extern int auditsc_get_stamp(struct audit_context *ctx, | 528 | extern int auditsc_get_stamp(struct audit_context *ctx, |
527 | struct timespec *t, unsigned int *serial); | 529 | struct timespec *t, unsigned int *serial); |
528 | extern int audit_set_loginuid(uid_t loginuid); | 530 | extern int audit_set_loginuid(kuid_t loginuid); |
529 | #define audit_get_loginuid(t) ((t)->loginuid) | 531 | #define audit_get_loginuid(t) ((t)->loginuid) |
530 | #define audit_get_sessionid(t) ((t)->sessionid) | 532 | #define audit_get_sessionid(t) ((t)->sessionid) |
531 | extern void audit_log_task_context(struct audit_buffer *ab); | 533 | extern void audit_log_task_context(struct audit_buffer *ab); |
@@ -637,7 +639,7 @@ extern int audit_signals; | |||
637 | #define audit_core_dumps(i) do { ; } while (0) | 639 | #define audit_core_dumps(i) do { ; } while (0) |
638 | #define audit_seccomp(i,s,c) do { ; } while (0) | 640 | #define audit_seccomp(i,s,c) do { ; } while (0) |
639 | #define auditsc_get_stamp(c,t,s) (0) | 641 | #define auditsc_get_stamp(c,t,s) (0) |
640 | #define audit_get_loginuid(t) (-1) | 642 | #define audit_get_loginuid(t) (INVALID_UID) |
641 | #define audit_get_sessionid(t) (-1) | 643 | #define audit_get_sessionid(t) (-1) |
642 | #define audit_log_task_context(b) do { ; } while (0) | 644 | #define audit_log_task_context(b) do { ; } while (0) |
643 | #define audit_ipc_obj(i) ((void)0) | 645 | #define audit_ipc_obj(i) ((void)0) |
@@ -700,10 +702,10 @@ extern void audit_log_secctx(struct audit_buffer *ab, u32 secid); | |||
700 | extern int audit_update_lsm_rules(void); | 702 | extern int audit_update_lsm_rules(void); |
701 | 703 | ||
702 | /* Private API (for audit.c only) */ | 704 | /* Private API (for audit.c only) */ |
703 | extern int audit_filter_user(struct netlink_skb_parms *cb); | 705 | extern int audit_filter_user(void); |
704 | extern int audit_filter_type(int type); | 706 | extern int audit_filter_type(int type); |
705 | extern int audit_receive_filter(int type, int pid, int uid, int seq, | 707 | extern int audit_receive_filter(int type, int pid, int seq, |
706 | void *data, size_t datasz, uid_t loginuid, | 708 | void *data, size_t datasz, kuid_t loginuid, |
707 | u32 sessionid, u32 sid); | 709 | u32 sessionid, u32 sid); |
708 | extern int audit_enabled; | 710 | extern int audit_enabled; |
709 | #else | 711 | #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 { | |||
159 | struct inet_connection_sock; | 159 | struct inet_connection_sock; |
160 | int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, | 160 | int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, |
161 | struct sk_buff *skb, struct inet_diag_req_v2 *req, | 161 | struct sk_buff *skb, struct inet_diag_req_v2 *req, |
162 | struct user_namespace *user_ns, | ||
162 | u32 pid, u32 seq, u16 nlmsg_flags, | 163 | u32 pid, u32 seq, u16 nlmsg_flags, |
163 | const struct nlmsghdr *unlh); | 164 | const struct nlmsghdr *unlh); |
164 | void inet_diag_dump_icsk(struct inet_hashinfo *h, struct sk_buff *skb, | 165 | 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; | |||
92 | 92 | ||
93 | #ifdef CONFIG_AUDITSYSCALL | 93 | #ifdef CONFIG_AUDITSYSCALL |
94 | #define INIT_IDS \ | 94 | #define INIT_IDS \ |
95 | .loginuid = -1, \ | 95 | .loginuid = INVALID_UID, \ |
96 | .sessionid = -1, | 96 | .sessionid = -1, |
97 | #else | 97 | #else |
98 | #define INIT_IDS | 98 | #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 { | |||
79 | 79 | ||
80 | #ifdef __KERNEL__ | 80 | #ifdef __KERNEL__ |
81 | #include <linux/spinlock.h> | 81 | #include <linux/spinlock.h> |
82 | #include <linux/uidgid.h> | ||
82 | 83 | ||
83 | #define IPCMNI 32768 /* <= MAX_INT limit for ipc arrays (including sysctl changes) */ | 84 | #define IPCMNI 32768 /* <= MAX_INT limit for ipc arrays (including sysctl changes) */ |
84 | 85 | ||
@@ -89,10 +90,10 @@ struct kern_ipc_perm | |||
89 | int deleted; | 90 | int deleted; |
90 | int id; | 91 | int id; |
91 | key_t key; | 92 | key_t key; |
92 | uid_t uid; | 93 | kuid_t uid; |
93 | gid_t gid; | 94 | kgid_t gid; |
94 | uid_t cuid; | 95 | kuid_t cuid; |
95 | gid_t cgid; | 96 | kgid_t cgid; |
96 | umode_t mode; | 97 | umode_t mode; |
97 | unsigned long seq; | 98 | unsigned long seq; |
98 | void *security; | 99 | 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 @@ | |||
24 | #include <linux/atomic.h> | 24 | #include <linux/atomic.h> |
25 | 25 | ||
26 | #ifdef __KERNEL__ | 26 | #ifdef __KERNEL__ |
27 | #include <linux/uidgid.h> | ||
27 | 28 | ||
28 | /* key handle serial number */ | 29 | /* key handle serial number */ |
29 | typedef int32_t key_serial_t; | 30 | typedef int32_t key_serial_t; |
@@ -137,8 +138,8 @@ struct key { | |||
137 | time_t revoked_at; /* time at which key was revoked */ | 138 | time_t revoked_at; /* time at which key was revoked */ |
138 | }; | 139 | }; |
139 | time_t last_used_at; /* last time used for LRU keyring discard */ | 140 | time_t last_used_at; /* last time used for LRU keyring discard */ |
140 | uid_t uid; | 141 | kuid_t uid; |
141 | gid_t gid; | 142 | kgid_t gid; |
142 | key_perm_t perm; /* access permissions */ | 143 | key_perm_t perm; /* access permissions */ |
143 | unsigned short quotalen; /* length added to quota */ | 144 | unsigned short quotalen; /* length added to quota */ |
144 | unsigned short datalen; /* payload data length | 145 | unsigned short datalen; /* payload data length |
@@ -193,7 +194,7 @@ struct key { | |||
193 | 194 | ||
194 | extern struct key *key_alloc(struct key_type *type, | 195 | extern struct key *key_alloc(struct key_type *type, |
195 | const char *desc, | 196 | const char *desc, |
196 | uid_t uid, gid_t gid, | 197 | kuid_t uid, kgid_t gid, |
197 | const struct cred *cred, | 198 | const struct cred *cred, |
198 | key_perm_t perm, | 199 | key_perm_t perm, |
199 | unsigned long flags); | 200 | unsigned long flags); |
@@ -262,7 +263,7 @@ extern int key_link(struct key *keyring, | |||
262 | extern int key_unlink(struct key *keyring, | 263 | extern int key_unlink(struct key *keyring, |
263 | struct key *key); | 264 | struct key *key); |
264 | 265 | ||
265 | extern struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, | 266 | extern struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid, |
266 | const struct cred *cred, | 267 | const struct cred *cred, |
267 | unsigned long flags, | 268 | unsigned long flags, |
268 | struct key *dest); | 269 | 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 { | |||
44 | int lo_encrypt_key_size; | 44 | int lo_encrypt_key_size; |
45 | struct loop_func_table *lo_encryption; | 45 | struct loop_func_table *lo_encryption; |
46 | __u32 lo_init[2]; | 46 | __u32 lo_init[2]; |
47 | uid_t lo_key_owner; /* Who set the key */ | 47 | kuid_t lo_key_owner; /* Who set the key */ |
48 | int (*ioctl)(struct loop_device *, int cmd, | 48 | int (*ioctl)(struct loop_device *, int cmd, |
49 | unsigned long arg); | 49 | unsigned long arg); |
50 | 50 | ||
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 { | |||
165 | struct ucred creds; /* Skb credentials */ | 165 | struct ucred creds; /* Skb credentials */ |
166 | __u32 pid; | 166 | __u32 pid; |
167 | __u32 dst_group; | 167 | __u32 dst_group; |
168 | struct sock *ssk; | ||
168 | }; | 169 | }; |
169 | 170 | ||
170 | #define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb)) | 171 | #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 @@ | |||
36 | struct posix_acl_entry { | 36 | struct posix_acl_entry { |
37 | short e_tag; | 37 | short e_tag; |
38 | unsigned short e_perm; | 38 | unsigned short e_perm; |
39 | unsigned int e_id; | 39 | union { |
40 | kuid_t e_uid; | ||
41 | kgid_t e_gid; | ||
42 | #ifndef CONFIG_UIDGID_STRICT_TYPE_CHECKS | ||
43 | unsigned int e_id; | ||
44 | #endif | ||
45 | }; | ||
40 | }; | 46 | }; |
41 | 47 | ||
42 | struct posix_acl { | 48 | 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) | |||
52 | return size / sizeof(posix_acl_xattr_entry); | 52 | return size / sizeof(posix_acl_xattr_entry); |
53 | } | 53 | } |
54 | 54 | ||
55 | struct posix_acl *posix_acl_from_xattr(const void *value, size_t size); | 55 | #ifdef CONFIG_FS_POSIX_ACL |
56 | int posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size); | 56 | void posix_acl_fix_xattr_from_user(void *value, size_t size); |
57 | void posix_acl_fix_xattr_to_user(void *value, size_t size); | ||
58 | #else | ||
59 | static inline void posix_acl_fix_xattr_from_user(void *value, size_t size) | ||
60 | { | ||
61 | } | ||
62 | static inline void posix_acl_fix_xattr_to_user(void *value, size_t size) | ||
63 | { | ||
64 | } | ||
65 | #endif | ||
66 | |||
67 | struct posix_acl *posix_acl_from_xattr(struct user_namespace *user_ns, | ||
68 | const void *value, size_t size); | ||
69 | int posix_acl_to_xattr(struct user_namespace *user_ns, | ||
70 | const struct posix_acl *acl, void *buffer, size_t size); | ||
57 | 71 | ||
58 | #endif /* _POSIX_ACL_XATTR_H */ | 72 | #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 @@ | |||
1 | #ifndef _LINUX_PROJID_H | ||
2 | #define _LINUX_PROJID_H | ||
3 | |||
4 | /* | ||
5 | * A set of types for the internal kernel types representing project ids. | ||
6 | * | ||
7 | * The types defined in this header allow distinguishing which project ids in | ||
8 | * the kernel are values used by userspace and which project id 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 | |||
16 | struct user_namespace; | ||
17 | extern struct user_namespace init_user_ns; | ||
18 | |||
19 | typedef __kernel_uid32_t projid_t; | ||
20 | |||
21 | #ifdef CONFIG_UIDGID_STRICT_TYPE_CHECKS | ||
22 | |||
23 | typedef struct { | ||
24 | projid_t val; | ||
25 | } kprojid_t; | ||
26 | |||
27 | static inline projid_t __kprojid_val(kprojid_t projid) | ||
28 | { | ||
29 | return projid.val; | ||
30 | } | ||
31 | |||
32 | #define KPROJIDT_INIT(value) (kprojid_t){ value } | ||
33 | |||
34 | #else | ||
35 | |||
36 | typedef projid_t kprojid_t; | ||
37 | |||
38 | static inline projid_t __kprojid_val(kprojid_t projid) | ||
39 | { | ||
40 | return projid; | ||
41 | } | ||
42 | |||
43 | #define KPROJIDT_INIT(value) ((kprojid_t) value ) | ||
44 | |||
45 | #endif | ||
46 | |||
47 | #define INVALID_PROJID KPROJIDT_INIT(-1) | ||
48 | #define OVERFLOW_PROJID 65534 | ||
49 | |||
50 | static inline bool projid_eq(kprojid_t left, kprojid_t right) | ||
51 | { | ||
52 | return __kprojid_val(left) == __kprojid_val(right); | ||
53 | } | ||
54 | |||
55 | static inline bool projid_lt(kprojid_t left, kprojid_t right) | ||
56 | { | ||
57 | return __kprojid_val(left) < __kprojid_val(right); | ||
58 | } | ||
59 | |||
60 | static inline bool projid_valid(kprojid_t projid) | ||
61 | { | ||
62 | return !projid_eq(projid, INVALID_PROJID); | ||
63 | } | ||
64 | |||
65 | #ifdef CONFIG_USER_NS | ||
66 | |||
67 | extern kprojid_t make_kprojid(struct user_namespace *from, projid_t projid); | ||
68 | |||
69 | extern projid_t from_kprojid(struct user_namespace *to, kprojid_t projid); | ||
70 | extern projid_t from_kprojid_munged(struct user_namespace *to, kprojid_t projid); | ||
71 | |||
72 | static inline bool kprojid_has_mapping(struct user_namespace *ns, kprojid_t projid) | ||
73 | { | ||
74 | return from_kprojid(ns, projid) != (projid_t)-1; | ||
75 | } | ||
76 | |||
77 | #else | ||
78 | |||
79 | static inline kprojid_t make_kprojid(struct user_namespace *from, projid_t projid) | ||
80 | { | ||
81 | return KPROJIDT_INIT(projid); | ||
82 | } | ||
83 | |||
84 | static inline projid_t from_kprojid(struct user_namespace *to, kprojid_t kprojid) | ||
85 | { | ||
86 | return __kprojid_val(kprojid); | ||
87 | } | ||
88 | |||
89 | static inline projid_t from_kprojid_munged(struct user_namespace *to, kprojid_t kprojid) | ||
90 | { | ||
91 | projid_t projid = from_kprojid(to, kprojid); | ||
92 | if (projid == (projid_t)-1) | ||
93 | projid = OVERFLOW_PROJID; | ||
94 | return projid; | ||
95 | } | ||
96 | |||
97 | static inline bool kprojid_has_mapping(struct user_namespace *ns, kprojid_t projid) | ||
98 | { | ||
99 | return true; | ||
100 | } | ||
101 | |||
102 | #endif /* CONFIG_USER_NS */ | ||
103 | |||
104 | #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 { | |||
181 | #include <linux/dqblk_v2.h> | 181 | #include <linux/dqblk_v2.h> |
182 | 182 | ||
183 | #include <linux/atomic.h> | 183 | #include <linux/atomic.h> |
184 | #include <linux/uidgid.h> | ||
185 | #include <linux/projid.h> | ||
186 | |||
187 | #undef USRQUOTA | ||
188 | #undef GRPQUOTA | ||
189 | enum quota_type { | ||
190 | USRQUOTA = 0, /* element used for user quotas */ | ||
191 | GRPQUOTA = 1, /* element used for group quotas */ | ||
192 | PRJQUOTA = 2, /* element used for project quotas */ | ||
193 | }; | ||
184 | 194 | ||
185 | typedef __kernel_uid32_t qid_t; /* Type in which we store ids in memory */ | 195 | typedef __kernel_uid32_t qid_t; /* Type in which we store ids in memory */ |
186 | typedef long long qsize_t; /* Type in which we store sizes */ | 196 | typedef long long qsize_t; /* Type in which we store sizes */ |
187 | 197 | ||
198 | struct kqid { /* Type in which we store the quota identifier */ | ||
199 | union { | ||
200 | kuid_t uid; | ||
201 | kgid_t gid; | ||
202 | kprojid_t projid; | ||
203 | }; | ||
204 | enum quota_type type; /* USRQUOTA (uid) or GRPQUOTA (gid) or PRJQUOTA (projid) */ | ||
205 | }; | ||
206 | |||
207 | extern bool qid_eq(struct kqid left, struct kqid right); | ||
208 | extern bool qid_lt(struct kqid left, struct kqid right); | ||
209 | extern qid_t from_kqid(struct user_namespace *to, struct kqid qid); | ||
210 | extern qid_t from_kqid_munged(struct user_namespace *to, struct kqid qid); | ||
211 | extern bool qid_valid(struct kqid qid); | ||
212 | |||
213 | /** | ||
214 | * make_kqid - Map a user-namespace, type, qid tuple into a kqid. | ||
215 | * @from: User namespace that the qid is in | ||
216 | * @type: The type of quota | ||
217 | * @qid: Quota identifier | ||
218 | * | ||
219 | * Maps a user-namespace, type qid tuple into a kernel internal | ||
220 | * kqid, and returns that kqid. | ||
221 | * | ||
222 | * When there is no mapping defined for the user-namespace, type, | ||
223 | * qid tuple an invalid kqid is returned. Callers are expected to | ||
224 | * test for and handle handle invalid kqids being returned. | ||
225 | * Invalid kqids may be tested for using qid_valid(). | ||
226 | */ | ||
227 | static inline struct kqid make_kqid(struct user_namespace *from, | ||
228 | enum quota_type type, qid_t qid) | ||
229 | { | ||
230 | struct kqid kqid; | ||
231 | |||
232 | kqid.type = type; | ||
233 | switch (type) { | ||
234 | case USRQUOTA: | ||
235 | kqid.uid = make_kuid(from, qid); | ||
236 | break; | ||
237 | case GRPQUOTA: | ||
238 | kqid.gid = make_kgid(from, qid); | ||
239 | break; | ||
240 | case PRJQUOTA: | ||
241 | kqid.projid = make_kprojid(from, qid); | ||
242 | break; | ||
243 | default: | ||
244 | BUG(); | ||
245 | } | ||
246 | return kqid; | ||
247 | } | ||
248 | |||
249 | /** | ||
250 | * make_kqid_invalid - Explicitly make an invalid kqid | ||
251 | * @type: The type of quota identifier | ||
252 | * | ||
253 | * Returns an invalid kqid with the specified type. | ||
254 | */ | ||
255 | static inline struct kqid make_kqid_invalid(enum quota_type type) | ||
256 | { | ||
257 | struct kqid kqid; | ||
258 | |||
259 | kqid.type = type; | ||
260 | switch (type) { | ||
261 | case USRQUOTA: | ||
262 | kqid.uid = INVALID_UID; | ||
263 | break; | ||
264 | case GRPQUOTA: | ||
265 | kqid.gid = INVALID_GID; | ||
266 | break; | ||
267 | case PRJQUOTA: | ||
268 | kqid.projid = INVALID_PROJID; | ||
269 | break; | ||
270 | default: | ||
271 | BUG(); | ||
272 | } | ||
273 | return kqid; | ||
274 | } | ||
275 | |||
276 | /** | ||
277 | * make_kqid_uid - Make a kqid from a kuid | ||
278 | * @uid: The kuid to make the quota identifier from | ||
279 | */ | ||
280 | static inline struct kqid make_kqid_uid(kuid_t uid) | ||
281 | { | ||
282 | struct kqid kqid; | ||
283 | kqid.type = USRQUOTA; | ||
284 | kqid.uid = uid; | ||
285 | return kqid; | ||
286 | } | ||
287 | |||
288 | /** | ||
289 | * make_kqid_gid - Make a kqid from a kgid | ||
290 | * @gid: The kgid to make the quota identifier from | ||
291 | */ | ||
292 | static inline struct kqid make_kqid_gid(kgid_t gid) | ||
293 | { | ||
294 | struct kqid kqid; | ||
295 | kqid.type = GRPQUOTA; | ||
296 | kqid.gid = gid; | ||
297 | return kqid; | ||
298 | } | ||
299 | |||
300 | /** | ||
301 | * make_kqid_projid - Make a kqid from a projid | ||
302 | * @projid: The kprojid to make the quota identifier from | ||
303 | */ | ||
304 | static inline struct kqid make_kqid_projid(kprojid_t projid) | ||
305 | { | ||
306 | struct kqid kqid; | ||
307 | kqid.type = PRJQUOTA; | ||
308 | kqid.projid = projid; | ||
309 | return kqid; | ||
310 | } | ||
311 | |||
312 | |||
188 | extern spinlock_t dq_data_lock; | 313 | extern spinlock_t dq_data_lock; |
189 | 314 | ||
190 | /* Maximal numbers of writes for quota operation (insert/delete/update) | 315 | /* Maximal numbers of writes for quota operation (insert/delete/update) |
@@ -294,10 +419,9 @@ struct dquot { | |||
294 | atomic_t dq_count; /* Use count */ | 419 | atomic_t dq_count; /* Use count */ |
295 | wait_queue_head_t dq_wait_unused; /* Wait queue for dquot to become unused */ | 420 | wait_queue_head_t dq_wait_unused; /* Wait queue for dquot to become unused */ |
296 | struct super_block *dq_sb; /* superblock this applies to */ | 421 | struct super_block *dq_sb; /* superblock this applies to */ |
297 | unsigned int dq_id; /* ID this applies to (uid, gid) */ | 422 | struct kqid dq_id; /* ID this applies to (uid, gid, projid) */ |
298 | loff_t dq_off; /* Offset of dquot on disk */ | 423 | loff_t dq_off; /* Offset of dquot on disk */ |
299 | unsigned long dq_flags; /* See DQ_* */ | 424 | unsigned long dq_flags; /* See DQ_* */ |
300 | short dq_type; /* Type of quota */ | ||
301 | struct mem_dqblk dq_dqb; /* Diskquota usage */ | 425 | struct mem_dqblk dq_dqb; /* Diskquota usage */ |
302 | }; | 426 | }; |
303 | 427 | ||
@@ -336,8 +460,8 @@ struct quotactl_ops { | |||
336 | int (*quota_sync)(struct super_block *, int); | 460 | int (*quota_sync)(struct super_block *, int); |
337 | int (*get_info)(struct super_block *, int, struct if_dqinfo *); | 461 | int (*get_info)(struct super_block *, int, struct if_dqinfo *); |
338 | int (*set_info)(struct super_block *, int, struct if_dqinfo *); | 462 | int (*set_info)(struct super_block *, int, struct if_dqinfo *); |
339 | int (*get_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *); | 463 | int (*get_dqblk)(struct super_block *, struct kqid, struct fs_disk_quota *); |
340 | int (*set_dqblk)(struct super_block *, int, qid_t, struct fs_disk_quota *); | 464 | int (*set_dqblk)(struct super_block *, struct kqid, struct fs_disk_quota *); |
341 | int (*get_xstate)(struct super_block *, struct fs_quota_stat *); | 465 | int (*get_xstate)(struct super_block *, struct fs_quota_stat *); |
342 | int (*set_xstate)(struct super_block *, unsigned int, int); | 466 | int (*set_xstate)(struct super_block *, unsigned int, int); |
343 | }; | 467 | }; |
@@ -386,10 +510,10 @@ static inline unsigned int dquot_generic_flag(unsigned int flags, int type) | |||
386 | } | 510 | } |
387 | 511 | ||
388 | #ifdef CONFIG_QUOTA_NETLINK_INTERFACE | 512 | #ifdef CONFIG_QUOTA_NETLINK_INTERFACE |
389 | extern void quota_send_warning(short type, unsigned int id, dev_t dev, | 513 | extern void quota_send_warning(struct kqid qid, dev_t dev, |
390 | const char warntype); | 514 | const char warntype); |
391 | #else | 515 | #else |
392 | static inline void quota_send_warning(short type, unsigned int id, dev_t dev, | 516 | static inline void quota_send_warning(struct kqid qid, dev_t dev, |
393 | const char warntype) | 517 | const char warntype) |
394 | { | 518 | { |
395 | return; | 519 | 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); | |||
44 | 44 | ||
45 | void dquot_initialize(struct inode *inode); | 45 | void dquot_initialize(struct inode *inode); |
46 | void dquot_drop(struct inode *inode); | 46 | void dquot_drop(struct inode *inode); |
47 | struct dquot *dqget(struct super_block *sb, unsigned int id, int type); | 47 | struct dquot *dqget(struct super_block *sb, struct kqid qid); |
48 | void dqput(struct dquot *dquot); | 48 | void dqput(struct dquot *dquot); |
49 | int dquot_scan_active(struct super_block *sb, | 49 | int dquot_scan_active(struct super_block *sb, |
50 | int (*fn)(struct dquot *dquot, unsigned long priv), | 50 | int (*fn)(struct dquot *dquot, unsigned long priv), |
@@ -87,9 +87,9 @@ int dquot_writeback_dquots(struct super_block *sb, int type); | |||
87 | int dquot_quota_sync(struct super_block *sb, int type); | 87 | int dquot_quota_sync(struct super_block *sb, int type); |
88 | int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); | 88 | int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); |
89 | int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); | 89 | int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); |
90 | int dquot_get_dqblk(struct super_block *sb, int type, qid_t id, | 90 | int dquot_get_dqblk(struct super_block *sb, struct kqid id, |
91 | struct fs_disk_quota *di); | 91 | struct fs_disk_quota *di); |
92 | int dquot_set_dqblk(struct super_block *sb, int type, qid_t id, | 92 | int dquot_set_dqblk(struct super_block *sb, struct kqid id, |
93 | struct fs_disk_quota *di); | 93 | struct fs_disk_quota *di); |
94 | 94 | ||
95 | int __dquot_transfer(struct inode *inode, struct dquot **transfer_to); | 95 | 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 { | |||
1414 | 1414 | ||
1415 | struct audit_context *audit_context; | 1415 | struct audit_context *audit_context; |
1416 | #ifdef CONFIG_AUDITSYSCALL | 1416 | #ifdef CONFIG_AUDITSYSCALL |
1417 | uid_t loginuid; | 1417 | kuid_t loginuid; |
1418 | unsigned int sessionid; | 1418 | unsigned int sessionid; |
1419 | #endif | 1419 | #endif |
1420 | struct seccomp seccomp; | 1420 | 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 { | |||
1436 | int (*path_rename) (struct path *old_dir, struct dentry *old_dentry, | 1436 | int (*path_rename) (struct path *old_dir, struct dentry *old_dentry, |
1437 | struct path *new_dir, struct dentry *new_dentry); | 1437 | struct path *new_dir, struct dentry *new_dentry); |
1438 | int (*path_chmod) (struct path *path, umode_t mode); | 1438 | int (*path_chmod) (struct path *path, umode_t mode); |
1439 | int (*path_chown) (struct path *path, uid_t uid, gid_t gid); | 1439 | int (*path_chown) (struct path *path, kuid_t uid, kgid_t gid); |
1440 | int (*path_chroot) (struct path *path); | 1440 | int (*path_chroot) (struct path *path); |
1441 | #endif | 1441 | #endif |
1442 | 1442 | ||
@@ -2831,7 +2831,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir, | |||
2831 | int security_path_rename(struct path *old_dir, struct dentry *old_dentry, | 2831 | int security_path_rename(struct path *old_dir, struct dentry *old_dentry, |
2832 | struct path *new_dir, struct dentry *new_dentry); | 2832 | struct path *new_dir, struct dentry *new_dentry); |
2833 | int security_path_chmod(struct path *path, umode_t mode); | 2833 | int security_path_chmod(struct path *path, umode_t mode); |
2834 | int security_path_chown(struct path *path, uid_t uid, gid_t gid); | 2834 | int security_path_chown(struct path *path, kuid_t uid, kgid_t gid); |
2835 | int security_path_chroot(struct path *path); | 2835 | int security_path_chroot(struct path *path); |
2836 | #else /* CONFIG_SECURITY_PATH */ | 2836 | #else /* CONFIG_SECURITY_PATH */ |
2837 | static inline int security_path_unlink(struct path *dir, struct dentry *dentry) | 2837 | 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) | |||
2887 | return 0; | 2887 | return 0; |
2888 | } | 2888 | } |
2889 | 2889 | ||
2890 | static inline int security_path_chown(struct path *path, uid_t uid, gid_t gid) | 2890 | static inline int security_path_chown(struct path *path, kuid_t uid, kgid_t gid) |
2891 | { | 2891 | { |
2892 | return 0; | 2892 | return 0; |
2893 | } | 2893 | } |
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; | |||
13 | struct path; | 13 | struct path; |
14 | struct inode; | 14 | struct inode; |
15 | struct dentry; | 15 | struct dentry; |
16 | struct user_namespace; | ||
16 | 17 | ||
17 | struct seq_file { | 18 | struct seq_file { |
18 | char *buf; | 19 | char *buf; |
@@ -25,6 +26,9 @@ struct seq_file { | |||
25 | struct mutex lock; | 26 | struct mutex lock; |
26 | const struct seq_operations *op; | 27 | const struct seq_operations *op; |
27 | int poll_event; | 28 | int poll_event; |
29 | #ifdef CONFIG_USER_NS | ||
30 | struct user_namespace *user_ns; | ||
31 | #endif | ||
28 | void *private; | 32 | void *private; |
29 | }; | 33 | }; |
30 | 34 | ||
@@ -128,6 +132,16 @@ int seq_put_decimal_ull(struct seq_file *m, char delimiter, | |||
128 | int seq_put_decimal_ll(struct seq_file *m, char delimiter, | 132 | int seq_put_decimal_ll(struct seq_file *m, char delimiter, |
129 | long long num); | 133 | long long num); |
130 | 134 | ||
135 | static inline struct user_namespace *seq_user_ns(struct seq_file *seq) | ||
136 | { | ||
137 | #ifdef CONFIG_USER_NS | ||
138 | return seq->user_ns; | ||
139 | #else | ||
140 | extern struct user_namespace init_user_ns; | ||
141 | return &init_user_ns; | ||
142 | #endif | ||
143 | } | ||
144 | |||
131 | #define SEQ_START_TOKEN ((void *)1) | 145 | #define SEQ_START_TOKEN ((void *)1) |
132 | /* | 146 | /* |
133 | * Helpers for iteration over list_head-s in seq_files | 147 | * 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 @@ | |||
10 | #include <linux/taskstats.h> | 10 | #include <linux/taskstats.h> |
11 | 11 | ||
12 | #ifdef CONFIG_TASKSTATS | 12 | #ifdef CONFIG_TASKSTATS |
13 | extern void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk); | 13 | extern void bacct_add_tsk(struct user_namespace *user_ns, |
14 | struct pid_namespace *pid_ns, | ||
15 | struct taskstats *stats, struct task_struct *tsk); | ||
14 | #else | 16 | #else |
15 | static inline void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) | 17 | static inline void bacct_add_tsk(struct user_namespace *user_ns, |
18 | struct pid_namespace *pid_ns, | ||
19 | struct taskstats *stats, struct task_struct *tsk) | ||
16 | {} | 20 | {} |
17 | #endif /* CONFIG_TASKSTATS */ | 21 | #endif /* CONFIG_TASKSTATS */ |
18 | 22 | ||
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); | |||
575 | extern void tty_audit_tiocsti(struct tty_struct *tty, char ch); | 575 | extern void tty_audit_tiocsti(struct tty_struct *tty, char ch); |
576 | extern void tty_audit_push(struct tty_struct *tty); | 576 | extern void tty_audit_push(struct tty_struct *tty); |
577 | extern int tty_audit_push_task(struct task_struct *tsk, | 577 | extern int tty_audit_push_task(struct task_struct *tsk, |
578 | uid_t loginuid, u32 sessionid); | 578 | kuid_t loginuid, u32 sessionid); |
579 | #else | 579 | #else |
580 | static inline void tty_audit_add_data(struct tty_struct *tty, | 580 | static inline void tty_audit_add_data(struct tty_struct *tty, |
581 | unsigned char *data, size_t size) | 581 | unsigned char *data, size_t size) |
@@ -594,7 +594,7 @@ static inline void tty_audit_push(struct tty_struct *tty) | |||
594 | { | 594 | { |
595 | } | 595 | } |
596 | static inline int tty_audit_push_task(struct task_struct *tsk, | 596 | static inline int tty_audit_push_task(struct task_struct *tsk, |
597 | uid_t loginuid, u32 sessionid) | 597 | kuid_t loginuid, u32 sessionid) |
598 | { | 598 | { |
599 | return 0; | 599 | return 0; |
600 | } | 600 | } |
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 */ | |||
20 | struct user_namespace { | 20 | struct user_namespace { |
21 | struct uid_gid_map uid_map; | 21 | struct uid_gid_map uid_map; |
22 | struct uid_gid_map gid_map; | 22 | struct uid_gid_map gid_map; |
23 | struct uid_gid_map projid_map; | ||
23 | struct kref kref; | 24 | struct kref kref; |
24 | struct user_namespace *parent; | 25 | struct user_namespace *parent; |
25 | kuid_t owner; | 26 | kuid_t owner; |
@@ -49,8 +50,10 @@ static inline void put_user_ns(struct user_namespace *ns) | |||
49 | struct seq_operations; | 50 | struct seq_operations; |
50 | extern struct seq_operations proc_uid_seq_operations; | 51 | extern struct seq_operations proc_uid_seq_operations; |
51 | extern struct seq_operations proc_gid_seq_operations; | 52 | extern struct seq_operations proc_gid_seq_operations; |
53 | extern struct seq_operations proc_projid_seq_operations; | ||
52 | extern ssize_t proc_uid_map_write(struct file *, const char __user *, size_t, loff_t *); | 54 | extern ssize_t proc_uid_map_write(struct file *, const char __user *, size_t, loff_t *); |
53 | extern ssize_t proc_gid_map_write(struct file *, const char __user *, size_t, loff_t *); | 55 | extern ssize_t proc_gid_map_write(struct file *, const char __user *, size_t, loff_t *); |
56 | extern ssize_t proc_projid_map_write(struct file *, const char __user *, size_t, loff_t *); | ||
54 | #else | 57 | #else |
55 | 58 | ||
56 | static inline struct user_namespace *get_user_ns(struct user_namespace *ns) | 59 | static inline struct user_namespace *get_user_ns(struct user_namespace *ns) |
diff --git a/include/net/ax25.h b/include/net/ax25.h index 5d2352154cf6..53539acbd81a 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h | |||
@@ -157,7 +157,7 @@ enum { | |||
157 | typedef struct ax25_uid_assoc { | 157 | typedef struct ax25_uid_assoc { |
158 | struct hlist_node uid_node; | 158 | struct hlist_node uid_node; |
159 | atomic_t refcount; | 159 | atomic_t refcount; |
160 | uid_t uid; | 160 | kuid_t uid; |
161 | ax25_address call; | 161 | ax25_address call; |
162 | } ax25_uid_assoc; | 162 | } ax25_uid_assoc; |
163 | 163 | ||
@@ -434,7 +434,7 @@ extern unsigned long ax25_display_timer(struct timer_list *); | |||
434 | 434 | ||
435 | /* ax25_uid.c */ | 435 | /* ax25_uid.c */ |
436 | extern int ax25_uid_policy; | 436 | extern int ax25_uid_policy; |
437 | extern ax25_uid_assoc *ax25_findbyuid(uid_t); | 437 | extern ax25_uid_assoc *ax25_findbyuid(kuid_t); |
438 | extern int __must_check ax25_uid_ioctl(int, struct sockaddr_ax25 *); | 438 | extern int __must_check ax25_uid_ioctl(int, struct sockaddr_ax25 *); |
439 | extern const struct file_operations ax25_uid_fops; | 439 | extern const struct file_operations ax25_uid_fops; |
440 | extern void ax25_uid_free(void); | 440 | extern void ax25_uid_free(void); |
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 01c34b363a34..c8a202436e01 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h | |||
@@ -222,7 +222,10 @@ struct ip6_flowlabel { | |||
222 | struct ipv6_txoptions *opt; | 222 | struct ipv6_txoptions *opt; |
223 | unsigned long linger; | 223 | unsigned long linger; |
224 | u8 share; | 224 | u8 share; |
225 | u32 owner; | 225 | union { |
226 | struct pid *pid; | ||
227 | kuid_t uid; | ||
228 | } owner; | ||
226 | unsigned long lastuse; | 229 | unsigned long lastuse; |
227 | unsigned long expires; | 230 | unsigned long expires; |
228 | struct net *fl_net; | 231 | struct net *fl_net; |
diff --git a/include/net/netlabel.h b/include/net/netlabel.h index f67440970d7e..2c95d55f7914 100644 --- a/include/net/netlabel.h +++ b/include/net/netlabel.h | |||
@@ -110,7 +110,7 @@ struct cipso_v4_doi; | |||
110 | /* NetLabel audit information */ | 110 | /* NetLabel audit information */ |
111 | struct netlbl_audit { | 111 | struct netlbl_audit { |
112 | u32 secid; | 112 | u32 secid; |
113 | uid_t loginuid; | 113 | kuid_t loginuid; |
114 | u32 sessionid; | 114 | u32 sessionid; |
115 | }; | 115 | }; |
116 | 116 | ||
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index eb24dbccd81e..69e50c789d96 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #ifndef __NETNS_IPV4_H__ | 5 | #ifndef __NETNS_IPV4_H__ |
6 | #define __NETNS_IPV4_H__ | 6 | #define __NETNS_IPV4_H__ |
7 | 7 | ||
8 | #include <linux/uidgid.h> | ||
8 | #include <net/inet_frag.h> | 9 | #include <net/inet_frag.h> |
9 | 10 | ||
10 | struct tcpm_hash_bucket; | 11 | struct tcpm_hash_bucket; |
@@ -62,7 +63,7 @@ struct netns_ipv4 { | |||
62 | int sysctl_icmp_ratemask; | 63 | int sysctl_icmp_ratemask; |
63 | int sysctl_icmp_errors_use_inbound_ifaddr; | 64 | int sysctl_icmp_errors_use_inbound_ifaddr; |
64 | 65 | ||
65 | unsigned int sysctl_ping_group_range[2]; | 66 | kgid_t sysctl_ping_group_range[2]; |
66 | long sysctl_tcp_mem[3]; | 67 | long sysctl_tcp_mem[3]; |
67 | 68 | ||
68 | atomic_t dev_addr_genid; | 69 | atomic_t dev_addr_genid; |
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index d9611e032418..4616f468d599 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h | |||
@@ -188,7 +188,8 @@ struct tcf_proto_ops { | |||
188 | 188 | ||
189 | unsigned long (*get)(struct tcf_proto*, u32 handle); | 189 | unsigned long (*get)(struct tcf_proto*, u32 handle); |
190 | void (*put)(struct tcf_proto*, unsigned long); | 190 | void (*put)(struct tcf_proto*, unsigned long); |
191 | int (*change)(struct tcf_proto*, unsigned long, | 191 | int (*change)(struct sk_buff *, |
192 | struct tcf_proto*, unsigned long, | ||
192 | u32 handle, struct nlattr **, | 193 | u32 handle, struct nlattr **, |
193 | unsigned long *); | 194 | unsigned long *); |
194 | int (*delete)(struct tcf_proto*, unsigned long); | 195 | int (*delete)(struct tcf_proto*, unsigned long); |
diff --git a/include/net/sock.h b/include/net/sock.h index 6e6ec18fb6d0..0d7e9834d9be 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -606,6 +606,15 @@ static inline void sk_add_bind_node(struct sock *sk, | |||
606 | #define sk_for_each_bound(__sk, node, list) \ | 606 | #define sk_for_each_bound(__sk, node, list) \ |
607 | hlist_for_each_entry(__sk, node, list, sk_bind_node) | 607 | hlist_for_each_entry(__sk, node, list, sk_bind_node) |
608 | 608 | ||
609 | static inline struct user_namespace *sk_user_ns(struct sock *sk) | ||
610 | { | ||
611 | /* Careful only use this in a context where these parameters | ||
612 | * can not change and must all be valid, such as recvmsg from | ||
613 | * userspace. | ||
614 | */ | ||
615 | return sk->sk_socket->file->f_cred->user_ns; | ||
616 | } | ||
617 | |||
609 | /* Sock flags */ | 618 | /* Sock flags */ |
610 | enum sock_flags { | 619 | enum sock_flags { |
611 | SOCK_DEAD, | 620 | SOCK_DEAD, |
@@ -1662,7 +1671,7 @@ static inline void sock_graft(struct sock *sk, struct socket *parent) | |||
1662 | write_unlock_bh(&sk->sk_callback_lock); | 1671 | write_unlock_bh(&sk->sk_callback_lock); |
1663 | } | 1672 | } |
1664 | 1673 | ||
1665 | extern int sock_i_uid(struct sock *sk); | 1674 | extern kuid_t sock_i_uid(struct sock *sk); |
1666 | extern unsigned long sock_i_ino(struct sock *sk); | 1675 | extern unsigned long sock_i_ino(struct sock *sk); |
1667 | 1676 | ||
1668 | static inline struct dst_entry * | 1677 | static inline struct dst_entry * |
diff --git a/include/net/tcp.h b/include/net/tcp.h index 1f000ffe7075..9a0021d16d91 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -1510,7 +1510,8 @@ struct tcp_iter_state { | |||
1510 | sa_family_t family; | 1510 | sa_family_t family; |
1511 | enum tcp_seq_states state; | 1511 | enum tcp_seq_states state; |
1512 | struct sock *syn_wait_sk; | 1512 | struct sock *syn_wait_sk; |
1513 | int bucket, offset, sbucket, num, uid; | 1513 | int bucket, offset, sbucket, num; |
1514 | kuid_t uid; | ||
1514 | loff_t last_pos; | 1515 | loff_t last_pos; |
1515 | }; | 1516 | }; |
1516 | 1517 | ||
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 639dd1316d37..411d83c9821d 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -671,7 +671,7 @@ struct xfrm_spi_skb_cb { | |||
671 | /* Audit Information */ | 671 | /* Audit Information */ |
672 | struct xfrm_audit { | 672 | struct xfrm_audit { |
673 | u32 secid; | 673 | u32 secid; |
674 | uid_t loginuid; | 674 | kuid_t loginuid; |
675 | u32 sessionid; | 675 | u32 sessionid; |
676 | }; | 676 | }; |
677 | 677 | ||
@@ -690,13 +690,14 @@ static inline struct audit_buffer *xfrm_audit_start(const char *op) | |||
690 | return audit_buf; | 690 | return audit_buf; |
691 | } | 691 | } |
692 | 692 | ||
693 | static inline void xfrm_audit_helper_usrinfo(uid_t auid, u32 ses, u32 secid, | 693 | static inline void xfrm_audit_helper_usrinfo(kuid_t auid, u32 ses, u32 secid, |
694 | struct audit_buffer *audit_buf) | 694 | struct audit_buffer *audit_buf) |
695 | { | 695 | { |
696 | char *secctx; | 696 | char *secctx; |
697 | u32 secctx_len; | 697 | u32 secctx_len; |
698 | 698 | ||
699 | audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses); | 699 | audit_log_format(audit_buf, " auid=%u ses=%u", |
700 | from_kuid(&init_user_ns, auid), ses); | ||
700 | if (secid != 0 && | 701 | if (secid != 0 && |
701 | security_secid_to_secctx(secid, &secctx, &secctx_len) == 0) { | 702 | security_secid_to_secctx(secid, &secctx, &secctx_len) == 0) { |
702 | audit_log_format(audit_buf, " subj=%s", secctx); | 703 | audit_log_format(audit_buf, " subj=%s", secctx); |
@@ -706,13 +707,13 @@ static inline void xfrm_audit_helper_usrinfo(uid_t auid, u32 ses, u32 secid, | |||
706 | } | 707 | } |
707 | 708 | ||
708 | extern void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, | 709 | extern void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, |
709 | u32 auid, u32 ses, u32 secid); | 710 | kuid_t auid, u32 ses, u32 secid); |
710 | extern void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, | 711 | extern void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, |
711 | u32 auid, u32 ses, u32 secid); | 712 | kuid_t auid, u32 ses, u32 secid); |
712 | extern void xfrm_audit_state_add(struct xfrm_state *x, int result, | 713 | extern void xfrm_audit_state_add(struct xfrm_state *x, int result, |
713 | u32 auid, u32 ses, u32 secid); | 714 | kuid_t auid, u32 ses, u32 secid); |
714 | extern void xfrm_audit_state_delete(struct xfrm_state *x, int result, | 715 | extern void xfrm_audit_state_delete(struct xfrm_state *x, int result, |
715 | u32 auid, u32 ses, u32 secid); | 716 | kuid_t auid, u32 ses, u32 secid); |
716 | extern void xfrm_audit_state_replay_overflow(struct xfrm_state *x, | 717 | extern void xfrm_audit_state_replay_overflow(struct xfrm_state *x, |
717 | struct sk_buff *skb); | 718 | struct sk_buff *skb); |
718 | extern void xfrm_audit_state_replay(struct xfrm_state *x, | 719 | extern void xfrm_audit_state_replay(struct xfrm_state *x, |
@@ -725,22 +726,22 @@ extern void xfrm_audit_state_icvfail(struct xfrm_state *x, | |||
725 | #else | 726 | #else |
726 | 727 | ||
727 | static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, | 728 | static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, |
728 | u32 auid, u32 ses, u32 secid) | 729 | kuid_t auid, u32 ses, u32 secid) |
729 | { | 730 | { |
730 | } | 731 | } |
731 | 732 | ||
732 | static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, | 733 | static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, |
733 | u32 auid, u32 ses, u32 secid) | 734 | kuid_t auid, u32 ses, u32 secid) |
734 | { | 735 | { |
735 | } | 736 | } |
736 | 737 | ||
737 | static inline void xfrm_audit_state_add(struct xfrm_state *x, int result, | 738 | static inline void xfrm_audit_state_add(struct xfrm_state *x, int result, |
738 | u32 auid, u32 ses, u32 secid) | 739 | kuid_t auid, u32 ses, u32 secid) |
739 | { | 740 | { |
740 | } | 741 | } |
741 | 742 | ||
742 | static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result, | 743 | static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result, |
743 | u32 auid, u32 ses, u32 secid) | 744 | kuid_t auid, u32 ses, u32 secid) |
744 | { | 745 | { |
745 | } | 746 | } |
746 | 747 | ||
diff --git a/init/Kconfig b/init/Kconfig index 73e4adfa91dc..cb003a3c9122 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -986,113 +986,24 @@ config UIDGID_CONVERTED | |||
986 | bool | 986 | bool |
987 | default y | 987 | default y |
988 | 988 | ||
989 | # List of kernel pieces that need user namespace work | ||
990 | # Features | ||
991 | depends on SYSVIPC = n | ||
992 | depends on IMA = n | ||
993 | depends on EVM = n | ||
994 | depends on KEYS = n | ||
995 | depends on AUDIT = n | ||
996 | depends on AUDITSYSCALL = n | ||
997 | depends on TASKSTATS = n | ||
998 | depends on TRACING = n | ||
999 | depends on FS_POSIX_ACL = n | ||
1000 | depends on QUOTA = n | ||
1001 | depends on QUOTACTL = n | ||
1002 | depends on DEBUG_CREDENTIALS = n | ||
1003 | depends on BSD_PROCESS_ACCT = n | ||
1004 | depends on DRM = n | ||
1005 | depends on PROC_EVENTS = n | ||
1006 | |||
1007 | # Networking | 989 | # Networking |
1008 | depends on NET = n | ||
1009 | depends on NET_9P = n | 990 | depends on NET_9P = n |
1010 | depends on IPX = n | ||
1011 | depends on PHONET = n | ||
1012 | depends on NET_CLS_FLOW = n | ||
1013 | depends on NETFILTER_XT_MATCH_OWNER = n | ||
1014 | depends on NETFILTER_XT_MATCH_RECENT = n | ||
1015 | depends on NETFILTER_XT_TARGET_LOG = n | ||
1016 | depends on NETFILTER_NETLINK_LOG = n | ||
1017 | depends on INET = n | ||
1018 | depends on IPV6 = n | ||
1019 | depends on IP_SCTP = n | ||
1020 | depends on AF_RXRPC = n | ||
1021 | depends on LLC2 = n | ||
1022 | depends on NET_KEY = n | ||
1023 | depends on INET_DIAG = n | ||
1024 | depends on DNS_RESOLVER = n | ||
1025 | depends on AX25 = n | ||
1026 | depends on ATALK = n | ||
1027 | 991 | ||
1028 | # Filesystems | 992 | # Filesystems |
1029 | depends on USB_DEVICEFS = n | ||
1030 | depends on USB_GADGETFS = n | ||
1031 | depends on USB_FUNCTIONFS = n | ||
1032 | depends on DEVTMPFS = n | ||
1033 | depends on XENFS = n | ||
1034 | |||
1035 | depends on 9P_FS = n | 993 | depends on 9P_FS = n |
1036 | depends on ADFS_FS = n | ||
1037 | depends on AFFS_FS = n | ||
1038 | depends on AFS_FS = n | 994 | depends on AFS_FS = n |
1039 | depends on AUTOFS4_FS = n | 995 | depends on AUTOFS4_FS = n |
1040 | depends on BEFS_FS = n | ||
1041 | depends on BFS_FS = n | ||
1042 | depends on BTRFS_FS = n | ||
1043 | depends on CEPH_FS = n | 996 | depends on CEPH_FS = n |
1044 | depends on CIFS = n | 997 | depends on CIFS = n |
1045 | depends on CODA_FS = n | 998 | depends on CODA_FS = n |
1046 | depends on CONFIGFS_FS = n | ||
1047 | depends on CRAMFS = n | ||
1048 | depends on DEBUG_FS = n | ||
1049 | depends on ECRYPT_FS = n | ||
1050 | depends on EFS_FS = n | ||
1051 | depends on EXOFS_FS = n | ||
1052 | depends on FAT_FS = n | ||
1053 | depends on FUSE_FS = n | 999 | depends on FUSE_FS = n |
1054 | depends on GFS2_FS = n | 1000 | depends on GFS2_FS = n |
1055 | depends on HFS_FS = n | ||
1056 | depends on HFSPLUS_FS = n | ||
1057 | depends on HPFS_FS = n | ||
1058 | depends on HUGETLBFS = n | ||
1059 | depends on ISO9660_FS = n | ||
1060 | depends on JFFS2_FS = n | ||
1061 | depends on JFS_FS = n | ||
1062 | depends on LOGFS = n | ||
1063 | depends on MINIX_FS = n | ||
1064 | depends on NCP_FS = n | 1001 | depends on NCP_FS = n |
1065 | depends on NFSD = n | 1002 | depends on NFSD = n |
1066 | depends on NFS_FS = n | 1003 | depends on NFS_FS = n |
1067 | depends on NILFS2_FS = n | ||
1068 | depends on NTFS_FS = n | ||
1069 | depends on OCFS2_FS = n | 1004 | depends on OCFS2_FS = n |
1070 | depends on OMFS_FS = n | ||
1071 | depends on QNX4FS_FS = n | ||
1072 | depends on QNX6FS_FS = n | ||
1073 | depends on REISERFS_FS = n | ||
1074 | depends on SQUASHFS = n | ||
1075 | depends on SYSV_FS = n | ||
1076 | depends on UBIFS_FS = n | ||
1077 | depends on UDF_FS = n | ||
1078 | depends on UFS_FS = n | ||
1079 | depends on VXFS_FS = n | ||
1080 | depends on XFS_FS = n | 1005 | depends on XFS_FS = n |
1081 | 1006 | ||
1082 | depends on !UML || HOSTFS = n | ||
1083 | |||
1084 | # The rare drivers that won't build | ||
1085 | depends on AIRO = n | ||
1086 | depends on AIRO_CS = n | ||
1087 | depends on TUN = n | ||
1088 | depends on INFINIBAND_QIB = n | ||
1089 | depends on BLK_DEV_LOOP = n | ||
1090 | depends on ANDROID_BINDER_IPC = n | ||
1091 | |||
1092 | # Security modules | ||
1093 | depends on SECURITY_TOMOYO = n | ||
1094 | depends on SECURITY_APPARMOR = n | ||
1095 | |||
1096 | config UIDGID_STRICT_TYPE_CHECKS | 1007 | config UIDGID_STRICT_TYPE_CHECKS |
1097 | bool "Require conversions between uid/gids and their internal representation" | 1008 | bool "Require conversions between uid/gids and their internal representation" |
1098 | depends on UIDGID_CONVERTED | 1009 | depends on UIDGID_CONVERTED |
@@ -443,9 +443,12 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd, | |||
443 | goto out_unlock; | 443 | goto out_unlock; |
444 | } | 444 | } |
445 | 445 | ||
446 | err = ipc_update_perm(&msqid64.msg_perm, ipcp); | ||
447 | if (err) | ||
448 | goto out_unlock; | ||
449 | |||
446 | msq->q_qbytes = msqid64.msg_qbytes; | 450 | msq->q_qbytes = msqid64.msg_qbytes; |
447 | 451 | ||
448 | ipc_update_perm(&msqid64.msg_perm, ipcp); | ||
449 | msq->q_ctime = get_seconds(); | 452 | msq->q_ctime = get_seconds(); |
450 | /* sleeping receivers might be excluded by | 453 | /* sleeping receivers might be excluded by |
451 | * stricter permissions. | 454 | * stricter permissions. |
@@ -922,6 +925,7 @@ out: | |||
922 | #ifdef CONFIG_PROC_FS | 925 | #ifdef CONFIG_PROC_FS |
923 | static int sysvipc_msg_proc_show(struct seq_file *s, void *it) | 926 | static int sysvipc_msg_proc_show(struct seq_file *s, void *it) |
924 | { | 927 | { |
928 | struct user_namespace *user_ns = seq_user_ns(s); | ||
925 | struct msg_queue *msq = it; | 929 | struct msg_queue *msq = it; |
926 | 930 | ||
927 | return seq_printf(s, | 931 | return seq_printf(s, |
@@ -933,10 +937,10 @@ static int sysvipc_msg_proc_show(struct seq_file *s, void *it) | |||
933 | msq->q_qnum, | 937 | msq->q_qnum, |
934 | msq->q_lspid, | 938 | msq->q_lspid, |
935 | msq->q_lrpid, | 939 | msq->q_lrpid, |
936 | msq->q_perm.uid, | 940 | from_kuid_munged(user_ns, msq->q_perm.uid), |
937 | msq->q_perm.gid, | 941 | from_kgid_munged(user_ns, msq->q_perm.gid), |
938 | msq->q_perm.cuid, | 942 | from_kuid_munged(user_ns, msq->q_perm.cuid), |
939 | msq->q_perm.cgid, | 943 | from_kgid_munged(user_ns, msq->q_perm.cgid), |
940 | msq->q_stime, | 944 | msq->q_stime, |
941 | msq->q_rtime, | 945 | msq->q_rtime, |
942 | msq->q_ctime); | 946 | msq->q_ctime); |
@@ -1104,7 +1104,9 @@ static int semctl_down(struct ipc_namespace *ns, int semid, | |||
1104 | freeary(ns, ipcp); | 1104 | freeary(ns, ipcp); |
1105 | goto out_up; | 1105 | goto out_up; |
1106 | case IPC_SET: | 1106 | case IPC_SET: |
1107 | ipc_update_perm(&semid64.sem_perm, ipcp); | 1107 | err = ipc_update_perm(&semid64.sem_perm, ipcp); |
1108 | if (err) | ||
1109 | goto out_unlock; | ||
1108 | sma->sem_ctime = get_seconds(); | 1110 | sma->sem_ctime = get_seconds(); |
1109 | break; | 1111 | break; |
1110 | default: | 1112 | default: |
@@ -1677,6 +1679,7 @@ void exit_sem(struct task_struct *tsk) | |||
1677 | #ifdef CONFIG_PROC_FS | 1679 | #ifdef CONFIG_PROC_FS |
1678 | static int sysvipc_sem_proc_show(struct seq_file *s, void *it) | 1680 | static int sysvipc_sem_proc_show(struct seq_file *s, void *it) |
1679 | { | 1681 | { |
1682 | struct user_namespace *user_ns = seq_user_ns(s); | ||
1680 | struct sem_array *sma = it; | 1683 | struct sem_array *sma = it; |
1681 | 1684 | ||
1682 | return seq_printf(s, | 1685 | return seq_printf(s, |
@@ -1685,10 +1688,10 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it) | |||
1685 | sma->sem_perm.id, | 1688 | sma->sem_perm.id, |
1686 | sma->sem_perm.mode, | 1689 | sma->sem_perm.mode, |
1687 | sma->sem_nsems, | 1690 | sma->sem_nsems, |
1688 | sma->sem_perm.uid, | 1691 | from_kuid_munged(user_ns, sma->sem_perm.uid), |
1689 | sma->sem_perm.gid, | 1692 | from_kgid_munged(user_ns, sma->sem_perm.gid), |
1690 | sma->sem_perm.cuid, | 1693 | from_kuid_munged(user_ns, sma->sem_perm.cuid), |
1691 | sma->sem_perm.cgid, | 1694 | from_kgid_munged(user_ns, sma->sem_perm.cgid), |
1692 | sma->sem_otime, | 1695 | sma->sem_otime, |
1693 | sma->sem_ctime); | 1696 | sma->sem_ctime); |
1694 | } | 1697 | } |
@@ -758,7 +758,9 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd, | |||
758 | do_shm_rmid(ns, ipcp); | 758 | do_shm_rmid(ns, ipcp); |
759 | goto out_up; | 759 | goto out_up; |
760 | case IPC_SET: | 760 | case IPC_SET: |
761 | ipc_update_perm(&shmid64.shm_perm, ipcp); | 761 | err = ipc_update_perm(&shmid64.shm_perm, ipcp); |
762 | if (err) | ||
763 | goto out_unlock; | ||
762 | shp->shm_ctim = get_seconds(); | 764 | shp->shm_ctim = get_seconds(); |
763 | break; | 765 | break; |
764 | default: | 766 | default: |
@@ -893,10 +895,10 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) | |||
893 | audit_ipc_obj(&(shp->shm_perm)); | 895 | audit_ipc_obj(&(shp->shm_perm)); |
894 | 896 | ||
895 | if (!ns_capable(ns->user_ns, CAP_IPC_LOCK)) { | 897 | if (!ns_capable(ns->user_ns, CAP_IPC_LOCK)) { |
896 | uid_t euid = current_euid(); | 898 | kuid_t euid = current_euid(); |
897 | err = -EPERM; | 899 | err = -EPERM; |
898 | if (euid != shp->shm_perm.uid && | 900 | if (!uid_eq(euid, shp->shm_perm.uid) && |
899 | euid != shp->shm_perm.cuid) | 901 | !uid_eq(euid, shp->shm_perm.cuid)) |
900 | goto out_unlock; | 902 | goto out_unlock; |
901 | if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK)) | 903 | if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK)) |
902 | goto out_unlock; | 904 | goto out_unlock; |
@@ -1220,6 +1222,7 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) | |||
1220 | #ifdef CONFIG_PROC_FS | 1222 | #ifdef CONFIG_PROC_FS |
1221 | static int sysvipc_shm_proc_show(struct seq_file *s, void *it) | 1223 | static int sysvipc_shm_proc_show(struct seq_file *s, void *it) |
1222 | { | 1224 | { |
1225 | struct user_namespace *user_ns = seq_user_ns(s); | ||
1223 | struct shmid_kernel *shp = it; | 1226 | struct shmid_kernel *shp = it; |
1224 | unsigned long rss = 0, swp = 0; | 1227 | unsigned long rss = 0, swp = 0; |
1225 | 1228 | ||
@@ -1242,10 +1245,10 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it) | |||
1242 | shp->shm_cprid, | 1245 | shp->shm_cprid, |
1243 | shp->shm_lprid, | 1246 | shp->shm_lprid, |
1244 | shp->shm_nattch, | 1247 | shp->shm_nattch, |
1245 | shp->shm_perm.uid, | 1248 | from_kuid_munged(user_ns, shp->shm_perm.uid), |
1246 | shp->shm_perm.gid, | 1249 | from_kgid_munged(user_ns, shp->shm_perm.gid), |
1247 | shp->shm_perm.cuid, | 1250 | from_kuid_munged(user_ns, shp->shm_perm.cuid), |
1248 | shp->shm_perm.cgid, | 1251 | from_kgid_munged(user_ns, shp->shm_perm.cgid), |
1249 | shp->shm_atim, | 1252 | shp->shm_atim, |
1250 | shp->shm_dtim, | 1253 | shp->shm_dtim, |
1251 | shp->shm_ctim, | 1254 | shp->shm_ctim, |
diff --git a/ipc/util.c b/ipc/util.c index eb07fd356f27..72fd0785ac94 100644 --- a/ipc/util.c +++ b/ipc/util.c | |||
@@ -249,8 +249,8 @@ int ipc_get_maxid(struct ipc_ids *ids) | |||
249 | 249 | ||
250 | int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) | 250 | int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) |
251 | { | 251 | { |
252 | uid_t euid; | 252 | kuid_t euid; |
253 | gid_t egid; | 253 | kgid_t egid; |
254 | int id, err; | 254 | int id, err; |
255 | 255 | ||
256 | if (size > IPCMNI) | 256 | if (size > IPCMNI) |
@@ -606,14 +606,14 @@ void ipc_rcu_putref(void *ptr) | |||
606 | 606 | ||
607 | int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flag) | 607 | int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flag) |
608 | { | 608 | { |
609 | uid_t euid = current_euid(); | 609 | kuid_t euid = current_euid(); |
610 | int requested_mode, granted_mode; | 610 | int requested_mode, granted_mode; |
611 | 611 | ||
612 | audit_ipc_obj(ipcp); | 612 | audit_ipc_obj(ipcp); |
613 | requested_mode = (flag >> 6) | (flag >> 3) | flag; | 613 | requested_mode = (flag >> 6) | (flag >> 3) | flag; |
614 | granted_mode = ipcp->mode; | 614 | granted_mode = ipcp->mode; |
615 | if (euid == ipcp->cuid || | 615 | if (uid_eq(euid, ipcp->cuid) || |
616 | euid == ipcp->uid) | 616 | uid_eq(euid, ipcp->uid)) |
617 | granted_mode >>= 6; | 617 | granted_mode >>= 6; |
618 | else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid)) | 618 | else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid)) |
619 | granted_mode >>= 3; | 619 | granted_mode >>= 3; |
@@ -643,10 +643,10 @@ int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flag) | |||
643 | void kernel_to_ipc64_perm (struct kern_ipc_perm *in, struct ipc64_perm *out) | 643 | void kernel_to_ipc64_perm (struct kern_ipc_perm *in, struct ipc64_perm *out) |
644 | { | 644 | { |
645 | out->key = in->key; | 645 | out->key = in->key; |
646 | out->uid = in->uid; | 646 | out->uid = from_kuid_munged(current_user_ns(), in->uid); |
647 | out->gid = in->gid; | 647 | out->gid = from_kgid_munged(current_user_ns(), in->gid); |
648 | out->cuid = in->cuid; | 648 | out->cuid = from_kuid_munged(current_user_ns(), in->cuid); |
649 | out->cgid = in->cgid; | 649 | out->cgid = from_kgid_munged(current_user_ns(), in->cgid); |
650 | out->mode = in->mode; | 650 | out->mode = in->mode; |
651 | out->seq = in->seq; | 651 | out->seq = in->seq; |
652 | } | 652 | } |
@@ -747,12 +747,19 @@ int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, | |||
747 | * @in: the permission given as input. | 747 | * @in: the permission given as input. |
748 | * @out: the permission of the ipc to set. | 748 | * @out: the permission of the ipc to set. |
749 | */ | 749 | */ |
750 | void ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out) | 750 | int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out) |
751 | { | 751 | { |
752 | out->uid = in->uid; | 752 | kuid_t uid = make_kuid(current_user_ns(), in->uid); |
753 | out->gid = in->gid; | 753 | kgid_t gid = make_kgid(current_user_ns(), in->gid); |
754 | if (!uid_valid(uid) || !gid_valid(gid)) | ||
755 | return -EINVAL; | ||
756 | |||
757 | out->uid = uid; | ||
758 | out->gid = gid; | ||
754 | out->mode = (out->mode & ~S_IRWXUGO) | 759 | out->mode = (out->mode & ~S_IRWXUGO) |
755 | | (in->mode & S_IRWXUGO); | 760 | | (in->mode & S_IRWXUGO); |
761 | |||
762 | return 0; | ||
756 | } | 763 | } |
757 | 764 | ||
758 | /** | 765 | /** |
@@ -777,7 +784,7 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns, | |||
777 | struct ipc64_perm *perm, int extra_perm) | 784 | struct ipc64_perm *perm, int extra_perm) |
778 | { | 785 | { |
779 | struct kern_ipc_perm *ipcp; | 786 | struct kern_ipc_perm *ipcp; |
780 | uid_t euid; | 787 | kuid_t euid; |
781 | int err; | 788 | int err; |
782 | 789 | ||
783 | down_write(&ids->rw_mutex); | 790 | down_write(&ids->rw_mutex); |
@@ -793,7 +800,7 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns, | |||
793 | perm->gid, perm->mode); | 800 | perm->gid, perm->mode); |
794 | 801 | ||
795 | euid = current_euid(); | 802 | euid = current_euid(); |
796 | if (euid == ipcp->cuid || euid == ipcp->uid || | 803 | if (uid_eq(euid, ipcp->cuid) || uid_eq(euid, ipcp->uid) || |
797 | ns_capable(ns->user_ns, CAP_SYS_ADMIN)) | 804 | ns_capable(ns->user_ns, CAP_SYS_ADMIN)) |
798 | return ipcp; | 805 | return ipcp; |
799 | 806 | ||
diff --git a/ipc/util.h b/ipc/util.h index 850ef3e962cb..c8fe2f7631e9 100644 --- a/ipc/util.h +++ b/ipc/util.h | |||
@@ -125,7 +125,7 @@ struct kern_ipc_perm *ipc_lock(struct ipc_ids *, int); | |||
125 | 125 | ||
126 | void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out); | 126 | void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out); |
127 | void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out); | 127 | void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out); |
128 | void ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out); | 128 | int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out); |
129 | struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns, | 129 | struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns, |
130 | struct ipc_ids *ids, int id, int cmd, | 130 | struct ipc_ids *ids, int id, int cmd, |
131 | struct ipc64_perm *perm, int extra_perm); | 131 | struct ipc64_perm *perm, int extra_perm); |
diff --git a/kernel/acct.c b/kernel/acct.c index 02e6167a53b0..6cd7529c9e6a 100644 --- a/kernel/acct.c +++ b/kernel/acct.c | |||
@@ -507,8 +507,8 @@ static void do_acct_process(struct bsd_acct_struct *acct, | |||
507 | do_div(elapsed, AHZ); | 507 | do_div(elapsed, AHZ); |
508 | ac.ac_btime = get_seconds() - elapsed; | 508 | ac.ac_btime = get_seconds() - elapsed; |
509 | /* we really need to bite the bullet and change layout */ | 509 | /* we really need to bite the bullet and change layout */ |
510 | ac.ac_uid = orig_cred->uid; | 510 | ac.ac_uid = from_kuid_munged(file->f_cred->user_ns, orig_cred->uid); |
511 | ac.ac_gid = orig_cred->gid; | 511 | ac.ac_gid = from_kgid_munged(file->f_cred->user_ns, orig_cred->gid); |
512 | #if ACCT_VERSION==2 | 512 | #if ACCT_VERSION==2 |
513 | ac.ac_ahz = AHZ; | 513 | ac.ac_ahz = AHZ; |
514 | #endif | 514 | #endif |
diff --git a/kernel/audit.c b/kernel/audit.c index ea3b7b6191c7..511488a7bc71 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -61,6 +61,7 @@ | |||
61 | #include <linux/netlink.h> | 61 | #include <linux/netlink.h> |
62 | #include <linux/freezer.h> | 62 | #include <linux/freezer.h> |
63 | #include <linux/tty.h> | 63 | #include <linux/tty.h> |
64 | #include <linux/pid_namespace.h> | ||
64 | 65 | ||
65 | #include "audit.h" | 66 | #include "audit.h" |
66 | 67 | ||
@@ -104,7 +105,7 @@ static int audit_backlog_wait_time = 60 * HZ; | |||
104 | static int audit_backlog_wait_overflow = 0; | 105 | static int audit_backlog_wait_overflow = 0; |
105 | 106 | ||
106 | /* The identity of the user shutting down the audit system. */ | 107 | /* The identity of the user shutting down the audit system. */ |
107 | uid_t audit_sig_uid = -1; | 108 | kuid_t audit_sig_uid = INVALID_UID; |
108 | pid_t audit_sig_pid = -1; | 109 | pid_t audit_sig_pid = -1; |
109 | u32 audit_sig_sid = 0; | 110 | u32 audit_sig_sid = 0; |
110 | 111 | ||
@@ -264,7 +265,7 @@ void audit_log_lost(const char *message) | |||
264 | } | 265 | } |
265 | 266 | ||
266 | static int audit_log_config_change(char *function_name, int new, int old, | 267 | static int audit_log_config_change(char *function_name, int new, int old, |
267 | uid_t loginuid, u32 sessionid, u32 sid, | 268 | kuid_t loginuid, u32 sessionid, u32 sid, |
268 | int allow_changes) | 269 | int allow_changes) |
269 | { | 270 | { |
270 | struct audit_buffer *ab; | 271 | struct audit_buffer *ab; |
@@ -272,7 +273,7 @@ static int audit_log_config_change(char *function_name, int new, int old, | |||
272 | 273 | ||
273 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 274 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
274 | audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new, | 275 | audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new, |
275 | old, loginuid, sessionid); | 276 | old, from_kuid(&init_user_ns, loginuid), sessionid); |
276 | if (sid) { | 277 | if (sid) { |
277 | char *ctx = NULL; | 278 | char *ctx = NULL; |
278 | u32 len; | 279 | u32 len; |
@@ -292,7 +293,7 @@ static int audit_log_config_change(char *function_name, int new, int old, | |||
292 | } | 293 | } |
293 | 294 | ||
294 | static int audit_do_config_change(char *function_name, int *to_change, | 295 | static int audit_do_config_change(char *function_name, int *to_change, |
295 | int new, uid_t loginuid, u32 sessionid, | 296 | int new, kuid_t loginuid, u32 sessionid, |
296 | u32 sid) | 297 | u32 sid) |
297 | { | 298 | { |
298 | int allow_changes, rc = 0, old = *to_change; | 299 | int allow_changes, rc = 0, old = *to_change; |
@@ -319,21 +320,21 @@ static int audit_do_config_change(char *function_name, int *to_change, | |||
319 | return rc; | 320 | return rc; |
320 | } | 321 | } |
321 | 322 | ||
322 | static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sessionid, | 323 | static int audit_set_rate_limit(int limit, kuid_t loginuid, u32 sessionid, |
323 | u32 sid) | 324 | u32 sid) |
324 | { | 325 | { |
325 | return audit_do_config_change("audit_rate_limit", &audit_rate_limit, | 326 | return audit_do_config_change("audit_rate_limit", &audit_rate_limit, |
326 | limit, loginuid, sessionid, sid); | 327 | limit, loginuid, sessionid, sid); |
327 | } | 328 | } |
328 | 329 | ||
329 | static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sessionid, | 330 | static int audit_set_backlog_limit(int limit, kuid_t loginuid, u32 sessionid, |
330 | u32 sid) | 331 | u32 sid) |
331 | { | 332 | { |
332 | return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, | 333 | return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, |
333 | limit, loginuid, sessionid, sid); | 334 | limit, loginuid, sessionid, sid); |
334 | } | 335 | } |
335 | 336 | ||
336 | static int audit_set_enabled(int state, uid_t loginuid, u32 sessionid, u32 sid) | 337 | static int audit_set_enabled(int state, kuid_t loginuid, u32 sessionid, u32 sid) |
337 | { | 338 | { |
338 | int rc; | 339 | int rc; |
339 | if (state < AUDIT_OFF || state > AUDIT_LOCKED) | 340 | if (state < AUDIT_OFF || state > AUDIT_LOCKED) |
@@ -348,7 +349,7 @@ static int audit_set_enabled(int state, uid_t loginuid, u32 sessionid, u32 sid) | |||
348 | return rc; | 349 | return rc; |
349 | } | 350 | } |
350 | 351 | ||
351 | static int audit_set_failure(int state, uid_t loginuid, u32 sessionid, u32 sid) | 352 | static int audit_set_failure(int state, kuid_t loginuid, u32 sessionid, u32 sid) |
352 | { | 353 | { |
353 | if (state != AUDIT_FAIL_SILENT | 354 | if (state != AUDIT_FAIL_SILENT |
354 | && state != AUDIT_FAIL_PRINTK | 355 | && state != AUDIT_FAIL_PRINTK |
@@ -467,24 +468,6 @@ static int kauditd_thread(void *dummy) | |||
467 | return 0; | 468 | return 0; |
468 | } | 469 | } |
469 | 470 | ||
470 | static int audit_prepare_user_tty(pid_t pid, uid_t loginuid, u32 sessionid) | ||
471 | { | ||
472 | struct task_struct *tsk; | ||
473 | int err; | ||
474 | |||
475 | rcu_read_lock(); | ||
476 | tsk = find_task_by_vpid(pid); | ||
477 | if (!tsk) { | ||
478 | rcu_read_unlock(); | ||
479 | return -ESRCH; | ||
480 | } | ||
481 | get_task_struct(tsk); | ||
482 | rcu_read_unlock(); | ||
483 | err = tty_audit_push_task(tsk, loginuid, sessionid); | ||
484 | put_task_struct(tsk); | ||
485 | return err; | ||
486 | } | ||
487 | |||
488 | int audit_send_list(void *_dest) | 471 | int audit_send_list(void *_dest) |
489 | { | 472 | { |
490 | struct audit_netlink_list *dest = _dest; | 473 | struct audit_netlink_list *dest = _dest; |
@@ -588,6 +571,11 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type) | |||
588 | { | 571 | { |
589 | int err = 0; | 572 | int err = 0; |
590 | 573 | ||
574 | /* Only support the initial namespaces for now. */ | ||
575 | if ((current_user_ns() != &init_user_ns) || | ||
576 | (task_active_pid_ns(current) != &init_pid_ns)) | ||
577 | return -EPERM; | ||
578 | |||
591 | switch (msg_type) { | 579 | switch (msg_type) { |
592 | case AUDIT_GET: | 580 | case AUDIT_GET: |
593 | case AUDIT_LIST: | 581 | case AUDIT_LIST: |
@@ -619,8 +607,7 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type) | |||
619 | } | 607 | } |
620 | 608 | ||
621 | static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, | 609 | static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, |
622 | u32 pid, u32 uid, uid_t auid, u32 ses, | 610 | kuid_t auid, u32 ses, u32 sid) |
623 | u32 sid) | ||
624 | { | 611 | { |
625 | int rc = 0; | 612 | int rc = 0; |
626 | char *ctx = NULL; | 613 | char *ctx = NULL; |
@@ -633,7 +620,9 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, | |||
633 | 620 | ||
634 | *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); | 621 | *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); |
635 | audit_log_format(*ab, "pid=%d uid=%u auid=%u ses=%u", | 622 | audit_log_format(*ab, "pid=%d uid=%u auid=%u ses=%u", |
636 | pid, uid, auid, ses); | 623 | task_tgid_vnr(current), |
624 | from_kuid(&init_user_ns, current_uid()), | ||
625 | from_kuid(&init_user_ns, auid), ses); | ||
637 | if (sid) { | 626 | if (sid) { |
638 | rc = security_secid_to_secctx(sid, &ctx, &len); | 627 | rc = security_secid_to_secctx(sid, &ctx, &len); |
639 | if (rc) | 628 | if (rc) |
@@ -649,13 +638,13 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, | |||
649 | 638 | ||
650 | static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | 639 | static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
651 | { | 640 | { |
652 | u32 uid, pid, seq, sid; | 641 | u32 seq, sid; |
653 | void *data; | 642 | void *data; |
654 | struct audit_status *status_get, status_set; | 643 | struct audit_status *status_get, status_set; |
655 | int err; | 644 | int err; |
656 | struct audit_buffer *ab; | 645 | struct audit_buffer *ab; |
657 | u16 msg_type = nlh->nlmsg_type; | 646 | u16 msg_type = nlh->nlmsg_type; |
658 | uid_t loginuid; /* loginuid of sender */ | 647 | kuid_t loginuid; /* loginuid of sender */ |
659 | u32 sessionid; | 648 | u32 sessionid; |
660 | struct audit_sig_info *sig_data; | 649 | struct audit_sig_info *sig_data; |
661 | char *ctx = NULL; | 650 | char *ctx = NULL; |
@@ -675,8 +664,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
675 | return err; | 664 | return err; |
676 | } | 665 | } |
677 | 666 | ||
678 | pid = NETLINK_CREDS(skb)->pid; | ||
679 | uid = NETLINK_CREDS(skb)->uid; | ||
680 | loginuid = audit_get_loginuid(current); | 667 | loginuid = audit_get_loginuid(current); |
681 | sessionid = audit_get_sessionid(current); | 668 | sessionid = audit_get_sessionid(current); |
682 | security_task_getsecid(current, &sid); | 669 | security_task_getsecid(current, &sid); |
@@ -738,16 +725,16 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
738 | if (!audit_enabled && msg_type != AUDIT_USER_AVC) | 725 | if (!audit_enabled && msg_type != AUDIT_USER_AVC) |
739 | return 0; | 726 | return 0; |
740 | 727 | ||
741 | err = audit_filter_user(&NETLINK_CB(skb)); | 728 | err = audit_filter_user(); |
742 | if (err == 1) { | 729 | if (err == 1) { |
743 | err = 0; | 730 | err = 0; |
744 | if (msg_type == AUDIT_USER_TTY) { | 731 | if (msg_type == AUDIT_USER_TTY) { |
745 | err = audit_prepare_user_tty(pid, loginuid, | 732 | err = tty_audit_push_task(current, loginuid, |
746 | sessionid); | 733 | sessionid); |
747 | if (err) | 734 | if (err) |
748 | break; | 735 | break; |
749 | } | 736 | } |
750 | audit_log_common_recv_msg(&ab, msg_type, pid, uid, | 737 | audit_log_common_recv_msg(&ab, msg_type, |
751 | loginuid, sessionid, sid); | 738 | loginuid, sessionid, sid); |
752 | 739 | ||
753 | if (msg_type != AUDIT_USER_TTY) | 740 | if (msg_type != AUDIT_USER_TTY) |
@@ -763,7 +750,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
763 | size--; | 750 | size--; |
764 | audit_log_n_untrustedstring(ab, data, size); | 751 | audit_log_n_untrustedstring(ab, data, size); |
765 | } | 752 | } |
766 | audit_set_pid(ab, pid); | 753 | audit_set_pid(ab, NETLINK_CB(skb).pid); |
767 | audit_log_end(ab); | 754 | audit_log_end(ab); |
768 | } | 755 | } |
769 | break; | 756 | break; |
@@ -772,8 +759,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
772 | if (nlmsg_len(nlh) < sizeof(struct audit_rule)) | 759 | if (nlmsg_len(nlh) < sizeof(struct audit_rule)) |
773 | return -EINVAL; | 760 | return -EINVAL; |
774 | if (audit_enabled == AUDIT_LOCKED) { | 761 | if (audit_enabled == AUDIT_LOCKED) { |
775 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 762 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, |
776 | uid, loginuid, sessionid, sid); | 763 | loginuid, sessionid, sid); |
777 | 764 | ||
778 | audit_log_format(ab, " audit_enabled=%d res=0", | 765 | audit_log_format(ab, " audit_enabled=%d res=0", |
779 | audit_enabled); | 766 | audit_enabled); |
@@ -783,7 +770,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
783 | /* fallthrough */ | 770 | /* fallthrough */ |
784 | case AUDIT_LIST: | 771 | case AUDIT_LIST: |
785 | err = audit_receive_filter(msg_type, NETLINK_CB(skb).pid, | 772 | err = audit_receive_filter(msg_type, NETLINK_CB(skb).pid, |
786 | uid, seq, data, nlmsg_len(nlh), | 773 | seq, data, nlmsg_len(nlh), |
787 | loginuid, sessionid, sid); | 774 | loginuid, sessionid, sid); |
788 | break; | 775 | break; |
789 | case AUDIT_ADD_RULE: | 776 | case AUDIT_ADD_RULE: |
@@ -791,8 +778,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
791 | if (nlmsg_len(nlh) < sizeof(struct audit_rule_data)) | 778 | if (nlmsg_len(nlh) < sizeof(struct audit_rule_data)) |
792 | return -EINVAL; | 779 | return -EINVAL; |
793 | if (audit_enabled == AUDIT_LOCKED) { | 780 | if (audit_enabled == AUDIT_LOCKED) { |
794 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 781 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, |
795 | uid, loginuid, sessionid, sid); | 782 | loginuid, sessionid, sid); |
796 | 783 | ||
797 | audit_log_format(ab, " audit_enabled=%d res=0", | 784 | audit_log_format(ab, " audit_enabled=%d res=0", |
798 | audit_enabled); | 785 | audit_enabled); |
@@ -802,14 +789,14 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
802 | /* fallthrough */ | 789 | /* fallthrough */ |
803 | case AUDIT_LIST_RULES: | 790 | case AUDIT_LIST_RULES: |
804 | err = audit_receive_filter(msg_type, NETLINK_CB(skb).pid, | 791 | err = audit_receive_filter(msg_type, NETLINK_CB(skb).pid, |
805 | uid, seq, data, nlmsg_len(nlh), | 792 | seq, data, nlmsg_len(nlh), |
806 | loginuid, sessionid, sid); | 793 | loginuid, sessionid, sid); |
807 | break; | 794 | break; |
808 | case AUDIT_TRIM: | 795 | case AUDIT_TRIM: |
809 | audit_trim_trees(); | 796 | audit_trim_trees(); |
810 | 797 | ||
811 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 798 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, |
812 | uid, loginuid, sessionid, sid); | 799 | loginuid, sessionid, sid); |
813 | 800 | ||
814 | audit_log_format(ab, " op=trim res=1"); | 801 | audit_log_format(ab, " op=trim res=1"); |
815 | audit_log_end(ab); | 802 | audit_log_end(ab); |
@@ -840,8 +827,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
840 | /* OK, here comes... */ | 827 | /* OK, here comes... */ |
841 | err = audit_tag_tree(old, new); | 828 | err = audit_tag_tree(old, new); |
842 | 829 | ||
843 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, pid, | 830 | audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, |
844 | uid, loginuid, sessionid, sid); | 831 | loginuid, sessionid, sid); |
845 | 832 | ||
846 | audit_log_format(ab, " op=make_equiv old="); | 833 | audit_log_format(ab, " op=make_equiv old="); |
847 | audit_log_untrustedstring(ab, old); | 834 | audit_log_untrustedstring(ab, old); |
@@ -866,7 +853,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
866 | security_release_secctx(ctx, len); | 853 | security_release_secctx(ctx, len); |
867 | return -ENOMEM; | 854 | return -ENOMEM; |
868 | } | 855 | } |
869 | sig_data->uid = audit_sig_uid; | 856 | sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid); |
870 | sig_data->pid = audit_sig_pid; | 857 | sig_data->pid = audit_sig_pid; |
871 | if (audit_sig_sid) { | 858 | if (audit_sig_sid) { |
872 | memcpy(sig_data->ctx, ctx, len); | 859 | memcpy(sig_data->ctx, ctx, len); |
@@ -878,41 +865,29 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
878 | break; | 865 | break; |
879 | case AUDIT_TTY_GET: { | 866 | case AUDIT_TTY_GET: { |
880 | struct audit_tty_status s; | 867 | struct audit_tty_status s; |
881 | struct task_struct *tsk; | 868 | struct task_struct *tsk = current; |
882 | unsigned long flags; | 869 | |
883 | 870 | spin_lock_irq(&tsk->sighand->siglock); | |
884 | rcu_read_lock(); | 871 | s.enabled = tsk->signal->audit_tty != 0; |
885 | tsk = find_task_by_vpid(pid); | 872 | spin_unlock_irq(&tsk->sighand->siglock); |
886 | if (tsk && lock_task_sighand(tsk, &flags)) { | 873 | |
887 | s.enabled = tsk->signal->audit_tty != 0; | 874 | audit_send_reply(NETLINK_CB(skb).pid, seq, |
888 | unlock_task_sighand(tsk, &flags); | 875 | AUDIT_TTY_GET, 0, 0, &s, sizeof(s)); |
889 | } else | ||
890 | err = -ESRCH; | ||
891 | rcu_read_unlock(); | ||
892 | |||
893 | if (!err) | ||
894 | audit_send_reply(NETLINK_CB(skb).pid, seq, | ||
895 | AUDIT_TTY_GET, 0, 0, &s, sizeof(s)); | ||
896 | break; | 876 | break; |
897 | } | 877 | } |
898 | case AUDIT_TTY_SET: { | 878 | case AUDIT_TTY_SET: { |
899 | struct audit_tty_status *s; | 879 | struct audit_tty_status *s; |
900 | struct task_struct *tsk; | 880 | struct task_struct *tsk = current; |
901 | unsigned long flags; | ||
902 | 881 | ||
903 | if (nlh->nlmsg_len < sizeof(struct audit_tty_status)) | 882 | if (nlh->nlmsg_len < sizeof(struct audit_tty_status)) |
904 | return -EINVAL; | 883 | return -EINVAL; |
905 | s = data; | 884 | s = data; |
906 | if (s->enabled != 0 && s->enabled != 1) | 885 | if (s->enabled != 0 && s->enabled != 1) |
907 | return -EINVAL; | 886 | return -EINVAL; |
908 | rcu_read_lock(); | 887 | |
909 | tsk = find_task_by_vpid(pid); | 888 | spin_lock_irq(&tsk->sighand->siglock); |
910 | if (tsk && lock_task_sighand(tsk, &flags)) { | 889 | tsk->signal->audit_tty = s->enabled != 0; |
911 | tsk->signal->audit_tty = s->enabled != 0; | 890 | spin_unlock_irq(&tsk->sighand->siglock); |
912 | unlock_task_sighand(tsk, &flags); | ||
913 | } else | ||
914 | err = -ESRCH; | ||
915 | rcu_read_unlock(); | ||
916 | break; | 891 | break; |
917 | } | 892 | } |
918 | default: | 893 | default: |
diff --git a/kernel/audit.h b/kernel/audit.h index 816766803371..9eb3d79482b6 100644 --- a/kernel/audit.h +++ b/kernel/audit.h | |||
@@ -76,6 +76,8 @@ static inline int audit_hash_ino(u32 ino) | |||
76 | 76 | ||
77 | extern int audit_match_class(int class, unsigned syscall); | 77 | extern int audit_match_class(int class, unsigned syscall); |
78 | extern int audit_comparator(const u32 left, const u32 op, const u32 right); | 78 | extern int audit_comparator(const u32 left, const u32 op, const u32 right); |
79 | extern int audit_uid_comparator(kuid_t left, u32 op, kuid_t right); | ||
80 | extern int audit_gid_comparator(kgid_t left, u32 op, kgid_t right); | ||
79 | extern int audit_compare_dname_path(const char *dname, const char *path, | 81 | extern int audit_compare_dname_path(const char *dname, const char *path, |
80 | int *dirlen); | 82 | int *dirlen); |
81 | extern struct sk_buff * audit_make_reply(int pid, int seq, int type, | 83 | extern struct sk_buff * audit_make_reply(int pid, int seq, int type, |
@@ -144,7 +146,7 @@ extern void audit_kill_trees(struct list_head *); | |||
144 | extern char *audit_unpack_string(void **, size_t *, size_t); | 146 | extern char *audit_unpack_string(void **, size_t *, size_t); |
145 | 147 | ||
146 | extern pid_t audit_sig_pid; | 148 | extern pid_t audit_sig_pid; |
147 | extern uid_t audit_sig_uid; | 149 | extern kuid_t audit_sig_uid; |
148 | extern u32 audit_sig_sid; | 150 | extern u32 audit_sig_sid; |
149 | 151 | ||
150 | #ifdef CONFIG_AUDITSYSCALL | 152 | #ifdef CONFIG_AUDITSYSCALL |
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index 3823281401b5..1c22ec3d87bc 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c | |||
@@ -241,7 +241,7 @@ static void audit_watch_log_rule_change(struct audit_krule *r, struct audit_watc | |||
241 | struct audit_buffer *ab; | 241 | struct audit_buffer *ab; |
242 | ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE); | 242 | ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE); |
243 | audit_log_format(ab, "auid=%u ses=%u op=", | 243 | audit_log_format(ab, "auid=%u ses=%u op=", |
244 | audit_get_loginuid(current), | 244 | from_kuid(&init_user_ns, audit_get_loginuid(current)), |
245 | audit_get_sessionid(current)); | 245 | audit_get_sessionid(current)); |
246 | audit_log_string(ab, op); | 246 | audit_log_string(ab, op); |
247 | audit_log_format(ab, " path="); | 247 | audit_log_format(ab, " path="); |
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index a6c3f1abd206..c4bcdbaf4d4d 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
@@ -342,6 +342,8 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) | |||
342 | 342 | ||
343 | f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS); | 343 | f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS); |
344 | f->val = rule->values[i]; | 344 | f->val = rule->values[i]; |
345 | f->uid = INVALID_UID; | ||
346 | f->gid = INVALID_GID; | ||
345 | 347 | ||
346 | err = -EINVAL; | 348 | err = -EINVAL; |
347 | if (f->op == Audit_bad) | 349 | if (f->op == Audit_bad) |
@@ -350,16 +352,32 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) | |||
350 | switch(f->type) { | 352 | switch(f->type) { |
351 | default: | 353 | default: |
352 | goto exit_free; | 354 | goto exit_free; |
353 | case AUDIT_PID: | ||
354 | case AUDIT_UID: | 355 | case AUDIT_UID: |
355 | case AUDIT_EUID: | 356 | case AUDIT_EUID: |
356 | case AUDIT_SUID: | 357 | case AUDIT_SUID: |
357 | case AUDIT_FSUID: | 358 | case AUDIT_FSUID: |
359 | case AUDIT_LOGINUID: | ||
360 | /* bit ops not implemented for uid comparisons */ | ||
361 | if (f->op == Audit_bitmask || f->op == Audit_bittest) | ||
362 | goto exit_free; | ||
363 | |||
364 | f->uid = make_kuid(current_user_ns(), f->val); | ||
365 | if (!uid_valid(f->uid)) | ||
366 | goto exit_free; | ||
367 | break; | ||
358 | case AUDIT_GID: | 368 | case AUDIT_GID: |
359 | case AUDIT_EGID: | 369 | case AUDIT_EGID: |
360 | case AUDIT_SGID: | 370 | case AUDIT_SGID: |
361 | case AUDIT_FSGID: | 371 | case AUDIT_FSGID: |
362 | case AUDIT_LOGINUID: | 372 | /* bit ops not implemented for gid comparisons */ |
373 | if (f->op == Audit_bitmask || f->op == Audit_bittest) | ||
374 | goto exit_free; | ||
375 | |||
376 | f->gid = make_kgid(current_user_ns(), f->val); | ||
377 | if (!gid_valid(f->gid)) | ||
378 | goto exit_free; | ||
379 | break; | ||
380 | case AUDIT_PID: | ||
363 | case AUDIT_PERS: | 381 | case AUDIT_PERS: |
364 | case AUDIT_MSGTYPE: | 382 | case AUDIT_MSGTYPE: |
365 | case AUDIT_PPID: | 383 | case AUDIT_PPID: |
@@ -437,19 +455,39 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
437 | 455 | ||
438 | f->type = data->fields[i]; | 456 | f->type = data->fields[i]; |
439 | f->val = data->values[i]; | 457 | f->val = data->values[i]; |
458 | f->uid = INVALID_UID; | ||
459 | f->gid = INVALID_GID; | ||
440 | f->lsm_str = NULL; | 460 | f->lsm_str = NULL; |
441 | f->lsm_rule = NULL; | 461 | f->lsm_rule = NULL; |
442 | switch(f->type) { | 462 | switch(f->type) { |
443 | case AUDIT_PID: | ||
444 | case AUDIT_UID: | 463 | case AUDIT_UID: |
445 | case AUDIT_EUID: | 464 | case AUDIT_EUID: |
446 | case AUDIT_SUID: | 465 | case AUDIT_SUID: |
447 | case AUDIT_FSUID: | 466 | case AUDIT_FSUID: |
467 | case AUDIT_LOGINUID: | ||
468 | case AUDIT_OBJ_UID: | ||
469 | /* bit ops not implemented for uid comparisons */ | ||
470 | if (f->op == Audit_bitmask || f->op == Audit_bittest) | ||
471 | goto exit_free; | ||
472 | |||
473 | f->uid = make_kuid(current_user_ns(), f->val); | ||
474 | if (!uid_valid(f->uid)) | ||
475 | goto exit_free; | ||
476 | break; | ||
448 | case AUDIT_GID: | 477 | case AUDIT_GID: |
449 | case AUDIT_EGID: | 478 | case AUDIT_EGID: |
450 | case AUDIT_SGID: | 479 | case AUDIT_SGID: |
451 | case AUDIT_FSGID: | 480 | case AUDIT_FSGID: |
452 | case AUDIT_LOGINUID: | 481 | case AUDIT_OBJ_GID: |
482 | /* bit ops not implemented for gid comparisons */ | ||
483 | if (f->op == Audit_bitmask || f->op == Audit_bittest) | ||
484 | goto exit_free; | ||
485 | |||
486 | f->gid = make_kgid(current_user_ns(), f->val); | ||
487 | if (!gid_valid(f->gid)) | ||
488 | goto exit_free; | ||
489 | break; | ||
490 | case AUDIT_PID: | ||
453 | case AUDIT_PERS: | 491 | case AUDIT_PERS: |
454 | case AUDIT_MSGTYPE: | 492 | case AUDIT_MSGTYPE: |
455 | case AUDIT_PPID: | 493 | case AUDIT_PPID: |
@@ -461,8 +499,6 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
461 | case AUDIT_ARG1: | 499 | case AUDIT_ARG1: |
462 | case AUDIT_ARG2: | 500 | case AUDIT_ARG2: |
463 | case AUDIT_ARG3: | 501 | case AUDIT_ARG3: |
464 | case AUDIT_OBJ_UID: | ||
465 | case AUDIT_OBJ_GID: | ||
466 | break; | 502 | break; |
467 | case AUDIT_ARCH: | 503 | case AUDIT_ARCH: |
468 | entry->rule.arch_f = f; | 504 | entry->rule.arch_f = f; |
@@ -707,6 +743,23 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b) | |||
707 | if (strcmp(a->filterkey, b->filterkey)) | 743 | if (strcmp(a->filterkey, b->filterkey)) |
708 | return 1; | 744 | return 1; |
709 | break; | 745 | break; |
746 | case AUDIT_UID: | ||
747 | case AUDIT_EUID: | ||
748 | case AUDIT_SUID: | ||
749 | case AUDIT_FSUID: | ||
750 | case AUDIT_LOGINUID: | ||
751 | case AUDIT_OBJ_UID: | ||
752 | if (!uid_eq(a->fields[i].uid, b->fields[i].uid)) | ||
753 | return 1; | ||
754 | break; | ||
755 | case AUDIT_GID: | ||
756 | case AUDIT_EGID: | ||
757 | case AUDIT_SGID: | ||
758 | case AUDIT_FSGID: | ||
759 | case AUDIT_OBJ_GID: | ||
760 | if (!gid_eq(a->fields[i].gid, b->fields[i].gid)) | ||
761 | return 1; | ||
762 | break; | ||
710 | default: | 763 | default: |
711 | if (a->fields[i].val != b->fields[i].val) | 764 | if (a->fields[i].val != b->fields[i].val) |
712 | return 1; | 765 | return 1; |
@@ -1056,7 +1109,7 @@ static void audit_list_rules(int pid, int seq, struct sk_buff_head *q) | |||
1056 | } | 1109 | } |
1057 | 1110 | ||
1058 | /* Log rule additions and removals */ | 1111 | /* Log rule additions and removals */ |
1059 | static void audit_log_rule_change(uid_t loginuid, u32 sessionid, u32 sid, | 1112 | static void audit_log_rule_change(kuid_t loginuid, u32 sessionid, u32 sid, |
1060 | char *action, struct audit_krule *rule, | 1113 | char *action, struct audit_krule *rule, |
1061 | int res) | 1114 | int res) |
1062 | { | 1115 | { |
@@ -1068,7 +1121,8 @@ static void audit_log_rule_change(uid_t loginuid, u32 sessionid, u32 sid, | |||
1068 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 1121 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
1069 | if (!ab) | 1122 | if (!ab) |
1070 | return; | 1123 | return; |
1071 | audit_log_format(ab, "auid=%u ses=%u", loginuid, sessionid); | 1124 | audit_log_format(ab, "auid=%u ses=%u", |
1125 | from_kuid(&init_user_ns, loginuid), sessionid); | ||
1072 | if (sid) { | 1126 | if (sid) { |
1073 | char *ctx = NULL; | 1127 | char *ctx = NULL; |
1074 | u32 len; | 1128 | u32 len; |
@@ -1098,8 +1152,8 @@ static void audit_log_rule_change(uid_t loginuid, u32 sessionid, u32 sid, | |||
1098 | * @sessionid: sessionid for netlink audit message | 1152 | * @sessionid: sessionid for netlink audit message |
1099 | * @sid: SE Linux Security ID of sender | 1153 | * @sid: SE Linux Security ID of sender |
1100 | */ | 1154 | */ |
1101 | int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | 1155 | int audit_receive_filter(int type, int pid, int seq, void *data, |
1102 | size_t datasz, uid_t loginuid, u32 sessionid, u32 sid) | 1156 | size_t datasz, kuid_t loginuid, u32 sessionid, u32 sid) |
1103 | { | 1157 | { |
1104 | struct task_struct *tsk; | 1158 | struct task_struct *tsk; |
1105 | struct audit_netlink_list *dest; | 1159 | struct audit_netlink_list *dest; |
@@ -1198,6 +1252,52 @@ int audit_comparator(u32 left, u32 op, u32 right) | |||
1198 | } | 1252 | } |
1199 | } | 1253 | } |
1200 | 1254 | ||
1255 | int audit_uid_comparator(kuid_t left, u32 op, kuid_t right) | ||
1256 | { | ||
1257 | switch (op) { | ||
1258 | case Audit_equal: | ||
1259 | return uid_eq(left, right); | ||
1260 | case Audit_not_equal: | ||
1261 | return !uid_eq(left, right); | ||
1262 | case Audit_lt: | ||
1263 | return uid_lt(left, right); | ||
1264 | case Audit_le: | ||
1265 | return uid_lte(left, right); | ||
1266 | case Audit_gt: | ||
1267 | return uid_gt(left, right); | ||
1268 | case Audit_ge: | ||
1269 | return uid_gte(left, right); | ||
1270 | case Audit_bitmask: | ||
1271 | case Audit_bittest: | ||
1272 | default: | ||
1273 | BUG(); | ||
1274 | return 0; | ||
1275 | } | ||
1276 | } | ||
1277 | |||
1278 | int audit_gid_comparator(kgid_t left, u32 op, kgid_t right) | ||
1279 | { | ||
1280 | switch (op) { | ||
1281 | case Audit_equal: | ||
1282 | return gid_eq(left, right); | ||
1283 | case Audit_not_equal: | ||
1284 | return !gid_eq(left, right); | ||
1285 | case Audit_lt: | ||
1286 | return gid_lt(left, right); | ||
1287 | case Audit_le: | ||
1288 | return gid_lte(left, right); | ||
1289 | case Audit_gt: | ||
1290 | return gid_gt(left, right); | ||
1291 | case Audit_ge: | ||
1292 | return gid_gte(left, right); | ||
1293 | case Audit_bitmask: | ||
1294 | case Audit_bittest: | ||
1295 | default: | ||
1296 | BUG(); | ||
1297 | return 0; | ||
1298 | } | ||
1299 | } | ||
1300 | |||
1201 | /* Compare given dentry name with last component in given path, | 1301 | /* Compare given dentry name with last component in given path, |
1202 | * return of 0 indicates a match. */ | 1302 | * return of 0 indicates a match. */ |
1203 | int audit_compare_dname_path(const char *dname, const char *path, | 1303 | int audit_compare_dname_path(const char *dname, const char *path, |
@@ -1236,8 +1336,7 @@ int audit_compare_dname_path(const char *dname, const char *path, | |||
1236 | return strncmp(p, dname, dlen); | 1336 | return strncmp(p, dname, dlen); |
1237 | } | 1337 | } |
1238 | 1338 | ||
1239 | static int audit_filter_user_rules(struct netlink_skb_parms *cb, | 1339 | static int audit_filter_user_rules(struct audit_krule *rule, |
1240 | struct audit_krule *rule, | ||
1241 | enum audit_state *state) | 1340 | enum audit_state *state) |
1242 | { | 1341 | { |
1243 | int i; | 1342 | int i; |
@@ -1249,17 +1348,17 @@ static int audit_filter_user_rules(struct netlink_skb_parms *cb, | |||
1249 | 1348 | ||
1250 | switch (f->type) { | 1349 | switch (f->type) { |
1251 | case AUDIT_PID: | 1350 | case AUDIT_PID: |
1252 | result = audit_comparator(cb->creds.pid, f->op, f->val); | 1351 | result = audit_comparator(task_pid_vnr(current), f->op, f->val); |
1253 | break; | 1352 | break; |
1254 | case AUDIT_UID: | 1353 | case AUDIT_UID: |
1255 | result = audit_comparator(cb->creds.uid, f->op, f->val); | 1354 | result = audit_uid_comparator(current_uid(), f->op, f->uid); |
1256 | break; | 1355 | break; |
1257 | case AUDIT_GID: | 1356 | case AUDIT_GID: |
1258 | result = audit_comparator(cb->creds.gid, f->op, f->val); | 1357 | result = audit_gid_comparator(current_gid(), f->op, f->gid); |
1259 | break; | 1358 | break; |
1260 | case AUDIT_LOGINUID: | 1359 | case AUDIT_LOGINUID: |
1261 | result = audit_comparator(audit_get_loginuid(current), | 1360 | result = audit_uid_comparator(audit_get_loginuid(current), |
1262 | f->op, f->val); | 1361 | f->op, f->uid); |
1263 | break; | 1362 | break; |
1264 | case AUDIT_SUBJ_USER: | 1363 | case AUDIT_SUBJ_USER: |
1265 | case AUDIT_SUBJ_ROLE: | 1364 | case AUDIT_SUBJ_ROLE: |
@@ -1287,7 +1386,7 @@ static int audit_filter_user_rules(struct netlink_skb_parms *cb, | |||
1287 | return 1; | 1386 | return 1; |
1288 | } | 1387 | } |
1289 | 1388 | ||
1290 | int audit_filter_user(struct netlink_skb_parms *cb) | 1389 | int audit_filter_user(void) |
1291 | { | 1390 | { |
1292 | enum audit_state state = AUDIT_DISABLED; | 1391 | enum audit_state state = AUDIT_DISABLED; |
1293 | struct audit_entry *e; | 1392 | struct audit_entry *e; |
@@ -1295,7 +1394,7 @@ int audit_filter_user(struct netlink_skb_parms *cb) | |||
1295 | 1394 | ||
1296 | rcu_read_lock(); | 1395 | rcu_read_lock(); |
1297 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) { | 1396 | list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) { |
1298 | if (audit_filter_user_rules(cb, &e->rule, &state)) { | 1397 | if (audit_filter_user_rules(&e->rule, &state)) { |
1299 | if (state == AUDIT_DISABLED) | 1398 | if (state == AUDIT_DISABLED) |
1300 | ret = 0; | 1399 | ret = 0; |
1301 | break; | 1400 | break; |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 4b96415527b8..ff4798fcb488 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -113,8 +113,8 @@ struct audit_names { | |||
113 | unsigned long ino; | 113 | unsigned long ino; |
114 | dev_t dev; | 114 | dev_t dev; |
115 | umode_t mode; | 115 | umode_t mode; |
116 | uid_t uid; | 116 | kuid_t uid; |
117 | gid_t gid; | 117 | kgid_t gid; |
118 | dev_t rdev; | 118 | dev_t rdev; |
119 | u32 osid; | 119 | u32 osid; |
120 | struct audit_cap_data fcap; | 120 | struct audit_cap_data fcap; |
@@ -149,8 +149,8 @@ struct audit_aux_data_execve { | |||
149 | struct audit_aux_data_pids { | 149 | struct audit_aux_data_pids { |
150 | struct audit_aux_data d; | 150 | struct audit_aux_data d; |
151 | pid_t target_pid[AUDIT_AUX_PIDS]; | 151 | pid_t target_pid[AUDIT_AUX_PIDS]; |
152 | uid_t target_auid[AUDIT_AUX_PIDS]; | 152 | kuid_t target_auid[AUDIT_AUX_PIDS]; |
153 | uid_t target_uid[AUDIT_AUX_PIDS]; | 153 | kuid_t target_uid[AUDIT_AUX_PIDS]; |
154 | unsigned int target_sessionid[AUDIT_AUX_PIDS]; | 154 | unsigned int target_sessionid[AUDIT_AUX_PIDS]; |
155 | u32 target_sid[AUDIT_AUX_PIDS]; | 155 | u32 target_sid[AUDIT_AUX_PIDS]; |
156 | char target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN]; | 156 | char target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN]; |
@@ -208,14 +208,14 @@ struct audit_context { | |||
208 | size_t sockaddr_len; | 208 | size_t sockaddr_len; |
209 | /* Save things to print about task_struct */ | 209 | /* Save things to print about task_struct */ |
210 | pid_t pid, ppid; | 210 | pid_t pid, ppid; |
211 | uid_t uid, euid, suid, fsuid; | 211 | kuid_t uid, euid, suid, fsuid; |
212 | gid_t gid, egid, sgid, fsgid; | 212 | kgid_t gid, egid, sgid, fsgid; |
213 | unsigned long personality; | 213 | unsigned long personality; |
214 | int arch; | 214 | int arch; |
215 | 215 | ||
216 | pid_t target_pid; | 216 | pid_t target_pid; |
217 | uid_t target_auid; | 217 | kuid_t target_auid; |
218 | uid_t target_uid; | 218 | kuid_t target_uid; |
219 | unsigned int target_sessionid; | 219 | unsigned int target_sessionid; |
220 | u32 target_sid; | 220 | u32 target_sid; |
221 | char target_comm[TASK_COMM_LEN]; | 221 | char target_comm[TASK_COMM_LEN]; |
@@ -231,8 +231,8 @@ struct audit_context { | |||
231 | long args[6]; | 231 | long args[6]; |
232 | } socketcall; | 232 | } socketcall; |
233 | struct { | 233 | struct { |
234 | uid_t uid; | 234 | kuid_t uid; |
235 | gid_t gid; | 235 | kgid_t gid; |
236 | umode_t mode; | 236 | umode_t mode; |
237 | u32 osid; | 237 | u32 osid; |
238 | int has_perm; | 238 | int has_perm; |
@@ -464,37 +464,47 @@ static int match_tree_refs(struct audit_context *ctx, struct audit_tree *tree) | |||
464 | return 0; | 464 | return 0; |
465 | } | 465 | } |
466 | 466 | ||
467 | static int audit_compare_id(uid_t uid1, | 467 | static int audit_compare_uid(kuid_t uid, |
468 | struct audit_names *name, | 468 | struct audit_names *name, |
469 | unsigned long name_offset, | 469 | struct audit_field *f, |
470 | struct audit_field *f, | 470 | struct audit_context *ctx) |
471 | struct audit_context *ctx) | ||
472 | { | 471 | { |
473 | struct audit_names *n; | 472 | struct audit_names *n; |
474 | unsigned long addr; | ||
475 | uid_t uid2; | ||
476 | int rc; | 473 | int rc; |
477 | 474 | ||
478 | BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t)); | ||
479 | |||
480 | if (name) { | 475 | if (name) { |
481 | addr = (unsigned long)name; | 476 | rc = audit_uid_comparator(uid, f->op, name->uid); |
482 | addr += name_offset; | ||
483 | |||
484 | uid2 = *(uid_t *)addr; | ||
485 | rc = audit_comparator(uid1, f->op, uid2); | ||
486 | if (rc) | 477 | if (rc) |
487 | return rc; | 478 | return rc; |
488 | } | 479 | } |
489 | 480 | ||
490 | if (ctx) { | 481 | if (ctx) { |
491 | list_for_each_entry(n, &ctx->names_list, list) { | 482 | list_for_each_entry(n, &ctx->names_list, list) { |
492 | addr = (unsigned long)n; | 483 | rc = audit_uid_comparator(uid, f->op, n->uid); |
493 | addr += name_offset; | 484 | if (rc) |
494 | 485 | return rc; | |
495 | uid2 = *(uid_t *)addr; | 486 | } |
487 | } | ||
488 | return 0; | ||
489 | } | ||
496 | 490 | ||
497 | rc = audit_comparator(uid1, f->op, uid2); | 491 | static int audit_compare_gid(kgid_t gid, |
492 | struct audit_names *name, | ||
493 | struct audit_field *f, | ||
494 | struct audit_context *ctx) | ||
495 | { | ||
496 | struct audit_names *n; | ||
497 | int rc; | ||
498 | |||
499 | if (name) { | ||
500 | rc = audit_gid_comparator(gid, f->op, name->gid); | ||
501 | if (rc) | ||
502 | return rc; | ||
503 | } | ||
504 | |||
505 | if (ctx) { | ||
506 | list_for_each_entry(n, &ctx->names_list, list) { | ||
507 | rc = audit_gid_comparator(gid, f->op, n->gid); | ||
498 | if (rc) | 508 | if (rc) |
499 | return rc; | 509 | return rc; |
500 | } | 510 | } |
@@ -511,80 +521,62 @@ static int audit_field_compare(struct task_struct *tsk, | |||
511 | switch (f->val) { | 521 | switch (f->val) { |
512 | /* process to file object comparisons */ | 522 | /* process to file object comparisons */ |
513 | case AUDIT_COMPARE_UID_TO_OBJ_UID: | 523 | case AUDIT_COMPARE_UID_TO_OBJ_UID: |
514 | return audit_compare_id(cred->uid, | 524 | return audit_compare_uid(cred->uid, name, f, ctx); |
515 | name, offsetof(struct audit_names, uid), | ||
516 | f, ctx); | ||
517 | case AUDIT_COMPARE_GID_TO_OBJ_GID: | 525 | case AUDIT_COMPARE_GID_TO_OBJ_GID: |
518 | return audit_compare_id(cred->gid, | 526 | return audit_compare_gid(cred->gid, name, f, ctx); |
519 | name, offsetof(struct audit_names, gid), | ||
520 | f, ctx); | ||
521 | case AUDIT_COMPARE_EUID_TO_OBJ_UID: | 527 | case AUDIT_COMPARE_EUID_TO_OBJ_UID: |
522 | return audit_compare_id(cred->euid, | 528 | return audit_compare_uid(cred->euid, name, f, ctx); |
523 | name, offsetof(struct audit_names, uid), | ||
524 | f, ctx); | ||
525 | case AUDIT_COMPARE_EGID_TO_OBJ_GID: | 529 | case AUDIT_COMPARE_EGID_TO_OBJ_GID: |
526 | return audit_compare_id(cred->egid, | 530 | return audit_compare_gid(cred->egid, name, f, ctx); |
527 | name, offsetof(struct audit_names, gid), | ||
528 | f, ctx); | ||
529 | case AUDIT_COMPARE_AUID_TO_OBJ_UID: | 531 | case AUDIT_COMPARE_AUID_TO_OBJ_UID: |
530 | return audit_compare_id(tsk->loginuid, | 532 | return audit_compare_uid(tsk->loginuid, name, f, ctx); |
531 | name, offsetof(struct audit_names, uid), | ||
532 | f, ctx); | ||
533 | case AUDIT_COMPARE_SUID_TO_OBJ_UID: | 533 | case AUDIT_COMPARE_SUID_TO_OBJ_UID: |
534 | return audit_compare_id(cred->suid, | 534 | return audit_compare_uid(cred->suid, name, f, ctx); |
535 | name, offsetof(struct audit_names, uid), | ||
536 | f, ctx); | ||
537 | case AUDIT_COMPARE_SGID_TO_OBJ_GID: | 535 | case AUDIT_COMPARE_SGID_TO_OBJ_GID: |
538 | return audit_compare_id(cred->sgid, | 536 | return audit_compare_gid(cred->sgid, name, f, ctx); |
539 | name, offsetof(struct audit_names, gid), | ||
540 | f, ctx); | ||
541 | case AUDIT_COMPARE_FSUID_TO_OBJ_UID: | 537 | case AUDIT_COMPARE_FSUID_TO_OBJ_UID: |
542 | return audit_compare_id(cred->fsuid, | 538 | return audit_compare_uid(cred->fsuid, name, f, ctx); |
543 | name, offsetof(struct audit_names, uid), | ||
544 | f, ctx); | ||
545 | case AUDIT_COMPARE_FSGID_TO_OBJ_GID: | 539 | case AUDIT_COMPARE_FSGID_TO_OBJ_GID: |
546 | return audit_compare_id(cred->fsgid, | 540 | return audit_compare_gid(cred->fsgid, name, f, ctx); |
547 | name, offsetof(struct audit_names, gid), | ||
548 | f, ctx); | ||
549 | /* uid comparisons */ | 541 | /* uid comparisons */ |
550 | case AUDIT_COMPARE_UID_TO_AUID: | 542 | case AUDIT_COMPARE_UID_TO_AUID: |
551 | return audit_comparator(cred->uid, f->op, tsk->loginuid); | 543 | return audit_uid_comparator(cred->uid, f->op, tsk->loginuid); |
552 | case AUDIT_COMPARE_UID_TO_EUID: | 544 | case AUDIT_COMPARE_UID_TO_EUID: |
553 | return audit_comparator(cred->uid, f->op, cred->euid); | 545 | return audit_uid_comparator(cred->uid, f->op, cred->euid); |
554 | case AUDIT_COMPARE_UID_TO_SUID: | 546 | case AUDIT_COMPARE_UID_TO_SUID: |
555 | return audit_comparator(cred->uid, f->op, cred->suid); | 547 | return audit_uid_comparator(cred->uid, f->op, cred->suid); |
556 | case AUDIT_COMPARE_UID_TO_FSUID: | 548 | case AUDIT_COMPARE_UID_TO_FSUID: |
557 | return audit_comparator(cred->uid, f->op, cred->fsuid); | 549 | return audit_uid_comparator(cred->uid, f->op, cred->fsuid); |
558 | /* auid comparisons */ | 550 | /* auid comparisons */ |
559 | case AUDIT_COMPARE_AUID_TO_EUID: | 551 | case AUDIT_COMPARE_AUID_TO_EUID: |
560 | return audit_comparator(tsk->loginuid, f->op, cred->euid); | 552 | return audit_uid_comparator(tsk->loginuid, f->op, cred->euid); |
561 | case AUDIT_COMPARE_AUID_TO_SUID: | 553 | case AUDIT_COMPARE_AUID_TO_SUID: |
562 | return audit_comparator(tsk->loginuid, f->op, cred->suid); | 554 | return audit_uid_comparator(tsk->loginuid, f->op, cred->suid); |
563 | case AUDIT_COMPARE_AUID_TO_FSUID: | 555 | case AUDIT_COMPARE_AUID_TO_FSUID: |
564 | return audit_comparator(tsk->loginuid, f->op, cred->fsuid); | 556 | return audit_uid_comparator(tsk->loginuid, f->op, cred->fsuid); |
565 | /* euid comparisons */ | 557 | /* euid comparisons */ |
566 | case AUDIT_COMPARE_EUID_TO_SUID: | 558 | case AUDIT_COMPARE_EUID_TO_SUID: |
567 | return audit_comparator(cred->euid, f->op, cred->suid); | 559 | return audit_uid_comparator(cred->euid, f->op, cred->suid); |
568 | case AUDIT_COMPARE_EUID_TO_FSUID: | 560 | case AUDIT_COMPARE_EUID_TO_FSUID: |
569 | return audit_comparator(cred->euid, f->op, cred->fsuid); | 561 | return audit_uid_comparator(cred->euid, f->op, cred->fsuid); |
570 | /* suid comparisons */ | 562 | /* suid comparisons */ |
571 | case AUDIT_COMPARE_SUID_TO_FSUID: | 563 | case AUDIT_COMPARE_SUID_TO_FSUID: |
572 | return audit_comparator(cred->suid, f->op, cred->fsuid); | 564 | return audit_uid_comparator(cred->suid, f->op, cred->fsuid); |
573 | /* gid comparisons */ | 565 | /* gid comparisons */ |
574 | case AUDIT_COMPARE_GID_TO_EGID: | 566 | case AUDIT_COMPARE_GID_TO_EGID: |
575 | return audit_comparator(cred->gid, f->op, cred->egid); | 567 | return audit_gid_comparator(cred->gid, f->op, cred->egid); |
576 | case AUDIT_COMPARE_GID_TO_SGID: | 568 | case AUDIT_COMPARE_GID_TO_SGID: |
577 | return audit_comparator(cred->gid, f->op, cred->sgid); | 569 | return audit_gid_comparator(cred->gid, f->op, cred->sgid); |
578 | case AUDIT_COMPARE_GID_TO_FSGID: | 570 | case AUDIT_COMPARE_GID_TO_FSGID: |
579 | return audit_comparator(cred->gid, f->op, cred->fsgid); | 571 | return audit_gid_comparator(cred->gid, f->op, cred->fsgid); |
580 | /* egid comparisons */ | 572 | /* egid comparisons */ |
581 | case AUDIT_COMPARE_EGID_TO_SGID: | 573 | case AUDIT_COMPARE_EGID_TO_SGID: |
582 | return audit_comparator(cred->egid, f->op, cred->sgid); | 574 | return audit_gid_comparator(cred->egid, f->op, cred->sgid); |
583 | case AUDIT_COMPARE_EGID_TO_FSGID: | 575 | case AUDIT_COMPARE_EGID_TO_FSGID: |
584 | return audit_comparator(cred->egid, f->op, cred->fsgid); | 576 | return audit_gid_comparator(cred->egid, f->op, cred->fsgid); |
585 | /* sgid comparison */ | 577 | /* sgid comparison */ |
586 | case AUDIT_COMPARE_SGID_TO_FSGID: | 578 | case AUDIT_COMPARE_SGID_TO_FSGID: |
587 | return audit_comparator(cred->sgid, f->op, cred->fsgid); | 579 | return audit_gid_comparator(cred->sgid, f->op, cred->fsgid); |
588 | default: | 580 | default: |
589 | WARN(1, "Missing AUDIT_COMPARE define. Report as a bug\n"); | 581 | WARN(1, "Missing AUDIT_COMPARE define. Report as a bug\n"); |
590 | return 0; | 582 | return 0; |
@@ -630,28 +622,28 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
630 | } | 622 | } |
631 | break; | 623 | break; |
632 | case AUDIT_UID: | 624 | case AUDIT_UID: |
633 | result = audit_comparator(cred->uid, f->op, f->val); | 625 | result = audit_uid_comparator(cred->uid, f->op, f->uid); |
634 | break; | 626 | break; |
635 | case AUDIT_EUID: | 627 | case AUDIT_EUID: |
636 | result = audit_comparator(cred->euid, f->op, f->val); | 628 | result = audit_uid_comparator(cred->euid, f->op, f->uid); |
637 | break; | 629 | break; |
638 | case AUDIT_SUID: | 630 | case AUDIT_SUID: |
639 | result = audit_comparator(cred->suid, f->op, f->val); | 631 | result = audit_uid_comparator(cred->suid, f->op, f->uid); |
640 | break; | 632 | break; |
641 | case AUDIT_FSUID: | 633 | case AUDIT_FSUID: |
642 | result = audit_comparator(cred->fsuid, f->op, f->val); | 634 | result = audit_uid_comparator(cred->fsuid, f->op, f->uid); |
643 | break; | 635 | break; |
644 | case AUDIT_GID: | 636 | case AUDIT_GID: |
645 | result = audit_comparator(cred->gid, f->op, f->val); | 637 | result = audit_gid_comparator(cred->gid, f->op, f->gid); |
646 | break; | 638 | break; |
647 | case AUDIT_EGID: | 639 | case AUDIT_EGID: |
648 | result = audit_comparator(cred->egid, f->op, f->val); | 640 | result = audit_gid_comparator(cred->egid, f->op, f->gid); |
649 | break; | 641 | break; |
650 | case AUDIT_SGID: | 642 | case AUDIT_SGID: |
651 | result = audit_comparator(cred->sgid, f->op, f->val); | 643 | result = audit_gid_comparator(cred->sgid, f->op, f->gid); |
652 | break; | 644 | break; |
653 | case AUDIT_FSGID: | 645 | case AUDIT_FSGID: |
654 | result = audit_comparator(cred->fsgid, f->op, f->val); | 646 | result = audit_gid_comparator(cred->fsgid, f->op, f->gid); |
655 | break; | 647 | break; |
656 | case AUDIT_PERS: | 648 | case AUDIT_PERS: |
657 | result = audit_comparator(tsk->personality, f->op, f->val); | 649 | result = audit_comparator(tsk->personality, f->op, f->val); |
@@ -717,10 +709,10 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
717 | break; | 709 | break; |
718 | case AUDIT_OBJ_UID: | 710 | case AUDIT_OBJ_UID: |
719 | if (name) { | 711 | if (name) { |
720 | result = audit_comparator(name->uid, f->op, f->val); | 712 | result = audit_uid_comparator(name->uid, f->op, f->uid); |
721 | } else if (ctx) { | 713 | } else if (ctx) { |
722 | list_for_each_entry(n, &ctx->names_list, list) { | 714 | list_for_each_entry(n, &ctx->names_list, list) { |
723 | if (audit_comparator(n->uid, f->op, f->val)) { | 715 | if (audit_uid_comparator(n->uid, f->op, f->uid)) { |
724 | ++result; | 716 | ++result; |
725 | break; | 717 | break; |
726 | } | 718 | } |
@@ -729,10 +721,10 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
729 | break; | 721 | break; |
730 | case AUDIT_OBJ_GID: | 722 | case AUDIT_OBJ_GID: |
731 | if (name) { | 723 | if (name) { |
732 | result = audit_comparator(name->gid, f->op, f->val); | 724 | result = audit_gid_comparator(name->gid, f->op, f->gid); |
733 | } else if (ctx) { | 725 | } else if (ctx) { |
734 | list_for_each_entry(n, &ctx->names_list, list) { | 726 | list_for_each_entry(n, &ctx->names_list, list) { |
735 | if (audit_comparator(n->gid, f->op, f->val)) { | 727 | if (audit_gid_comparator(n->gid, f->op, f->gid)) { |
736 | ++result; | 728 | ++result; |
737 | break; | 729 | break; |
738 | } | 730 | } |
@@ -750,7 +742,7 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
750 | case AUDIT_LOGINUID: | 742 | case AUDIT_LOGINUID: |
751 | result = 0; | 743 | result = 0; |
752 | if (ctx) | 744 | if (ctx) |
753 | result = audit_comparator(tsk->loginuid, f->op, f->val); | 745 | result = audit_uid_comparator(tsk->loginuid, f->op, f->uid); |
754 | break; | 746 | break; |
755 | case AUDIT_SUBJ_USER: | 747 | case AUDIT_SUBJ_USER: |
756 | case AUDIT_SUBJ_ROLE: | 748 | case AUDIT_SUBJ_ROLE: |
@@ -1184,7 +1176,7 @@ static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk | |||
1184 | } | 1176 | } |
1185 | 1177 | ||
1186 | static int audit_log_pid_context(struct audit_context *context, pid_t pid, | 1178 | static int audit_log_pid_context(struct audit_context *context, pid_t pid, |
1187 | uid_t auid, uid_t uid, unsigned int sessionid, | 1179 | kuid_t auid, kuid_t uid, unsigned int sessionid, |
1188 | u32 sid, char *comm) | 1180 | u32 sid, char *comm) |
1189 | { | 1181 | { |
1190 | struct audit_buffer *ab; | 1182 | struct audit_buffer *ab; |
@@ -1196,8 +1188,9 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, | |||
1196 | if (!ab) | 1188 | if (!ab) |
1197 | return rc; | 1189 | return rc; |
1198 | 1190 | ||
1199 | audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, auid, | 1191 | audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, |
1200 | uid, sessionid); | 1192 | from_kuid(&init_user_ns, auid), |
1193 | from_kuid(&init_user_ns, uid), sessionid); | ||
1201 | if (security_secid_to_secctx(sid, &ctx, &len)) { | 1194 | if (security_secid_to_secctx(sid, &ctx, &len)) { |
1202 | audit_log_format(ab, " obj=(none)"); | 1195 | audit_log_format(ab, " obj=(none)"); |
1203 | rc = 1; | 1196 | rc = 1; |
@@ -1447,7 +1440,9 @@ static void show_special(struct audit_context *context, int *call_panic) | |||
1447 | u32 osid = context->ipc.osid; | 1440 | u32 osid = context->ipc.osid; |
1448 | 1441 | ||
1449 | audit_log_format(ab, "ouid=%u ogid=%u mode=%#ho", | 1442 | audit_log_format(ab, "ouid=%u ogid=%u mode=%#ho", |
1450 | context->ipc.uid, context->ipc.gid, context->ipc.mode); | 1443 | from_kuid(&init_user_ns, context->ipc.uid), |
1444 | from_kgid(&init_user_ns, context->ipc.gid), | ||
1445 | context->ipc.mode); | ||
1451 | if (osid) { | 1446 | if (osid) { |
1452 | char *ctx = NULL; | 1447 | char *ctx = NULL; |
1453 | u32 len; | 1448 | u32 len; |
@@ -1560,8 +1555,8 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, | |||
1560 | MAJOR(n->dev), | 1555 | MAJOR(n->dev), |
1561 | MINOR(n->dev), | 1556 | MINOR(n->dev), |
1562 | n->mode, | 1557 | n->mode, |
1563 | n->uid, | 1558 | from_kuid(&init_user_ns, n->uid), |
1564 | n->gid, | 1559 | from_kgid(&init_user_ns, n->gid), |
1565 | MAJOR(n->rdev), | 1560 | MAJOR(n->rdev), |
1566 | MINOR(n->rdev)); | 1561 | MINOR(n->rdev)); |
1567 | } | 1562 | } |
@@ -1638,11 +1633,16 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1638 | context->name_count, | 1633 | context->name_count, |
1639 | context->ppid, | 1634 | context->ppid, |
1640 | context->pid, | 1635 | context->pid, |
1641 | tsk->loginuid, | 1636 | from_kuid(&init_user_ns, tsk->loginuid), |
1642 | context->uid, | 1637 | from_kuid(&init_user_ns, context->uid), |
1643 | context->gid, | 1638 | from_kgid(&init_user_ns, context->gid), |
1644 | context->euid, context->suid, context->fsuid, | 1639 | from_kuid(&init_user_ns, context->euid), |
1645 | context->egid, context->sgid, context->fsgid, tty, | 1640 | from_kuid(&init_user_ns, context->suid), |
1641 | from_kuid(&init_user_ns, context->fsuid), | ||
1642 | from_kgid(&init_user_ns, context->egid), | ||
1643 | from_kgid(&init_user_ns, context->sgid), | ||
1644 | from_kgid(&init_user_ns, context->fsgid), | ||
1645 | tty, | ||
1646 | tsk->sessionid); | 1646 | tsk->sessionid); |
1647 | 1647 | ||
1648 | 1648 | ||
@@ -2299,14 +2299,14 @@ static atomic_t session_id = ATOMIC_INIT(0); | |||
2299 | * | 2299 | * |
2300 | * Called (set) from fs/proc/base.c::proc_loginuid_write(). | 2300 | * Called (set) from fs/proc/base.c::proc_loginuid_write(). |
2301 | */ | 2301 | */ |
2302 | int audit_set_loginuid(uid_t loginuid) | 2302 | int audit_set_loginuid(kuid_t loginuid) |
2303 | { | 2303 | { |
2304 | struct task_struct *task = current; | 2304 | struct task_struct *task = current; |
2305 | struct audit_context *context = task->audit_context; | 2305 | struct audit_context *context = task->audit_context; |
2306 | unsigned int sessionid; | 2306 | unsigned int sessionid; |
2307 | 2307 | ||
2308 | #ifdef CONFIG_AUDIT_LOGINUID_IMMUTABLE | 2308 | #ifdef CONFIG_AUDIT_LOGINUID_IMMUTABLE |
2309 | if (task->loginuid != -1) | 2309 | if (uid_valid(task->loginuid)) |
2310 | return -EPERM; | 2310 | return -EPERM; |
2311 | #else /* CONFIG_AUDIT_LOGINUID_IMMUTABLE */ | 2311 | #else /* CONFIG_AUDIT_LOGINUID_IMMUTABLE */ |
2312 | if (!capable(CAP_AUDIT_CONTROL)) | 2312 | if (!capable(CAP_AUDIT_CONTROL)) |
@@ -2322,8 +2322,10 @@ int audit_set_loginuid(uid_t loginuid) | |||
2322 | audit_log_format(ab, "login pid=%d uid=%u " | 2322 | audit_log_format(ab, "login pid=%d uid=%u " |
2323 | "old auid=%u new auid=%u" | 2323 | "old auid=%u new auid=%u" |
2324 | " old ses=%u new ses=%u", | 2324 | " old ses=%u new ses=%u", |
2325 | task->pid, task_uid(task), | 2325 | task->pid, |
2326 | task->loginuid, loginuid, | 2326 | from_kuid(&init_user_ns, task_uid(task)), |
2327 | from_kuid(&init_user_ns, task->loginuid), | ||
2328 | from_kuid(&init_user_ns, loginuid), | ||
2327 | task->sessionid, sessionid); | 2329 | task->sessionid, sessionid); |
2328 | audit_log_end(ab); | 2330 | audit_log_end(ab); |
2329 | } | 2331 | } |
@@ -2546,12 +2548,12 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
2546 | struct audit_aux_data_pids *axp; | 2548 | struct audit_aux_data_pids *axp; |
2547 | struct task_struct *tsk = current; | 2549 | struct task_struct *tsk = current; |
2548 | struct audit_context *ctx = tsk->audit_context; | 2550 | struct audit_context *ctx = tsk->audit_context; |
2549 | uid_t uid = current_uid(), t_uid = task_uid(t); | 2551 | kuid_t uid = current_uid(), t_uid = task_uid(t); |
2550 | 2552 | ||
2551 | if (audit_pid && t->tgid == audit_pid) { | 2553 | if (audit_pid && t->tgid == audit_pid) { |
2552 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) { | 2554 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) { |
2553 | audit_sig_pid = tsk->pid; | 2555 | audit_sig_pid = tsk->pid; |
2554 | if (tsk->loginuid != -1) | 2556 | if (uid_valid(tsk->loginuid)) |
2555 | audit_sig_uid = tsk->loginuid; | 2557 | audit_sig_uid = tsk->loginuid; |
2556 | else | 2558 | else |
2557 | audit_sig_uid = uid; | 2559 | audit_sig_uid = uid; |
@@ -2672,8 +2674,8 @@ void __audit_mmap_fd(int fd, int flags) | |||
2672 | 2674 | ||
2673 | static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr) | 2675 | static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr) |
2674 | { | 2676 | { |
2675 | uid_t auid, uid; | 2677 | kuid_t auid, uid; |
2676 | gid_t gid; | 2678 | kgid_t gid; |
2677 | unsigned int sessionid; | 2679 | unsigned int sessionid; |
2678 | 2680 | ||
2679 | auid = audit_get_loginuid(current); | 2681 | auid = audit_get_loginuid(current); |
@@ -2681,7 +2683,10 @@ static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr) | |||
2681 | current_uid_gid(&uid, &gid); | 2683 | current_uid_gid(&uid, &gid); |
2682 | 2684 | ||
2683 | audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u", | 2685 | audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u", |
2684 | auid, uid, gid, sessionid); | 2686 | from_kuid(&init_user_ns, auid), |
2687 | from_kuid(&init_user_ns, uid), | ||
2688 | from_kgid(&init_user_ns, gid), | ||
2689 | sessionid); | ||
2685 | audit_log_task_context(ab); | 2690 | audit_log_task_context(ab); |
2686 | audit_log_format(ab, " pid=%d comm=", current->pid); | 2691 | audit_log_format(ab, " pid=%d comm=", current->pid); |
2687 | audit_log_untrustedstring(ab, current->comm); | 2692 | audit_log_untrustedstring(ab, current->comm); |
diff --git a/kernel/cred.c b/kernel/cred.c index de728ac50d82..48cea3da6d05 100644 --- a/kernel/cred.c +++ b/kernel/cred.c | |||
@@ -799,9 +799,15 @@ static void dump_invalid_creds(const struct cred *cred, const char *label, | |||
799 | atomic_read(&cred->usage), | 799 | atomic_read(&cred->usage), |
800 | read_cred_subscribers(cred)); | 800 | read_cred_subscribers(cred)); |
801 | printk(KERN_ERR "CRED: ->*uid = { %d,%d,%d,%d }\n", | 801 | printk(KERN_ERR "CRED: ->*uid = { %d,%d,%d,%d }\n", |
802 | cred->uid, cred->euid, cred->suid, cred->fsuid); | 802 | from_kuid_munged(&init_user_ns, cred->uid), |
803 | from_kuid_munged(&init_user_ns, cred->euid), | ||
804 | from_kuid_munged(&init_user_ns, cred->suid), | ||
805 | from_kuid_munged(&init_user_ns, cred->fsuid)); | ||
803 | printk(KERN_ERR "CRED: ->*gid = { %d,%d,%d,%d }\n", | 806 | printk(KERN_ERR "CRED: ->*gid = { %d,%d,%d,%d }\n", |
804 | cred->gid, cred->egid, cred->sgid, cred->fsgid); | 807 | from_kgid_munged(&init_user_ns, cred->gid), |
808 | from_kgid_munged(&init_user_ns, cred->egid), | ||
809 | from_kgid_munged(&init_user_ns, cred->sgid), | ||
810 | from_kgid_munged(&init_user_ns, cred->fsgid)); | ||
805 | #ifdef CONFIG_SECURITY | 811 | #ifdef CONFIG_SECURITY |
806 | printk(KERN_ERR "CRED: ->security is %p\n", cred->security); | 812 | printk(KERN_ERR "CRED: ->security is %p\n", cred->security); |
807 | if ((unsigned long) cred->security >= PAGE_SIZE && | 813 | if ((unsigned long) cred->security >= PAGE_SIZE && |
diff --git a/kernel/pid.c b/kernel/pid.c index e86b291ad834..aebd4f5aaf41 100644 --- a/kernel/pid.c +++ b/kernel/pid.c | |||
@@ -479,6 +479,7 @@ pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns) | |||
479 | } | 479 | } |
480 | return nr; | 480 | return nr; |
481 | } | 481 | } |
482 | EXPORT_SYMBOL_GPL(pid_nr_ns); | ||
482 | 483 | ||
483 | pid_t pid_vnr(struct pid *pid) | 484 | pid_t pid_vnr(struct pid *pid) |
484 | { | 485 | { |
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 6144bab8fd8e..478bad2745e3 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/proc_fs.h> | 17 | #include <linux/proc_fs.h> |
18 | #include <linux/reboot.h> | 18 | #include <linux/reboot.h> |
19 | #include <linux/export.h> | ||
19 | 20 | ||
20 | #define BITS_PER_PAGE (PAGE_SIZE*8) | 21 | #define BITS_PER_PAGE (PAGE_SIZE*8) |
21 | 22 | ||
@@ -144,6 +145,7 @@ void free_pid_ns(struct kref *kref) | |||
144 | if (parent != NULL) | 145 | if (parent != NULL) |
145 | put_pid_ns(parent); | 146 | put_pid_ns(parent); |
146 | } | 147 | } |
148 | EXPORT_SYMBOL_GPL(free_pid_ns); | ||
147 | 149 | ||
148 | void zap_pid_ns_processes(struct pid_namespace *pid_ns) | 150 | void zap_pid_ns_processes(struct pid_namespace *pid_ns) |
149 | { | 151 | { |
diff --git a/kernel/taskstats.c b/kernel/taskstats.c index d0a32796550f..3880df2acf05 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/cgroup.h> | 27 | #include <linux/cgroup.h> |
28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
29 | #include <linux/file.h> | 29 | #include <linux/file.h> |
30 | #include <linux/pid_namespace.h> | ||
30 | #include <net/genetlink.h> | 31 | #include <net/genetlink.h> |
31 | #include <linux/atomic.h> | 32 | #include <linux/atomic.h> |
32 | 33 | ||
@@ -174,7 +175,9 @@ static void send_cpu_listeners(struct sk_buff *skb, | |||
174 | up_write(&listeners->sem); | 175 | up_write(&listeners->sem); |
175 | } | 176 | } |
176 | 177 | ||
177 | static void fill_stats(struct task_struct *tsk, struct taskstats *stats) | 178 | static void fill_stats(struct user_namespace *user_ns, |
179 | struct pid_namespace *pid_ns, | ||
180 | struct task_struct *tsk, struct taskstats *stats) | ||
178 | { | 181 | { |
179 | memset(stats, 0, sizeof(*stats)); | 182 | memset(stats, 0, sizeof(*stats)); |
180 | /* | 183 | /* |
@@ -190,7 +193,7 @@ static void fill_stats(struct task_struct *tsk, struct taskstats *stats) | |||
190 | stats->version = TASKSTATS_VERSION; | 193 | stats->version = TASKSTATS_VERSION; |
191 | stats->nvcsw = tsk->nvcsw; | 194 | stats->nvcsw = tsk->nvcsw; |
192 | stats->nivcsw = tsk->nivcsw; | 195 | stats->nivcsw = tsk->nivcsw; |
193 | bacct_add_tsk(stats, tsk); | 196 | bacct_add_tsk(user_ns, pid_ns, stats, tsk); |
194 | 197 | ||
195 | /* fill in extended acct fields */ | 198 | /* fill in extended acct fields */ |
196 | xacct_add_tsk(stats, tsk); | 199 | xacct_add_tsk(stats, tsk); |
@@ -207,7 +210,7 @@ static int fill_stats_for_pid(pid_t pid, struct taskstats *stats) | |||
207 | rcu_read_unlock(); | 210 | rcu_read_unlock(); |
208 | if (!tsk) | 211 | if (!tsk) |
209 | return -ESRCH; | 212 | return -ESRCH; |
210 | fill_stats(tsk, stats); | 213 | fill_stats(current_user_ns(), task_active_pid_ns(current), tsk, stats); |
211 | put_task_struct(tsk); | 214 | put_task_struct(tsk); |
212 | return 0; | 215 | return 0; |
213 | } | 216 | } |
@@ -291,6 +294,12 @@ static int add_del_listener(pid_t pid, const struct cpumask *mask, int isadd) | |||
291 | if (!cpumask_subset(mask, cpu_possible_mask)) | 294 | if (!cpumask_subset(mask, cpu_possible_mask)) |
292 | return -EINVAL; | 295 | return -EINVAL; |
293 | 296 | ||
297 | if (current_user_ns() != &init_user_ns) | ||
298 | return -EINVAL; | ||
299 | |||
300 | if (task_active_pid_ns(current) != &init_pid_ns) | ||
301 | return -EINVAL; | ||
302 | |||
294 | if (isadd == REGISTER) { | 303 | if (isadd == REGISTER) { |
295 | for_each_cpu(cpu, mask) { | 304 | for_each_cpu(cpu, mask) { |
296 | s = kmalloc_node(sizeof(struct listener), | 305 | s = kmalloc_node(sizeof(struct listener), |
@@ -631,11 +640,12 @@ void taskstats_exit(struct task_struct *tsk, int group_dead) | |||
631 | if (rc < 0) | 640 | if (rc < 0) |
632 | return; | 641 | return; |
633 | 642 | ||
634 | stats = mk_reply(rep_skb, TASKSTATS_TYPE_PID, tsk->pid); | 643 | stats = mk_reply(rep_skb, TASKSTATS_TYPE_PID, |
644 | task_pid_nr_ns(tsk, &init_pid_ns)); | ||
635 | if (!stats) | 645 | if (!stats) |
636 | goto err; | 646 | goto err; |
637 | 647 | ||
638 | fill_stats(tsk, stats); | 648 | fill_stats(&init_user_ns, &init_pid_ns, tsk, stats); |
639 | 649 | ||
640 | /* | 650 | /* |
641 | * Doesn't matter if tsk is the leader or the last group member leaving | 651 | * Doesn't matter if tsk is the leader or the last group member leaving |
@@ -643,7 +653,8 @@ void taskstats_exit(struct task_struct *tsk, int group_dead) | |||
643 | if (!is_thread_group || !group_dead) | 653 | if (!is_thread_group || !group_dead) |
644 | goto send; | 654 | goto send; |
645 | 655 | ||
646 | stats = mk_reply(rep_skb, TASKSTATS_TYPE_TGID, tsk->tgid); | 656 | stats = mk_reply(rep_skb, TASKSTATS_TYPE_TGID, |
657 | task_tgid_nr_ns(tsk, &init_pid_ns)); | ||
647 | if (!stats) | 658 | if (!stats) |
648 | goto err; | 659 | goto err; |
649 | 660 | ||
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 1ec5c1dab629..cdcb59450b49 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -2061,7 +2061,8 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter) | |||
2061 | seq_puts(m, "# -----------------\n"); | 2061 | seq_puts(m, "# -----------------\n"); |
2062 | seq_printf(m, "# | task: %.16s-%d " | 2062 | seq_printf(m, "# | task: %.16s-%d " |
2063 | "(uid:%d nice:%ld policy:%ld rt_prio:%ld)\n", | 2063 | "(uid:%d nice:%ld policy:%ld rt_prio:%ld)\n", |
2064 | data->comm, data->pid, data->uid, data->nice, | 2064 | data->comm, data->pid, |
2065 | from_kuid_munged(seq_user_ns(m), data->uid), data->nice, | ||
2065 | data->policy, data->rt_priority); | 2066 | data->policy, data->rt_priority); |
2066 | seq_puts(m, "# -----------------\n"); | 2067 | seq_puts(m, "# -----------------\n"); |
2067 | 2068 | ||
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 63a2da0b9a6e..c15f528c1af4 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -147,7 +147,7 @@ struct trace_array_cpu { | |||
147 | unsigned long skipped_entries; | 147 | unsigned long skipped_entries; |
148 | cycle_t preempt_timestamp; | 148 | cycle_t preempt_timestamp; |
149 | pid_t pid; | 149 | pid_t pid; |
150 | uid_t uid; | 150 | kuid_t uid; |
151 | char comm[TASK_COMM_LEN]; | 151 | char comm[TASK_COMM_LEN]; |
152 | }; | 152 | }; |
153 | 153 | ||
diff --git a/kernel/tsacct.c b/kernel/tsacct.c index 23b4d784ebdd..625df0b44690 100644 --- a/kernel/tsacct.c +++ b/kernel/tsacct.c | |||
@@ -26,7 +26,9 @@ | |||
26 | /* | 26 | /* |
27 | * fill in basic accounting fields | 27 | * fill in basic accounting fields |
28 | */ | 28 | */ |
29 | void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) | 29 | void bacct_add_tsk(struct user_namespace *user_ns, |
30 | struct pid_namespace *pid_ns, | ||
31 | struct taskstats *stats, struct task_struct *tsk) | ||
30 | { | 32 | { |
31 | const struct cred *tcred; | 33 | const struct cred *tcred; |
32 | struct timespec uptime, ts; | 34 | struct timespec uptime, ts; |
@@ -55,13 +57,13 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) | |||
55 | stats->ac_flag |= AXSIG; | 57 | stats->ac_flag |= AXSIG; |
56 | stats->ac_nice = task_nice(tsk); | 58 | stats->ac_nice = task_nice(tsk); |
57 | stats->ac_sched = tsk->policy; | 59 | stats->ac_sched = tsk->policy; |
58 | stats->ac_pid = tsk->pid; | 60 | stats->ac_pid = task_pid_nr_ns(tsk, pid_ns); |
59 | rcu_read_lock(); | 61 | rcu_read_lock(); |
60 | tcred = __task_cred(tsk); | 62 | tcred = __task_cred(tsk); |
61 | stats->ac_uid = tcred->uid; | 63 | stats->ac_uid = from_kuid_munged(user_ns, tcred->uid); |
62 | stats->ac_gid = tcred->gid; | 64 | stats->ac_gid = from_kgid_munged(user_ns, tcred->gid); |
63 | stats->ac_ppid = pid_alive(tsk) ? | 65 | stats->ac_ppid = pid_alive(tsk) ? |
64 | rcu_dereference(tsk->real_parent)->tgid : 0; | 66 | task_tgid_nr_ns(rcu_dereference(tsk->real_parent), pid_ns) : 0; |
65 | rcu_read_unlock(); | 67 | rcu_read_unlock(); |
66 | stats->ac_utime = cputime_to_usecs(tsk->utime); | 68 | stats->ac_utime = cputime_to_usecs(tsk->utime); |
67 | stats->ac_stime = cputime_to_usecs(tsk->stime); | 69 | stats->ac_stime = cputime_to_usecs(tsk->stime); |
diff --git a/kernel/user.c b/kernel/user.c index b815fefbe76f..750acffbe9ec 100644 --- a/kernel/user.c +++ b/kernel/user.c | |||
@@ -38,6 +38,14 @@ struct user_namespace init_user_ns = { | |||
38 | .count = 4294967295U, | 38 | .count = 4294967295U, |
39 | }, | 39 | }, |
40 | }, | 40 | }, |
41 | .projid_map = { | ||
42 | .nr_extents = 1, | ||
43 | .extent[0] = { | ||
44 | .first = 0, | ||
45 | .lower_first = 0, | ||
46 | .count = 4294967295U, | ||
47 | }, | ||
48 | }, | ||
41 | .kref = { | 49 | .kref = { |
42 | .refcount = ATOMIC_INIT(3), | 50 | .refcount = ATOMIC_INIT(3), |
43 | }, | 51 | }, |
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 86602316422d..456a6b9fba34 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
20 | #include <linux/uaccess.h> | 20 | #include <linux/uaccess.h> |
21 | #include <linux/ctype.h> | 21 | #include <linux/ctype.h> |
22 | #include <linux/projid.h> | ||
22 | 23 | ||
23 | static struct kmem_cache *user_ns_cachep __read_mostly; | 24 | static struct kmem_cache *user_ns_cachep __read_mostly; |
24 | 25 | ||
@@ -295,6 +296,75 @@ gid_t from_kgid_munged(struct user_namespace *targ, kgid_t kgid) | |||
295 | } | 296 | } |
296 | EXPORT_SYMBOL(from_kgid_munged); | 297 | EXPORT_SYMBOL(from_kgid_munged); |
297 | 298 | ||
299 | /** | ||
300 | * make_kprojid - Map a user-namespace projid pair into a kprojid. | ||
301 | * @ns: User namespace that the projid is in | ||
302 | * @projid: Project identifier | ||
303 | * | ||
304 | * Maps a user-namespace uid pair into a kernel internal kuid, | ||
305 | * and returns that kuid. | ||
306 | * | ||
307 | * When there is no mapping defined for the user-namespace projid | ||
308 | * pair INVALID_PROJID is returned. Callers are expected to test | ||
309 | * for and handle handle INVALID_PROJID being returned. INVALID_PROJID | ||
310 | * may be tested for using projid_valid(). | ||
311 | */ | ||
312 | kprojid_t make_kprojid(struct user_namespace *ns, projid_t projid) | ||
313 | { | ||
314 | /* Map the uid to a global kernel uid */ | ||
315 | return KPROJIDT_INIT(map_id_down(&ns->projid_map, projid)); | ||
316 | } | ||
317 | EXPORT_SYMBOL(make_kprojid); | ||
318 | |||
319 | /** | ||
320 | * from_kprojid - Create a projid from a kprojid user-namespace pair. | ||
321 | * @targ: The user namespace we want a projid in. | ||
322 | * @kprojid: The kernel internal project identifier to start with. | ||
323 | * | ||
324 | * Map @kprojid into the user-namespace specified by @targ and | ||
325 | * return the resulting projid. | ||
326 | * | ||
327 | * There is always a mapping into the initial user_namespace. | ||
328 | * | ||
329 | * If @kprojid has no mapping in @targ (projid_t)-1 is returned. | ||
330 | */ | ||
331 | projid_t from_kprojid(struct user_namespace *targ, kprojid_t kprojid) | ||
332 | { | ||
333 | /* Map the uid from a global kernel uid */ | ||
334 | return map_id_up(&targ->projid_map, __kprojid_val(kprojid)); | ||
335 | } | ||
336 | EXPORT_SYMBOL(from_kprojid); | ||
337 | |||
338 | /** | ||
339 | * from_kprojid_munged - Create a projiid from a kprojid user-namespace pair. | ||
340 | * @targ: The user namespace we want a projid in. | ||
341 | * @kprojid: The kernel internal projid to start with. | ||
342 | * | ||
343 | * Map @kprojid into the user-namespace specified by @targ and | ||
344 | * return the resulting projid. | ||
345 | * | ||
346 | * There is always a mapping into the initial user_namespace. | ||
347 | * | ||
348 | * Unlike from_kprojid from_kprojid_munged never fails and always | ||
349 | * returns a valid projid. This makes from_kprojid_munged | ||
350 | * appropriate for use in syscalls like stat and where | ||
351 | * failing the system call and failing to provide a valid projid are | ||
352 | * not an options. | ||
353 | * | ||
354 | * If @kprojid has no mapping in @targ OVERFLOW_PROJID is returned. | ||
355 | */ | ||
356 | projid_t from_kprojid_munged(struct user_namespace *targ, kprojid_t kprojid) | ||
357 | { | ||
358 | projid_t projid; | ||
359 | projid = from_kprojid(targ, kprojid); | ||
360 | |||
361 | if (projid == (projid_t) -1) | ||
362 | projid = OVERFLOW_PROJID; | ||
363 | return projid; | ||
364 | } | ||
365 | EXPORT_SYMBOL(from_kprojid_munged); | ||
366 | |||
367 | |||
298 | static int uid_m_show(struct seq_file *seq, void *v) | 368 | static int uid_m_show(struct seq_file *seq, void *v) |
299 | { | 369 | { |
300 | struct user_namespace *ns = seq->private; | 370 | struct user_namespace *ns = seq->private; |
@@ -337,6 +407,27 @@ static int gid_m_show(struct seq_file *seq, void *v) | |||
337 | return 0; | 407 | return 0; |
338 | } | 408 | } |
339 | 409 | ||
410 | static int projid_m_show(struct seq_file *seq, void *v) | ||
411 | { | ||
412 | struct user_namespace *ns = seq->private; | ||
413 | struct uid_gid_extent *extent = v; | ||
414 | struct user_namespace *lower_ns; | ||
415 | projid_t lower; | ||
416 | |||
417 | lower_ns = seq_user_ns(seq); | ||
418 | if ((lower_ns == ns) && lower_ns->parent) | ||
419 | lower_ns = lower_ns->parent; | ||
420 | |||
421 | lower = from_kprojid(lower_ns, KPROJIDT_INIT(extent->lower_first)); | ||
422 | |||
423 | seq_printf(seq, "%10u %10u %10u\n", | ||
424 | extent->first, | ||
425 | lower, | ||
426 | extent->count); | ||
427 | |||
428 | return 0; | ||
429 | } | ||
430 | |||
340 | static void *m_start(struct seq_file *seq, loff_t *ppos, struct uid_gid_map *map) | 431 | static void *m_start(struct seq_file *seq, loff_t *ppos, struct uid_gid_map *map) |
341 | { | 432 | { |
342 | struct uid_gid_extent *extent = NULL; | 433 | struct uid_gid_extent *extent = NULL; |
@@ -362,6 +453,13 @@ static void *gid_m_start(struct seq_file *seq, loff_t *ppos) | |||
362 | return m_start(seq, ppos, &ns->gid_map); | 453 | return m_start(seq, ppos, &ns->gid_map); |
363 | } | 454 | } |
364 | 455 | ||
456 | static void *projid_m_start(struct seq_file *seq, loff_t *ppos) | ||
457 | { | ||
458 | struct user_namespace *ns = seq->private; | ||
459 | |||
460 | return m_start(seq, ppos, &ns->projid_map); | ||
461 | } | ||
462 | |||
365 | static void *m_next(struct seq_file *seq, void *v, loff_t *pos) | 463 | static void *m_next(struct seq_file *seq, void *v, loff_t *pos) |
366 | { | 464 | { |
367 | (*pos)++; | 465 | (*pos)++; |
@@ -387,6 +485,13 @@ struct seq_operations proc_gid_seq_operations = { | |||
387 | .show = gid_m_show, | 485 | .show = gid_m_show, |
388 | }; | 486 | }; |
389 | 487 | ||
488 | struct seq_operations proc_projid_seq_operations = { | ||
489 | .start = projid_m_start, | ||
490 | .stop = m_stop, | ||
491 | .next = m_next, | ||
492 | .show = projid_m_show, | ||
493 | }; | ||
494 | |||
390 | static DEFINE_MUTEX(id_map_mutex); | 495 | static DEFINE_MUTEX(id_map_mutex); |
391 | 496 | ||
392 | static ssize_t map_write(struct file *file, const char __user *buf, | 497 | static ssize_t map_write(struct file *file, const char __user *buf, |
@@ -434,7 +539,7 @@ static ssize_t map_write(struct file *file, const char __user *buf, | |||
434 | /* Require the appropriate privilege CAP_SETUID or CAP_SETGID | 539 | /* Require the appropriate privilege CAP_SETUID or CAP_SETGID |
435 | * over the user namespace in order to set the id mapping. | 540 | * over the user namespace in order to set the id mapping. |
436 | */ | 541 | */ |
437 | if (!ns_capable(ns, cap_setid)) | 542 | if (cap_valid(cap_setid) && !ns_capable(ns, cap_setid)) |
438 | goto out; | 543 | goto out; |
439 | 544 | ||
440 | /* Get a buffer */ | 545 | /* Get a buffer */ |
@@ -584,9 +689,30 @@ ssize_t proc_gid_map_write(struct file *file, const char __user *buf, size_t siz | |||
584 | &ns->gid_map, &ns->parent->gid_map); | 689 | &ns->gid_map, &ns->parent->gid_map); |
585 | } | 690 | } |
586 | 691 | ||
692 | ssize_t proc_projid_map_write(struct file *file, const char __user *buf, size_t size, loff_t *ppos) | ||
693 | { | ||
694 | struct seq_file *seq = file->private_data; | ||
695 | struct user_namespace *ns = seq->private; | ||
696 | struct user_namespace *seq_ns = seq_user_ns(seq); | ||
697 | |||
698 | if (!ns->parent) | ||
699 | return -EPERM; | ||
700 | |||
701 | if ((seq_ns != ns) && (seq_ns != ns->parent)) | ||
702 | return -EPERM; | ||
703 | |||
704 | /* Anyone can set any valid project id no capability needed */ | ||
705 | return map_write(file, buf, size, ppos, -1, | ||
706 | &ns->projid_map, &ns->parent->projid_map); | ||
707 | } | ||
708 | |||
587 | static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid, | 709 | static bool new_idmap_permitted(struct user_namespace *ns, int cap_setid, |
588 | struct uid_gid_map *new_map) | 710 | struct uid_gid_map *new_map) |
589 | { | 711 | { |
712 | /* Allow anyone to set a mapping that doesn't require privilege */ | ||
713 | if (!cap_valid(cap_setid)) | ||
714 | return true; | ||
715 | |||
590 | /* Allow the specified ids if we have the appropriate capability | 716 | /* Allow the specified ids if we have the appropriate capability |
591 | * (CAP_SETUID or CAP_SETGID) over the parent user namespace. | 717 | * (CAP_SETUID or CAP_SETGID) over the parent user namespace. |
592 | */ | 718 | */ |
diff --git a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c index b5b1a221c242..c30f3a0717fb 100644 --- a/net/appletalk/atalk_proc.c +++ b/net/appletalk/atalk_proc.c | |||
@@ -183,7 +183,8 @@ static int atalk_seq_socket_show(struct seq_file *seq, void *v) | |||
183 | ntohs(at->dest_net), at->dest_node, at->dest_port, | 183 | ntohs(at->dest_net), at->dest_node, at->dest_port, |
184 | sk_wmem_alloc_get(s), | 184 | sk_wmem_alloc_get(s), |
185 | sk_rmem_alloc_get(s), | 185 | sk_rmem_alloc_get(s), |
186 | s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); | 186 | s->sk_state, |
187 | from_kuid_munged(seq_user_ns(seq), sock_i_uid(s))); | ||
187 | out: | 188 | out: |
188 | return 0; | 189 | return 0; |
189 | } | 190 | } |
diff --git a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c index e3c579ba6325..957999e43ff7 100644 --- a/net/ax25/ax25_uid.c +++ b/net/ax25/ax25_uid.c | |||
@@ -51,14 +51,14 @@ int ax25_uid_policy; | |||
51 | 51 | ||
52 | EXPORT_SYMBOL(ax25_uid_policy); | 52 | EXPORT_SYMBOL(ax25_uid_policy); |
53 | 53 | ||
54 | ax25_uid_assoc *ax25_findbyuid(uid_t uid) | 54 | ax25_uid_assoc *ax25_findbyuid(kuid_t uid) |
55 | { | 55 | { |
56 | ax25_uid_assoc *ax25_uid, *res = NULL; | 56 | ax25_uid_assoc *ax25_uid, *res = NULL; |
57 | struct hlist_node *node; | 57 | struct hlist_node *node; |
58 | 58 | ||
59 | read_lock(&ax25_uid_lock); | 59 | read_lock(&ax25_uid_lock); |
60 | ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) { | 60 | ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) { |
61 | if (ax25_uid->uid == uid) { | 61 | if (uid_eq(ax25_uid->uid, uid)) { |
62 | ax25_uid_hold(ax25_uid); | 62 | ax25_uid_hold(ax25_uid); |
63 | res = ax25_uid; | 63 | res = ax25_uid; |
64 | break; | 64 | break; |
@@ -84,7 +84,7 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) | |||
84 | read_lock(&ax25_uid_lock); | 84 | read_lock(&ax25_uid_lock); |
85 | ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) { | 85 | ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) { |
86 | if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0) { | 86 | if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0) { |
87 | res = ax25_uid->uid; | 87 | res = from_kuid_munged(current_user_ns(), ax25_uid->uid); |
88 | break; | 88 | break; |
89 | } | 89 | } |
90 | } | 90 | } |
@@ -93,9 +93,14 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) | |||
93 | return res; | 93 | return res; |
94 | 94 | ||
95 | case SIOCAX25ADDUID: | 95 | case SIOCAX25ADDUID: |
96 | { | ||
97 | kuid_t sax25_kuid; | ||
96 | if (!capable(CAP_NET_ADMIN)) | 98 | if (!capable(CAP_NET_ADMIN)) |
97 | return -EPERM; | 99 | return -EPERM; |
98 | user = ax25_findbyuid(sax->sax25_uid); | 100 | sax25_kuid = make_kuid(current_user_ns(), sax->sax25_uid); |
101 | if (!uid_valid(sax25_kuid)) | ||
102 | return -EINVAL; | ||
103 | user = ax25_findbyuid(sax25_kuid); | ||
99 | if (user) { | 104 | if (user) { |
100 | ax25_uid_put(user); | 105 | ax25_uid_put(user); |
101 | return -EEXIST; | 106 | return -EEXIST; |
@@ -106,7 +111,7 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) | |||
106 | return -ENOMEM; | 111 | return -ENOMEM; |
107 | 112 | ||
108 | atomic_set(&ax25_uid->refcount, 1); | 113 | atomic_set(&ax25_uid->refcount, 1); |
109 | ax25_uid->uid = sax->sax25_uid; | 114 | ax25_uid->uid = sax25_kuid; |
110 | ax25_uid->call = sax->sax25_call; | 115 | ax25_uid->call = sax->sax25_call; |
111 | 116 | ||
112 | write_lock(&ax25_uid_lock); | 117 | write_lock(&ax25_uid_lock); |
@@ -114,7 +119,7 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) | |||
114 | write_unlock(&ax25_uid_lock); | 119 | write_unlock(&ax25_uid_lock); |
115 | 120 | ||
116 | return 0; | 121 | return 0; |
117 | 122 | } | |
118 | case SIOCAX25DELUID: | 123 | case SIOCAX25DELUID: |
119 | if (!capable(CAP_NET_ADMIN)) | 124 | if (!capable(CAP_NET_ADMIN)) |
120 | return -EPERM; | 125 | return -EPERM; |
@@ -172,7 +177,9 @@ static int ax25_uid_seq_show(struct seq_file *seq, void *v) | |||
172 | struct ax25_uid_assoc *pt; | 177 | struct ax25_uid_assoc *pt; |
173 | 178 | ||
174 | pt = hlist_entry(v, struct ax25_uid_assoc, uid_node); | 179 | pt = hlist_entry(v, struct ax25_uid_assoc, uid_node); |
175 | seq_printf(seq, "%6d %s\n", pt->uid, ax2asc(buf, &pt->call)); | 180 | seq_printf(seq, "%6d %s\n", |
181 | from_kuid_munged(seq_user_ns(seq), pt->uid), | ||
182 | ax2asc(buf, &pt->call)); | ||
176 | } | 183 | } |
177 | return 0; | 184 | return 0; |
178 | } | 185 | } |
diff --git a/net/core/dev.c b/net/core/dev.c index 36c4a0cdb6c1..17e912f9b711 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -4512,8 +4512,8 @@ static void dev_change_rx_flags(struct net_device *dev, int flags) | |||
4512 | static int __dev_set_promiscuity(struct net_device *dev, int inc) | 4512 | static int __dev_set_promiscuity(struct net_device *dev, int inc) |
4513 | { | 4513 | { |
4514 | unsigned int old_flags = dev->flags; | 4514 | unsigned int old_flags = dev->flags; |
4515 | uid_t uid; | 4515 | kuid_t uid; |
4516 | gid_t gid; | 4516 | kgid_t gid; |
4517 | 4517 | ||
4518 | ASSERT_RTNL(); | 4518 | ASSERT_RTNL(); |
4519 | 4519 | ||
@@ -4544,8 +4544,9 @@ static int __dev_set_promiscuity(struct net_device *dev, int inc) | |||
4544 | "dev=%s prom=%d old_prom=%d auid=%u uid=%u gid=%u ses=%u", | 4544 | "dev=%s prom=%d old_prom=%d auid=%u uid=%u gid=%u ses=%u", |
4545 | dev->name, (dev->flags & IFF_PROMISC), | 4545 | dev->name, (dev->flags & IFF_PROMISC), |
4546 | (old_flags & IFF_PROMISC), | 4546 | (old_flags & IFF_PROMISC), |
4547 | audit_get_loginuid(current), | 4547 | from_kuid(&init_user_ns, audit_get_loginuid(current)), |
4548 | uid, gid, | 4548 | from_kuid(&init_user_ns, uid), |
4549 | from_kgid(&init_user_ns, gid), | ||
4549 | audit_get_sessionid(current)); | 4550 | audit_get_sessionid(current)); |
4550 | } | 4551 | } |
4551 | 4552 | ||
diff --git a/net/core/scm.c b/net/core/scm.c index 040cebeed45b..6ab491d6c26f 100644 --- a/net/core/scm.c +++ b/net/core/scm.c | |||
@@ -45,12 +45,17 @@ | |||
45 | static __inline__ int scm_check_creds(struct ucred *creds) | 45 | static __inline__ int scm_check_creds(struct ucred *creds) |
46 | { | 46 | { |
47 | const struct cred *cred = current_cred(); | 47 | const struct cred *cred = current_cred(); |
48 | kuid_t uid = make_kuid(cred->user_ns, creds->uid); | ||
49 | kgid_t gid = make_kgid(cred->user_ns, creds->gid); | ||
50 | |||
51 | if (!uid_valid(uid) || !gid_valid(gid)) | ||
52 | return -EINVAL; | ||
48 | 53 | ||
49 | if ((creds->pid == task_tgid_vnr(current) || capable(CAP_SYS_ADMIN)) && | 54 | if ((creds->pid == task_tgid_vnr(current) || capable(CAP_SYS_ADMIN)) && |
50 | ((creds->uid == cred->uid || creds->uid == cred->euid || | 55 | ((uid_eq(uid, cred->uid) || uid_eq(uid, cred->euid) || |
51 | creds->uid == cred->suid) || capable(CAP_SETUID)) && | 56 | uid_eq(uid, cred->suid)) || capable(CAP_SETUID)) && |
52 | ((creds->gid == cred->gid || creds->gid == cred->egid || | 57 | ((gid_eq(gid, cred->gid) || gid_eq(gid, cred->egid) || |
53 | creds->gid == cred->sgid) || capable(CAP_SETGID))) { | 58 | gid_eq(gid, cred->sgid)) || capable(CAP_SETGID))) { |
54 | return 0; | 59 | return 0; |
55 | } | 60 | } |
56 | return -EPERM; | 61 | return -EPERM; |
@@ -149,6 +154,9 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) | |||
149 | goto error; | 154 | goto error; |
150 | break; | 155 | break; |
151 | case SCM_CREDENTIALS: | 156 | case SCM_CREDENTIALS: |
157 | { | ||
158 | kuid_t uid; | ||
159 | kgid_t gid; | ||
152 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) | 160 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) |
153 | goto error; | 161 | goto error; |
154 | memcpy(&p->creds, CMSG_DATA(cmsg), sizeof(struct ucred)); | 162 | memcpy(&p->creds, CMSG_DATA(cmsg), sizeof(struct ucred)); |
@@ -166,22 +174,29 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) | |||
166 | p->pid = pid; | 174 | p->pid = pid; |
167 | } | 175 | } |
168 | 176 | ||
177 | err = -EINVAL; | ||
178 | uid = make_kuid(current_user_ns(), p->creds.uid); | ||
179 | gid = make_kgid(current_user_ns(), p->creds.gid); | ||
180 | if (!uid_valid(uid) || !gid_valid(gid)) | ||
181 | goto error; | ||
182 | |||
169 | if (!p->cred || | 183 | if (!p->cred || |
170 | (p->cred->euid != p->creds.uid) || | 184 | !uid_eq(p->cred->euid, uid) || |
171 | (p->cred->egid != p->creds.gid)) { | 185 | !gid_eq(p->cred->egid, gid)) { |
172 | struct cred *cred; | 186 | struct cred *cred; |
173 | err = -ENOMEM; | 187 | err = -ENOMEM; |
174 | cred = prepare_creds(); | 188 | cred = prepare_creds(); |
175 | if (!cred) | 189 | if (!cred) |
176 | goto error; | 190 | goto error; |
177 | 191 | ||
178 | cred->uid = cred->euid = p->creds.uid; | 192 | cred->uid = cred->euid = uid; |
179 | cred->gid = cred->egid = p->creds.gid; | 193 | cred->gid = cred->egid = gid; |
180 | if (p->cred) | 194 | if (p->cred) |
181 | put_cred(p->cred); | 195 | put_cred(p->cred); |
182 | p->cred = cred; | 196 | p->cred = cred; |
183 | } | 197 | } |
184 | break; | 198 | break; |
199 | } | ||
185 | default: | 200 | default: |
186 | goto error; | 201 | goto error; |
187 | } | 202 | } |
diff --git a/net/core/sock.c b/net/core/sock.c index 341fa1c3bd69..12cddd037bce 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -858,8 +858,8 @@ void cred_to_ucred(struct pid *pid, const struct cred *cred, | |||
858 | if (cred) { | 858 | if (cred) { |
859 | struct user_namespace *current_ns = current_user_ns(); | 859 | struct user_namespace *current_ns = current_user_ns(); |
860 | 860 | ||
861 | ucred->uid = from_kuid(current_ns, cred->euid); | 861 | ucred->uid = from_kuid_munged(current_ns, cred->euid); |
862 | ucred->gid = from_kgid(current_ns, cred->egid); | 862 | ucred->gid = from_kgid_munged(current_ns, cred->egid); |
863 | } | 863 | } |
864 | } | 864 | } |
865 | EXPORT_SYMBOL_GPL(cred_to_ucred); | 865 | EXPORT_SYMBOL_GPL(cred_to_ucred); |
@@ -1528,12 +1528,12 @@ void sock_edemux(struct sk_buff *skb) | |||
1528 | } | 1528 | } |
1529 | EXPORT_SYMBOL(sock_edemux); | 1529 | EXPORT_SYMBOL(sock_edemux); |
1530 | 1530 | ||
1531 | int sock_i_uid(struct sock *sk) | 1531 | kuid_t sock_i_uid(struct sock *sk) |
1532 | { | 1532 | { |
1533 | int uid; | 1533 | kuid_t uid; |
1534 | 1534 | ||
1535 | read_lock_bh(&sk->sk_callback_lock); | 1535 | read_lock_bh(&sk->sk_callback_lock); |
1536 | uid = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : 0; | 1536 | uid = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : GLOBAL_ROOT_UID; |
1537 | read_unlock_bh(&sk->sk_callback_lock); | 1537 | read_unlock_bh(&sk->sk_callback_lock); |
1538 | return uid; | 1538 | return uid; |
1539 | } | 1539 | } |
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c index d9507dd05818..9807945a56d9 100644 --- a/net/dns_resolver/dns_key.c +++ b/net/dns_resolver/dns_key.c | |||
@@ -259,7 +259,8 @@ static int __init init_dns_resolver(void) | |||
259 | if (!cred) | 259 | if (!cred) |
260 | return -ENOMEM; | 260 | return -ENOMEM; |
261 | 261 | ||
262 | keyring = key_alloc(&key_type_keyring, ".dns_resolver", 0, 0, cred, | 262 | keyring = key_alloc(&key_type_keyring, ".dns_resolver", |
263 | GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, | ||
263 | (KEY_POS_ALL & ~KEY_POS_SETATTR) | | 264 | (KEY_POS_ALL & ~KEY_POS_SETATTR) | |
264 | KEY_USR_VIEW | KEY_USR_READ, | 265 | KEY_USR_VIEW | KEY_USR_READ, |
265 | KEY_ALLOC_NOT_IN_QUOTA); | 266 | KEY_ALLOC_NOT_IN_QUOTA); |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 570e61f9611f..8bc005b1435f 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
@@ -69,6 +69,7 @@ static inline void inet_diag_unlock_handler( | |||
69 | 69 | ||
70 | int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, | 70 | int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, |
71 | struct sk_buff *skb, struct inet_diag_req_v2 *req, | 71 | struct sk_buff *skb, struct inet_diag_req_v2 *req, |
72 | struct user_namespace *user_ns, | ||
72 | u32 pid, u32 seq, u16 nlmsg_flags, | 73 | u32 pid, u32 seq, u16 nlmsg_flags, |
73 | const struct nlmsghdr *unlh) | 74 | const struct nlmsghdr *unlh) |
74 | { | 75 | { |
@@ -124,7 +125,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, | |||
124 | } | 125 | } |
125 | #endif | 126 | #endif |
126 | 127 | ||
127 | r->idiag_uid = sock_i_uid(sk); | 128 | r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk)); |
128 | r->idiag_inode = sock_i_ino(sk); | 129 | r->idiag_inode = sock_i_ino(sk); |
129 | 130 | ||
130 | if (ext & (1 << (INET_DIAG_MEMINFO - 1))) { | 131 | if (ext & (1 << (INET_DIAG_MEMINFO - 1))) { |
@@ -199,11 +200,12 @@ EXPORT_SYMBOL_GPL(inet_sk_diag_fill); | |||
199 | 200 | ||
200 | static int inet_csk_diag_fill(struct sock *sk, | 201 | static int inet_csk_diag_fill(struct sock *sk, |
201 | struct sk_buff *skb, struct inet_diag_req_v2 *req, | 202 | struct sk_buff *skb, struct inet_diag_req_v2 *req, |
203 | struct user_namespace *user_ns, | ||
202 | u32 pid, u32 seq, u16 nlmsg_flags, | 204 | u32 pid, u32 seq, u16 nlmsg_flags, |
203 | const struct nlmsghdr *unlh) | 205 | const struct nlmsghdr *unlh) |
204 | { | 206 | { |
205 | return inet_sk_diag_fill(sk, inet_csk(sk), | 207 | return inet_sk_diag_fill(sk, inet_csk(sk), |
206 | skb, req, pid, seq, nlmsg_flags, unlh); | 208 | skb, req, user_ns, pid, seq, nlmsg_flags, unlh); |
207 | } | 209 | } |
208 | 210 | ||
209 | static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, | 211 | static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, |
@@ -256,14 +258,16 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, | |||
256 | } | 258 | } |
257 | 259 | ||
258 | static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, | 260 | static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, |
259 | struct inet_diag_req_v2 *r, u32 pid, u32 seq, u16 nlmsg_flags, | 261 | struct inet_diag_req_v2 *r, |
262 | struct user_namespace *user_ns, | ||
263 | u32 pid, u32 seq, u16 nlmsg_flags, | ||
260 | const struct nlmsghdr *unlh) | 264 | const struct nlmsghdr *unlh) |
261 | { | 265 | { |
262 | if (sk->sk_state == TCP_TIME_WAIT) | 266 | if (sk->sk_state == TCP_TIME_WAIT) |
263 | return inet_twsk_diag_fill((struct inet_timewait_sock *)sk, | 267 | return inet_twsk_diag_fill((struct inet_timewait_sock *)sk, |
264 | skb, r, pid, seq, nlmsg_flags, | 268 | skb, r, pid, seq, nlmsg_flags, |
265 | unlh); | 269 | unlh); |
266 | return inet_csk_diag_fill(sk, skb, r, pid, seq, nlmsg_flags, unlh); | 270 | return inet_csk_diag_fill(sk, skb, r, user_ns, pid, seq, nlmsg_flags, unlh); |
267 | } | 271 | } |
268 | 272 | ||
269 | int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb, | 273 | int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_skb, |
@@ -311,6 +315,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s | |||
311 | } | 315 | } |
312 | 316 | ||
313 | err = sk_diag_fill(sk, rep, req, | 317 | err = sk_diag_fill(sk, rep, req, |
318 | sk_user_ns(NETLINK_CB(in_skb).ssk), | ||
314 | NETLINK_CB(in_skb).pid, | 319 | NETLINK_CB(in_skb).pid, |
315 | nlh->nlmsg_seq, 0, nlh); | 320 | nlh->nlmsg_seq, 0, nlh); |
316 | if (err < 0) { | 321 | if (err < 0) { |
@@ -551,6 +556,7 @@ static int inet_csk_diag_dump(struct sock *sk, | |||
551 | return 0; | 556 | return 0; |
552 | 557 | ||
553 | return inet_csk_diag_fill(sk, skb, r, | 558 | return inet_csk_diag_fill(sk, skb, r, |
559 | sk_user_ns(NETLINK_CB(cb->skb).ssk), | ||
554 | NETLINK_CB(cb->skb).pid, | 560 | NETLINK_CB(cb->skb).pid, |
555 | cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); | 561 | cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); |
556 | } | 562 | } |
@@ -591,7 +597,9 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, | |||
591 | } | 597 | } |
592 | 598 | ||
593 | static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, | 599 | static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, |
594 | struct request_sock *req, u32 pid, u32 seq, | 600 | struct request_sock *req, |
601 | struct user_namespace *user_ns, | ||
602 | u32 pid, u32 seq, | ||
595 | const struct nlmsghdr *unlh) | 603 | const struct nlmsghdr *unlh) |
596 | { | 604 | { |
597 | const struct inet_request_sock *ireq = inet_rsk(req); | 605 | const struct inet_request_sock *ireq = inet_rsk(req); |
@@ -625,7 +633,7 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk, | |||
625 | r->idiag_expires = jiffies_to_msecs(tmo); | 633 | r->idiag_expires = jiffies_to_msecs(tmo); |
626 | r->idiag_rqueue = 0; | 634 | r->idiag_rqueue = 0; |
627 | r->idiag_wqueue = 0; | 635 | r->idiag_wqueue = 0; |
628 | r->idiag_uid = sock_i_uid(sk); | 636 | r->idiag_uid = from_kuid_munged(user_ns, sock_i_uid(sk)); |
629 | r->idiag_inode = 0; | 637 | r->idiag_inode = 0; |
630 | #if IS_ENABLED(CONFIG_IPV6) | 638 | #if IS_ENABLED(CONFIG_IPV6) |
631 | if (r->idiag_family == AF_INET6) { | 639 | if (r->idiag_family == AF_INET6) { |
@@ -702,6 +710,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, | |||
702 | } | 710 | } |
703 | 711 | ||
704 | err = inet_diag_fill_req(skb, sk, req, | 712 | err = inet_diag_fill_req(skb, sk, req, |
713 | sk_user_ns(NETLINK_CB(cb->skb).ssk), | ||
705 | NETLINK_CB(cb->skb).pid, | 714 | NETLINK_CB(cb->skb).pid, |
706 | cb->nlh->nlmsg_seq, cb->nlh); | 715 | cb->nlh->nlmsg_seq, cb->nlh); |
707 | if (err < 0) { | 716 | if (err < 0) { |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 6232d476f37e..8f3d05424a3e 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
@@ -185,10 +185,10 @@ exit: | |||
185 | return sk; | 185 | return sk; |
186 | } | 186 | } |
187 | 187 | ||
188 | static void inet_get_ping_group_range_net(struct net *net, gid_t *low, | 188 | static void inet_get_ping_group_range_net(struct net *net, kgid_t *low, |
189 | gid_t *high) | 189 | kgid_t *high) |
190 | { | 190 | { |
191 | gid_t *data = net->ipv4.sysctl_ping_group_range; | 191 | kgid_t *data = net->ipv4.sysctl_ping_group_range; |
192 | unsigned int seq; | 192 | unsigned int seq; |
193 | 193 | ||
194 | do { | 194 | do { |
@@ -203,19 +203,13 @@ static void inet_get_ping_group_range_net(struct net *net, gid_t *low, | |||
203 | static int ping_init_sock(struct sock *sk) | 203 | static int ping_init_sock(struct sock *sk) |
204 | { | 204 | { |
205 | struct net *net = sock_net(sk); | 205 | struct net *net = sock_net(sk); |
206 | gid_t group = current_egid(); | 206 | kgid_t group = current_egid(); |
207 | gid_t range[2]; | ||
208 | struct group_info *group_info = get_current_groups(); | 207 | struct group_info *group_info = get_current_groups(); |
209 | int i, j, count = group_info->ngroups; | 208 | int i, j, count = group_info->ngroups; |
210 | kgid_t low, high; | 209 | kgid_t low, high; |
211 | 210 | ||
212 | inet_get_ping_group_range_net(net, range, range+1); | 211 | inet_get_ping_group_range_net(net, &low, &high); |
213 | low = make_kgid(&init_user_ns, range[0]); | 212 | if (gid_lte(low, group) && gid_lte(group, high)) |
214 | high = make_kgid(&init_user_ns, range[1]); | ||
215 | if (!gid_valid(low) || !gid_valid(high) || gid_lt(high, low)) | ||
216 | return -EACCES; | ||
217 | |||
218 | if (range[0] <= group && group <= range[1]) | ||
219 | return 0; | 213 | return 0; |
220 | 214 | ||
221 | for (i = 0; i < group_info->nblocks; i++) { | 215 | for (i = 0; i < group_info->nblocks; i++) { |
@@ -845,7 +839,9 @@ static void ping_format_sock(struct sock *sp, struct seq_file *f, | |||
845 | bucket, src, srcp, dest, destp, sp->sk_state, | 839 | bucket, src, srcp, dest, destp, sp->sk_state, |
846 | sk_wmem_alloc_get(sp), | 840 | sk_wmem_alloc_get(sp), |
847 | sk_rmem_alloc_get(sp), | 841 | sk_rmem_alloc_get(sp), |
848 | 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), | 842 | 0, 0L, 0, |
843 | from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)), | ||
844 | 0, sock_i_ino(sp), | ||
849 | atomic_read(&sp->sk_refcnt), sp, | 845 | atomic_read(&sp->sk_refcnt), sp, |
850 | atomic_read(&sp->sk_drops), len); | 846 | atomic_read(&sp->sk_drops), len); |
851 | } | 847 | } |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index d23c6571ba1c..73d1e4df4bf6 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -994,7 +994,9 @@ static void raw_sock_seq_show(struct seq_file *seq, struct sock *sp, int i) | |||
994 | i, src, srcp, dest, destp, sp->sk_state, | 994 | i, src, srcp, dest, destp, sp->sk_state, |
995 | sk_wmem_alloc_get(sp), | 995 | sk_wmem_alloc_get(sp), |
996 | sk_rmem_alloc_get(sp), | 996 | sk_rmem_alloc_get(sp), |
997 | 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), | 997 | 0, 0L, 0, |
998 | from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)), | ||
999 | 0, sock_i_ino(sp), | ||
998 | atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); | 1000 | atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); |
999 | } | 1001 | } |
1000 | 1002 | ||
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 1b5ce96707a3..3e78c79b5586 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
@@ -76,9 +76,9 @@ static int ipv4_local_port_range(ctl_table *table, int write, | |||
76 | } | 76 | } |
77 | 77 | ||
78 | 78 | ||
79 | static void inet_get_ping_group_range_table(struct ctl_table *table, gid_t *low, gid_t *high) | 79 | static void inet_get_ping_group_range_table(struct ctl_table *table, kgid_t *low, kgid_t *high) |
80 | { | 80 | { |
81 | gid_t *data = table->data; | 81 | kgid_t *data = table->data; |
82 | unsigned int seq; | 82 | unsigned int seq; |
83 | do { | 83 | do { |
84 | seq = read_seqbegin(&sysctl_local_ports.lock); | 84 | seq = read_seqbegin(&sysctl_local_ports.lock); |
@@ -89,12 +89,12 @@ static void inet_get_ping_group_range_table(struct ctl_table *table, gid_t *low, | |||
89 | } | 89 | } |
90 | 90 | ||
91 | /* Update system visible IP port range */ | 91 | /* Update system visible IP port range */ |
92 | static void set_ping_group_range(struct ctl_table *table, gid_t range[2]) | 92 | static void set_ping_group_range(struct ctl_table *table, kgid_t low, kgid_t high) |
93 | { | 93 | { |
94 | gid_t *data = table->data; | 94 | kgid_t *data = table->data; |
95 | write_seqlock(&sysctl_local_ports.lock); | 95 | write_seqlock(&sysctl_local_ports.lock); |
96 | data[0] = range[0]; | 96 | data[0] = low; |
97 | data[1] = range[1]; | 97 | data[1] = high; |
98 | write_sequnlock(&sysctl_local_ports.lock); | 98 | write_sequnlock(&sysctl_local_ports.lock); |
99 | } | 99 | } |
100 | 100 | ||
@@ -103,21 +103,33 @@ static int ipv4_ping_group_range(ctl_table *table, int write, | |||
103 | void __user *buffer, | 103 | void __user *buffer, |
104 | size_t *lenp, loff_t *ppos) | 104 | size_t *lenp, loff_t *ppos) |
105 | { | 105 | { |
106 | struct user_namespace *user_ns = current_user_ns(); | ||
106 | int ret; | 107 | int ret; |
107 | gid_t range[2]; | 108 | gid_t urange[2]; |
109 | kgid_t low, high; | ||
108 | ctl_table tmp = { | 110 | ctl_table tmp = { |
109 | .data = &range, | 111 | .data = &urange, |
110 | .maxlen = sizeof(range), | 112 | .maxlen = sizeof(urange), |
111 | .mode = table->mode, | 113 | .mode = table->mode, |
112 | .extra1 = &ip_ping_group_range_min, | 114 | .extra1 = &ip_ping_group_range_min, |
113 | .extra2 = &ip_ping_group_range_max, | 115 | .extra2 = &ip_ping_group_range_max, |
114 | }; | 116 | }; |
115 | 117 | ||
116 | inet_get_ping_group_range_table(table, range, range + 1); | 118 | inet_get_ping_group_range_table(table, &low, &high); |
119 | urange[0] = from_kgid_munged(user_ns, low); | ||
120 | urange[1] = from_kgid_munged(user_ns, high); | ||
117 | ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); | 121 | ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); |
118 | 122 | ||
119 | if (write && ret == 0) | 123 | if (write && ret == 0) { |
120 | set_ping_group_range(table, range); | 124 | low = make_kgid(user_ns, urange[0]); |
125 | high = make_kgid(user_ns, urange[1]); | ||
126 | if (!gid_valid(low) || !gid_valid(high) || | ||
127 | (urange[1] < urange[0]) || gid_lt(high, low)) { | ||
128 | low = make_kgid(&init_user_ns, 1); | ||
129 | high = make_kgid(&init_user_ns, 0); | ||
130 | } | ||
131 | set_ping_group_range(table, low, high); | ||
132 | } | ||
121 | 133 | ||
122 | return ret; | 134 | return ret; |
123 | } | 135 | } |
@@ -786,7 +798,7 @@ static struct ctl_table ipv4_net_table[] = { | |||
786 | { | 798 | { |
787 | .procname = "ping_group_range", | 799 | .procname = "ping_group_range", |
788 | .data = &init_net.ipv4.sysctl_ping_group_range, | 800 | .data = &init_net.ipv4.sysctl_ping_group_range, |
789 | .maxlen = sizeof(init_net.ipv4.sysctl_ping_group_range), | 801 | .maxlen = sizeof(gid_t)*2, |
790 | .mode = 0644, | 802 | .mode = 0644, |
791 | .proc_handler = ipv4_ping_group_range, | 803 | .proc_handler = ipv4_ping_group_range, |
792 | }, | 804 | }, |
@@ -830,8 +842,8 @@ static __net_init int ipv4_sysctl_init_net(struct net *net) | |||
830 | * Sane defaults - nobody may create ping sockets. | 842 | * Sane defaults - nobody may create ping sockets. |
831 | * Boot scripts should set this to distro-specific group. | 843 | * Boot scripts should set this to distro-specific group. |
832 | */ | 844 | */ |
833 | net->ipv4.sysctl_ping_group_range[0] = 1; | 845 | net->ipv4.sysctl_ping_group_range[0] = make_kgid(&init_user_ns, 1); |
834 | net->ipv4.sysctl_ping_group_range[1] = 0; | 846 | net->ipv4.sysctl_ping_group_range[1] = make_kgid(&init_user_ns, 0); |
835 | 847 | ||
836 | tcp_init_mem(net); | 848 | tcp_init_mem(net); |
837 | 849 | ||
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 00a748d14062..be23a0b7b89e 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -2393,7 +2393,7 @@ void tcp_proc_unregister(struct net *net, struct tcp_seq_afinfo *afinfo) | |||
2393 | EXPORT_SYMBOL(tcp_proc_unregister); | 2393 | EXPORT_SYMBOL(tcp_proc_unregister); |
2394 | 2394 | ||
2395 | static void get_openreq4(const struct sock *sk, const struct request_sock *req, | 2395 | static void get_openreq4(const struct sock *sk, const struct request_sock *req, |
2396 | struct seq_file *f, int i, int uid, int *len) | 2396 | struct seq_file *f, int i, kuid_t uid, int *len) |
2397 | { | 2397 | { |
2398 | const struct inet_request_sock *ireq = inet_rsk(req); | 2398 | const struct inet_request_sock *ireq = inet_rsk(req); |
2399 | int ttd = req->expires - jiffies; | 2399 | int ttd = req->expires - jiffies; |
@@ -2410,7 +2410,7 @@ static void get_openreq4(const struct sock *sk, const struct request_sock *req, | |||
2410 | 1, /* timers active (only the expire timer) */ | 2410 | 1, /* timers active (only the expire timer) */ |
2411 | jiffies_to_clock_t(ttd), | 2411 | jiffies_to_clock_t(ttd), |
2412 | req->retrans, | 2412 | req->retrans, |
2413 | uid, | 2413 | from_kuid_munged(seq_user_ns(f), uid), |
2414 | 0, /* non standard timer */ | 2414 | 0, /* non standard timer */ |
2415 | 0, /* open_requests have no inode */ | 2415 | 0, /* open_requests have no inode */ |
2416 | atomic_read(&sk->sk_refcnt), | 2416 | atomic_read(&sk->sk_refcnt), |
@@ -2461,7 +2461,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) | |||
2461 | timer_active, | 2461 | timer_active, |
2462 | jiffies_to_clock_t(timer_expires - jiffies), | 2462 | jiffies_to_clock_t(timer_expires - jiffies), |
2463 | icsk->icsk_retransmits, | 2463 | icsk->icsk_retransmits, |
2464 | sock_i_uid(sk), | 2464 | from_kuid_munged(seq_user_ns(f), sock_i_uid(sk)), |
2465 | icsk->icsk_probes_out, | 2465 | icsk->icsk_probes_out, |
2466 | sock_i_ino(sk), | 2466 | sock_i_ino(sk), |
2467 | atomic_read(&sk->sk_refcnt), sk, | 2467 | atomic_read(&sk->sk_refcnt), sk, |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 2814f66dac64..79c8dbe59b54 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -2115,7 +2115,9 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f, | |||
2115 | bucket, src, srcp, dest, destp, sp->sk_state, | 2115 | bucket, src, srcp, dest, destp, sp->sk_state, |
2116 | sk_wmem_alloc_get(sp), | 2116 | sk_wmem_alloc_get(sp), |
2117 | sk_rmem_alloc_get(sp), | 2117 | sk_rmem_alloc_get(sp), |
2118 | 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), | 2118 | 0, 0L, 0, |
2119 | from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)), | ||
2120 | 0, sock_i_ino(sp), | ||
2119 | atomic_read(&sp->sk_refcnt), sp, | 2121 | atomic_read(&sp->sk_refcnt), sp, |
2120 | atomic_read(&sp->sk_drops), len); | 2122 | atomic_read(&sp->sk_drops), len); |
2121 | } | 2123 | } |
diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c index 16d0960062be..d2f336ea82ca 100644 --- a/net/ipv4/udp_diag.c +++ b/net/ipv4/udp_diag.c | |||
@@ -24,7 +24,9 @@ static int sk_diag_dump(struct sock *sk, struct sk_buff *skb, | |||
24 | if (!inet_diag_bc_sk(bc, sk)) | 24 | if (!inet_diag_bc_sk(bc, sk)) |
25 | return 0; | 25 | return 0; |
26 | 26 | ||
27 | return inet_sk_diag_fill(sk, NULL, skb, req, NETLINK_CB(cb->skb).pid, | 27 | return inet_sk_diag_fill(sk, NULL, skb, req, |
28 | sk_user_ns(NETLINK_CB(cb->skb).ssk), | ||
29 | NETLINK_CB(cb->skb).pid, | ||
28 | cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); | 30 | cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh); |
29 | } | 31 | } |
30 | 32 | ||
@@ -69,6 +71,7 @@ static int udp_dump_one(struct udp_table *tbl, struct sk_buff *in_skb, | |||
69 | goto out; | 71 | goto out; |
70 | 72 | ||
71 | err = inet_sk_diag_fill(sk, NULL, rep, req, | 73 | err = inet_sk_diag_fill(sk, NULL, rep, req, |
74 | sk_user_ns(NETLINK_CB(in_skb).ssk), | ||
72 | NETLINK_CB(in_skb).pid, | 75 | NETLINK_CB(in_skb).pid, |
73 | nlh->nlmsg_seq, 0, nlh); | 76 | nlh->nlmsg_seq, 0, nlh); |
74 | if (err < 0) { | 77 | if (err < 0) { |
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 9772fbd8a3f5..90bbefb57943 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/seq_file.h> | 22 | #include <linux/seq_file.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/export.h> | 24 | #include <linux/export.h> |
25 | #include <linux/pid_namespace.h> | ||
25 | 26 | ||
26 | #include <net/net_namespace.h> | 27 | #include <net/net_namespace.h> |
27 | #include <net/sock.h> | 28 | #include <net/sock.h> |
@@ -91,6 +92,8 @@ static struct ip6_flowlabel *fl_lookup(struct net *net, __be32 label) | |||
91 | static void fl_free(struct ip6_flowlabel *fl) | 92 | static void fl_free(struct ip6_flowlabel *fl) |
92 | { | 93 | { |
93 | if (fl) { | 94 | if (fl) { |
95 | if (fl->share == IPV6_FL_S_PROCESS) | ||
96 | put_pid(fl->owner.pid); | ||
94 | release_net(fl->fl_net); | 97 | release_net(fl->fl_net); |
95 | kfree(fl->opt); | 98 | kfree(fl->opt); |
96 | } | 99 | } |
@@ -394,10 +397,10 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq, | |||
394 | case IPV6_FL_S_ANY: | 397 | case IPV6_FL_S_ANY: |
395 | break; | 398 | break; |
396 | case IPV6_FL_S_PROCESS: | 399 | case IPV6_FL_S_PROCESS: |
397 | fl->owner = current->pid; | 400 | fl->owner.pid = get_task_pid(current, PIDTYPE_PID); |
398 | break; | 401 | break; |
399 | case IPV6_FL_S_USER: | 402 | case IPV6_FL_S_USER: |
400 | fl->owner = current_euid(); | 403 | fl->owner.uid = current_euid(); |
401 | break; | 404 | break; |
402 | default: | 405 | default: |
403 | err = -EINVAL; | 406 | err = -EINVAL; |
@@ -561,7 +564,10 @@ recheck: | |||
561 | err = -EPERM; | 564 | err = -EPERM; |
562 | if (fl1->share == IPV6_FL_S_EXCL || | 565 | if (fl1->share == IPV6_FL_S_EXCL || |
563 | fl1->share != fl->share || | 566 | fl1->share != fl->share || |
564 | fl1->owner != fl->owner) | 567 | ((fl1->share == IPV6_FL_S_PROCESS) && |
568 | (fl1->owner.pid == fl->owner.pid)) || | ||
569 | ((fl1->share == IPV6_FL_S_USER) && | ||
570 | uid_eq(fl1->owner.uid, fl->owner.uid))) | ||
565 | goto release; | 571 | goto release; |
566 | 572 | ||
567 | err = -EINVAL; | 573 | err = -EINVAL; |
@@ -621,6 +627,7 @@ done: | |||
621 | 627 | ||
622 | struct ip6fl_iter_state { | 628 | struct ip6fl_iter_state { |
623 | struct seq_net_private p; | 629 | struct seq_net_private p; |
630 | struct pid_namespace *pid_ns; | ||
624 | int bucket; | 631 | int bucket; |
625 | }; | 632 | }; |
626 | 633 | ||
@@ -699,6 +706,7 @@ static void ip6fl_seq_stop(struct seq_file *seq, void *v) | |||
699 | 706 | ||
700 | static int ip6fl_seq_show(struct seq_file *seq, void *v) | 707 | static int ip6fl_seq_show(struct seq_file *seq, void *v) |
701 | { | 708 | { |
709 | struct ip6fl_iter_state *state = ip6fl_seq_private(seq); | ||
702 | if (v == SEQ_START_TOKEN) | 710 | if (v == SEQ_START_TOKEN) |
703 | seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", | 711 | seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", |
704 | "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); | 712 | "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); |
@@ -708,7 +716,11 @@ static int ip6fl_seq_show(struct seq_file *seq, void *v) | |||
708 | "%05X %-1d %-6d %-6d %-6ld %-8ld %pi6 %-4d\n", | 716 | "%05X %-1d %-6d %-6d %-6ld %-8ld %pi6 %-4d\n", |
709 | (unsigned int)ntohl(fl->label), | 717 | (unsigned int)ntohl(fl->label), |
710 | fl->share, | 718 | fl->share, |
711 | (int)fl->owner, | 719 | ((fl->share == IPV6_FL_S_PROCESS) ? |
720 | pid_nr_ns(fl->owner.pid, state->pid_ns) : | ||
721 | ((fl->share == IPV6_FL_S_USER) ? | ||
722 | from_kuid_munged(seq_user_ns(seq), fl->owner.uid) : | ||
723 | 0)), | ||
712 | atomic_read(&fl->users), | 724 | atomic_read(&fl->users), |
713 | fl->linger/HZ, | 725 | fl->linger/HZ, |
714 | (long)(fl->expires - jiffies)/HZ, | 726 | (long)(fl->expires - jiffies)/HZ, |
@@ -727,8 +739,29 @@ static const struct seq_operations ip6fl_seq_ops = { | |||
727 | 739 | ||
728 | static int ip6fl_seq_open(struct inode *inode, struct file *file) | 740 | static int ip6fl_seq_open(struct inode *inode, struct file *file) |
729 | { | 741 | { |
730 | return seq_open_net(inode, file, &ip6fl_seq_ops, | 742 | struct seq_file *seq; |
731 | sizeof(struct ip6fl_iter_state)); | 743 | struct ip6fl_iter_state *state; |
744 | int err; | ||
745 | |||
746 | err = seq_open_net(inode, file, &ip6fl_seq_ops, | ||
747 | sizeof(struct ip6fl_iter_state)); | ||
748 | |||
749 | if (!err) { | ||
750 | seq = file->private_data; | ||
751 | state = ip6fl_seq_private(seq); | ||
752 | rcu_read_lock(); | ||
753 | state->pid_ns = get_pid_ns(task_active_pid_ns(current)); | ||
754 | rcu_read_unlock(); | ||
755 | } | ||
756 | return err; | ||
757 | } | ||
758 | |||
759 | static int ip6fl_seq_release(struct inode *inode, struct file *file) | ||
760 | { | ||
761 | struct seq_file *seq = file->private_data; | ||
762 | struct ip6fl_iter_state *state = ip6fl_seq_private(seq); | ||
763 | put_pid_ns(state->pid_ns); | ||
764 | return seq_release_net(inode, file); | ||
732 | } | 765 | } |
733 | 766 | ||
734 | static const struct file_operations ip6fl_seq_fops = { | 767 | static const struct file_operations ip6fl_seq_fops = { |
@@ -736,7 +769,7 @@ static const struct file_operations ip6fl_seq_fops = { | |||
736 | .open = ip6fl_seq_open, | 769 | .open = ip6fl_seq_open, |
737 | .read = seq_read, | 770 | .read = seq_read, |
738 | .llseek = seq_lseek, | 771 | .llseek = seq_lseek, |
739 | .release = seq_release_net, | 772 | .release = ip6fl_seq_release, |
740 | }; | 773 | }; |
741 | 774 | ||
742 | static int __net_init ip6_flowlabel_proc_init(struct net *net) | 775 | static int __net_init ip6_flowlabel_proc_init(struct net *net) |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 4a5f78b50495..d8e95c77db99 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -1250,7 +1250,8 @@ static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i) | |||
1250 | sk_wmem_alloc_get(sp), | 1250 | sk_wmem_alloc_get(sp), |
1251 | sk_rmem_alloc_get(sp), | 1251 | sk_rmem_alloc_get(sp), |
1252 | 0, 0L, 0, | 1252 | 0, 0L, 0, |
1253 | sock_i_uid(sp), 0, | 1253 | from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)), |
1254 | 0, | ||
1254 | sock_i_ino(sp), | 1255 | sock_i_ino(sp), |
1255 | atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); | 1256 | atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); |
1256 | } | 1257 | } |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index acd32e3f1b68..342ec62cdbde 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -1829,7 +1829,7 @@ static void tcp_v6_destroy_sock(struct sock *sk) | |||
1829 | #ifdef CONFIG_PROC_FS | 1829 | #ifdef CONFIG_PROC_FS |
1830 | /* Proc filesystem TCPv6 sock list dumping. */ | 1830 | /* Proc filesystem TCPv6 sock list dumping. */ |
1831 | static void get_openreq6(struct seq_file *seq, | 1831 | static void get_openreq6(struct seq_file *seq, |
1832 | const struct sock *sk, struct request_sock *req, int i, int uid) | 1832 | const struct sock *sk, struct request_sock *req, int i, kuid_t uid) |
1833 | { | 1833 | { |
1834 | int ttd = req->expires - jiffies; | 1834 | int ttd = req->expires - jiffies; |
1835 | const struct in6_addr *src = &inet6_rsk(req)->loc_addr; | 1835 | const struct in6_addr *src = &inet6_rsk(req)->loc_addr; |
@@ -1853,7 +1853,7 @@ static void get_openreq6(struct seq_file *seq, | |||
1853 | 1, /* timers active (only the expire timer) */ | 1853 | 1, /* timers active (only the expire timer) */ |
1854 | jiffies_to_clock_t(ttd), | 1854 | jiffies_to_clock_t(ttd), |
1855 | req->retrans, | 1855 | req->retrans, |
1856 | uid, | 1856 | from_kuid_munged(seq_user_ns(seq), uid), |
1857 | 0, /* non standard timer */ | 1857 | 0, /* non standard timer */ |
1858 | 0, /* open_requests have no inode */ | 1858 | 0, /* open_requests have no inode */ |
1859 | 0, req); | 1859 | 0, req); |
@@ -1903,7 +1903,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) | |||
1903 | timer_active, | 1903 | timer_active, |
1904 | jiffies_to_clock_t(timer_expires - jiffies), | 1904 | jiffies_to_clock_t(timer_expires - jiffies), |
1905 | icsk->icsk_retransmits, | 1905 | icsk->icsk_retransmits, |
1906 | sock_i_uid(sp), | 1906 | from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)), |
1907 | icsk->icsk_probes_out, | 1907 | icsk->icsk_probes_out, |
1908 | sock_i_ino(sp), | 1908 | sock_i_ino(sp), |
1909 | atomic_read(&sp->sk_refcnt), sp, | 1909 | atomic_read(&sp->sk_refcnt), sp, |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 07e2bfef6845..fc9997260a6b 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -1469,7 +1469,8 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket | |||
1469 | sk_wmem_alloc_get(sp), | 1469 | sk_wmem_alloc_get(sp), |
1470 | sk_rmem_alloc_get(sp), | 1470 | sk_rmem_alloc_get(sp), |
1471 | 0, 0L, 0, | 1471 | 0, 0L, 0, |
1472 | sock_i_uid(sp), 0, | 1472 | from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)), |
1473 | 0, | ||
1473 | sock_i_ino(sp), | 1474 | sock_i_ino(sp), |
1474 | atomic_read(&sp->sk_refcnt), sp, | 1475 | atomic_read(&sp->sk_refcnt), sp, |
1475 | atomic_read(&sp->sk_drops)); | 1476 | atomic_read(&sp->sk_drops)); |
diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c index f8ba30dfecae..02ff7f2f60d4 100644 --- a/net/ipx/ipx_proc.c +++ b/net/ipx/ipx_proc.c | |||
@@ -217,7 +217,8 @@ static int ipx_seq_socket_show(struct seq_file *seq, void *v) | |||
217 | seq_printf(seq, "%08X %08X %02X %03d\n", | 217 | seq_printf(seq, "%08X %08X %02X %03d\n", |
218 | sk_wmem_alloc_get(s), | 218 | sk_wmem_alloc_get(s), |
219 | sk_rmem_alloc_get(s), | 219 | sk_rmem_alloc_get(s), |
220 | s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); | 220 | s->sk_state, |
221 | from_kuid_munged(seq_user_ns(seq), sock_i_uid(s))); | ||
221 | out: | 222 | out: |
222 | return 0; | 223 | return 0; |
223 | } | 224 | } |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 34e418508a67..0481d4b51476 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -3661,7 +3661,7 @@ static int pfkey_seq_show(struct seq_file *f, void *v) | |||
3661 | atomic_read(&s->sk_refcnt), | 3661 | atomic_read(&s->sk_refcnt), |
3662 | sk_rmem_alloc_get(s), | 3662 | sk_rmem_alloc_get(s), |
3663 | sk_wmem_alloc_get(s), | 3663 | sk_wmem_alloc_get(s), |
3664 | sock_i_uid(s), | 3664 | from_kuid_munged(seq_user_ns(f), sock_i_uid(s)), |
3665 | sock_i_ino(s) | 3665 | sock_i_ino(s) |
3666 | ); | 3666 | ); |
3667 | return 0; | 3667 | return 0; |
diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c index a1839c004357..7b4799cfbf8d 100644 --- a/net/llc/llc_proc.c +++ b/net/llc/llc_proc.c | |||
@@ -151,7 +151,7 @@ static int llc_seq_socket_show(struct seq_file *seq, void *v) | |||
151 | sk_wmem_alloc_get(sk), | 151 | sk_wmem_alloc_get(sk), |
152 | sk_rmem_alloc_get(sk) - llc->copied_seq, | 152 | sk_rmem_alloc_get(sk) - llc->copied_seq, |
153 | sk->sk_state, | 153 | sk->sk_state, |
154 | sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : -1, | 154 | from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)), |
155 | llc->link); | 155 | llc->link); |
156 | out: | 156 | out: |
157 | return 0; | 157 | return 0; |
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 5cfb5bedb2b8..8cfc401e197e 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -55,6 +55,7 @@ struct nfulnl_instance { | |||
55 | unsigned int qlen; /* number of nlmsgs in skb */ | 55 | unsigned int qlen; /* number of nlmsgs in skb */ |
56 | struct sk_buff *skb; /* pre-allocatd skb */ | 56 | struct sk_buff *skb; /* pre-allocatd skb */ |
57 | struct timer_list timer; | 57 | struct timer_list timer; |
58 | struct user_namespace *peer_user_ns; /* User namespace of the peer process */ | ||
58 | int peer_pid; /* PID of the peer process */ | 59 | int peer_pid; /* PID of the peer process */ |
59 | 60 | ||
60 | /* configurable parameters */ | 61 | /* configurable parameters */ |
@@ -132,7 +133,7 @@ instance_put(struct nfulnl_instance *inst) | |||
132 | static void nfulnl_timer(unsigned long data); | 133 | static void nfulnl_timer(unsigned long data); |
133 | 134 | ||
134 | static struct nfulnl_instance * | 135 | static struct nfulnl_instance * |
135 | instance_create(u_int16_t group_num, int pid) | 136 | instance_create(u_int16_t group_num, int pid, struct user_namespace *user_ns) |
136 | { | 137 | { |
137 | struct nfulnl_instance *inst; | 138 | struct nfulnl_instance *inst; |
138 | int err; | 139 | int err; |
@@ -162,6 +163,7 @@ instance_create(u_int16_t group_num, int pid) | |||
162 | 163 | ||
163 | setup_timer(&inst->timer, nfulnl_timer, (unsigned long)inst); | 164 | setup_timer(&inst->timer, nfulnl_timer, (unsigned long)inst); |
164 | 165 | ||
166 | inst->peer_user_ns = user_ns; | ||
165 | inst->peer_pid = pid; | 167 | inst->peer_pid = pid; |
166 | inst->group_num = group_num; | 168 | inst->group_num = group_num; |
167 | 169 | ||
@@ -505,8 +507,10 @@ __build_packet_message(struct nfulnl_instance *inst, | |||
505 | read_lock_bh(&sk->sk_callback_lock); | 507 | read_lock_bh(&sk->sk_callback_lock); |
506 | if (sk->sk_socket && sk->sk_socket->file) { | 508 | if (sk->sk_socket && sk->sk_socket->file) { |
507 | struct file *file = sk->sk_socket->file; | 509 | struct file *file = sk->sk_socket->file; |
508 | __be32 uid = htonl(file->f_cred->fsuid); | 510 | const struct cred *cred = file->f_cred; |
509 | __be32 gid = htonl(file->f_cred->fsgid); | 511 | struct user_namespace *user_ns = inst->peer_user_ns; |
512 | __be32 uid = htonl(from_kuid_munged(user_ns, cred->fsuid)); | ||
513 | __be32 gid = htonl(from_kgid_munged(user_ns, cred->fsgid)); | ||
510 | read_unlock_bh(&sk->sk_callback_lock); | 514 | read_unlock_bh(&sk->sk_callback_lock); |
511 | if (nla_put_be32(inst->skb, NFULA_UID, uid) || | 515 | if (nla_put_be32(inst->skb, NFULA_UID, uid) || |
512 | nla_put_be32(inst->skb, NFULA_GID, gid)) | 516 | nla_put_be32(inst->skb, NFULA_GID, gid)) |
@@ -785,7 +789,8 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, | |||
785 | } | 789 | } |
786 | 790 | ||
787 | inst = instance_create(group_num, | 791 | inst = instance_create(group_num, |
788 | NETLINK_CB(skb).pid); | 792 | NETLINK_CB(skb).pid, |
793 | sk_user_ns(NETLINK_CB(skb).ssk)); | ||
789 | if (IS_ERR(inst)) { | 794 | if (IS_ERR(inst)) { |
790 | ret = PTR_ERR(inst); | 795 | ret = PTR_ERR(inst); |
791 | goto out; | 796 | goto out; |
diff --git a/net/netfilter/xt_LOG.c b/net/netfilter/xt_LOG.c index 91e9af4d1f42..fa40096940a1 100644 --- a/net/netfilter/xt_LOG.c +++ b/net/netfilter/xt_LOG.c | |||
@@ -151,10 +151,12 @@ static void dump_sk_uid_gid(struct sbuff *m, struct sock *sk) | |||
151 | return; | 151 | return; |
152 | 152 | ||
153 | read_lock_bh(&sk->sk_callback_lock); | 153 | read_lock_bh(&sk->sk_callback_lock); |
154 | if (sk->sk_socket && sk->sk_socket->file) | 154 | if (sk->sk_socket && sk->sk_socket->file) { |
155 | const struct cred *cred = sk->sk_socket->file->f_cred; | ||
155 | sb_add(m, "UID=%u GID=%u ", | 156 | sb_add(m, "UID=%u GID=%u ", |
156 | sk->sk_socket->file->f_cred->fsuid, | 157 | from_kuid_munged(&init_user_ns, cred->fsuid), |
157 | sk->sk_socket->file->f_cred->fsgid); | 158 | from_kgid_munged(&init_user_ns, cred->fsgid)); |
159 | } | ||
158 | read_unlock_bh(&sk->sk_callback_lock); | 160 | read_unlock_bh(&sk->sk_callback_lock); |
159 | } | 161 | } |
160 | 162 | ||
diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c index 772d7389b337..ca2e577ed8ac 100644 --- a/net/netfilter/xt_owner.c +++ b/net/netfilter/xt_owner.c | |||
@@ -17,6 +17,17 @@ | |||
17 | #include <linux/netfilter/x_tables.h> | 17 | #include <linux/netfilter/x_tables.h> |
18 | #include <linux/netfilter/xt_owner.h> | 18 | #include <linux/netfilter/xt_owner.h> |
19 | 19 | ||
20 | static int owner_check(const struct xt_mtchk_param *par) | ||
21 | { | ||
22 | struct xt_owner_match_info *info = par->matchinfo; | ||
23 | |||
24 | /* For now only allow adding matches from the initial user namespace */ | ||
25 | if ((info->match & (XT_OWNER_UID|XT_OWNER_GID)) && | ||
26 | (current_user_ns() != &init_user_ns)) | ||
27 | return -EINVAL; | ||
28 | return 0; | ||
29 | } | ||
30 | |||
20 | static bool | 31 | static bool |
21 | owner_mt(const struct sk_buff *skb, struct xt_action_param *par) | 32 | owner_mt(const struct sk_buff *skb, struct xt_action_param *par) |
22 | { | 33 | { |
@@ -37,17 +48,23 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
37 | return ((info->match ^ info->invert) & | 48 | return ((info->match ^ info->invert) & |
38 | (XT_OWNER_UID | XT_OWNER_GID)) == 0; | 49 | (XT_OWNER_UID | XT_OWNER_GID)) == 0; |
39 | 50 | ||
40 | if (info->match & XT_OWNER_UID) | 51 | if (info->match & XT_OWNER_UID) { |
41 | if ((filp->f_cred->fsuid >= info->uid_min && | 52 | kuid_t uid_min = make_kuid(&init_user_ns, info->uid_min); |
42 | filp->f_cred->fsuid <= info->uid_max) ^ | 53 | kuid_t uid_max = make_kuid(&init_user_ns, info->uid_max); |
54 | if ((uid_gte(filp->f_cred->fsuid, uid_min) && | ||
55 | uid_lte(filp->f_cred->fsuid, uid_max)) ^ | ||
43 | !(info->invert & XT_OWNER_UID)) | 56 | !(info->invert & XT_OWNER_UID)) |
44 | return false; | 57 | return false; |
58 | } | ||
45 | 59 | ||
46 | if (info->match & XT_OWNER_GID) | 60 | if (info->match & XT_OWNER_GID) { |
47 | if ((filp->f_cred->fsgid >= info->gid_min && | 61 | kgid_t gid_min = make_kgid(&init_user_ns, info->gid_min); |
48 | filp->f_cred->fsgid <= info->gid_max) ^ | 62 | kgid_t gid_max = make_kgid(&init_user_ns, info->gid_max); |
63 | if ((gid_gte(filp->f_cred->fsgid, gid_min) && | ||
64 | gid_lte(filp->f_cred->fsgid, gid_max)) ^ | ||
49 | !(info->invert & XT_OWNER_GID)) | 65 | !(info->invert & XT_OWNER_GID)) |
50 | return false; | 66 | return false; |
67 | } | ||
51 | 68 | ||
52 | return true; | 69 | return true; |
53 | } | 70 | } |
@@ -56,6 +73,7 @@ static struct xt_match owner_mt_reg __read_mostly = { | |||
56 | .name = "owner", | 73 | .name = "owner", |
57 | .revision = 1, | 74 | .revision = 1, |
58 | .family = NFPROTO_UNSPEC, | 75 | .family = NFPROTO_UNSPEC, |
76 | .checkentry = owner_check, | ||
59 | .match = owner_mt, | 77 | .match = owner_mt, |
60 | .matchsize = sizeof(struct xt_owner_match_info), | 78 | .matchsize = sizeof(struct xt_owner_match_info), |
61 | .hooks = (1 << NF_INET_LOCAL_OUT) | | 79 | .hooks = (1 << NF_INET_LOCAL_OUT) | |
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c index ae2ad1eec8d0..4635c9b00459 100644 --- a/net/netfilter/xt_recent.c +++ b/net/netfilter/xt_recent.c | |||
@@ -317,6 +317,8 @@ static int recent_mt_check(const struct xt_mtchk_param *par, | |||
317 | struct recent_table *t; | 317 | struct recent_table *t; |
318 | #ifdef CONFIG_PROC_FS | 318 | #ifdef CONFIG_PROC_FS |
319 | struct proc_dir_entry *pde; | 319 | struct proc_dir_entry *pde; |
320 | kuid_t uid; | ||
321 | kgid_t gid; | ||
320 | #endif | 322 | #endif |
321 | unsigned int i; | 323 | unsigned int i; |
322 | int ret = -EINVAL; | 324 | int ret = -EINVAL; |
@@ -372,6 +374,13 @@ static int recent_mt_check(const struct xt_mtchk_param *par, | |||
372 | for (i = 0; i < ip_list_hash_size; i++) | 374 | for (i = 0; i < ip_list_hash_size; i++) |
373 | INIT_LIST_HEAD(&t->iphash[i]); | 375 | INIT_LIST_HEAD(&t->iphash[i]); |
374 | #ifdef CONFIG_PROC_FS | 376 | #ifdef CONFIG_PROC_FS |
377 | uid = make_kuid(&init_user_ns, ip_list_uid); | ||
378 | gid = make_kgid(&init_user_ns, ip_list_gid); | ||
379 | if (!uid_valid(uid) || !gid_valid(gid)) { | ||
380 | kfree(t); | ||
381 | ret = -EINVAL; | ||
382 | goto out; | ||
383 | } | ||
375 | pde = proc_create_data(t->name, ip_list_perms, recent_net->xt_recent, | 384 | pde = proc_create_data(t->name, ip_list_perms, recent_net->xt_recent, |
376 | &recent_mt_fops, t); | 385 | &recent_mt_fops, t); |
377 | if (pde == NULL) { | 386 | if (pde == NULL) { |
@@ -379,8 +388,8 @@ static int recent_mt_check(const struct xt_mtchk_param *par, | |||
379 | ret = -ENOMEM; | 388 | ret = -ENOMEM; |
380 | goto out; | 389 | goto out; |
381 | } | 390 | } |
382 | pde->uid = ip_list_uid; | 391 | pde->uid = uid; |
383 | pde->gid = ip_list_gid; | 392 | pde->gid = gid; |
384 | #endif | 393 | #endif |
385 | spin_lock_bh(&recent_lock); | 394 | spin_lock_bh(&recent_lock); |
386 | list_add_tail(&t->list, &recent_net->tables); | 395 | list_add_tail(&t->list, &recent_net->tables); |
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index e7ff694f1049..729a345c75a4 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
@@ -1541,7 +1541,7 @@ int __init netlbl_unlabel_defconf(void) | |||
1541 | * it is called is at bootup before the audit subsystem is reporting | 1541 | * it is called is at bootup before the audit subsystem is reporting |
1542 | * messages so don't worry to much about these values. */ | 1542 | * messages so don't worry to much about these values. */ |
1543 | security_task_getsecid(current, &audit_info.secid); | 1543 | security_task_getsecid(current, &audit_info.secid); |
1544 | audit_info.loginuid = 0; | 1544 | audit_info.loginuid = GLOBAL_ROOT_UID; |
1545 | audit_info.sessionid = 0; | 1545 | audit_info.sessionid = 0; |
1546 | 1546 | ||
1547 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); | 1547 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); |
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 9fae63f10298..9650c4ad5f88 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c | |||
@@ -109,7 +109,7 @@ struct audit_buffer *netlbl_audit_start_common(int type, | |||
109 | return NULL; | 109 | return NULL; |
110 | 110 | ||
111 | audit_log_format(audit_buf, "netlabel: auid=%u ses=%u", | 111 | audit_log_format(audit_buf, "netlabel: auid=%u ses=%u", |
112 | audit_info->loginuid, | 112 | from_kuid(&init_user_ns, audit_info->loginuid), |
113 | audit_info->sessionid); | 113 | audit_info->sessionid); |
114 | 114 | ||
115 | if (audit_info->secid != 0 && | 115 | if (audit_info->secid != 0 && |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 527023823b5c..382119917166 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -912,7 +912,8 @@ static void netlink_rcv_wake(struct sock *sk) | |||
912 | wake_up_interruptible(&nlk->wait); | 912 | wake_up_interruptible(&nlk->wait); |
913 | } | 913 | } |
914 | 914 | ||
915 | static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb) | 915 | static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb, |
916 | struct sock *ssk) | ||
916 | { | 917 | { |
917 | int ret; | 918 | int ret; |
918 | struct netlink_sock *nlk = nlk_sk(sk); | 919 | struct netlink_sock *nlk = nlk_sk(sk); |
@@ -921,6 +922,7 @@ static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb) | |||
921 | if (nlk->netlink_rcv != NULL) { | 922 | if (nlk->netlink_rcv != NULL) { |
922 | ret = skb->len; | 923 | ret = skb->len; |
923 | skb_set_owner_r(skb, sk); | 924 | skb_set_owner_r(skb, sk); |
925 | NETLINK_CB(skb).ssk = ssk; | ||
924 | nlk->netlink_rcv(skb); | 926 | nlk->netlink_rcv(skb); |
925 | consume_skb(skb); | 927 | consume_skb(skb); |
926 | } else { | 928 | } else { |
@@ -947,7 +949,7 @@ retry: | |||
947 | return PTR_ERR(sk); | 949 | return PTR_ERR(sk); |
948 | } | 950 | } |
949 | if (netlink_is_kernel(sk)) | 951 | if (netlink_is_kernel(sk)) |
950 | return netlink_unicast_kernel(sk, skb); | 952 | return netlink_unicast_kernel(sk, skb, ssk); |
951 | 953 | ||
952 | if (sk_filter(sk, skb)) { | 954 | if (sk_filter(sk, skb)) { |
953 | err = skb->len; | 955 | err = skb->len; |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index c5c9e2a54218..048fba476aa5 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -3854,7 +3854,7 @@ static int packet_seq_show(struct seq_file *seq, void *v) | |||
3854 | po->ifindex, | 3854 | po->ifindex, |
3855 | po->running, | 3855 | po->running, |
3856 | atomic_read(&s->sk_rmem_alloc), | 3856 | atomic_read(&s->sk_rmem_alloc), |
3857 | sock_i_uid(s), | 3857 | from_kuid_munged(seq_user_ns(seq), sock_i_uid(s)), |
3858 | sock_i_ino(s)); | 3858 | sock_i_ino(s)); |
3859 | } | 3859 | } |
3860 | 3860 | ||
diff --git a/net/phonet/socket.c b/net/phonet/socket.c index 0acc943f713a..b7e982782255 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c | |||
@@ -612,7 +612,8 @@ static int pn_sock_seq_show(struct seq_file *seq, void *v) | |||
612 | sk->sk_protocol, pn->sobject, pn->dobject, | 612 | sk->sk_protocol, pn->sobject, pn->dobject, |
613 | pn->resource, sk->sk_state, | 613 | pn->resource, sk->sk_state, |
614 | sk_wmem_alloc_get(sk), sk_rmem_alloc_get(sk), | 614 | sk_wmem_alloc_get(sk), sk_rmem_alloc_get(sk), |
615 | sock_i_uid(sk), sock_i_ino(sk), | 615 | from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)), |
616 | sock_i_ino(sk), | ||
616 | atomic_read(&sk->sk_refcnt), sk, | 617 | atomic_read(&sk->sk_refcnt), sk, |
617 | atomic_read(&sk->sk_drops), &len); | 618 | atomic_read(&sk->sk_drops), &len); |
618 | } | 619 | } |
@@ -796,7 +797,8 @@ static int pn_res_seq_show(struct seq_file *seq, void *v) | |||
796 | struct sock *sk = *psk; | 797 | struct sock *sk = *psk; |
797 | 798 | ||
798 | seq_printf(seq, "%02X %5d %lu%n", | 799 | seq_printf(seq, "%02X %5d %lu%n", |
799 | (int) (psk - pnres.sk), sock_i_uid(sk), | 800 | (int) (psk - pnres.sk), |
801 | from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)), | ||
800 | sock_i_ino(sk), &len); | 802 | sock_i_ino(sk), &len); |
801 | } | 803 | } |
802 | seq_printf(seq, "%*s\n", 63 - len, ""); | 804 | seq_printf(seq, "%*s\n", 63 - len, ""); |
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c index 8b1f9f49960f..011d2384b115 100644 --- a/net/rxrpc/ar-key.c +++ b/net/rxrpc/ar-key.c | |||
@@ -948,7 +948,8 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *conn, | |||
948 | 948 | ||
949 | _enter(""); | 949 | _enter(""); |
950 | 950 | ||
951 | key = key_alloc(&key_type_rxrpc, "x", 0, 0, cred, 0, | 951 | key = key_alloc(&key_type_rxrpc, "x", |
952 | GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 0, | ||
952 | KEY_ALLOC_NOT_IN_QUOTA); | 953 | KEY_ALLOC_NOT_IN_QUOTA); |
953 | if (IS_ERR(key)) { | 954 | if (IS_ERR(key)) { |
954 | _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key)); | 955 | _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key)); |
@@ -994,7 +995,8 @@ struct key *rxrpc_get_null_key(const char *keyname) | |||
994 | struct key *key; | 995 | struct key *key; |
995 | int ret; | 996 | int ret; |
996 | 997 | ||
997 | key = key_alloc(&key_type_rxrpc, keyname, 0, 0, cred, | 998 | key = key_alloc(&key_type_rxrpc, keyname, |
999 | GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, | ||
998 | KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA); | 1000 | KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA); |
999 | if (IS_ERR(key)) | 1001 | if (IS_ERR(key)) |
1000 | return key; | 1002 | return key; |
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 6dd1131f2ec1..dc3ef5aef355 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -319,7 +319,7 @@ replay: | |||
319 | } | 319 | } |
320 | } | 320 | } |
321 | 321 | ||
322 | err = tp->ops->change(tp, cl, t->tcm_handle, tca, &fh); | 322 | err = tp->ops->change(skb, tp, cl, t->tcm_handle, tca, &fh); |
323 | if (err == 0) { | 323 | if (err == 0) { |
324 | if (tp_created) { | 324 | if (tp_created) { |
325 | spin_lock_bh(root_lock); | 325 | spin_lock_bh(root_lock); |
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index 590960a22a77..344a11b342e5 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c | |||
@@ -162,7 +162,8 @@ errout: | |||
162 | return err; | 162 | return err; |
163 | } | 163 | } |
164 | 164 | ||
165 | static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle, | 165 | static int basic_change(struct sk_buff *in_skb, |
166 | struct tcf_proto *tp, unsigned long base, u32 handle, | ||
166 | struct nlattr **tca, unsigned long *arg) | 167 | struct nlattr **tca, unsigned long *arg) |
167 | { | 168 | { |
168 | int err; | 169 | int err; |
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index 4a23ccca6b70..2ecde225ae60 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c | |||
@@ -158,7 +158,8 @@ static const struct nla_policy cgroup_policy[TCA_CGROUP_MAX + 1] = { | |||
158 | [TCA_CGROUP_EMATCHES] = { .type = NLA_NESTED }, | 158 | [TCA_CGROUP_EMATCHES] = { .type = NLA_NESTED }, |
159 | }; | 159 | }; |
160 | 160 | ||
161 | static int cls_cgroup_change(struct tcf_proto *tp, unsigned long base, | 161 | static int cls_cgroup_change(struct sk_buff *in_skb, |
162 | struct tcf_proto *tp, unsigned long base, | ||
162 | u32 handle, struct nlattr **tca, | 163 | u32 handle, struct nlattr **tca, |
163 | unsigned long *arg) | 164 | unsigned long *arg) |
164 | { | 165 | { |
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index ccd08c8dc6a7..ce82d0cb1b47 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c | |||
@@ -193,15 +193,19 @@ static u32 flow_get_rtclassid(const struct sk_buff *skb) | |||
193 | 193 | ||
194 | static u32 flow_get_skuid(const struct sk_buff *skb) | 194 | static u32 flow_get_skuid(const struct sk_buff *skb) |
195 | { | 195 | { |
196 | if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) | 196 | if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) { |
197 | return skb->sk->sk_socket->file->f_cred->fsuid; | 197 | kuid_t skuid = skb->sk->sk_socket->file->f_cred->fsuid; |
198 | return from_kuid(&init_user_ns, skuid); | ||
199 | } | ||
198 | return 0; | 200 | return 0; |
199 | } | 201 | } |
200 | 202 | ||
201 | static u32 flow_get_skgid(const struct sk_buff *skb) | 203 | static u32 flow_get_skgid(const struct sk_buff *skb) |
202 | { | 204 | { |
203 | if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) | 205 | if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) { |
204 | return skb->sk->sk_socket->file->f_cred->fsgid; | 206 | kgid_t skgid = skb->sk->sk_socket->file->f_cred->fsgid; |
207 | return from_kgid(&init_user_ns, skgid); | ||
208 | } | ||
205 | return 0; | 209 | return 0; |
206 | } | 210 | } |
207 | 211 | ||
@@ -347,7 +351,8 @@ static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = { | |||
347 | [TCA_FLOW_PERTURB] = { .type = NLA_U32 }, | 351 | [TCA_FLOW_PERTURB] = { .type = NLA_U32 }, |
348 | }; | 352 | }; |
349 | 353 | ||
350 | static int flow_change(struct tcf_proto *tp, unsigned long base, | 354 | static int flow_change(struct sk_buff *in_skb, |
355 | struct tcf_proto *tp, unsigned long base, | ||
351 | u32 handle, struct nlattr **tca, | 356 | u32 handle, struct nlattr **tca, |
352 | unsigned long *arg) | 357 | unsigned long *arg) |
353 | { | 358 | { |
@@ -386,6 +391,10 @@ static int flow_change(struct tcf_proto *tp, unsigned long base, | |||
386 | 391 | ||
387 | if (fls(keymask) - 1 > FLOW_KEY_MAX) | 392 | if (fls(keymask) - 1 > FLOW_KEY_MAX) |
388 | return -EOPNOTSUPP; | 393 | return -EOPNOTSUPP; |
394 | |||
395 | if ((keymask & (FLOW_KEY_SKUID|FLOW_KEY_SKGID)) && | ||
396 | sk_user_ns(NETLINK_CB(in_skb).ssk) != &init_user_ns) | ||
397 | return -EOPNOTSUPP; | ||
389 | } | 398 | } |
390 | 399 | ||
391 | err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &flow_ext_map); | 400 | err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &flow_ext_map); |
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index 8384a4797240..4075a0aef2aa 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c | |||
@@ -233,7 +233,8 @@ errout: | |||
233 | return err; | 233 | return err; |
234 | } | 234 | } |
235 | 235 | ||
236 | static int fw_change(struct tcf_proto *tp, unsigned long base, | 236 | static int fw_change(struct sk_buff *in_skb, |
237 | struct tcf_proto *tp, unsigned long base, | ||
237 | u32 handle, | 238 | u32 handle, |
238 | struct nlattr **tca, | 239 | struct nlattr **tca, |
239 | unsigned long *arg) | 240 | unsigned long *arg) |
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index 44f405cb9aaf..c10d57bf98f2 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c | |||
@@ -427,7 +427,8 @@ errout: | |||
427 | return err; | 427 | return err; |
428 | } | 428 | } |
429 | 429 | ||
430 | static int route4_change(struct tcf_proto *tp, unsigned long base, | 430 | static int route4_change(struct sk_buff *in_skb, |
431 | struct tcf_proto *tp, unsigned long base, | ||
431 | u32 handle, | 432 | u32 handle, |
432 | struct nlattr **tca, | 433 | struct nlattr **tca, |
433 | unsigned long *arg) | 434 | unsigned long *arg) |
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 18ab93ec8d7e..494bbb90924a 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h | |||
@@ -416,7 +416,8 @@ static const struct nla_policy rsvp_policy[TCA_RSVP_MAX + 1] = { | |||
416 | [TCA_RSVP_PINFO] = { .len = sizeof(struct tc_rsvp_pinfo) }, | 416 | [TCA_RSVP_PINFO] = { .len = sizeof(struct tc_rsvp_pinfo) }, |
417 | }; | 417 | }; |
418 | 418 | ||
419 | static int rsvp_change(struct tcf_proto *tp, unsigned long base, | 419 | static int rsvp_change(struct sk_buff *in_skb, |
420 | struct tcf_proto *tp, unsigned long base, | ||
420 | u32 handle, | 421 | u32 handle, |
421 | struct nlattr **tca, | 422 | struct nlattr **tca, |
422 | unsigned long *arg) | 423 | unsigned long *arg) |
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index fe29420d0b0e..a1293b4ab7a1 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c | |||
@@ -332,7 +332,8 @@ errout: | |||
332 | } | 332 | } |
333 | 333 | ||
334 | static int | 334 | static int |
335 | tcindex_change(struct tcf_proto *tp, unsigned long base, u32 handle, | 335 | tcindex_change(struct sk_buff *in_skb, |
336 | struct tcf_proto *tp, unsigned long base, u32 handle, | ||
336 | struct nlattr **tca, unsigned long *arg) | 337 | struct nlattr **tca, unsigned long *arg) |
337 | { | 338 | { |
338 | struct nlattr *opt = tca[TCA_OPTIONS]; | 339 | struct nlattr *opt = tca[TCA_OPTIONS]; |
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index d45373fb00b9..c7c27bc91b5a 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c | |||
@@ -544,7 +544,8 @@ errout: | |||
544 | return err; | 544 | return err; |
545 | } | 545 | } |
546 | 546 | ||
547 | static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, | 547 | static int u32_change(struct sk_buff *in_skb, |
548 | struct tcf_proto *tp, unsigned long base, u32 handle, | ||
548 | struct nlattr **tca, | 549 | struct nlattr **tca, |
549 | unsigned long *arg) | 550 | unsigned long *arg) |
550 | { | 551 | { |
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index 1e2eee88c3ea..dc12febc977a 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c | |||
@@ -216,7 +216,8 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v) | |||
216 | seq_printf(seq, "%8pK %8pK %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk, | 216 | seq_printf(seq, "%8pK %8pK %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk, |
217 | sctp_sk(sk)->type, sk->sk_state, hash, | 217 | sctp_sk(sk)->type, sk->sk_state, hash, |
218 | epb->bind_addr.port, | 218 | epb->bind_addr.port, |
219 | sock_i_uid(sk), sock_i_ino(sk)); | 219 | from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)), |
220 | sock_i_ino(sk)); | ||
220 | 221 | ||
221 | sctp_seq_dump_local_addrs(seq, epb); | 222 | sctp_seq_dump_local_addrs(seq, epb); |
222 | seq_printf(seq, "\n"); | 223 | seq_printf(seq, "\n"); |
@@ -324,7 +325,8 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) | |||
324 | assoc->assoc_id, | 325 | assoc->assoc_id, |
325 | assoc->sndbuf_used, | 326 | assoc->sndbuf_used, |
326 | atomic_read(&assoc->rmem_alloc), | 327 | atomic_read(&assoc->rmem_alloc), |
327 | sock_i_uid(sk), sock_i_ino(sk), | 328 | from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)), |
329 | sock_i_ino(sk), | ||
328 | epb->bind_addr.port, | 330 | epb->bind_addr.port, |
329 | assoc->peer.port); | 331 | assoc->peer.port); |
330 | seq_printf(seq, " "); | 332 | seq_printf(seq, " "); |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 387848e90078..46550997548c 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -2633,12 +2633,12 @@ static void xfrm_policy_fini(struct net *net) | |||
2633 | 2633 | ||
2634 | flush_work(&net->xfrm.policy_hash_work); | 2634 | flush_work(&net->xfrm.policy_hash_work); |
2635 | #ifdef CONFIG_XFRM_SUB_POLICY | 2635 | #ifdef CONFIG_XFRM_SUB_POLICY |
2636 | audit_info.loginuid = -1; | 2636 | audit_info.loginuid = INVALID_UID; |
2637 | audit_info.sessionid = -1; | 2637 | audit_info.sessionid = -1; |
2638 | audit_info.secid = 0; | 2638 | audit_info.secid = 0; |
2639 | xfrm_policy_flush(net, XFRM_POLICY_TYPE_SUB, &audit_info); | 2639 | xfrm_policy_flush(net, XFRM_POLICY_TYPE_SUB, &audit_info); |
2640 | #endif | 2640 | #endif |
2641 | audit_info.loginuid = -1; | 2641 | audit_info.loginuid = INVALID_UID; |
2642 | audit_info.sessionid = -1; | 2642 | audit_info.sessionid = -1; |
2643 | audit_info.secid = 0; | 2643 | audit_info.secid = 0; |
2644 | xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info); | 2644 | xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, &audit_info); |
@@ -2745,7 +2745,7 @@ static void xfrm_audit_common_policyinfo(struct xfrm_policy *xp, | |||
2745 | } | 2745 | } |
2746 | 2746 | ||
2747 | void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, | 2747 | void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, |
2748 | uid_t auid, u32 sessionid, u32 secid) | 2748 | kuid_t auid, u32 sessionid, u32 secid) |
2749 | { | 2749 | { |
2750 | struct audit_buffer *audit_buf; | 2750 | struct audit_buffer *audit_buf; |
2751 | 2751 | ||
@@ -2760,7 +2760,7 @@ void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, | |||
2760 | EXPORT_SYMBOL_GPL(xfrm_audit_policy_add); | 2760 | EXPORT_SYMBOL_GPL(xfrm_audit_policy_add); |
2761 | 2761 | ||
2762 | void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, | 2762 | void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, |
2763 | uid_t auid, u32 sessionid, u32 secid) | 2763 | kuid_t auid, u32 sessionid, u32 secid) |
2764 | { | 2764 | { |
2765 | struct audit_buffer *audit_buf; | 2765 | struct audit_buffer *audit_buf; |
2766 | 2766 | ||
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 210be48d8ae3..bd2d9841ad59 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -2060,7 +2060,7 @@ void xfrm_state_fini(struct net *net) | |||
2060 | unsigned int sz; | 2060 | unsigned int sz; |
2061 | 2061 | ||
2062 | flush_work(&net->xfrm.state_hash_work); | 2062 | flush_work(&net->xfrm.state_hash_work); |
2063 | audit_info.loginuid = -1; | 2063 | audit_info.loginuid = INVALID_UID; |
2064 | audit_info.sessionid = -1; | 2064 | audit_info.sessionid = -1; |
2065 | audit_info.secid = 0; | 2065 | audit_info.secid = 0; |
2066 | xfrm_state_flush(net, IPSEC_PROTO_ANY, &audit_info); | 2066 | xfrm_state_flush(net, IPSEC_PROTO_ANY, &audit_info); |
@@ -2127,7 +2127,7 @@ static void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family, | |||
2127 | } | 2127 | } |
2128 | 2128 | ||
2129 | void xfrm_audit_state_add(struct xfrm_state *x, int result, | 2129 | void xfrm_audit_state_add(struct xfrm_state *x, int result, |
2130 | uid_t auid, u32 sessionid, u32 secid) | 2130 | kuid_t auid, u32 sessionid, u32 secid) |
2131 | { | 2131 | { |
2132 | struct audit_buffer *audit_buf; | 2132 | struct audit_buffer *audit_buf; |
2133 | 2133 | ||
@@ -2142,7 +2142,7 @@ void xfrm_audit_state_add(struct xfrm_state *x, int result, | |||
2142 | EXPORT_SYMBOL_GPL(xfrm_audit_state_add); | 2142 | EXPORT_SYMBOL_GPL(xfrm_audit_state_add); |
2143 | 2143 | ||
2144 | void xfrm_audit_state_delete(struct xfrm_state *x, int result, | 2144 | void xfrm_audit_state_delete(struct xfrm_state *x, int result, |
2145 | uid_t auid, u32 sessionid, u32 secid) | 2145 | kuid_t auid, u32 sessionid, u32 secid) |
2146 | { | 2146 | { |
2147 | struct audit_buffer *audit_buf; | 2147 | struct audit_buffer *audit_buf; |
2148 | 2148 | ||
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 289f4bf18ff0..bc542448307a 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -595,7 +595,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
595 | struct xfrm_state *x; | 595 | struct xfrm_state *x; |
596 | int err; | 596 | int err; |
597 | struct km_event c; | 597 | struct km_event c; |
598 | uid_t loginuid = audit_get_loginuid(current); | 598 | kuid_t loginuid = audit_get_loginuid(current); |
599 | u32 sessionid = audit_get_sessionid(current); | 599 | u32 sessionid = audit_get_sessionid(current); |
600 | u32 sid; | 600 | u32 sid; |
601 | 601 | ||
@@ -674,7 +674,7 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
674 | int err = -ESRCH; | 674 | int err = -ESRCH; |
675 | struct km_event c; | 675 | struct km_event c; |
676 | struct xfrm_usersa_id *p = nlmsg_data(nlh); | 676 | struct xfrm_usersa_id *p = nlmsg_data(nlh); |
677 | uid_t loginuid = audit_get_loginuid(current); | 677 | kuid_t loginuid = audit_get_loginuid(current); |
678 | u32 sessionid = audit_get_sessionid(current); | 678 | u32 sessionid = audit_get_sessionid(current); |
679 | u32 sid; | 679 | u32 sid; |
680 | 680 | ||
@@ -1393,7 +1393,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1393 | struct km_event c; | 1393 | struct km_event c; |
1394 | int err; | 1394 | int err; |
1395 | int excl; | 1395 | int excl; |
1396 | uid_t loginuid = audit_get_loginuid(current); | 1396 | kuid_t loginuid = audit_get_loginuid(current); |
1397 | u32 sessionid = audit_get_sessionid(current); | 1397 | u32 sessionid = audit_get_sessionid(current); |
1398 | u32 sid; | 1398 | u32 sid; |
1399 | 1399 | ||
@@ -1651,7 +1651,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1651 | NETLINK_CB(skb).pid); | 1651 | NETLINK_CB(skb).pid); |
1652 | } | 1652 | } |
1653 | } else { | 1653 | } else { |
1654 | uid_t loginuid = audit_get_loginuid(current); | 1654 | kuid_t loginuid = audit_get_loginuid(current); |
1655 | u32 sessionid = audit_get_sessionid(current); | 1655 | u32 sessionid = audit_get_sessionid(current); |
1656 | u32 sid; | 1656 | u32 sid; |
1657 | 1657 | ||
@@ -1945,7 +1945,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1945 | 1945 | ||
1946 | err = 0; | 1946 | err = 0; |
1947 | if (up->hard) { | 1947 | if (up->hard) { |
1948 | uid_t loginuid = audit_get_loginuid(current); | 1948 | kuid_t loginuid = audit_get_loginuid(current); |
1949 | u32 sessionid = audit_get_sessionid(current); | 1949 | u32 sessionid = audit_get_sessionid(current); |
1950 | u32 sid; | 1950 | u32 sid; |
1951 | 1951 | ||
@@ -1988,7 +1988,7 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1988 | km_state_expired(x, ue->hard, current->pid); | 1988 | km_state_expired(x, ue->hard, current->pid); |
1989 | 1989 | ||
1990 | if (ue->hard) { | 1990 | if (ue->hard) { |
1991 | uid_t loginuid = audit_get_loginuid(current); | 1991 | kuid_t loginuid = audit_get_loginuid(current); |
1992 | u32 sessionid = audit_get_sessionid(current); | 1992 | u32 sessionid = audit_get_sessionid(current); |
1993 | u32 sid; | 1993 | u32 sid; |
1994 | 1994 | ||
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index b81ea10a17a3..60f0c76a27d3 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c | |||
@@ -721,7 +721,7 @@ audit: | |||
721 | if (!permtest) | 721 | if (!permtest) |
722 | error = aa_audit_file(profile, &perms, GFP_KERNEL, | 722 | error = aa_audit_file(profile, &perms, GFP_KERNEL, |
723 | OP_CHANGE_HAT, AA_MAY_CHANGEHAT, NULL, | 723 | OP_CHANGE_HAT, AA_MAY_CHANGEHAT, NULL, |
724 | target, 0, info, error); | 724 | target, GLOBAL_ROOT_UID, info, error); |
725 | 725 | ||
726 | out: | 726 | out: |
727 | aa_put_profile(hat); | 727 | aa_put_profile(hat); |
@@ -848,7 +848,7 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec, | |||
848 | audit: | 848 | audit: |
849 | if (!permtest) | 849 | if (!permtest) |
850 | error = aa_audit_file(profile, &perms, GFP_KERNEL, op, request, | 850 | error = aa_audit_file(profile, &perms, GFP_KERNEL, op, request, |
851 | name, hname, 0, info, error); | 851 | name, hname, GLOBAL_ROOT_UID, info, error); |
852 | 852 | ||
853 | aa_put_namespace(ns); | 853 | aa_put_namespace(ns); |
854 | aa_put_profile(target); | 854 | aa_put_profile(target); |
diff --git a/security/apparmor/file.c b/security/apparmor/file.c index cf19d4093ca4..cd21ec5b90af 100644 --- a/security/apparmor/file.c +++ b/security/apparmor/file.c | |||
@@ -65,7 +65,7 @@ static void audit_file_mask(struct audit_buffer *ab, u32 mask) | |||
65 | static void file_audit_cb(struct audit_buffer *ab, void *va) | 65 | static void file_audit_cb(struct audit_buffer *ab, void *va) |
66 | { | 66 | { |
67 | struct common_audit_data *sa = va; | 67 | struct common_audit_data *sa = va; |
68 | uid_t fsuid = current_fsuid(); | 68 | kuid_t fsuid = current_fsuid(); |
69 | 69 | ||
70 | if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) { | 70 | if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) { |
71 | audit_log_format(ab, " requested_mask="); | 71 | audit_log_format(ab, " requested_mask="); |
@@ -76,8 +76,10 @@ static void file_audit_cb(struct audit_buffer *ab, void *va) | |||
76 | audit_file_mask(ab, sa->aad->fs.denied); | 76 | audit_file_mask(ab, sa->aad->fs.denied); |
77 | } | 77 | } |
78 | if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) { | 78 | if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) { |
79 | audit_log_format(ab, " fsuid=%d", fsuid); | 79 | audit_log_format(ab, " fsuid=%d", |
80 | audit_log_format(ab, " ouid=%d", sa->aad->fs.ouid); | 80 | from_kuid(&init_user_ns, fsuid)); |
81 | audit_log_format(ab, " ouid=%d", | ||
82 | from_kuid(&init_user_ns, sa->aad->fs.ouid)); | ||
81 | } | 83 | } |
82 | 84 | ||
83 | if (sa->aad->fs.target) { | 85 | if (sa->aad->fs.target) { |
@@ -103,7 +105,7 @@ static void file_audit_cb(struct audit_buffer *ab, void *va) | |||
103 | */ | 105 | */ |
104 | int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, | 106 | int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, |
105 | gfp_t gfp, int op, u32 request, const char *name, | 107 | gfp_t gfp, int op, u32 request, const char *name, |
106 | const char *target, uid_t ouid, const char *info, int error) | 108 | const char *target, kuid_t ouid, const char *info, int error) |
107 | { | 109 | { |
108 | int type = AUDIT_APPARMOR_AUTO; | 110 | int type = AUDIT_APPARMOR_AUTO; |
109 | struct common_audit_data sa; | 111 | struct common_audit_data sa; |
@@ -201,7 +203,7 @@ static struct file_perms compute_perms(struct aa_dfa *dfa, unsigned int state, | |||
201 | */ | 203 | */ |
202 | perms.kill = 0; | 204 | perms.kill = 0; |
203 | 205 | ||
204 | if (current_fsuid() == cond->uid) { | 206 | if (uid_eq(current_fsuid(), cond->uid)) { |
205 | perms.allow = map_old_perms(dfa_user_allow(dfa, state)); | 207 | perms.allow = map_old_perms(dfa_user_allow(dfa, state)); |
206 | perms.audit = map_old_perms(dfa_user_audit(dfa, state)); | 208 | perms.audit = map_old_perms(dfa_user_audit(dfa, state)); |
207 | perms.quiet = map_old_perms(dfa_user_quiet(dfa, state)); | 209 | perms.quiet = map_old_perms(dfa_user_quiet(dfa, state)); |
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h index 4b7e18951aea..69d8cae634e7 100644 --- a/security/apparmor/include/audit.h +++ b/security/apparmor/include/audit.h | |||
@@ -125,7 +125,7 @@ struct apparmor_audit_data { | |||
125 | const char *target; | 125 | const char *target; |
126 | u32 request; | 126 | u32 request; |
127 | u32 denied; | 127 | u32 denied; |
128 | uid_t ouid; | 128 | kuid_t ouid; |
129 | } fs; | 129 | } fs; |
130 | }; | 130 | }; |
131 | }; | 131 | }; |
diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h index f98fd4701d80..967b2deda376 100644 --- a/security/apparmor/include/file.h +++ b/security/apparmor/include/file.h | |||
@@ -71,7 +71,7 @@ struct path; | |||
71 | 71 | ||
72 | /* need to make conditional which ones are being set */ | 72 | /* need to make conditional which ones are being set */ |
73 | struct path_cond { | 73 | struct path_cond { |
74 | uid_t uid; | 74 | kuid_t uid; |
75 | umode_t mode; | 75 | umode_t mode; |
76 | }; | 76 | }; |
77 | 77 | ||
@@ -146,7 +146,7 @@ static inline u16 dfa_map_xindex(u16 mask) | |||
146 | 146 | ||
147 | int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, | 147 | int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, |
148 | gfp_t gfp, int op, u32 request, const char *name, | 148 | gfp_t gfp, int op, u32 request, const char *name, |
149 | const char *target, uid_t ouid, const char *info, int error); | 149 | const char *target, kuid_t ouid, const char *info, int error); |
150 | 150 | ||
151 | /** | 151 | /** |
152 | * struct aa_file_rules - components used for file rule permissions | 152 | * struct aa_file_rules - components used for file rule permissions |
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 8ea39aabe948..8c2a7f6b35e2 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
@@ -352,7 +352,7 @@ static int apparmor_path_chmod(struct path *path, umode_t mode) | |||
352 | return common_perm_mnt_dentry(OP_CHMOD, path->mnt, path->dentry, AA_MAY_CHMOD); | 352 | return common_perm_mnt_dentry(OP_CHMOD, path->mnt, path->dentry, AA_MAY_CHMOD); |
353 | } | 353 | } |
354 | 354 | ||
355 | static int apparmor_path_chown(struct path *path, uid_t uid, gid_t gid) | 355 | static int apparmor_path_chown(struct path *path, kuid_t uid, kgid_t gid) |
356 | { | 356 | { |
357 | struct path_cond cond = { path->dentry->d_inode->i_uid, | 357 | struct path_cond cond = { path->dentry->d_inode->i_uid, |
358 | path->dentry->d_inode->i_mode | 358 | path->dentry->d_inode->i_mode |
diff --git a/security/capability.c b/security/capability.c index 61095df8b89a..a40aac677c72 100644 --- a/security/capability.c +++ b/security/capability.c | |||
@@ -284,7 +284,7 @@ static int cap_path_chmod(struct path *path, umode_t mode) | |||
284 | return 0; | 284 | return 0; |
285 | } | 285 | } |
286 | 286 | ||
287 | static int cap_path_chown(struct path *path, uid_t uid, gid_t gid) | 287 | static int cap_path_chown(struct path *path, kuid_t uid, kgid_t gid) |
288 | { | 288 | { |
289 | return 0; | 289 | return 0; |
290 | } | 290 | } |
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index 49a464f5595b..dfb26918699c 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c | |||
@@ -106,8 +106,8 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode, | |||
106 | memset(&hmac_misc, 0, sizeof hmac_misc); | 106 | memset(&hmac_misc, 0, sizeof hmac_misc); |
107 | hmac_misc.ino = inode->i_ino; | 107 | hmac_misc.ino = inode->i_ino; |
108 | hmac_misc.generation = inode->i_generation; | 108 | hmac_misc.generation = inode->i_generation; |
109 | hmac_misc.uid = inode->i_uid; | 109 | hmac_misc.uid = from_kuid(&init_user_ns, inode->i_uid); |
110 | hmac_misc.gid = inode->i_gid; | 110 | hmac_misc.gid = from_kgid(&init_user_ns, inode->i_gid); |
111 | hmac_misc.mode = inode->i_mode; | 111 | hmac_misc.mode = inode->i_mode; |
112 | crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof hmac_misc); | 112 | crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof hmac_misc); |
113 | crypto_shash_final(desc, digest); | 113 | crypto_shash_final(desc, digest); |
diff --git a/security/integrity/ima/ima_audit.c b/security/integrity/ima/ima_audit.c index 7a57f6769e9c..c586faae8fd6 100644 --- a/security/integrity/ima/ima_audit.c +++ b/security/integrity/ima/ima_audit.c | |||
@@ -39,8 +39,9 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode, | |||
39 | 39 | ||
40 | ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno); | 40 | ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno); |
41 | audit_log_format(ab, "pid=%d uid=%u auid=%u ses=%u", | 41 | audit_log_format(ab, "pid=%d uid=%u auid=%u ses=%u", |
42 | current->pid, current_cred()->uid, | 42 | current->pid, |
43 | audit_get_loginuid(current), | 43 | from_kuid(&init_user_ns, current_cred()->uid), |
44 | from_kuid(&init_user_ns, audit_get_loginuid(current)), | ||
44 | audit_get_sessionid(current)); | 45 | audit_get_sessionid(current)); |
45 | audit_log_task_context(ab); | 46 | audit_log_task_context(ab); |
46 | audit_log_format(ab, " op="); | 47 | audit_log_format(ab, " op="); |
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 1a9583008aae..c84df05180cb 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c | |||
@@ -39,7 +39,7 @@ struct ima_measure_rule_entry { | |||
39 | enum ima_hooks func; | 39 | enum ima_hooks func; |
40 | int mask; | 40 | int mask; |
41 | unsigned long fsmagic; | 41 | unsigned long fsmagic; |
42 | uid_t uid; | 42 | kuid_t uid; |
43 | struct { | 43 | struct { |
44 | void *rule; /* LSM file metadata specific */ | 44 | void *rule; /* LSM file metadata specific */ |
45 | int type; /* audit type */ | 45 | int type; /* audit type */ |
@@ -71,7 +71,7 @@ static struct ima_measure_rule_entry default_rules[] = { | |||
71 | .flags = IMA_FUNC | IMA_MASK}, | 71 | .flags = IMA_FUNC | IMA_MASK}, |
72 | {.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC, | 72 | {.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC, |
73 | .flags = IMA_FUNC | IMA_MASK}, | 73 | .flags = IMA_FUNC | IMA_MASK}, |
74 | {.action = MEASURE,.func = FILE_CHECK,.mask = MAY_READ,.uid = 0, | 74 | {.action = MEASURE,.func = FILE_CHECK,.mask = MAY_READ,.uid = GLOBAL_ROOT_UID, |
75 | .flags = IMA_FUNC | IMA_MASK | IMA_UID}, | 75 | .flags = IMA_FUNC | IMA_MASK | IMA_UID}, |
76 | }; | 76 | }; |
77 | 77 | ||
@@ -112,7 +112,7 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule, | |||
112 | if ((rule->flags & IMA_FSMAGIC) | 112 | if ((rule->flags & IMA_FSMAGIC) |
113 | && rule->fsmagic != inode->i_sb->s_magic) | 113 | && rule->fsmagic != inode->i_sb->s_magic) |
114 | return false; | 114 | return false; |
115 | if ((rule->flags & IMA_UID) && rule->uid != cred->uid) | 115 | if ((rule->flags & IMA_UID) && !uid_eq(rule->uid, cred->uid)) |
116 | return false; | 116 | return false; |
117 | for (i = 0; i < MAX_LSM_RULES; i++) { | 117 | for (i = 0; i < MAX_LSM_RULES; i++) { |
118 | int rc = 0; | 118 | int rc = 0; |
@@ -277,7 +277,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry) | |||
277 | 277 | ||
278 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE); | 278 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE); |
279 | 279 | ||
280 | entry->uid = -1; | 280 | entry->uid = INVALID_UID; |
281 | entry->action = UNKNOWN; | 281 | entry->action = UNKNOWN; |
282 | while ((p = strsep(&rule, " \t")) != NULL) { | 282 | while ((p = strsep(&rule, " \t")) != NULL) { |
283 | substring_t args[MAX_OPT_ARGS]; | 283 | substring_t args[MAX_OPT_ARGS]; |
@@ -361,15 +361,15 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry) | |||
361 | case Opt_uid: | 361 | case Opt_uid: |
362 | ima_log_string(ab, "uid", args[0].from); | 362 | ima_log_string(ab, "uid", args[0].from); |
363 | 363 | ||
364 | if (entry->uid != -1) { | 364 | if (uid_valid(entry->uid)) { |
365 | result = -EINVAL; | 365 | result = -EINVAL; |
366 | break; | 366 | break; |
367 | } | 367 | } |
368 | 368 | ||
369 | result = strict_strtoul(args[0].from, 10, &lnum); | 369 | result = strict_strtoul(args[0].from, 10, &lnum); |
370 | if (!result) { | 370 | if (!result) { |
371 | entry->uid = (uid_t) lnum; | 371 | entry->uid = make_kuid(current_user_ns(), (uid_t)lnum); |
372 | if (entry->uid != lnum) | 372 | if (!uid_valid(entry->uid) || (((uid_t)lnum) != lnum)) |
373 | result = -EINVAL; | 373 | result = -EINVAL; |
374 | else | 374 | else |
375 | entry->flags |= IMA_UID; | 375 | entry->flags |= IMA_UID; |
diff --git a/security/keys/internal.h b/security/keys/internal.h index 22ff05269e3d..8bbefc3b55d4 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h | |||
@@ -52,8 +52,7 @@ struct key_user { | |||
52 | atomic_t usage; /* for accessing qnkeys & qnbytes */ | 52 | atomic_t usage; /* for accessing qnkeys & qnbytes */ |
53 | atomic_t nkeys; /* number of keys */ | 53 | atomic_t nkeys; /* number of keys */ |
54 | atomic_t nikeys; /* number of instantiated keys */ | 54 | atomic_t nikeys; /* number of instantiated keys */ |
55 | uid_t uid; | 55 | kuid_t uid; |
56 | struct user_namespace *user_ns; | ||
57 | int qnkeys; /* number of keys allocated to this user */ | 56 | int qnkeys; /* number of keys allocated to this user */ |
58 | int qnbytes; /* number of bytes allocated to this user */ | 57 | int qnbytes; /* number of bytes allocated to this user */ |
59 | }; | 58 | }; |
@@ -62,8 +61,7 @@ extern struct rb_root key_user_tree; | |||
62 | extern spinlock_t key_user_lock; | 61 | extern spinlock_t key_user_lock; |
63 | extern struct key_user root_key_user; | 62 | extern struct key_user root_key_user; |
64 | 63 | ||
65 | extern struct key_user *key_user_lookup(uid_t uid, | 64 | extern struct key_user *key_user_lookup(kuid_t uid); |
66 | struct user_namespace *user_ns); | ||
67 | extern void key_user_put(struct key_user *user); | 65 | extern void key_user_put(struct key_user *user); |
68 | 66 | ||
69 | /* | 67 | /* |
diff --git a/security/keys/key.c b/security/keys/key.c index 3cbe3529c418..a30e92734905 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/workqueue.h> | 18 | #include <linux/workqueue.h> |
19 | #include <linux/random.h> | 19 | #include <linux/random.h> |
20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/user_namespace.h> | ||
22 | #include "internal.h" | 21 | #include "internal.h" |
23 | 22 | ||
24 | struct kmem_cache *key_jar; | 23 | struct kmem_cache *key_jar; |
@@ -52,7 +51,7 @@ void __key_check(const struct key *key) | |||
52 | * Get the key quota record for a user, allocating a new record if one doesn't | 51 | * Get the key quota record for a user, allocating a new record if one doesn't |
53 | * already exist. | 52 | * already exist. |
54 | */ | 53 | */ |
55 | struct key_user *key_user_lookup(uid_t uid, struct user_namespace *user_ns) | 54 | struct key_user *key_user_lookup(kuid_t uid) |
56 | { | 55 | { |
57 | struct key_user *candidate = NULL, *user; | 56 | struct key_user *candidate = NULL, *user; |
58 | struct rb_node *parent = NULL; | 57 | struct rb_node *parent = NULL; |
@@ -67,13 +66,9 @@ try_again: | |||
67 | parent = *p; | 66 | parent = *p; |
68 | user = rb_entry(parent, struct key_user, node); | 67 | user = rb_entry(parent, struct key_user, node); |
69 | 68 | ||
70 | if (uid < user->uid) | 69 | if (uid_lt(uid, user->uid)) |
71 | p = &(*p)->rb_left; | 70 | p = &(*p)->rb_left; |
72 | else if (uid > user->uid) | 71 | else if (uid_gt(uid, user->uid)) |
73 | p = &(*p)->rb_right; | ||
74 | else if (user_ns < user->user_ns) | ||
75 | p = &(*p)->rb_left; | ||
76 | else if (user_ns > user->user_ns) | ||
77 | p = &(*p)->rb_right; | 72 | p = &(*p)->rb_right; |
78 | else | 73 | else |
79 | goto found; | 74 | goto found; |
@@ -102,7 +97,6 @@ try_again: | |||
102 | atomic_set(&candidate->nkeys, 0); | 97 | atomic_set(&candidate->nkeys, 0); |
103 | atomic_set(&candidate->nikeys, 0); | 98 | atomic_set(&candidate->nikeys, 0); |
104 | candidate->uid = uid; | 99 | candidate->uid = uid; |
105 | candidate->user_ns = get_user_ns(user_ns); | ||
106 | candidate->qnkeys = 0; | 100 | candidate->qnkeys = 0; |
107 | candidate->qnbytes = 0; | 101 | candidate->qnbytes = 0; |
108 | spin_lock_init(&candidate->lock); | 102 | spin_lock_init(&candidate->lock); |
@@ -131,7 +125,6 @@ void key_user_put(struct key_user *user) | |||
131 | if (atomic_dec_and_lock(&user->usage, &key_user_lock)) { | 125 | if (atomic_dec_and_lock(&user->usage, &key_user_lock)) { |
132 | rb_erase(&user->node, &key_user_tree); | 126 | rb_erase(&user->node, &key_user_tree); |
133 | spin_unlock(&key_user_lock); | 127 | spin_unlock(&key_user_lock); |
134 | put_user_ns(user->user_ns); | ||
135 | 128 | ||
136 | kfree(user); | 129 | kfree(user); |
137 | } | 130 | } |
@@ -229,7 +222,7 @@ serial_exists: | |||
229 | * key_alloc() calls don't race with module unloading. | 222 | * key_alloc() calls don't race with module unloading. |
230 | */ | 223 | */ |
231 | struct key *key_alloc(struct key_type *type, const char *desc, | 224 | struct key *key_alloc(struct key_type *type, const char *desc, |
232 | uid_t uid, gid_t gid, const struct cred *cred, | 225 | kuid_t uid, kgid_t gid, const struct cred *cred, |
233 | key_perm_t perm, unsigned long flags) | 226 | key_perm_t perm, unsigned long flags) |
234 | { | 227 | { |
235 | struct key_user *user = NULL; | 228 | struct key_user *user = NULL; |
@@ -253,16 +246,16 @@ struct key *key_alloc(struct key_type *type, const char *desc, | |||
253 | quotalen = desclen + type->def_datalen; | 246 | quotalen = desclen + type->def_datalen; |
254 | 247 | ||
255 | /* get hold of the key tracking for this user */ | 248 | /* get hold of the key tracking for this user */ |
256 | user = key_user_lookup(uid, cred->user_ns); | 249 | user = key_user_lookup(uid); |
257 | if (!user) | 250 | if (!user) |
258 | goto no_memory_1; | 251 | goto no_memory_1; |
259 | 252 | ||
260 | /* check that the user's quota permits allocation of another key and | 253 | /* check that the user's quota permits allocation of another key and |
261 | * its description */ | 254 | * its description */ |
262 | if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) { | 255 | if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) { |
263 | unsigned maxkeys = (uid == 0) ? | 256 | unsigned maxkeys = uid_eq(uid, GLOBAL_ROOT_UID) ? |
264 | key_quota_root_maxkeys : key_quota_maxkeys; | 257 | key_quota_root_maxkeys : key_quota_maxkeys; |
265 | unsigned maxbytes = (uid == 0) ? | 258 | unsigned maxbytes = uid_eq(uid, GLOBAL_ROOT_UID) ? |
266 | key_quota_root_maxbytes : key_quota_maxbytes; | 259 | key_quota_root_maxbytes : key_quota_maxbytes; |
267 | 260 | ||
268 | spin_lock(&user->lock); | 261 | spin_lock(&user->lock); |
@@ -380,7 +373,7 @@ int key_payload_reserve(struct key *key, size_t datalen) | |||
380 | 373 | ||
381 | /* contemplate the quota adjustment */ | 374 | /* contemplate the quota adjustment */ |
382 | if (delta != 0 && test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { | 375 | if (delta != 0 && test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { |
383 | unsigned maxbytes = (key->user->uid == 0) ? | 376 | unsigned maxbytes = uid_eq(key->user->uid, GLOBAL_ROOT_UID) ? |
384 | key_quota_root_maxbytes : key_quota_maxbytes; | 377 | key_quota_root_maxbytes : key_quota_maxbytes; |
385 | 378 | ||
386 | spin_lock(&key->user->lock); | 379 | spin_lock(&key->user->lock); |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 6cfc6478863e..305ecb76519c 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -569,8 +569,8 @@ okay: | |||
569 | ret = snprintf(tmpbuf, PAGE_SIZE - 1, | 569 | ret = snprintf(tmpbuf, PAGE_SIZE - 1, |
570 | "%s;%d;%d;%08x;%s", | 570 | "%s;%d;%d;%08x;%s", |
571 | key->type->name, | 571 | key->type->name, |
572 | key->uid, | 572 | from_kuid_munged(current_user_ns(), key->uid), |
573 | key->gid, | 573 | from_kgid_munged(current_user_ns(), key->gid), |
574 | key->perm, | 574 | key->perm, |
575 | key->description ?: ""); | 575 | key->description ?: ""); |
576 | 576 | ||
@@ -766,15 +766,25 @@ error: | |||
766 | * | 766 | * |
767 | * If successful, 0 will be returned. | 767 | * If successful, 0 will be returned. |
768 | */ | 768 | */ |
769 | long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) | 769 | long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group) |
770 | { | 770 | { |
771 | struct key_user *newowner, *zapowner = NULL; | 771 | struct key_user *newowner, *zapowner = NULL; |
772 | struct key *key; | 772 | struct key *key; |
773 | key_ref_t key_ref; | 773 | key_ref_t key_ref; |
774 | long ret; | 774 | long ret; |
775 | kuid_t uid; | ||
776 | kgid_t gid; | ||
777 | |||
778 | uid = make_kuid(current_user_ns(), user); | ||
779 | gid = make_kgid(current_user_ns(), group); | ||
780 | ret = -EINVAL; | ||
781 | if ((user != (uid_t) -1) && !uid_valid(uid)) | ||
782 | goto error; | ||
783 | if ((group != (gid_t) -1) && !gid_valid(gid)) | ||
784 | goto error; | ||
775 | 785 | ||
776 | ret = 0; | 786 | ret = 0; |
777 | if (uid == (uid_t) -1 && gid == (gid_t) -1) | 787 | if (user == (uid_t) -1 && group == (gid_t) -1) |
778 | goto error; | 788 | goto error; |
779 | 789 | ||
780 | key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, | 790 | key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, |
@@ -792,27 +802,27 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) | |||
792 | 802 | ||
793 | if (!capable(CAP_SYS_ADMIN)) { | 803 | if (!capable(CAP_SYS_ADMIN)) { |
794 | /* only the sysadmin can chown a key to some other UID */ | 804 | /* only the sysadmin can chown a key to some other UID */ |
795 | if (uid != (uid_t) -1 && key->uid != uid) | 805 | if (user != (uid_t) -1 && !uid_eq(key->uid, uid)) |
796 | goto error_put; | 806 | goto error_put; |
797 | 807 | ||
798 | /* only the sysadmin can set the key's GID to a group other | 808 | /* only the sysadmin can set the key's GID to a group other |
799 | * than one of those that the current process subscribes to */ | 809 | * than one of those that the current process subscribes to */ |
800 | if (gid != (gid_t) -1 && gid != key->gid && !in_group_p(gid)) | 810 | if (group != (gid_t) -1 && !gid_eq(gid, key->gid) && !in_group_p(gid)) |
801 | goto error_put; | 811 | goto error_put; |
802 | } | 812 | } |
803 | 813 | ||
804 | /* change the UID */ | 814 | /* change the UID */ |
805 | if (uid != (uid_t) -1 && uid != key->uid) { | 815 | if (user != (uid_t) -1 && !uid_eq(uid, key->uid)) { |
806 | ret = -ENOMEM; | 816 | ret = -ENOMEM; |
807 | newowner = key_user_lookup(uid, current_user_ns()); | 817 | newowner = key_user_lookup(uid); |
808 | if (!newowner) | 818 | if (!newowner) |
809 | goto error_put; | 819 | goto error_put; |
810 | 820 | ||
811 | /* transfer the quota burden to the new user */ | 821 | /* transfer the quota burden to the new user */ |
812 | if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { | 822 | if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { |
813 | unsigned maxkeys = (uid == 0) ? | 823 | unsigned maxkeys = uid_eq(uid, GLOBAL_ROOT_UID) ? |
814 | key_quota_root_maxkeys : key_quota_maxkeys; | 824 | key_quota_root_maxkeys : key_quota_maxkeys; |
815 | unsigned maxbytes = (uid == 0) ? | 825 | unsigned maxbytes = uid_eq(uid, GLOBAL_ROOT_UID) ? |
816 | key_quota_root_maxbytes : key_quota_maxbytes; | 826 | key_quota_root_maxbytes : key_quota_maxbytes; |
817 | 827 | ||
818 | spin_lock(&newowner->lock); | 828 | spin_lock(&newowner->lock); |
@@ -846,7 +856,7 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) | |||
846 | } | 856 | } |
847 | 857 | ||
848 | /* change the GID */ | 858 | /* change the GID */ |
849 | if (gid != (gid_t) -1) | 859 | if (group != (gid_t) -1) |
850 | key->gid = gid; | 860 | key->gid = gid; |
851 | 861 | ||
852 | ret = 0; | 862 | ret = 0; |
@@ -897,7 +907,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm) | |||
897 | down_write(&key->sem); | 907 | down_write(&key->sem); |
898 | 908 | ||
899 | /* if we're not the sysadmin, we can only change a key that we own */ | 909 | /* if we're not the sysadmin, we can only change a key that we own */ |
900 | if (capable(CAP_SYS_ADMIN) || key->uid == current_fsuid()) { | 910 | if (capable(CAP_SYS_ADMIN) || uid_eq(key->uid, current_fsuid())) { |
901 | key->perm = perm; | 911 | key->perm = perm; |
902 | ret = 0; | 912 | ret = 0; |
903 | } | 913 | } |
@@ -1506,18 +1516,18 @@ long keyctl_session_to_parent(void) | |||
1506 | 1516 | ||
1507 | /* the parent must have the same effective ownership and mustn't be | 1517 | /* the parent must have the same effective ownership and mustn't be |
1508 | * SUID/SGID */ | 1518 | * SUID/SGID */ |
1509 | if (pcred->uid != mycred->euid || | 1519 | if (!uid_eq(pcred->uid, mycred->euid) || |
1510 | pcred->euid != mycred->euid || | 1520 | !uid_eq(pcred->euid, mycred->euid) || |
1511 | pcred->suid != mycred->euid || | 1521 | !uid_eq(pcred->suid, mycred->euid) || |
1512 | pcred->gid != mycred->egid || | 1522 | !gid_eq(pcred->gid, mycred->egid) || |
1513 | pcred->egid != mycred->egid || | 1523 | !gid_eq(pcred->egid, mycred->egid) || |
1514 | pcred->sgid != mycred->egid) | 1524 | !gid_eq(pcred->sgid, mycred->egid)) |
1515 | goto unlock; | 1525 | goto unlock; |
1516 | 1526 | ||
1517 | /* the keyrings must have the same UID */ | 1527 | /* the keyrings must have the same UID */ |
1518 | if ((pcred->tgcred->session_keyring && | 1528 | if ((pcred->tgcred->session_keyring && |
1519 | pcred->tgcred->session_keyring->uid != mycred->euid) || | 1529 | !uid_eq(pcred->tgcred->session_keyring->uid, mycred->euid)) || |
1520 | mycred->tgcred->session_keyring->uid != mycred->euid) | 1530 | !uid_eq(mycred->tgcred->session_keyring->uid, mycred->euid)) |
1521 | goto unlock; | 1531 | goto unlock; |
1522 | 1532 | ||
1523 | /* cancel an already pending keyring replacement */ | 1533 | /* cancel an already pending keyring replacement */ |
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 81e7852d281d..a5f5c4b6edc5 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -256,7 +256,7 @@ error: | |||
256 | /* | 256 | /* |
257 | * Allocate a keyring and link into the destination keyring. | 257 | * Allocate a keyring and link into the destination keyring. |
258 | */ | 258 | */ |
259 | struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, | 259 | struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid, |
260 | const struct cred *cred, unsigned long flags, | 260 | const struct cred *cred, unsigned long flags, |
261 | struct key *dest) | 261 | struct key *dest) |
262 | { | 262 | { |
@@ -612,7 +612,7 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check) | |||
612 | &keyring_name_hash[bucket], | 612 | &keyring_name_hash[bucket], |
613 | type_data.link | 613 | type_data.link |
614 | ) { | 614 | ) { |
615 | if (keyring->user->user_ns != current_user_ns()) | 615 | if (!kuid_has_mapping(current_user_ns(), keyring->user->uid)) |
616 | continue; | 616 | continue; |
617 | 617 | ||
618 | if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) | 618 | if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) |
diff --git a/security/keys/permission.c b/security/keys/permission.c index 0b4d019e027d..efcc0c855a0d 100644 --- a/security/keys/permission.c +++ b/security/keys/permission.c | |||
@@ -36,33 +36,27 @@ int key_task_permission(const key_ref_t key_ref, const struct cred *cred, | |||
36 | 36 | ||
37 | key = key_ref_to_ptr(key_ref); | 37 | key = key_ref_to_ptr(key_ref); |
38 | 38 | ||
39 | if (key->user->user_ns != cred->user_ns) | ||
40 | goto use_other_perms; | ||
41 | |||
42 | /* use the second 8-bits of permissions for keys the caller owns */ | 39 | /* use the second 8-bits of permissions for keys the caller owns */ |
43 | if (key->uid == cred->fsuid) { | 40 | if (uid_eq(key->uid, cred->fsuid)) { |
44 | kperm = key->perm >> 16; | 41 | kperm = key->perm >> 16; |
45 | goto use_these_perms; | 42 | goto use_these_perms; |
46 | } | 43 | } |
47 | 44 | ||
48 | /* use the third 8-bits of permissions for keys the caller has a group | 45 | /* use the third 8-bits of permissions for keys the caller has a group |
49 | * membership in common with */ | 46 | * membership in common with */ |
50 | if (key->gid != -1 && key->perm & KEY_GRP_ALL) { | 47 | if (gid_valid(key->gid) && key->perm & KEY_GRP_ALL) { |
51 | if (key->gid == cred->fsgid) { | 48 | if (gid_eq(key->gid, cred->fsgid)) { |
52 | kperm = key->perm >> 8; | 49 | kperm = key->perm >> 8; |
53 | goto use_these_perms; | 50 | goto use_these_perms; |
54 | } | 51 | } |
55 | 52 | ||
56 | ret = groups_search(cred->group_info, | 53 | ret = groups_search(cred->group_info, key->gid); |
57 | make_kgid(current_user_ns(), key->gid)); | ||
58 | if (ret) { | 54 | if (ret) { |
59 | kperm = key->perm >> 8; | 55 | kperm = key->perm >> 8; |
60 | goto use_these_perms; | 56 | goto use_these_perms; |
61 | } | 57 | } |
62 | } | 58 | } |
63 | 59 | ||
64 | use_other_perms: | ||
65 | |||
66 | /* otherwise use the least-significant 8-bits */ | 60 | /* otherwise use the least-significant 8-bits */ |
67 | kperm = key->perm; | 61 | kperm = key->perm; |
68 | 62 | ||
diff --git a/security/keys/proc.c b/security/keys/proc.c index 30d1ddfd9cef..217b6855e815 100644 --- a/security/keys/proc.c +++ b/security/keys/proc.c | |||
@@ -88,14 +88,14 @@ __initcall(key_proc_init); | |||
88 | */ | 88 | */ |
89 | #ifdef CONFIG_KEYS_DEBUG_PROC_KEYS | 89 | #ifdef CONFIG_KEYS_DEBUG_PROC_KEYS |
90 | 90 | ||
91 | static struct rb_node *key_serial_next(struct rb_node *n) | 91 | static struct rb_node *key_serial_next(struct seq_file *p, struct rb_node *n) |
92 | { | 92 | { |
93 | struct user_namespace *user_ns = current_user_ns(); | 93 | struct user_namespace *user_ns = seq_user_ns(p); |
94 | 94 | ||
95 | n = rb_next(n); | 95 | n = rb_next(n); |
96 | while (n) { | 96 | while (n) { |
97 | struct key *key = rb_entry(n, struct key, serial_node); | 97 | struct key *key = rb_entry(n, struct key, serial_node); |
98 | if (key->user->user_ns == user_ns) | 98 | if (kuid_has_mapping(user_ns, key->user->uid)) |
99 | break; | 99 | break; |
100 | n = rb_next(n); | 100 | n = rb_next(n); |
101 | } | 101 | } |
@@ -107,9 +107,9 @@ static int proc_keys_open(struct inode *inode, struct file *file) | |||
107 | return seq_open(file, &proc_keys_ops); | 107 | return seq_open(file, &proc_keys_ops); |
108 | } | 108 | } |
109 | 109 | ||
110 | static struct key *find_ge_key(key_serial_t id) | 110 | static struct key *find_ge_key(struct seq_file *p, key_serial_t id) |
111 | { | 111 | { |
112 | struct user_namespace *user_ns = current_user_ns(); | 112 | struct user_namespace *user_ns = seq_user_ns(p); |
113 | struct rb_node *n = key_serial_tree.rb_node; | 113 | struct rb_node *n = key_serial_tree.rb_node; |
114 | struct key *minkey = NULL; | 114 | struct key *minkey = NULL; |
115 | 115 | ||
@@ -132,7 +132,7 @@ static struct key *find_ge_key(key_serial_t id) | |||
132 | return NULL; | 132 | return NULL; |
133 | 133 | ||
134 | for (;;) { | 134 | for (;;) { |
135 | if (minkey->user->user_ns == user_ns) | 135 | if (kuid_has_mapping(user_ns, minkey->user->uid)) |
136 | return minkey; | 136 | return minkey; |
137 | n = rb_next(&minkey->serial_node); | 137 | n = rb_next(&minkey->serial_node); |
138 | if (!n) | 138 | if (!n) |
@@ -151,7 +151,7 @@ static void *proc_keys_start(struct seq_file *p, loff_t *_pos) | |||
151 | 151 | ||
152 | if (*_pos > INT_MAX) | 152 | if (*_pos > INT_MAX) |
153 | return NULL; | 153 | return NULL; |
154 | key = find_ge_key(pos); | 154 | key = find_ge_key(p, pos); |
155 | if (!key) | 155 | if (!key) |
156 | return NULL; | 156 | return NULL; |
157 | *_pos = key->serial; | 157 | *_pos = key->serial; |
@@ -168,7 +168,7 @@ static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos) | |||
168 | { | 168 | { |
169 | struct rb_node *n; | 169 | struct rb_node *n; |
170 | 170 | ||
171 | n = key_serial_next(v); | 171 | n = key_serial_next(p, v); |
172 | if (n) | 172 | if (n) |
173 | *_pos = key_node_serial(n); | 173 | *_pos = key_node_serial(n); |
174 | return n; | 174 | return n; |
@@ -254,8 +254,8 @@ static int proc_keys_show(struct seq_file *m, void *v) | |||
254 | atomic_read(&key->usage), | 254 | atomic_read(&key->usage), |
255 | xbuf, | 255 | xbuf, |
256 | key->perm, | 256 | key->perm, |
257 | key->uid, | 257 | from_kuid_munged(seq_user_ns(m), key->uid), |
258 | key->gid, | 258 | from_kgid_munged(seq_user_ns(m), key->gid), |
259 | key->type->name); | 259 | key->type->name); |
260 | 260 | ||
261 | #undef showflag | 261 | #undef showflag |
@@ -270,26 +270,26 @@ static int proc_keys_show(struct seq_file *m, void *v) | |||
270 | 270 | ||
271 | #endif /* CONFIG_KEYS_DEBUG_PROC_KEYS */ | 271 | #endif /* CONFIG_KEYS_DEBUG_PROC_KEYS */ |
272 | 272 | ||
273 | static struct rb_node *__key_user_next(struct rb_node *n) | 273 | static struct rb_node *__key_user_next(struct user_namespace *user_ns, struct rb_node *n) |
274 | { | 274 | { |
275 | while (n) { | 275 | while (n) { |
276 | struct key_user *user = rb_entry(n, struct key_user, node); | 276 | struct key_user *user = rb_entry(n, struct key_user, node); |
277 | if (user->user_ns == current_user_ns()) | 277 | if (kuid_has_mapping(user_ns, user->uid)) |
278 | break; | 278 | break; |
279 | n = rb_next(n); | 279 | n = rb_next(n); |
280 | } | 280 | } |
281 | return n; | 281 | return n; |
282 | } | 282 | } |
283 | 283 | ||
284 | static struct rb_node *key_user_next(struct rb_node *n) | 284 | static struct rb_node *key_user_next(struct user_namespace *user_ns, struct rb_node *n) |
285 | { | 285 | { |
286 | return __key_user_next(rb_next(n)); | 286 | return __key_user_next(user_ns, rb_next(n)); |
287 | } | 287 | } |
288 | 288 | ||
289 | static struct rb_node *key_user_first(struct rb_root *r) | 289 | static struct rb_node *key_user_first(struct user_namespace *user_ns, struct rb_root *r) |
290 | { | 290 | { |
291 | struct rb_node *n = rb_first(r); | 291 | struct rb_node *n = rb_first(r); |
292 | return __key_user_next(n); | 292 | return __key_user_next(user_ns, n); |
293 | } | 293 | } |
294 | 294 | ||
295 | /* | 295 | /* |
@@ -309,10 +309,10 @@ static void *proc_key_users_start(struct seq_file *p, loff_t *_pos) | |||
309 | 309 | ||
310 | spin_lock(&key_user_lock); | 310 | spin_lock(&key_user_lock); |
311 | 311 | ||
312 | _p = key_user_first(&key_user_tree); | 312 | _p = key_user_first(seq_user_ns(p), &key_user_tree); |
313 | while (pos > 0 && _p) { | 313 | while (pos > 0 && _p) { |
314 | pos--; | 314 | pos--; |
315 | _p = key_user_next(_p); | 315 | _p = key_user_next(seq_user_ns(p), _p); |
316 | } | 316 | } |
317 | 317 | ||
318 | return _p; | 318 | return _p; |
@@ -321,7 +321,7 @@ static void *proc_key_users_start(struct seq_file *p, loff_t *_pos) | |||
321 | static void *proc_key_users_next(struct seq_file *p, void *v, loff_t *_pos) | 321 | static void *proc_key_users_next(struct seq_file *p, void *v, loff_t *_pos) |
322 | { | 322 | { |
323 | (*_pos)++; | 323 | (*_pos)++; |
324 | return key_user_next((struct rb_node *)v); | 324 | return key_user_next(seq_user_ns(p), (struct rb_node *)v); |
325 | } | 325 | } |
326 | 326 | ||
327 | static void proc_key_users_stop(struct seq_file *p, void *v) | 327 | static void proc_key_users_stop(struct seq_file *p, void *v) |
@@ -334,13 +334,13 @@ static int proc_key_users_show(struct seq_file *m, void *v) | |||
334 | { | 334 | { |
335 | struct rb_node *_p = v; | 335 | struct rb_node *_p = v; |
336 | struct key_user *user = rb_entry(_p, struct key_user, node); | 336 | struct key_user *user = rb_entry(_p, struct key_user, node); |
337 | unsigned maxkeys = (user->uid == 0) ? | 337 | unsigned maxkeys = uid_eq(user->uid, GLOBAL_ROOT_UID) ? |
338 | key_quota_root_maxkeys : key_quota_maxkeys; | 338 | key_quota_root_maxkeys : key_quota_maxkeys; |
339 | unsigned maxbytes = (user->uid == 0) ? | 339 | unsigned maxbytes = uid_eq(user->uid, GLOBAL_ROOT_UID) ? |
340 | key_quota_root_maxbytes : key_quota_maxbytes; | 340 | key_quota_root_maxbytes : key_quota_maxbytes; |
341 | 341 | ||
342 | seq_printf(m, "%5u: %5d %d/%d %d/%d %d/%d\n", | 342 | seq_printf(m, "%5u: %5d %d/%d %d/%d %d/%d\n", |
343 | user->uid, | 343 | from_kuid_munged(seq_user_ns(m), user->uid), |
344 | atomic_read(&user->usage), | 344 | atomic_read(&user->usage), |
345 | atomic_read(&user->nkeys), | 345 | atomic_read(&user->nkeys), |
346 | atomic_read(&user->nikeys), | 346 | atomic_read(&user->nikeys), |
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 54339cfd6734..a58f712605d8 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
@@ -34,8 +34,7 @@ struct key_user root_key_user = { | |||
34 | .lock = __SPIN_LOCK_UNLOCKED(root_key_user.lock), | 34 | .lock = __SPIN_LOCK_UNLOCKED(root_key_user.lock), |
35 | .nkeys = ATOMIC_INIT(2), | 35 | .nkeys = ATOMIC_INIT(2), |
36 | .nikeys = ATOMIC_INIT(2), | 36 | .nikeys = ATOMIC_INIT(2), |
37 | .uid = 0, | 37 | .uid = GLOBAL_ROOT_UID, |
38 | .user_ns = &init_user_ns, | ||
39 | }; | 38 | }; |
40 | 39 | ||
41 | /* | 40 | /* |
@@ -48,11 +47,13 @@ int install_user_keyrings(void) | |||
48 | struct key *uid_keyring, *session_keyring; | 47 | struct key *uid_keyring, *session_keyring; |
49 | char buf[20]; | 48 | char buf[20]; |
50 | int ret; | 49 | int ret; |
50 | uid_t uid; | ||
51 | 51 | ||
52 | cred = current_cred(); | 52 | cred = current_cred(); |
53 | user = cred->user; | 53 | user = cred->user; |
54 | uid = from_kuid(cred->user_ns, user->uid); | ||
54 | 55 | ||
55 | kenter("%p{%u}", user, user->uid); | 56 | kenter("%p{%u}", user, uid); |
56 | 57 | ||
57 | if (user->uid_keyring) { | 58 | if (user->uid_keyring) { |
58 | kleave(" = 0 [exist]"); | 59 | kleave(" = 0 [exist]"); |
@@ -67,11 +68,11 @@ int install_user_keyrings(void) | |||
67 | * - there may be one in existence already as it may have been | 68 | * - there may be one in existence already as it may have been |
68 | * pinned by a session, but the user_struct pointing to it | 69 | * pinned by a session, but the user_struct pointing to it |
69 | * may have been destroyed by setuid */ | 70 | * may have been destroyed by setuid */ |
70 | sprintf(buf, "_uid.%u", user->uid); | 71 | sprintf(buf, "_uid.%u", uid); |
71 | 72 | ||
72 | uid_keyring = find_keyring_by_name(buf, true); | 73 | uid_keyring = find_keyring_by_name(buf, true); |
73 | if (IS_ERR(uid_keyring)) { | 74 | if (IS_ERR(uid_keyring)) { |
74 | uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, | 75 | uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID, |
75 | cred, KEY_ALLOC_IN_QUOTA, | 76 | cred, KEY_ALLOC_IN_QUOTA, |
76 | NULL); | 77 | NULL); |
77 | if (IS_ERR(uid_keyring)) { | 78 | if (IS_ERR(uid_keyring)) { |
@@ -82,12 +83,12 @@ int install_user_keyrings(void) | |||
82 | 83 | ||
83 | /* get a default session keyring (which might also exist | 84 | /* get a default session keyring (which might also exist |
84 | * already) */ | 85 | * already) */ |
85 | sprintf(buf, "_uid_ses.%u", user->uid); | 86 | sprintf(buf, "_uid_ses.%u", uid); |
86 | 87 | ||
87 | session_keyring = find_keyring_by_name(buf, true); | 88 | session_keyring = find_keyring_by_name(buf, true); |
88 | if (IS_ERR(session_keyring)) { | 89 | if (IS_ERR(session_keyring)) { |
89 | session_keyring = | 90 | session_keyring = |
90 | keyring_alloc(buf, user->uid, (gid_t) -1, | 91 | keyring_alloc(buf, user->uid, INVALID_GID, |
91 | cred, KEY_ALLOC_IN_QUOTA, NULL); | 92 | cred, KEY_ALLOC_IN_QUOTA, NULL); |
92 | if (IS_ERR(session_keyring)) { | 93 | if (IS_ERR(session_keyring)) { |
93 | ret = PTR_ERR(session_keyring); | 94 | ret = PTR_ERR(session_keyring); |
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 000e75017520..66e21184b559 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
@@ -139,8 +139,8 @@ static int call_sbin_request_key(struct key_construction *cons, | |||
139 | goto error_link; | 139 | goto error_link; |
140 | 140 | ||
141 | /* record the UID and GID */ | 141 | /* record the UID and GID */ |
142 | sprintf(uid_str, "%d", cred->fsuid); | 142 | sprintf(uid_str, "%d", from_kuid(&init_user_ns, cred->fsuid)); |
143 | sprintf(gid_str, "%d", cred->fsgid); | 143 | sprintf(gid_str, "%d", from_kgid(&init_user_ns, cred->fsgid)); |
144 | 144 | ||
145 | /* we say which key is under construction */ | 145 | /* we say which key is under construction */ |
146 | sprintf(key_str, "%d", key->serial); | 146 | sprintf(key_str, "%d", key->serial); |
@@ -442,7 +442,7 @@ static struct key *construct_key_and_link(struct key_type *type, | |||
442 | 442 | ||
443 | kenter(""); | 443 | kenter(""); |
444 | 444 | ||
445 | user = key_user_lookup(current_fsuid(), current_user_ns()); | 445 | user = key_user_lookup(current_fsuid()); |
446 | if (!user) | 446 | if (!user) |
447 | return ERR_PTR(-ENOMEM); | 447 | return ERR_PTR(-ENOMEM); |
448 | 448 | ||
diff --git a/security/security.c b/security/security.c index 860aeb349cb3..f9a2f2ef2454 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -434,7 +434,7 @@ int security_path_chmod(struct path *path, umode_t mode) | |||
434 | return security_ops->path_chmod(path, mode); | 434 | return security_ops->path_chmod(path, mode); |
435 | } | 435 | } |
436 | 436 | ||
437 | int security_path_chown(struct path *path, uid_t uid, gid_t gid) | 437 | int security_path_chown(struct path *path, kuid_t uid, kgid_t gid) |
438 | { | 438 | { |
439 | if (unlikely(IS_PRIVATE(path->dentry->d_inode))) | 439 | if (unlikely(IS_PRIVATE(path->dentry->d_inode))) |
440 | return 0; | 440 | return 0; |
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 298e695d6822..55af8c5b57e6 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
@@ -174,7 +174,7 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf, | |||
174 | audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, | 174 | audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, |
175 | "enforcing=%d old_enforcing=%d auid=%u ses=%u", | 175 | "enforcing=%d old_enforcing=%d auid=%u ses=%u", |
176 | new_value, selinux_enforcing, | 176 | new_value, selinux_enforcing, |
177 | audit_get_loginuid(current), | 177 | from_kuid(&init_user_ns, audit_get_loginuid(current)), |
178 | audit_get_sessionid(current)); | 178 | audit_get_sessionid(current)); |
179 | selinux_enforcing = new_value; | 179 | selinux_enforcing = new_value; |
180 | if (selinux_enforcing) | 180 | if (selinux_enforcing) |
@@ -305,7 +305,7 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf, | |||
305 | goto out; | 305 | goto out; |
306 | audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, | 306 | audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, |
307 | "selinux=0 auid=%u ses=%u", | 307 | "selinux=0 auid=%u ses=%u", |
308 | audit_get_loginuid(current), | 308 | from_kuid(&init_user_ns, audit_get_loginuid(current)), |
309 | audit_get_sessionid(current)); | 309 | audit_get_sessionid(current)); |
310 | } | 310 | } |
311 | 311 | ||
@@ -551,7 +551,7 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, | |||
551 | out1: | 551 | out1: |
552 | audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD, | 552 | audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD, |
553 | "policy loaded auid=%u ses=%u", | 553 | "policy loaded auid=%u ses=%u", |
554 | audit_get_loginuid(current), | 554 | from_kuid(&init_user_ns, audit_get_loginuid(current)), |
555 | audit_get_sessionid(current)); | 555 | audit_get_sessionid(current)); |
556 | out: | 556 | out: |
557 | mutex_unlock(&sel_mutex); | 557 | mutex_unlock(&sel_mutex); |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 4321b8fc8863..b4feecc3fe01 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -2440,7 +2440,7 @@ int security_set_bools(int len, int *values) | |||
2440 | sym_name(&policydb, SYM_BOOLS, i), | 2440 | sym_name(&policydb, SYM_BOOLS, i), |
2441 | !!values[i], | 2441 | !!values[i], |
2442 | policydb.bool_val_to_struct[i]->state, | 2442 | policydb.bool_val_to_struct[i]->state, |
2443 | audit_get_loginuid(current), | 2443 | from_kuid(&init_user_ns, audit_get_loginuid(current)), |
2444 | audit_get_sessionid(current)); | 2444 | audit_get_sessionid(current)); |
2445 | } | 2445 | } |
2446 | if (values[i]) | 2446 | if (values[i]) |
diff --git a/security/tomoyo/audit.c b/security/tomoyo/audit.c index 7ef9fa3e37e0..c1b00375c9ad 100644 --- a/security/tomoyo/audit.c +++ b/security/tomoyo/audit.c | |||
@@ -168,9 +168,14 @@ static char *tomoyo_print_header(struct tomoyo_request_info *r) | |||
168 | stamp.day, stamp.hour, stamp.min, stamp.sec, r->profile, | 168 | stamp.day, stamp.hour, stamp.min, stamp.sec, r->profile, |
169 | tomoyo_mode[r->mode], tomoyo_yesno(r->granted), gpid, | 169 | tomoyo_mode[r->mode], tomoyo_yesno(r->granted), gpid, |
170 | tomoyo_sys_getpid(), tomoyo_sys_getppid(), | 170 | tomoyo_sys_getpid(), tomoyo_sys_getppid(), |
171 | current_uid(), current_gid(), current_euid(), | 171 | from_kuid(&init_user_ns, current_uid()), |
172 | current_egid(), current_suid(), current_sgid(), | 172 | from_kgid(&init_user_ns, current_gid()), |
173 | current_fsuid(), current_fsgid()); | 173 | from_kuid(&init_user_ns, current_euid()), |
174 | from_kgid(&init_user_ns, current_egid()), | ||
175 | from_kuid(&init_user_ns, current_suid()), | ||
176 | from_kgid(&init_user_ns, current_sgid()), | ||
177 | from_kuid(&init_user_ns, current_fsuid()), | ||
178 | from_kgid(&init_user_ns, current_fsgid())); | ||
174 | if (!obj) | 179 | if (!obj) |
175 | goto no_obj_info; | 180 | goto no_obj_info; |
176 | if (!obj->validate_done) { | 181 | if (!obj->validate_done) { |
@@ -191,15 +196,19 @@ static char *tomoyo_print_header(struct tomoyo_request_info *r) | |||
191 | tomoyo_buffer_len - 1 - pos, | 196 | tomoyo_buffer_len - 1 - pos, |
192 | " path%u.parent={ uid=%u gid=%u " | 197 | " path%u.parent={ uid=%u gid=%u " |
193 | "ino=%lu perm=0%o }", (i >> 1) + 1, | 198 | "ino=%lu perm=0%o }", (i >> 1) + 1, |
194 | stat->uid, stat->gid, (unsigned long) | 199 | from_kuid(&init_user_ns, stat->uid), |
195 | stat->ino, stat->mode & S_IALLUGO); | 200 | from_kgid(&init_user_ns, stat->gid), |
201 | (unsigned long)stat->ino, | ||
202 | stat->mode & S_IALLUGO); | ||
196 | continue; | 203 | continue; |
197 | } | 204 | } |
198 | pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos, | 205 | pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos, |
199 | " path%u={ uid=%u gid=%u ino=%lu major=%u" | 206 | " path%u={ uid=%u gid=%u ino=%lu major=%u" |
200 | " minor=%u perm=0%o type=%s", (i >> 1) + 1, | 207 | " minor=%u perm=0%o type=%s", (i >> 1) + 1, |
201 | stat->uid, stat->gid, (unsigned long) | 208 | from_kuid(&init_user_ns, stat->uid), |
202 | stat->ino, MAJOR(dev), MINOR(dev), | 209 | from_kgid(&init_user_ns, stat->gid), |
210 | (unsigned long)stat->ino, | ||
211 | MAJOR(dev), MINOR(dev), | ||
203 | mode & S_IALLUGO, tomoyo_filetype(mode)); | 212 | mode & S_IALLUGO, tomoyo_filetype(mode)); |
204 | if (S_ISCHR(mode) || S_ISBLK(mode)) { | 213 | if (S_ISCHR(mode) || S_ISBLK(mode)) { |
205 | dev = stat->rdev; | 214 | dev = stat->rdev; |
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 2e0f12c62938..f89a0333b813 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -925,7 +925,9 @@ static bool tomoyo_manager(void) | |||
925 | 925 | ||
926 | if (!tomoyo_policy_loaded) | 926 | if (!tomoyo_policy_loaded) |
927 | return true; | 927 | return true; |
928 | if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid)) | 928 | if (!tomoyo_manage_by_non_root && |
929 | (!uid_eq(task->cred->uid, GLOBAL_ROOT_UID) || | ||
930 | !uid_eq(task->cred->euid, GLOBAL_ROOT_UID))) | ||
929 | return false; | 931 | return false; |
930 | exe = tomoyo_get_exe(); | 932 | exe = tomoyo_get_exe(); |
931 | if (!exe) | 933 | if (!exe) |
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 75e4dc1c02a0..af010b62d544 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h | |||
@@ -561,8 +561,8 @@ struct tomoyo_address_group { | |||
561 | 561 | ||
562 | /* Subset of "struct stat". Used by conditional ACL and audit logs. */ | 562 | /* Subset of "struct stat". Used by conditional ACL and audit logs. */ |
563 | struct tomoyo_mini_stat { | 563 | struct tomoyo_mini_stat { |
564 | uid_t uid; | 564 | kuid_t uid; |
565 | gid_t gid; | 565 | kgid_t gid; |
566 | ino_t ino; | 566 | ino_t ino; |
567 | umode_t mode; | 567 | umode_t mode; |
568 | dev_t dev; | 568 | dev_t dev; |
diff --git a/security/tomoyo/condition.c b/security/tomoyo/condition.c index 986330b8c73e..63681e8be628 100644 --- a/security/tomoyo/condition.c +++ b/security/tomoyo/condition.c | |||
@@ -813,28 +813,28 @@ bool tomoyo_condition(struct tomoyo_request_info *r, | |||
813 | unsigned long value = 0; | 813 | unsigned long value = 0; |
814 | switch (index) { | 814 | switch (index) { |
815 | case TOMOYO_TASK_UID: | 815 | case TOMOYO_TASK_UID: |
816 | value = current_uid(); | 816 | value = from_kuid(&init_user_ns, current_uid()); |
817 | break; | 817 | break; |
818 | case TOMOYO_TASK_EUID: | 818 | case TOMOYO_TASK_EUID: |
819 | value = current_euid(); | 819 | value = from_kuid(&init_user_ns, current_euid()); |
820 | break; | 820 | break; |
821 | case TOMOYO_TASK_SUID: | 821 | case TOMOYO_TASK_SUID: |
822 | value = current_suid(); | 822 | value = from_kuid(&init_user_ns, current_suid()); |
823 | break; | 823 | break; |
824 | case TOMOYO_TASK_FSUID: | 824 | case TOMOYO_TASK_FSUID: |
825 | value = current_fsuid(); | 825 | value = from_kuid(&init_user_ns, current_fsuid()); |
826 | break; | 826 | break; |
827 | case TOMOYO_TASK_GID: | 827 | case TOMOYO_TASK_GID: |
828 | value = current_gid(); | 828 | value = from_kgid(&init_user_ns, current_gid()); |
829 | break; | 829 | break; |
830 | case TOMOYO_TASK_EGID: | 830 | case TOMOYO_TASK_EGID: |
831 | value = current_egid(); | 831 | value = from_kgid(&init_user_ns, current_egid()); |
832 | break; | 832 | break; |
833 | case TOMOYO_TASK_SGID: | 833 | case TOMOYO_TASK_SGID: |
834 | value = current_sgid(); | 834 | value = from_kgid(&init_user_ns, current_sgid()); |
835 | break; | 835 | break; |
836 | case TOMOYO_TASK_FSGID: | 836 | case TOMOYO_TASK_FSGID: |
837 | value = current_fsgid(); | 837 | value = from_kgid(&init_user_ns, current_fsgid()); |
838 | break; | 838 | break; |
839 | case TOMOYO_TASK_PID: | 839 | case TOMOYO_TASK_PID: |
840 | value = tomoyo_sys_getpid(); | 840 | value = tomoyo_sys_getpid(); |
@@ -970,13 +970,13 @@ bool tomoyo_condition(struct tomoyo_request_info *r, | |||
970 | case TOMOYO_PATH2_UID: | 970 | case TOMOYO_PATH2_UID: |
971 | case TOMOYO_PATH1_PARENT_UID: | 971 | case TOMOYO_PATH1_PARENT_UID: |
972 | case TOMOYO_PATH2_PARENT_UID: | 972 | case TOMOYO_PATH2_PARENT_UID: |
973 | value = stat->uid; | 973 | value = from_kuid(&init_user_ns, stat->uid); |
974 | break; | 974 | break; |
975 | case TOMOYO_PATH1_GID: | 975 | case TOMOYO_PATH1_GID: |
976 | case TOMOYO_PATH2_GID: | 976 | case TOMOYO_PATH2_GID: |
977 | case TOMOYO_PATH1_PARENT_GID: | 977 | case TOMOYO_PATH1_PARENT_GID: |
978 | case TOMOYO_PATH2_PARENT_GID: | 978 | case TOMOYO_PATH2_PARENT_GID: |
979 | value = stat->gid; | 979 | value = from_kgid(&init_user_ns, stat->gid); |
980 | break; | 980 | break; |
981 | case TOMOYO_PATH1_INO: | 981 | case TOMOYO_PATH1_INO: |
982 | case TOMOYO_PATH2_INO: | 982 | case TOMOYO_PATH2_INO: |
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c index c2d04a50f76a..d88eb3a046ed 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c | |||
@@ -373,13 +373,15 @@ static int tomoyo_path_chmod(struct path *path, umode_t mode) | |||
373 | * | 373 | * |
374 | * Returns 0 on success, negative value otherwise. | 374 | * Returns 0 on success, negative value otherwise. |
375 | */ | 375 | */ |
376 | static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid) | 376 | static int tomoyo_path_chown(struct path *path, kuid_t uid, kgid_t gid) |
377 | { | 377 | { |
378 | int error = 0; | 378 | int error = 0; |
379 | if (uid != (uid_t) -1) | 379 | if (uid_valid(uid)) |
380 | error = tomoyo_path_number_perm(TOMOYO_TYPE_CHOWN, path, uid); | 380 | error = tomoyo_path_number_perm(TOMOYO_TYPE_CHOWN, path, |
381 | if (!error && gid != (gid_t) -1) | 381 | from_kuid(&init_user_ns, uid)); |
382 | error = tomoyo_path_number_perm(TOMOYO_TYPE_CHGRP, path, gid); | 382 | if (!error && gid_valid(gid)) |
383 | error = tomoyo_path_number_perm(TOMOYO_TYPE_CHGRP, path, | ||
384 | from_kgid(&init_user_ns, gid)); | ||
383 | return error; | 385 | return error; |
384 | } | 386 | } |
385 | 387 | ||