/sys/block will only be scanned with CONFIG_SYSFS_DEPRECATED=y and
deprecated sysfs enabled (using CONFIG_SYSFS_DEPRECATED_V2=y or the
related kernel boot param).  In that case, all of /sys/block/* will be
a real directory, so we don't need to follow symlinks.  Additionally,
following symlinks causes a bug for mtd in this case, e.g. several
people have been seeing that /dev/mtd0 was getting created by this
traversal as a block device.  Subsequent investigation revealed that
was caused by this pass following the /sys/block/mtdblock0/device
symlink and resulting in both
- /sys/block/mtdblock0/dev
- /sys/block/mtdblock0/device/dev
being used here, and the second results in that incorrect /dev/mtd0.
Change to not follow symlinks while traversing /sys/block to fix this.

Fixes BZ #6806.

Signed-off-by: Gregory Fong <[email protected]>
Cc: Denys Vlasenko <[email protected]>
Cc: Simon Edlund <[email protected]>
---
 util-linux/mdev.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index ca4b915..af986a2 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -1063,22 +1063,27 @@ int mdev_main(int argc UNUSED_PARAM, char **argv)
 
                putenv((char*)"ACTION=add");
 
-               /* ACTION_FOLLOWLINKS is needed since in newer kernels
-                * /sys/block/loop* (for example) are symlinks to dirs,
-                * not real directories.
-                * (kernel's CONFIG_SYSFS_DEPRECATED makes them real dirs,
-                * but we can't enforce that on users)
-                */
                if (access("/sys/class/block", F_OK) != 0) {
                        /* Scan obsolete /sys/block only if /sys/class/block
                         * doesn't exist. Otherwise we'll have dupes.
                         * Also, do not complain if it doesn't exist.
                         * Some people configure kernel to have no blockdevs.
+                        *
+                        * Don't use ACTION_FOLLOWLINKS here. This will only be
+                        * run if CONFIG_SYSFS_DEPRECATED=y, in which case
+                        * everything at the top-level will be a real dir, and
+                        * following symlinks can result in the 'device'
+                        * symlink being followed and resulting in e.g. mtd0
+                        * being set up as a block dev instead of a char dev.
                         */
                        recursive_action("/sys/block",
-                               ACTION_RECURSE | ACTION_FOLLOWLINKS | 
ACTION_QUIET,
+                               ACTION_RECURSE | ACTION_QUIET,
                                fileAction, dirAction, temp, 0);
                }
+               /* ACTION_FOLLOWLINKS is needed since in newer kernels
+                * /sys/class/block/loop* (for example) are symlinks to dirs,
+                * not real directories.
+                */
                recursive_action("/sys/class",
                        ACTION_RECURSE | ACTION_FOLLOWLINKS,
                        fileAction, dirAction, temp, 0);
-- 
1.9.1

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to