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
Touch seeded packages, 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

-- 
Mailing list: https://launchpad.net/~touch-packages
Post to     : touch-packages@lists.launchpad.net
Unsubscribe : https://launchpad.net/~touch-packages
More help   : https://help.launchpad.net/ListHelp

Reply via email to