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:
"While reading through the code of detach_mounts I realized the code
was slightly off. Testing it revealed two buggy corner cases that can
send the code of detach_mounts into an infinite loop.

Fixing the code to do the right thing removes the possibility of these
user triggered infinite loops in the code"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace:
mnt: In detach_mounts detach the appropriate unmounted mount
mnt: Clarify and correct the disconnect logic in umount_tree

+33 -11
+33 -9
fs/namespace.c
··· 1361 1361 UMOUNT_PROPAGATE = 2, 1362 1362 UMOUNT_CONNECTED = 4, 1363 1363 }; 1364 + 1365 + static bool disconnect_mount(struct mount *mnt, enum umount_tree_flags how) 1366 + { 1367 + /* Leaving mounts connected is only valid for lazy umounts */ 1368 + if (how & UMOUNT_SYNC) 1369 + return true; 1370 + 1371 + /* A mount without a parent has nothing to be connected to */ 1372 + if (!mnt_has_parent(mnt)) 1373 + return true; 1374 + 1375 + /* Because the reference counting rules change when mounts are 1376 + * unmounted and connected, umounted mounts may not be 1377 + * connected to mounted mounts. 1378 + */ 1379 + if (!(mnt->mnt_parent->mnt.mnt_flags & MNT_UMOUNT)) 1380 + return true; 1381 + 1382 + /* Has it been requested that the mount remain connected? */ 1383 + if (how & UMOUNT_CONNECTED) 1384 + return false; 1385 + 1386 + /* Is the mount locked such that it needs to remain connected? */ 1387 + if (IS_MNT_LOCKED(mnt)) 1388 + return false; 1389 + 1390 + /* By default disconnect the mount */ 1391 + return true; 1392 + } 1393 + 1364 1394 /* 1365 1395 * mount_lock must be held 1366 1396 * namespace_sem must be held for write ··· 1428 1398 if (how & UMOUNT_SYNC) 1429 1399 p->mnt.mnt_flags |= MNT_SYNC_UMOUNT; 1430 1400 1431 - disconnect = !(((how & UMOUNT_CONNECTED) && 1432 - mnt_has_parent(p) && 1433 - (p->mnt_parent->mnt.mnt_flags & MNT_UMOUNT)) || 1434 - IS_MNT_LOCKED_AND_LAZY(p)); 1401 + disconnect = disconnect_mount(p, how); 1435 1402 1436 1403 pin_insert_group(&p->mnt_umount, &p->mnt_parent->mnt, 1437 1404 disconnect ? &unmounted : NULL); ··· 1565 1538 while (!hlist_empty(&mp->m_list)) { 1566 1539 mnt = hlist_entry(mp->m_list.first, struct mount, mnt_mp_list); 1567 1540 if (mnt->mnt.mnt_flags & MNT_UMOUNT) { 1568 - struct mount *p, *tmp; 1569 - list_for_each_entry_safe(p, tmp, &mnt->mnt_mounts, mnt_child) { 1570 - hlist_add_head(&p->mnt_umount.s_list, &unmounted); 1571 - umount_mnt(p); 1572 - } 1541 + hlist_add_head(&mnt->mnt_umount.s_list, &unmounted); 1542 + umount_mnt(mnt); 1573 1543 } 1574 1544 else umount_tree(mnt, UMOUNT_CONNECTED); 1575 1545 }
-2
fs/pnode.h
··· 20 20 #define SET_MNT_MARK(m) ((m)->mnt.mnt_flags |= MNT_MARKED) 21 21 #define CLEAR_MNT_MARK(m) ((m)->mnt.mnt_flags &= ~MNT_MARKED) 22 22 #define IS_MNT_LOCKED(m) ((m)->mnt.mnt_flags & MNT_LOCKED) 23 - #define IS_MNT_LOCKED_AND_LAZY(m) \ 24 - (((m)->mnt.mnt_flags & (MNT_LOCKED|MNT_SYNC_UMOUNT)) == MNT_LOCKED) 25 23 26 24 #define CL_EXPIRE 0x01 27 25 #define CL_SLAVE 0x02