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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace

Pull mqueuefs revert from Eric Biederman:
"This fixes a regression that came in the merge window for v4.16.

The problem is that the permissions for mounting and using the
mqueuefs filesystem are broken. The necessary permission check is
missing letting people who should not be able to mount mqueuefs mount
mqueuefs. The field sb->s_user_ns is set incorrectly not allowing the
mounter of mqueuefs to remount and otherwise have proper control over
the filesystem.

Al Viro and I see the path to the necessary fixes differently and I am
not even certain at this point he actually sees all of the necessary
fixes. Given a couple weeks we can probably work something out but I
don't see the review being resolved in time for the final v4.16. I
don't want v4.16 shipping with a nasty regression. So unfortunately I
am sending a revert"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace:
Revert "mqueue: switch to on-demand creation of internal mount"

+19 -55
+19 -55
ipc/mqueue.c
··· 325 325 static int mqueue_fill_super(struct super_block *sb, void *data, int silent) 326 326 { 327 327 struct inode *inode; 328 - struct ipc_namespace *ns = data; 328 + struct ipc_namespace *ns = sb->s_fs_info; 329 329 330 - sb->s_fs_info = ns; 331 330 sb->s_iflags |= SB_I_NOEXEC | SB_I_NODEV; 332 331 sb->s_blocksize = PAGE_SIZE; 333 332 sb->s_blocksize_bits = PAGE_SHIFT; ··· 343 344 return 0; 344 345 } 345 346 346 - static struct file_system_type mqueue_fs_type; 347 - /* 348 - * Return value is pinned only by reference in ->mq_mnt; it will 349 - * live until ipcns dies. Caller does not need to drop it. 350 - */ 351 - static struct vfsmount *mq_internal_mount(void) 352 - { 353 - struct ipc_namespace *ns = current->nsproxy->ipc_ns; 354 - struct vfsmount *m = ns->mq_mnt; 355 - if (m) 356 - return m; 357 - m = kern_mount_data(&mqueue_fs_type, ns); 358 - spin_lock(&mq_lock); 359 - if (unlikely(ns->mq_mnt)) { 360 - spin_unlock(&mq_lock); 361 - if (!IS_ERR(m)) 362 - kern_unmount(m); 363 - return ns->mq_mnt; 364 - } 365 - if (!IS_ERR(m)) 366 - ns->mq_mnt = m; 367 - spin_unlock(&mq_lock); 368 - return m; 369 - } 370 - 371 347 static struct dentry *mqueue_mount(struct file_system_type *fs_type, 372 348 int flags, const char *dev_name, 373 349 void *data) 374 350 { 375 - struct vfsmount *m; 376 - if (flags & SB_KERNMOUNT) 377 - return mount_nodev(fs_type, flags, data, mqueue_fill_super); 378 - m = mq_internal_mount(); 379 - if (IS_ERR(m)) 380 - return ERR_CAST(m); 381 - atomic_inc(&m->mnt_sb->s_active); 382 - down_write(&m->mnt_sb->s_umount); 383 - return dget(m->mnt_root); 351 + struct ipc_namespace *ns; 352 + if (flags & SB_KERNMOUNT) { 353 + ns = data; 354 + data = NULL; 355 + } else { 356 + ns = current->nsproxy->ipc_ns; 357 + } 358 + return mount_ns(fs_type, flags, data, ns, ns->user_ns, mqueue_fill_super); 384 359 } 385 360 386 361 static void init_once(void *foo) ··· 744 771 static int do_mq_open(const char __user *u_name, int oflag, umode_t mode, 745 772 struct mq_attr *attr) 746 773 { 747 - struct vfsmount *mnt = mq_internal_mount(); 748 - struct dentry *root; 774 + struct vfsmount *mnt = current->nsproxy->ipc_ns->mq_mnt; 775 + struct dentry *root = mnt->mnt_root; 749 776 struct filename *name; 750 777 struct path path; 751 778 int fd, error; 752 779 int ro; 753 - 754 - if (IS_ERR(mnt)) 755 - return PTR_ERR(mnt); 756 780 757 781 audit_mq_open(oflag, mode, attr); 758 782 ··· 761 791 goto out_putname; 762 792 763 793 ro = mnt_want_write(mnt); /* we'll drop it in any case */ 764 - root = mnt->mnt_root; 765 794 inode_lock(d_inode(root)); 766 795 path.dentry = lookup_one_len(name->name, root, strlen(name->name)); 767 796 if (IS_ERR(path.dentry)) { ··· 808 839 struct inode *inode = NULL; 809 840 struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; 810 841 struct vfsmount *mnt = ipc_ns->mq_mnt; 811 - 812 - if (!mnt) 813 - return -ENOENT; 814 842 815 843 name = getname(u_name); 816 844 if (IS_ERR(name)) ··· 1535 1569 ns->mq_msgsize_max = DFLT_MSGSIZEMAX; 1536 1570 ns->mq_msg_default = DFLT_MSG; 1537 1571 ns->mq_msgsize_default = DFLT_MSGSIZE; 1538 - ns->mq_mnt = NULL; 1539 1572 1573 + ns->mq_mnt = kern_mount_data(&mqueue_fs_type, ns); 1574 + if (IS_ERR(ns->mq_mnt)) { 1575 + int err = PTR_ERR(ns->mq_mnt); 1576 + ns->mq_mnt = NULL; 1577 + return err; 1578 + } 1540 1579 return 0; 1541 1580 } 1542 1581 1543 1582 void mq_clear_sbinfo(struct ipc_namespace *ns) 1544 1583 { 1545 - if (ns->mq_mnt) 1546 - ns->mq_mnt->mnt_sb->s_fs_info = NULL; 1584 + ns->mq_mnt->mnt_sb->s_fs_info = NULL; 1547 1585 } 1548 1586 1549 1587 void mq_put_mnt(struct ipc_namespace *ns) 1550 1588 { 1551 - if (ns->mq_mnt) 1552 - kern_unmount(ns->mq_mnt); 1589 + kern_unmount(ns->mq_mnt); 1553 1590 } 1554 1591 1555 1592 static int __init init_mqueue_fs(void) 1556 1593 { 1557 - struct vfsmount *m; 1558 1594 int error; 1559 1595 1560 1596 mqueue_inode_cachep = kmem_cache_create("mqueue_inode_cache", ··· 1578 1610 if (error) 1579 1611 goto out_filesystem; 1580 1612 1581 - m = kern_mount_data(&mqueue_fs_type, &init_ipc_ns); 1582 - if (IS_ERR(m)) 1583 - goto out_filesystem; 1584 - init_ipc_ns.mq_mnt = m; 1585 1613 return 0; 1586 1614 1587 1615 out_filesystem: