bug-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug #43430] grub's probing code incorrectly identifies an ext4 file sys


From: C
Subject: [bug #43430] grub's probing code incorrectly identifies an ext4 file system as a minix2
Date: Fri, 17 Oct 2014 11:45:32 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:33.0) Gecko/20100101 Firefox/33.0

URL:
  <http://savannah.gnu.org/bugs/?43430>

                 Summary: grub's probing code incorrectly identifies an ext4
file system as a minix2
                 Project: GNU GRUB
            Submitted by: mekanofox
            Submitted on: Fri 17 Oct 2014 04:45:30 AM PDT
                Category: Booting
                Severity: Major
                Priority: 5 - Normal
              Item Group: Software Error
                  Status: None
                 Privacy: Public
             Assigned to: None
         Originator Name: 
        Originator Email: 
             Open/Closed: Open
         Discussion Lock: Any
                 Release: 
                 Release: Git master
         Reproducibility: Every Time
         Planned Release: None

    _______________________________________________________

Details:

This is for version grub-2.02~beta2. 

grub-install/grub-probe fail with the puzzling message 'error: not a
directory.'
The result is a failed grub install/upgrade; in my case, it caused the next
boot to end up on a 'grub>' prompt. (my boot partition is ext4)

To investigate/reproduce, grub-probe can be run on a disk with suitable values
in certain fields of the ext4 partition superblock used for boot.

What is happening: in function 'grub_probe_fs' (grub-core/kern/fs.c:49), a
loop runs over all the possible file systems known by grub and attempts to
detect the type of the file system present on the device (the for on line
grub-core/kern/fs.c:54). The detection is done by a callback-style function
specific to each file system (the '(p->dir)' indirect call on line
grub-core/kern/fs.c:73).
For a minix2 file system the detection is done primarily by looking for a
magic 16 bit value and if that succeeds, it is followed by validating another
specific minix2 superblock value.

*These fields map to valid, in-use, ext4 superblock values.* If the values
pass the tests, the ext2/3/4 superblock (and possibly other fs types) will be
wrongly taken to be minix2 instead.

More precisely, the relevant minix2 superblock fields map onto the ext4
superblocks fields as follows:

* the minix2 'magic' number corresponds to the lower 16 bits of the ext4's
free_inodes_count
* the 'log2_zone_size' corresponds to the upper 16 bits of the ext4's
reserved_block_count

In my case, by (incredibly bad, but not totally rare) luck, the bug started to
manifest when the lower 16 bits of the free inodes counter in my ext4 matched
the magic number for a minix2 file system. (that would be 0x2468). The
following test was also passing: that test was involving the ext4's reserved
block count which was incorrectly taken to be the log2_zone_size of the minix2
superblock. (this 2nd test would fail if the upper 16 bits of the ext4's
reserved_block_count would be at least 20 (decimal); at the default percentage
of 5% for the reserved blocks, that would imply gargantuan disks, unlikely to
exist in the near future; thus, once the magic passes, this 2nd test is quite
irrelevant)

After these two tests, the code had firmly considering the partition a minix2.
When a subsequent call failed (trying to find the root directory for the file
system), the end result was reported to the parent caller ('grub_probe_fs') as
a bad/corrupted minix2, using a GRUB_ERR_BAD_FILE_TYPE. In turn, grub_probe_fs
simply gave up on trying to check other file system types and went back
further up to its caller ('probe', at util/grub-probe.c:380) with the error.
The 'probe' function then printed the aforementioned message "not a
directory".

You can follow all the details in the gdb trace attached (gdb2.txt --
grub-probe run under debugger with source lines and explanations).

A few observations and a discussion of potential fixes:

* It seems checking for magic values is a common method and widely used for
other (most?) file systems. There should be a way to give a perfect match (no
errors) a higher priority than a match that only partially succeeds, even if
the latter is performed first. That is, 'grub_probe_fs' should not give up on
errors that might indicate corruption, but only on tests that definitely rule
out a certain type (such as a missing magic).
 
* Currently, the partition types are checked in (reverse) alphabetical order.
Well, a bit arbitrary, but I suppose keeps the sources tidy. A different
ordering might help, maybe checking certain magic first, ruling out magic that
cannot be present in other fields for other types, etc. But I am not sure a
general solution is possible just based on order.

* A minimal and quick-and-dirty solution is to print together with the error
message the file system class/type that GRUB thinks it has found. At least
that would more easily point to a major inconsistency. So, in my example,
saying 'error: minix: not a directory' -- it gives a starting hint that there
was a major screw up (unrelated to ext4!) and helps when searching the
internet for similar errors.

To make the above error reporting addition a more consistent and general
solution would require changing all the filesystem probing callbacks in
grub-core/fs. That's about 24 files at my last count, although there are more
than a few places in each.

For example, changing in minix.c :

    grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));

... to:

    grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("minix: not a directory"));


A search for grub_error should list the possible lines to check. The fs name
should be added for errors different than GRUB_ERR_BAD_FS and
GRUB_ERR_OUT_OF_RANGE, since these are handled in grub_fs_probe and they do
not break the detection loop (see grub-core/kern/fs.c:81,82).
That is, from the grub-2.02~beta2 project root dir, run:


find grub-core/fs -type f -name \*.c \
    | xargs grep -nE '[[:space:]]*grub_error[[:space:]]\('
    | grep -v -e 'GRUB_ERR_BAD_FS\|GRUB_ERR_OUT_OF_RANGE'


This finds about 100 places that need changed.
I've attached a diff with the changes for these; I've prepended in the error
message the base file name since that in the majority of cases is the same as
the name of the filesystem. (but fshelp.c seem to contain general helper
routines; nonetheless, it would be still useful to recognize errors generated
there).





    _______________________________________________________

File Attachments:


-------------------------------------------------------
Date: Fri 17 Oct 2014 04:45:30 AM PDT  Name: gdb2.txt  Size: 21kB   By:
mekanofox
gdb2.txt contains a gdb trace of grub-probe run on a disk with an ext4 boot
partition
<http://savannah.gnu.org/bugs/download.php?file_id=32284>
-------------------------------------------------------
Date: Fri 17 Oct 2014 04:45:30 AM PDT  Name:
patch-grub-2.02~beta2_fstypeerrmsg.diff  Size: 31kB   By: mekanofox
gdb2.txt contains a gdb trace of grub-probe run on a disk with an ext4 boot
partition
<http://savannah.gnu.org/bugs/download.php?file_id=32285>

    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?43430>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]