Xenial: libblkid: fix false-positive/misdetection of nilfs2 filesystem with udev
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
util-linux (Ubuntu) |
Fix Released
|
Undecided
|
Unassigned | ||
Xenial |
Fix Released
|
Medium
|
Mauricio Faria de Oliveira |
Bug Description
[Impact]
* Users / systemd can fail to mount a filesystem by UUID
(e.g., during boot, triggering emergency shell prompt)
if the magic bytes for the nilfs filesystem are written
to the right place in a partition of another filesystem,
(for whatever reason or coincidence).
* Note this can happen after the filesystem/mount is working
correctly, so a change of behavior/problem can potentially
be noticed when trying to mount the filesystem again, which
can very well be the next time the system boots.
* This happens because if udev blkid detects more than one
filesystem, it does not print the UUID env vars required
to create the /dev/disk/by-id symlinks and other things.
* The fix enhances the check for valid nilfs superblock by
specifically checking a value read from disk to be valid/
within a value range, which addresses this one occurrence
and prevents a lot more.
[Test Case]
* Synthetic test case written for this problem on comment #6.
[Regression Potential]
* Low. The code is contained in the probe for the nilfs filesystem.
* This just makes it be more restrictive about the possibly valid
values for a few bytes read from disk (that now need to be within
the acceptable range of valid values) so this only decreases false-
positives, and cannot increase false-negatives of valid filesystems.
[Original Description]
The nilfs filesystem has a backup superblock at the end of the device.
If the magic number is coincidentally found at the right position
and the filesystem is on a partition/
the only check left is for checksum verification,
which is explicitly ignored in 'udev built-in blkid'.
This causes blkid to detect one actually valid filesystem with a
superblock at the beginning of the device (e.g., ext4), and then
an invalid nilfs2 filesystem due to a coincidental magic number
at the end of the device.
And this causes blkid to break out of the safeprobe routine
(which expects a single filesystem to be detected), and not
print the UUIDs, thus not creating /dev/disk/by-uuid/ links
which prevent mounting the partition by-uuid at boot time,
causing emergency shell/boot failures.
This upstream fix resolved the problem by introducing a check
for the 'bytes' paramenters in the superblock, which is read
from disk, and turns out to have an out-of-range value.
- 'liblkid: Add length check in probe_nilfs2 before crc32'
https:/
$ git describe --contains ac681a310c32319
v2.29-rc1~172
Xenial, which is v2.27.1-based, is the only release that needs it.
Bionic is v2.31.1, so all post-Xenial supported releases have it.
Changed in util-linux (Ubuntu): | |
status: | New → Fix Released |
Changed in util-linux (Ubuntu Xenial): | |
status: | New → In Progress |
assignee: | nobody → Mauricio Faria de Oliveira (mfo) |
importance: | Undecided → Medium |
tags: | added: sts |
tags: | added: sts-sponsor-slashd |
tags: | removed: sts-sponsor-slashd |
Problem:
- the ext4 filesystem is detected correctly at the beginning of the partition.
- the nilfs2 filesystem is detected incorrectly at the end of the partition.
- the nilfs2 checksum is invalid, but that is ignored by udev builtin blkid.
- the detection of more than one filesystems causes an error and stop blkid.
# LIBBLKID_DEBUG=all udevadm test-builtin blkid /sys/block/ loop0/loop0p1 00000246: 0000007B
...
30555: libblkid: LOWPROBE: [28] ext4:
30555: libblkid: LOWPROBE: reuse buffer: off=1024 len=1024 pr=0x558f3ea3dec0
30555: libblkid: LOWPROBE: magic sboff=56, kboff=1
30555: libblkid: LOWPROBE: call probefunc()
30555: libblkid: LOWPROBE: reuse buffer: off=1024 len=1024 pr=0x558f3ea3dec0
30555: libblkid: PROBE: ext2_sb.compat = 0000003C:
30555: libblkid: LOWPROBE: assigning UUID [superblocks]
30555: libblkid: LOWPROBE: assigning VERSION [superblocks]
30555: libblkid: LOWPROBE: assigning TYPE [superblocks]
30555: libblkid: LOWPROBE: assigning USAGE [superblocks]
...
30555: libblkid: LOWPROBE: [63] nilfs2:
30555: libblkid: LOWPROBE: call probefunc()
30555: libblkid: LOWPROBE: reuse buffer: off=1024 len=1024 pr=0x558f3ea3dec0
30555: libblkid: LOWPROBE: reuse buffer: off=1072689152 len=4096 pr=0x558f3ea3dec0
30555: libblkid: LOWPROBE: incorrect checksum for type nilfs2, got 3F8DC6BA, expected 2D2D206B
30555: libblkid: LOWPROBE: assigning SBBADCSUM [superblocks]
30555: libblkid: LOWPROBE: nilfs2: primary=0, backup=1, swap=1
30555: libblkid: LOWPROBE: assigning LABEL [superblocks]
30555: libblkid: LOWPROBE: assigning UUID [superblocks]
30555: libblkid: LOWPROBE: assigning VERSION [superblocks]
30555: libblkid: LOWPROBE: assigning TYPE [superblocks]
30555: libblkid: LOWPROBE: assigning USAGE [superblocks]
...
30555: libblkid: LOWPROBE: ERROR: superblocks chain: ambivalent result detected (2 filesystems)!
...
# echo $?
1