Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'serge-next' into next

+96 -129
+6 -7
fs/ecryptfs/messaging.c
··· 360 360 struct ecryptfs_msg_ctx *msg_ctx; 361 361 size_t msg_size; 362 362 struct nsproxy *nsproxy; 363 - struct user_namespace *current_user_ns; 363 + struct user_namespace *tsk_user_ns; 364 364 uid_t ctx_euid; 365 365 int rc; 366 366 ··· 385 385 mutex_unlock(&ecryptfs_daemon_hash_mux); 386 386 goto wake_up; 387 387 } 388 - current_user_ns = nsproxy->user_ns; 388 + tsk_user_ns = __task_cred(msg_ctx->task)->user->user_ns; 389 389 ctx_euid = task_euid(msg_ctx->task); 390 - rc = ecryptfs_find_daemon_by_euid(&daemon, ctx_euid, current_user_ns); 390 + rc = ecryptfs_find_daemon_by_euid(&daemon, ctx_euid, tsk_user_ns); 391 391 rcu_read_unlock(); 392 392 mutex_unlock(&ecryptfs_daemon_hash_mux); 393 393 if (rc) { ··· 405 405 euid, ctx_euid); 406 406 goto unlock; 407 407 } 408 - if (current_user_ns != user_ns) { 408 + if (tsk_user_ns != user_ns) { 409 409 rc = -EBADMSG; 410 410 printk(KERN_WARNING "%s: Received message from user_ns " 411 411 "[0x%p]; expected message from user_ns [0x%p]\n", 412 - __func__, user_ns, nsproxy->user_ns); 412 + __func__, user_ns, tsk_user_ns); 413 413 goto unlock; 414 414 } 415 415 if (daemon->pid != pid) { ··· 468 468 uid_t euid = current_euid(); 469 469 int rc; 470 470 471 - rc = ecryptfs_find_daemon_by_euid(&daemon, euid, 472 - current->nsproxy->user_ns); 471 + rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); 473 472 if (rc || !daemon) { 474 473 rc = -ENOTCONN; 475 474 printk(KERN_ERR "%s: User [%d] does not have a daemon "
+7 -12
fs/ecryptfs/miscdev.c
··· 47 47 48 48 mutex_lock(&ecryptfs_daemon_hash_mux); 49 49 /* TODO: Just use file->private_data? */ 50 - rc = ecryptfs_find_daemon_by_euid(&daemon, euid, 51 - current->nsproxy->user_ns); 50 + rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); 52 51 BUG_ON(rc || !daemon); 53 52 mutex_lock(&daemon->mux); 54 53 mutex_unlock(&ecryptfs_daemon_hash_mux); ··· 94 95 "count; rc = [%d]\n", __func__, rc); 95 96 goto out_unlock_daemon_list; 96 97 } 97 - rc = ecryptfs_find_daemon_by_euid(&daemon, euid, 98 - current->nsproxy->user_ns); 98 + rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); 99 99 if (rc || !daemon) { 100 - rc = ecryptfs_spawn_daemon(&daemon, euid, 101 - current->nsproxy->user_ns, 100 + rc = ecryptfs_spawn_daemon(&daemon, euid, current_user_ns(), 102 101 task_pid(current)); 103 102 if (rc) { 104 103 printk(KERN_ERR "%s: Error attempting to spawn daemon; " ··· 150 153 int rc; 151 154 152 155 mutex_lock(&ecryptfs_daemon_hash_mux); 153 - rc = ecryptfs_find_daemon_by_euid(&daemon, euid, 154 - current->nsproxy->user_ns); 156 + rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); 155 157 BUG_ON(rc || !daemon); 156 158 mutex_lock(&daemon->mux); 157 159 BUG_ON(daemon->pid != task_pid(current)); ··· 250 254 251 255 mutex_lock(&ecryptfs_daemon_hash_mux); 252 256 /* TODO: Just use file->private_data? */ 253 - rc = ecryptfs_find_daemon_by_euid(&daemon, euid, 254 - current->nsproxy->user_ns); 257 + rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); 255 258 BUG_ON(rc || !daemon); 256 259 mutex_lock(&daemon->mux); 257 260 if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { ··· 290 295 goto check_list; 291 296 } 292 297 BUG_ON(euid != daemon->euid); 293 - BUG_ON(current->nsproxy->user_ns != daemon->user_ns); 298 + BUG_ON(current_user_ns() != daemon->user_ns); 294 299 BUG_ON(task_pid(current) != daemon->pid); 295 300 msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue, 296 301 struct ecryptfs_msg_ctx, daemon_out_list); ··· 463 468 goto out_free; 464 469 } 465 470 rc = ecryptfs_miscdev_response(&data[i], packet_size, 466 - euid, current->nsproxy->user_ns, 471 + euid, current_user_ns(), 467 472 task_pid(current), seq); 468 473 if (rc) 469 474 printk(KERN_WARNING "%s: Failed to deliver miscdev "
+2
include/linux/cred.h
··· 60 60 } while (0) 61 61 62 62 extern struct group_info *groups_alloc(int); 63 + extern struct group_info init_groups; 63 64 extern void groups_free(struct group_info *); 64 65 extern int set_current_groups(struct group_info *); 65 66 extern int set_groups(struct cred *, struct group_info *); ··· 316 315 #define current_fsgid() (current_cred_xxx(fsgid)) 317 316 #define current_cap() (current_cred_xxx(cap_effective)) 318 317 #define current_user() (current_cred_xxx(user)) 318 + #define current_user_ns() (current_cred_xxx(user)->user_ns) 319 319 #define current_security() (current_cred_xxx(security)) 320 320 321 321 #define current_uid_gid(_uid, _gid) \
-1
include/linux/init_task.h
··· 57 57 .mnt_ns = NULL, \ 58 58 INIT_NET_NS(net_ns) \ 59 59 INIT_IPC_NS(ipc_ns) \ 60 - .user_ns = &init_user_ns, \ 61 60 } 62 61 63 62 #define INIT_SIGHAND(sighand) { \
-1
include/linux/nsproxy.h
··· 27 27 struct ipc_namespace *ipc_ns; 28 28 struct mnt_namespace *mnt_ns; 29 29 struct pid_namespace *pid_ns; 30 - struct user_namespace *user_ns; 31 30 struct net *net_ns; 32 31 }; 33 32 extern struct nsproxy init_nsproxy;
+1
include/linux/sched.h
··· 638 638 /* Hash table maintenance information */ 639 639 struct hlist_node uidhash_node; 640 640 uid_t uid; 641 + struct user_namespace *user_ns; 641 642 642 643 #ifdef CONFIG_USER_SCHED 643 644 struct task_group *tg;
+4 -9
include/linux/user_namespace.h
··· 12 12 struct user_namespace { 13 13 struct kref kref; 14 14 struct hlist_head uidhash_table[UIDHASH_SZ]; 15 - struct user_struct *root_user; 15 + struct user_struct *creator; 16 16 }; 17 17 18 18 extern struct user_namespace init_user_ns; ··· 26 26 return ns; 27 27 } 28 28 29 - extern struct user_namespace *copy_user_ns(int flags, 30 - struct user_namespace *old_ns); 29 + extern int create_user_ns(struct cred *new); 31 30 extern void free_user_ns(struct kref *kref); 32 31 33 32 static inline void put_user_ns(struct user_namespace *ns) ··· 42 43 return &init_user_ns; 43 44 } 44 45 45 - static inline struct user_namespace *copy_user_ns(int flags, 46 - struct user_namespace *old_ns) 46 + static inline int create_user_ns(struct cred *new) 47 47 { 48 - if (flags & CLONE_NEWUSER) 49 - return ERR_PTR(-EINVAL); 50 - 51 - return old_ns; 48 + return -EINVAL; 52 49 } 53 50 54 51 static inline void put_user_ns(struct user_namespace *ns)
+13 -2
kernel/cred.c
··· 274 274 struct thread_group_cred *tgcred; 275 275 #endif 276 276 struct cred *new; 277 + int ret; 277 278 278 279 mutex_init(&p->cred_exec_mutex); 279 280 ··· 294 293 if (!new) 295 294 return -ENOMEM; 296 295 296 + if (clone_flags & CLONE_NEWUSER) { 297 + ret = create_user_ns(new); 298 + if (ret < 0) 299 + goto error_put; 300 + } 301 + 297 302 #ifdef CONFIG_KEYS 298 303 /* new threads get their own thread keyrings if their parent already 299 304 * had one */ ··· 316 309 if (!(clone_flags & CLONE_THREAD)) { 317 310 tgcred = kmalloc(sizeof(*tgcred), GFP_KERNEL); 318 311 if (!tgcred) { 319 - put_cred(new); 320 - return -ENOMEM; 312 + ret = -ENOMEM; 313 + goto error_put; 321 314 } 322 315 atomic_set(&tgcred->usage, 1); 323 316 spin_lock_init(&tgcred->lock); ··· 332 325 atomic_inc(&new->user->processes); 333 326 p->cred = p->real_cred = get_cred(new); 334 327 return 0; 328 + 329 + error_put: 330 + put_cred(new); 331 + return ret; 335 332 } 336 333 337 334 /**
+16 -3
kernel/fork.c
··· 976 976 if (atomic_read(&p->real_cred->user->processes) >= 977 977 p->signal->rlim[RLIMIT_NPROC].rlim_cur) { 978 978 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && 979 - p->real_cred->user != current->nsproxy->user_ns->root_user) 979 + p->real_cred->user != INIT_USER) 980 980 goto bad_fork_free; 981 981 } 982 982 ··· 1335 1335 long nr; 1336 1336 1337 1337 /* 1338 + * Do some preliminary argument and permissions checking before we 1339 + * actually start allocating stuff 1340 + */ 1341 + if (clone_flags & CLONE_NEWUSER) { 1342 + if (clone_flags & CLONE_THREAD) 1343 + return -EINVAL; 1344 + /* hopefully this check will go away when userns support is 1345 + * complete 1346 + */ 1347 + if (!capable(CAP_SYS_ADMIN)) 1348 + return -EPERM; 1349 + } 1350 + 1351 + /* 1338 1352 * We hope to recycle these flags after 2.6.26 1339 1353 */ 1340 1354 if (unlikely(clone_flags & CLONE_STOPPED)) { ··· 1595 1581 err = -EINVAL; 1596 1582 if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND| 1597 1583 CLONE_VM|CLONE_FILES|CLONE_SYSVSEM| 1598 - CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWUSER| 1599 - CLONE_NEWNET)) 1584 + CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET)) 1600 1585 goto bad_unshare_out; 1601 1586 1602 1587 /*
+2 -13
kernel/nsproxy.c
··· 80 80 goto out_pid; 81 81 } 82 82 83 - new_nsp->user_ns = copy_user_ns(flags, tsk->nsproxy->user_ns); 84 - if (IS_ERR(new_nsp->user_ns)) { 85 - err = PTR_ERR(new_nsp->user_ns); 86 - goto out_user; 87 - } 88 - 89 83 new_nsp->net_ns = copy_net_ns(flags, tsk->nsproxy->net_ns); 90 84 if (IS_ERR(new_nsp->net_ns)) { 91 85 err = PTR_ERR(new_nsp->net_ns); ··· 89 95 return new_nsp; 90 96 91 97 out_net: 92 - if (new_nsp->user_ns) 93 - put_user_ns(new_nsp->user_ns); 94 - out_user: 95 98 if (new_nsp->pid_ns) 96 99 put_pid_ns(new_nsp->pid_ns); 97 100 out_pid: ··· 121 130 get_nsproxy(old_ns); 122 131 123 132 if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | 124 - CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNET))) 133 + CLONE_NEWPID | CLONE_NEWNET))) 125 134 return 0; 126 135 127 136 if (!capable(CAP_SYS_ADMIN)) { ··· 164 173 put_ipc_ns(ns->ipc_ns); 165 174 if (ns->pid_ns) 166 175 put_pid_ns(ns->pid_ns); 167 - if (ns->user_ns) 168 - put_user_ns(ns->user_ns); 169 176 put_net(ns->net_ns); 170 177 kmem_cache_free(nsproxy_cachep, ns); 171 178 } ··· 178 189 int err = 0; 179 190 180 191 if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | 181 - CLONE_NEWUSER | CLONE_NEWNET))) 192 + CLONE_NEWNET))) 182 193 return 0; 183 194 184 195 if (!capable(CAP_SYS_ADMIN))
+2 -2
kernel/sys.c
··· 565 565 { 566 566 struct user_struct *new_user; 567 567 568 - new_user = alloc_uid(current->nsproxy->user_ns, new->uid); 568 + new_user = alloc_uid(current_user_ns(), new->uid); 569 569 if (!new_user) 570 570 return -EAGAIN; 571 571 572 572 if (atomic_read(&new_user->processes) >= 573 573 current->signal->rlim[RLIMIT_NPROC].rlim_cur && 574 - new_user != current->nsproxy->user_ns->root_user) { 574 + new_user != INIT_USER) { 575 575 free_uid(new_user); 576 576 return -EAGAIN; 577 577 }
+13 -34
kernel/user.c
··· 20 20 21 21 struct user_namespace init_user_ns = { 22 22 .kref = { 23 - .refcount = ATOMIC_INIT(2), 23 + .refcount = ATOMIC_INIT(1), 24 24 }, 25 - .root_user = &root_user, 25 + .creator = &root_user, 26 26 }; 27 27 EXPORT_SYMBOL_GPL(init_user_ns); 28 28 ··· 48 48 */ 49 49 static DEFINE_SPINLOCK(uidhash_lock); 50 50 51 + /* root_user.__count is 2, 1 for init task cred, 1 for init_user_ns->creator */ 51 52 struct user_struct root_user = { 52 - .__count = ATOMIC_INIT(1), 53 + .__count = ATOMIC_INIT(2), 53 54 .processes = ATOMIC_INIT(1), 54 55 .files = ATOMIC_INIT(0), 55 56 .sigpending = ATOMIC_INIT(0), 56 57 .locked_shm = 0, 58 + .user_ns = &init_user_ns, 57 59 #ifdef CONFIG_USER_SCHED 58 60 .tg = &init_task_group, 59 61 #endif ··· 316 314 * IRQ state (as stored in flags) is restored and uidhash_lock released 317 315 * upon function exit. 318 316 */ 319 - static inline void free_user(struct user_struct *up, unsigned long flags) 317 + static void free_user(struct user_struct *up, unsigned long flags) 320 318 { 321 319 /* restore back the count */ 322 320 atomic_inc(&up->__count); 323 321 spin_unlock_irqrestore(&uidhash_lock, flags); 324 322 323 + put_user_ns(up->user_ns); 325 324 INIT_WORK(&up->work, remove_user_sysfs_dir); 326 325 schedule_work(&up->work); 327 326 } ··· 338 335 * IRQ state (as stored in flags) is restored and uidhash_lock released 339 336 * upon function exit. 340 337 */ 341 - static inline void free_user(struct user_struct *up, unsigned long flags) 338 + static void free_user(struct user_struct *up, unsigned long flags) 342 339 { 343 340 uid_hash_remove(up); 344 341 spin_unlock_irqrestore(&uidhash_lock, flags); 345 342 sched_destroy_user(up); 346 343 key_put(up->uid_keyring); 347 344 key_put(up->session_keyring); 345 + put_user_ns(up->user_ns); 348 346 kmem_cache_free(uid_cachep, up); 349 347 } 350 348 ··· 361 357 { 362 358 struct user_struct *ret; 363 359 unsigned long flags; 364 - struct user_namespace *ns = current->nsproxy->user_ns; 360 + struct user_namespace *ns = current_user_ns(); 365 361 366 362 spin_lock_irqsave(&uidhash_lock, flags); 367 363 ret = uid_hash_find(uid, uidhashentry(ns, uid)); ··· 408 404 if (sched_create_user(new) < 0) 409 405 goto out_free_user; 410 406 407 + new->user_ns = get_user_ns(ns); 408 + 411 409 if (uids_user_create(new)) 412 410 goto out_destoy_sched; 413 411 ··· 433 427 up = new; 434 428 } 435 429 spin_unlock_irq(&uidhash_lock); 436 - 437 430 } 438 431 439 432 uids_mutex_unlock(); ··· 441 436 442 437 out_destoy_sched: 443 438 sched_destroy_user(new); 439 + put_user_ns(new->user_ns); 444 440 out_free_user: 445 441 kmem_cache_free(uid_cachep, new); 446 442 out_unlock: 447 443 uids_mutex_unlock(); 448 444 return NULL; 449 445 } 450 - 451 - #ifdef CONFIG_USER_NS 452 - void release_uids(struct user_namespace *ns) 453 - { 454 - int i; 455 - unsigned long flags; 456 - struct hlist_head *head; 457 - struct hlist_node *nd; 458 - 459 - spin_lock_irqsave(&uidhash_lock, flags); 460 - /* 461 - * collapse the chains so that the user_struct-s will 462 - * be still alive, but not in hashes. subsequent free_uid() 463 - * will free them. 464 - */ 465 - for (i = 0; i < UIDHASH_SZ; i++) { 466 - head = ns->uidhash_table + i; 467 - while (!hlist_empty(head)) { 468 - nd = head->first; 469 - hlist_del_init(nd); 470 - } 471 - } 472 - spin_unlock_irqrestore(&uidhash_lock, flags); 473 - 474 - free_uid(ns->root_user); 475 - } 476 - #endif 477 446 478 447 static int __init uid_cache_init(void) 479 448 {
+30 -45
kernel/user_namespace.c
··· 9 9 #include <linux/nsproxy.h> 10 10 #include <linux/slab.h> 11 11 #include <linux/user_namespace.h> 12 + #include <linux/cred.h> 12 13 13 14 /* 14 - * Clone a new ns copying an original user ns, setting refcount to 1 15 - * @old_ns: namespace to clone 16 - * Return NULL on error (failure to kmalloc), new ns otherwise 15 + * Create a new user namespace, deriving the creator from the user in the 16 + * passed credentials, and replacing that user with the new root user for the 17 + * new namespace. 18 + * 19 + * This is called by copy_creds(), which will finish setting the target task's 20 + * credentials. 17 21 */ 18 - static struct user_namespace *clone_user_ns(struct user_namespace *old_ns) 22 + int create_user_ns(struct cred *new) 19 23 { 20 24 struct user_namespace *ns; 21 - struct user_struct *new_user; 22 - struct cred *new; 25 + struct user_struct *root_user; 23 26 int n; 24 27 25 28 ns = kmalloc(sizeof(struct user_namespace), GFP_KERNEL); 26 29 if (!ns) 27 - return ERR_PTR(-ENOMEM); 30 + return -ENOMEM; 28 31 29 32 kref_init(&ns->kref); 30 33 31 34 for (n = 0; n < UIDHASH_SZ; ++n) 32 35 INIT_HLIST_HEAD(ns->uidhash_table + n); 33 36 34 - /* Insert new root user. */ 35 - ns->root_user = alloc_uid(ns, 0); 36 - if (!ns->root_user) { 37 + /* Alloc new root user. */ 38 + root_user = alloc_uid(ns, 0); 39 + if (!root_user) { 37 40 kfree(ns); 38 - return ERR_PTR(-ENOMEM); 41 + return -ENOMEM; 39 42 } 40 43 41 - /* Reset current->user with a new one */ 42 - new_user = alloc_uid(ns, current_uid()); 43 - if (!new_user) { 44 - free_uid(ns->root_user); 45 - kfree(ns); 46 - return ERR_PTR(-ENOMEM); 47 - } 44 + /* set the new root user in the credentials under preparation */ 45 + ns->creator = new->user; 46 + new->user = root_user; 47 + new->uid = new->euid = new->suid = new->fsuid = 0; 48 + new->gid = new->egid = new->sgid = new->fsgid = 0; 49 + put_group_info(new->group_info); 50 + new->group_info = get_group_info(&init_groups); 51 + #ifdef CONFIG_KEYS 52 + key_put(new->request_key_auth); 53 + new->request_key_auth = NULL; 54 + #endif 55 + /* tgcred will be cleared in our caller bc CLONE_THREAD won't be set */ 48 56 49 - /* Install the new user */ 50 - new = prepare_creds(); 51 - if (!new) { 52 - free_uid(new_user); 53 - free_uid(ns->root_user); 54 - kfree(ns); 55 - } 56 - free_uid(new->user); 57 - new->user = new_user; 58 - commit_creds(new); 59 - return ns; 60 - } 57 + /* alloc_uid() incremented the userns refcount. Just set it to 1 */ 58 + kref_set(&ns->kref, 1); 61 59 62 - struct user_namespace * copy_user_ns(int flags, struct user_namespace *old_ns) 63 - { 64 - struct user_namespace *new_ns; 65 - 66 - BUG_ON(!old_ns); 67 - get_user_ns(old_ns); 68 - 69 - if (!(flags & CLONE_NEWUSER)) 70 - return old_ns; 71 - 72 - new_ns = clone_user_ns(old_ns); 73 - 74 - put_user_ns(old_ns); 75 - return new_ns; 60 + return 0; 76 61 } 77 62 78 63 void free_user_ns(struct kref *kref) ··· 65 80 struct user_namespace *ns; 66 81 67 82 ns = container_of(kref, struct user_namespace, kref); 68 - release_uids(ns); 83 + free_uid(ns->creator); 69 84 kfree(ns); 70 85 } 71 86 EXPORT_SYMBOL(free_user_ns);