bugGNU GRUB - Bugs: bug #43430, grub's probing code incorrectly...

 
 

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

bug #43430: grub's probing code incorrectly identifies an ext4 file system as a minix2

Submitter:  C <mekanofox>
Submitted:  Fri 17 Oct 2014 11:45:30 AM UTC
   
 
Category:  Booting Severity:  Major
Priority:  5 - Normal Item Group:  Software Error
Status:  None Privacy:  Public
Assigned to:  None Originator Name: 
Open/Closed:  Open Release:  Git master
Release:  Reproducibility:  Every Time
Planned Release:  2.03+

Thu 19 Feb 2015 03:14:38 PM UTC, comment #1: 

This just bit me.  Had to change the magic numbers in minix.c to 9999, and all went well afterwards.

Seems like there are multiple failures here.  It'd be nice to at least improve error messages, considering that there's at least a patch.

And, what motivation does anyone have to submit further patches, when such a good, logical, usable one as this -- doesn't even rate a response or patching?


Brad Barnett <bbarnett>
Fri 17 Oct 2014 11:45:30 AM UTC, original submission:  

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).


C <mekanofox>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attached Files
file #32284:  gdb2.txt added by mekanofox (21KiB - text/plain - gdb2.txt contains a gdb trace of grub-probe run on a disk with an ext4 boot partition)
file #32285:  patch-grub-2.02~beta2_fstypeerrmsg.diff added by mekanofox (31KiB - text/plain - gdb2.txt contains a gdb trace of grub-probe run on a disk with an ext4 boot partition)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by phcoder (Updated the item)
  • -email is unavailable- added by bbarnett (Posted a comment)
  • -email is unavailable- added by mekanofox (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

     

    Follow 4 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2017-03-05 phcoder Planned Release2.02 2.03+
    2016-03-02 phcoder Planned ReleaseNone 2.02
    2014-10-17 mekanofox Attached File- Added gdb2.txt, #32284
        Attached File- Added patch-grub-2.02~beta2_fstypeerrmsg.diff, #32285

    Back to the top

    Powered by Savane 3.13-f8d8.
    Corresponding source code