bugGNU GRUB - Bugs: bug #57652, minix filesystem detection too...


You are not allowed to post comments on this tracker with your current authentication level.

bug #57652: minix filesystem detection too optimistic

Submitted by:  Stefan Seyfried <seife>
Submitted on:  Wed 22 Jan 2020 08:24:04 AM UTC  
Category:  Filesystem Severity:  Major
Priority:  5 - Normal Item Group:  Software Error
Status:  None Privacy:  Public
Assigned to:  None Originator Name: 
Open/Closed:  Open Release: 
Release:  2.02 Reproducibility:  Every Time
Planned Release:  None

Fri 24 Jan 2020 10:10:20 AM UTC, comment #2: 

maybe a non-intrusive fix would be to ensure that ext2 gets initialized before minix:

diff --git a/Makefile.am b/Makefile.am
index 1f4bb9b8c..0bef226d3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -42,8 +42,11 @@ libgrub.pp: grub_script.tab.h grub_script.yy.h $(libgrubmods_a_SOURCES) $(libgru
          -D'GRUB_MOD_INIT(x)=@MARKER@x@' $^ > $@ || (rm -f $@; exit 1)
 CLEANFILES += libgrub.pp

+# the grep/sed ensures that ext2 gets initialized before minix*
+# see https://savannah.gnu.org/bugs/?57652
 libgrub_a_init.lst: libgrub.pp
        cat $< | grep '@MARKER@' | sed 's/@MARKER@\(.*\)@/\1/g' | sort -u > $@ || (rm -f $@; exit 1)
+       if grep ^ext2 $@ >/dev/null; then sed '/ext2/d;/newc/iext2' < $@ > $@.tmp && mv $@.tmp $@; fi
 CLEANFILES += libgrub_a_init.lst

 libgrub_a_init.c: libgrub_a_init.lst $(top_srcdir)/geninit.sh

Stefan Seyfried <seife>
Wed 22 Jan 2020 10:24:56 AM UTC, comment #1: 

Adding a reproducer script.
This does the following:

  • create a filesystem image file sized 1GB
  • create a partition on the image and an ext3 file system in it
  • mount the partition
  • debootstrap debian stable into the mountpoint
  • install grub2 into the debian image (from package, here you could install your self-built grub2...)
  • check for the number of free inodes
  • create as many dummy files to exactly hit a bad magic number
  • unmount / mount to update the superblock
  • chroot => grub-install

grub-install will fail.

it is called as root:

# bash ./grub-bug-57652-reproduce.sh /space/grub.img /mnt

/space should have 1GB of free space of course :-)

Stefan Seyfried <seife>
Wed 22 Jan 2020 08:24:04 AM UTC, original submission:  

I encountered an intermittent issue where grub-install would fail with "not a directory" error after trying minix_be detection:

grub-core/kern/fs.c:79: nilfs2 detection failed.
grub-core/kern/fs.c:57: Detecting newc...
grub-core/kern/fs.c:79: newc detection failed.
grub-core/kern/fs.c:57: Detecting minix_be...
grub-core/osdep/hostdisk.c:408: reusing open device `/dev/loop0'
grub-core/kern/fs.c:79: minix_be detection failed.
grub2-install: error: not a directory.

The reason for this (I found this after days of debugging...) is, that the minix filesystem detection in grub-core/fs/minix.c:grub_minix_mount() is overly optimistic. It just checks for the FS magic number and sanity-checks some other size fields, then decides "this is minix".

The problem is, that grub_fs_probe calls the dir() function of every file system as

   dir(device, "/", ...)

and if this does not return an error other than GRUB_ERR_BAD_FS, then this is considered fatal.

Now the grub_minix_dir(.., path, ...) function (which is dir() for minix) does the following (pseudocode):

  grub_minix_mount() || return GRUB_ERR_BAD_FS # this is the detection if it is a minix fs
  data = grub_minix_find_file(path) || return grub_errno
  if (MODE(data) != ISDIR)
     return "not a directory"

if grub_minix_mount would have failed, this would be a non-fatal error, but it only fails afterwards when checking if "/" is a directory, which is then considered fatal, and causes grub-install to abort with the strange (if you do not know all the circumstances :-) "not a directory" message.

Now how can the MINIX FS magic number appear?

The answer is easy: the on-disk location of grub_minix_sblock.magic is the same as the on-disk location of grub_ext2_sblock.free_inodes, so if you happen to install grub onto a file system with a matching number of free inodes, you can trigger this reliably. Any you'll never guess what the problem is ;-)

I wrote about this with more hints and a workaorund on https://seifesrants.blogspot.com/2020/01/fun-with-grub2-install.html

The attached patch fixes the issue for me.
It is not ready for inclusion and includes some additional debug code, which of course can be omitted.

What it does is put the additional steps that "dir('/')" does directly into the grub_minix_mount() code, and only return successfully if this succeeds and finds that "/" actually is a directory.

In the long run, it would be beneficial if grub-install got an option to specify "--filesystems=ext2,xfs,btrfs" to skip probing for unrelated filesystems. I'm quite sure there are more possibilities to get this autodetection wrong for different filesystem types.

I'll try to craft a script to reproduce this easily.

Note that I have encountered and debugged this on a SUSE Linux Enterprise Server 15 SP1 code base. However, I checked the current git masterand the minix fs code is identical, so I'm pretty sure the problem is still present in the current code base.

Stefan Seyfried <seife>


Attached Files
file #48272:  grub-bug-57652-reproduce.sh added by seife (3KiB - text/x-sh - reproducer script)
file #48271:  grub2-minix-probe-fix.diff added by seife (4KiB - application/octet-stream - POC fix (with debug code))


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -email is unavailable- added by seife (Submitted the item)
  • -email is unavailable- added by seife

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.




    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2020-01-22 seife Attached File- => Added grub-bug-57652-reproduce.sh, #48272
    2020-01-22 seife Attached File- => Added grub2-minix-probe-fix.diff, #48271
        Carbon-Copy- => Added seife

    Back to the top

    Powered by Savane 3.5