bugGNU GRUB - Bugs: bug #42466, GRUB cannot load symlinks of...

 
 

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

bug #42466: GRUB cannot load symlinks of length 60 on ext4

Submitted by:  KOVACS Krisztian <hidden_balabit>
Submitted on:  Fri 30 May 2014 01:24:13 PM UTC  
 
Category: FilesystemSeverity: Major
Priority: 5 - NormalItem Group: Software Error
Status: NonePrivacy: Public
Assigned to: NoneOriginator Name: 
Open/Closed: OpenRelease: 
Release: Git masterReproducibility: Every Time
Planned Release: None

Sun 22 Jun 2014 01:35:06 AM UTC, comment #1:

That's disturbing. The big problem is that different OS may have different behaviour (there are several ext* writers). Perhaps we should check blocks count instead.

Vladimir Serbinenko <phcoder>
Project Administrator
Fri 30 May 2014 01:24:13 PM UTC, original submission:

We have a setup where the kernel to be loaded is accessed through a path containing a symbolic link. The config is something like this:

- 8< -
search --set=root --label boot

linux '/boot/active/kernel'
initrd '/boot/active/initrd'
- 8< -

If '/boot/active' is a symbolic link to a directory whose name is exactly 60 characters long, loading the kernel fails and GRUB cannot boot. Directories whose name is less than 60 or more than 60 work perfectly.

It seems to be that there is a difference in how the Linux ext4 implementation handles in-inode symbolic links and what the GRUB implementation expects.

In the Linux implementation of ext4, symbolic links whose target is shorter than 60 bytes are stored directly in the inode. (See https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/ext4/namei.c?id=455c6fdbd219161bd09b1165f11699d6d73de11c#n2831)

It's worth noting that the code performs the comparison '(l > 60)', where l equals strlen(symname)+1. That means in practice that if the lenth of the symlink target is 60, the comparison is true, meaning that it is stored as a non-fast symlink in a separate block.

In the GRUB implementation, however, the following comparison is made to check if the symlink target is stored in the inode structure: diro->inode.size <= 60. (sizeof(diro->inode.symlink) == 60) Unfortunately, if size is 60, this leads to GRUB looking for the symlink target in the inode, but the ext4 implementation has not stored that info there.

I've attached a patch that seems to fix the issue by making sure that GRUB handles symlink targets of length 60 as non-fast.

KOVACS Krisztian <hidden_balabit>

 

Attached Files
file #31471:  grub-ext4-symlink-target-of-length-60.diff added by hidden_balabit (671B - text/x-patch - Patch fixing the issue with 60 char symlink targets.)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by phcoder (Posted a comment)
  • -unavailable- added by hidden_balabit (Submitted the item)
  •  

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

    Only logged-in users can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    Follows 1 latest change.

    Date Changed By Updated Field Previous Value => Replaced By
    Fri 30 May 2014 01:24:13 PM UTChidden_balabitAttached File-=>Added grub-ext4-symlink-target-of-length-60.diff, #31471

    Back to the top


    Powered by Savane 3.1-cleanup