[Bug 1842437] Re: Xenial: libblkid: fix false-positive/misdetection of nilfs2 filesystem with udev

Mauricio Faria de Oliveira mfo at canonical.com
Tue Sep 3 17:41:51 UTC 2019


This problem can be reproduced with a synthetic test case.

Essentially, 
1) create a zero-filled disk image with one partition.
2) format it as ext4.
3) insert the nilfs2 magic bytes at the right position.
4) insert the nilfs2 bytes field at the right position.

--

Step 1)

        # dd if=/dev/zero of=test.img bs=512 count=$((16 * 2048)) # 16
MiB

        # dev=$(losetup --find --show test.img)

	# parted $dev --script 'mklabel msdos'
	# parted $dev --script "mkpart primary 1s $((16 * 2048 - 1))s"

	# parted $dev --script 'unit s' --script 'print'
	Model: Loopback device (loopback)
	Disk /dev/loop0: 32768s
	Sector size (logical/physical): 512B/512B
	Partition Table: msdos
	Disk Flags: 

	Number  Start  End     Size    Type     File system  Flags
	 1      1s     32767s  32767s  primary

	# hexdump -C $dev
	... <partition table until 0x200 (first sector) > ...
	*
	000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
	00000200  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
	*
	01000000

	# printf '\x00\x00\x00\x00\x00\x00\x34\x34' | hexdump -C
	00000000  00 00 00 00 00 00 34 34                           |......44|
	00000008

	# partprobe $dev
	# part=${dev}p1

Step 2)

        # mkfs.ext4 $part

Steps 3 and 4)

        From gdb/source:

	(gdb) ptype/o struct nilfs_super_block
	/* offset    |  size */  type = struct nilfs_super_block {
	...
	/*    6      |     2 */    uint16_t s_magic;
	/*    8      |     2 */    uint16_t s_bytes;
	...

	#define NILFS_SB_MAGIC          0x3434
	#define NILFS_SB_OFFSET         0x400
	#define NILFS_SBB_OFFSET(_sz)   ((((_sz) / 0x200) - 8) * 0x200)

        Then (magic is 0x3434, bytes is 0x0401 == 1025 in litte endian
-- value targeted at the fix)

        # printf '\x00\x00\x00\x00\x00\x00\x34\x34\x01\x04' | dd
of=$part bs=1 count=10 conv=notrunc seek=$(( ( (16 * 2048 - 1) - 8) *
512 ))

	# hexdump -C $part
	00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
	*
	00ffee00  00 00 00 00 00 00 34 34  01 04 00 00 00 00 00 00  |......44........|
	00ffee10  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
	*
	00fffe00


Original Package)

	# LIBBLKID_DEBUG=all udevadm test-builtin blkid /sys/block/$(basename $dev)/$(basename $part)
	...
	9576: libblkid: LOWPROBE: [28] ext4:                                             
	9576: libblkid: LOWPROBE:       reuse buffer: off=1024 len=1024 pr=0x55744f2daec0
	9576: libblkid: LOWPROBE:       magic sboff=56, kboff=1                          
	9576: libblkid: LOWPROBE:       call probefunc()                                 
	9576: libblkid: LOWPROBE:       reuse buffer: off=1024 len=1024 pr=0x55744f2daec0
	9576: libblkid:    PROBE: ext2_sb.compat = 0000003C:00000242:0000007B
	9576: libblkid: LOWPROBE: assigning UUID [superblocks]                          
	9576: libblkid: LOWPROBE: assigning VERSION [superblocks]
	9576: libblkid: LOWPROBE: assigning TYPE [superblocks]
	9576: libblkid: LOWPROBE: assigning USAGE [superblocks]
	9576: libblkid: LOWPROBE: <-- leaving probing loop (type=ext4) [SUBLKS idx=28]
	...
	9576: libblkid: LOWPROBE: [63] nilfs2:
	9576: libblkid: LOWPROBE:       call probefunc()
	9576: libblkid: LOWPROBE:       reuse buffer: off=1024 len=1024 pr=0x55744f2daec0
	9576: libblkid: LOWPROBE:       reuse buffer: off=16772608 len=4096 pr=0x55744f2daec0
	9576: libblkid: LOWPROBE: incorrect checksum for type nilfs2, got 2C077E8F, expected 0
	9576: libblkid: LOWPROBE: assigning SBBADCSUM [superblocks]
	9576: libblkid: LOWPROBE: nilfs2: primary=0, backup=1, swap=1
	9576: libblkid: LOWPROBE: assigning VERSION [superblocks]
	9576: libblkid: LOWPROBE: assigning TYPE [superblocks]
	9576: libblkid: LOWPROBE: assigning USAGE [superblocks]
	9576: libblkid: LOWPROBE: <-- leaving probing loop (type=nilfs2) [SUBLKS idx=63]
	...
	9576: libblkid: LOWPROBE: ERROR: superblocks chain: ambivalent result detected (2 filesystems)!
	...
	# echo $?
	1

Original Package with Debug Print)

	9604: libblkid: LOWPROBE: [63] nilfs2:                                            
	9604: libblkid: LOWPROBE:       call probefunc()                                 
	9604: libblkid: LOWPROBE:       reuse buffer: off=1024 len=1024 pr=0x55c076c8eec0   
	9604: libblkid: LOWPROBE:       reuse buffer: off=16772608 len=4096 pr=0x55c076c8eec0
	9604: libblkid: LOWPROBE: nilfs2: nilfs_valid_sb:77 :: entry                      
	9604: libblkid: LOWPROBE: nilfs2: nilfs_valid_sb:80 :: not sb or not magic
	9604: libblkid: LOWPROBE: nilfs2: nilfs_valid_sb:77 :: entry                     
	9604: libblkid: LOWPROBE: nilfs2: nilfs_valid_sb:84 :: is_bak 1                  
	9604: libblkid: LOWPROBE: nilfs2: nilfs_valid_sb:85 :: is_wholedisk 0            
	9604: libblkid: LOWPROBE: nilfs2: nilfs_valid_sb:86 :: sb->s_dev_size 0          
	9604: libblkid: LOWPROBE: nilfs2: nilfs_valid_sb:87 :: pr->size 16776704          
	9604: libblkid: LOWPROBE: nilfs2: nilfs_valid_sb:96 :: bytes 1025                 
	9604: libblkid: LOWPROBE: incorrect checksum for type nilfs2, got 2C077E8F, expected 0
	9604: libblkid: LOWPROBE: assigning SBBADCSUM [superblocks]                       
	9604: libblkid: LOWPROBE: nilfs2: primary=0, backup=1                             
	9604: libblkid: LOWPROBE: nilfs2: primary=0, backup=1, swap=1 

Modified Package)

	9691: libblkid: LOWPROBE: [63] nilfs2:              
	9691: libblkid: LOWPROBE:       call probefunc()                              
	9691: libblkid: LOWPROBE:       reuse buffer: off=1024 len=1024 pr=0x55c12bac1ec0
	9691: libblkid: LOWPROBE:       reuse buffer: off=16772608 len=4096 pr=0x55c12bac1ec0
	9691: libblkid: LOWPROBE: [64] exfat: 

Modified Package with Debug Print)

	9632: libblkid: LOWPROBE: [63] nilfs2:                
	9632: libblkid: LOWPROBE:       call probefunc()
	9632: libblkid: LOWPROBE:       reuse buffer: off=1024 len=1024 pr=0x557da562eec0    
	9632: libblkid: LOWPROBE:       reuse buffer: off=16772608 len=4096 pr=0x557da562eec0
	9632: libblkid: LOWPROBE: nilfs2: nilfs_valid_sb:78 :: entry                 
	9632: libblkid: LOWPROBE: nilfs2: nilfs_valid_sb:81 :: not sb or not magic    
	9632: libblkid: LOWPROBE: nilfs2: nilfs_valid_sb:78 :: entry                  
	9632: libblkid: LOWPROBE: nilfs2: nilfs_valid_sb:85 :: is_bak 1               
	9632: libblkid: LOWPROBE: nilfs2: nilfs_valid_sb:86 :: is_wholedisk 0
	9632: libblkid: LOWPROBE: nilfs2: nilfs_valid_sb:87 :: sb->s_dev_size 0
	9632: libblkid: LOWPROBE: nilfs2: nilfs_valid_sb:88 :: pr->size 16776704      
	9632: libblkid: LOWPROBE: nilfs2: nilfs_valid_sb:100 :: bytes 1025            
	9632: libblkid: LOWPROBE: nilfs2: primary=0, backup=0                         
	9632: libblkid: LOWPROBE: [64] exfat:

-- 
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to util-linux in Ubuntu.
https://bugs.launchpad.net/bugs/1842437

Title:
  Xenial: libblkid: fix false-positive/misdetection of nilfs2 filesystem
  with udev

Status in util-linux package in Ubuntu:
  Fix Released
Status in util-linux source package in Xenial:
  In Progress

Bug 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/not-wholedisk device,
  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.kernel.org/pub/scm/utils/util-linux/util-linux.git/commit/?id=ac681a310c32319423297544833932f4d689a7a2

  $ git describe --contains ac681a310c32319423297544833932f4d689a7a2
  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.

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/util-linux/+bug/1842437/+subscriptions



More information about the foundations-bugs mailing list