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 namespace fixes from Eric Biederman:
"This tree contains 4 fixes.

The first is a fix for a race that can causes oopses under the right
circumstances, and that someone just recently encountered.

Past that are several small trivial correct fixes. A real issue that
was blocking development of an out of tree driver, but does not appear
to have caused any actual problems for in-tree code. A potential
deadlock that was reported by lockdep. And a deadlock people have
experienced and took the time to track down caused by a cleanup that
removed the code to drop a reference count"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace:
sysctl: Drop reference added by grab_header in proc_sys_readdir
pid: fix lockdep deadlock warning due to ucount_lock
libfs: Modify mount_pseudo_xattr to be clear it is not a userspace mount
mnt: Protect the mountpoint hashtable with mount_lock

+62 -29
+5 -2
fs/dcache.c
··· 1336 1336 } 1337 1337 spin_lock(&dentry->d_lock); 1338 1338 if (!d_unlinked(dentry)) { 1339 - dentry->d_flags |= DCACHE_MOUNTED; 1340 - ret = 0; 1339 + ret = -EBUSY; 1340 + if (!d_mountpoint(dentry)) { 1341 + dentry->d_flags |= DCACHE_MOUNTED; 1342 + ret = 0; 1343 + } 1341 1344 } 1342 1345 spin_unlock(&dentry->d_lock); 1343 1346 out:
+2 -1
fs/libfs.c
··· 245 245 struct inode *root; 246 246 struct qstr d_name = QSTR_INIT(name, strlen(name)); 247 247 248 - s = sget(fs_type, NULL, set_anon_super, MS_NOUSER, NULL); 248 + s = sget_userns(fs_type, NULL, set_anon_super, MS_KERNMOUNT|MS_NOUSER, 249 + &init_user_ns, NULL); 249 250 if (IS_ERR(s)) 250 251 return ERR_CAST(s); 251 252
+47 -21
fs/namespace.c
··· 742 742 return NULL; 743 743 } 744 744 745 - static struct mountpoint *new_mountpoint(struct dentry *dentry) 745 + static struct mountpoint *get_mountpoint(struct dentry *dentry) 746 746 { 747 - struct hlist_head *chain = mp_hash(dentry); 748 - struct mountpoint *mp; 747 + struct mountpoint *mp, *new = NULL; 749 748 int ret; 750 749 751 - mp = kmalloc(sizeof(struct mountpoint), GFP_KERNEL); 752 - if (!mp) 753 - return ERR_PTR(-ENOMEM); 754 - 755 - ret = d_set_mounted(dentry); 756 - if (ret) { 757 - kfree(mp); 758 - return ERR_PTR(ret); 750 + if (d_mountpoint(dentry)) { 751 + mountpoint: 752 + read_seqlock_excl(&mount_lock); 753 + mp = lookup_mountpoint(dentry); 754 + read_sequnlock_excl(&mount_lock); 755 + if (mp) 756 + goto done; 759 757 } 760 758 761 - mp->m_dentry = dentry; 762 - mp->m_count = 1; 763 - hlist_add_head(&mp->m_hash, chain); 764 - INIT_HLIST_HEAD(&mp->m_list); 759 + if (!new) 760 + new = kmalloc(sizeof(struct mountpoint), GFP_KERNEL); 761 + if (!new) 762 + return ERR_PTR(-ENOMEM); 763 + 764 + 765 + /* Exactly one processes may set d_mounted */ 766 + ret = d_set_mounted(dentry); 767 + 768 + /* Someone else set d_mounted? */ 769 + if (ret == -EBUSY) 770 + goto mountpoint; 771 + 772 + /* The dentry is not available as a mountpoint? */ 773 + mp = ERR_PTR(ret); 774 + if (ret) 775 + goto done; 776 + 777 + /* Add the new mountpoint to the hash table */ 778 + read_seqlock_excl(&mount_lock); 779 + new->m_dentry = dentry; 780 + new->m_count = 1; 781 + hlist_add_head(&new->m_hash, mp_hash(dentry)); 782 + INIT_HLIST_HEAD(&new->m_list); 783 + read_sequnlock_excl(&mount_lock); 784 + 785 + mp = new; 786 + new = NULL; 787 + done: 788 + kfree(new); 765 789 return mp; 766 790 } 767 791 ··· 1619 1595 struct mount *mnt; 1620 1596 1621 1597 namespace_lock(); 1598 + lock_mount_hash(); 1622 1599 mp = lookup_mountpoint(dentry); 1623 1600 if (IS_ERR_OR_NULL(mp)) 1624 1601 goto out_unlock; 1625 1602 1626 - lock_mount_hash(); 1627 1603 event++; 1628 1604 while (!hlist_empty(&mp->m_list)) { 1629 1605 mnt = hlist_entry(mp->m_list.first, struct mount, mnt_mp_list); ··· 1633 1609 } 1634 1610 else umount_tree(mnt, UMOUNT_CONNECTED); 1635 1611 } 1636 - unlock_mount_hash(); 1637 1612 put_mountpoint(mp); 1638 1613 out_unlock: 1614 + unlock_mount_hash(); 1639 1615 namespace_unlock(); 1640 1616 } 1641 1617 ··· 2062 2038 namespace_lock(); 2063 2039 mnt = lookup_mnt(path); 2064 2040 if (likely(!mnt)) { 2065 - struct mountpoint *mp = lookup_mountpoint(dentry); 2066 - if (!mp) 2067 - mp = new_mountpoint(dentry); 2041 + struct mountpoint *mp = get_mountpoint(dentry); 2068 2042 if (IS_ERR(mp)) { 2069 2043 namespace_unlock(); 2070 2044 inode_unlock(dentry->d_inode); ··· 2081 2059 static void unlock_mount(struct mountpoint *where) 2082 2060 { 2083 2061 struct dentry *dentry = where->m_dentry; 2062 + 2063 + read_seqlock_excl(&mount_lock); 2084 2064 put_mountpoint(where); 2065 + read_sequnlock_excl(&mount_lock); 2066 + 2085 2067 namespace_unlock(); 2086 2068 inode_unlock(dentry->d_inode); 2087 2069 } ··· 3161 3135 touch_mnt_namespace(current->nsproxy->mnt_ns); 3162 3136 /* A moved mount should not expire automatically */ 3163 3137 list_del_init(&new_mnt->mnt_expire); 3138 + put_mountpoint(root_mp); 3164 3139 unlock_mount_hash(); 3165 3140 chroot_fs_refs(&root, &new); 3166 - put_mountpoint(root_mp); 3167 3141 error = 0; 3168 3142 out4: 3169 3143 unlock_mount(old_mp);
+2 -1
fs/proc/proc_sysctl.c
··· 709 709 ctl_dir = container_of(head, struct ctl_dir, header); 710 710 711 711 if (!dir_emit_dots(file, ctx)) 712 - return 0; 712 + goto out; 713 713 714 714 pos = 2; 715 715 ··· 719 719 break; 720 720 } 721 721 } 722 + out: 722 723 sysctl_head_finish(head); 723 724 return 0; 724 725 }
+6 -4
kernel/pid_namespace.c
··· 151 151 152 152 static void delayed_free_pidns(struct rcu_head *p) 153 153 { 154 - kmem_cache_free(pid_ns_cachep, 155 - container_of(p, struct pid_namespace, rcu)); 154 + struct pid_namespace *ns = container_of(p, struct pid_namespace, rcu); 155 + 156 + dec_pid_namespaces(ns->ucounts); 157 + put_user_ns(ns->user_ns); 158 + 159 + kmem_cache_free(pid_ns_cachep, ns); 156 160 } 157 161 158 162 static void destroy_pid_namespace(struct pid_namespace *ns) ··· 166 162 ns_free_inum(&ns->ns); 167 163 for (i = 0; i < PIDMAP_ENTRIES; i++) 168 164 kfree(ns->pidmap[i].page); 169 - dec_pid_namespaces(ns->ucounts); 170 - put_user_ns(ns->user_ns); 171 165 call_rcu(&ns->rcu, delayed_free_pidns); 172 166 } 173 167