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

                 Summary: GRUB fails to read FAT filesystem label
                 Project: GNU GRUB
            Submitted by: qwertial
            Submitted on: Sun 17 Jun 2012 08:52:24 AM GMT
                Category: None
                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: Bazaar - trunk
         Reproducibility: None
         Planned Release: None

    _______________________________________________________

Details:

Steps to reproduce:
1. Start GRUB on a system with a disk containing a FAT partition with a label.
It may even be QEMU with a VVFAT.
2. ls -l
3. Stare at the machine in confusion as it reboots.

As I investigated, it turned out that the root problem is probably a compiler
bug, so it probably should be sent to the GCC team, but...

When gdb.mod is loaded, GRUB catches exception 0xd (GPF) and prints a stack
trace pointing to the FAT module. From what I have found out, GRUB returns to
an invalid address from iter_hook inside grub_fat_label. While digging through
the assembly, I found that the jump target in the trampoline points to
iter_hook+1 instead of iter_hook. Here is the disassembly for iter_hook:

=> 0x7ffa644 <iter_hook>:       cmpb   $0x8,0xb(%edx)
   0x7ffa648 <iter_hook+4>:     jne    0x7ffa662 <iter_hook+30>
   0x7ffa64a <iter_hook+6>:     push   %esi
   0x7ffa64b <iter_hook+7>:     push   %ebp
   0x7ffa64c <iter_hook+8>:     mov    %esp,%ebp
   0x7ffa64e <iter_hook+10>:    push   %ecx
   0x7ffa64f <iter_hook+11>:    call   0xd120 <grub_strdup>
   0x7ffa654 <iter_hook+16>:    mov    0x4(%ebp),%edx
   0x7ffa657 <iter_hook+19>:    mov    (%edx),%edx
   0x7ffa659 <iter_hook+21>:    mov    %eax,(%edx)
   0x7ffa65b <iter_hook+23>:    mov    $0x1,%eax
   0x7ffa660 <iter_hook+28>:    jmp    0x7ffa665 <iter_hook+33>
   0x7ffa662 <iter_hook+30>:    xor    %eax,%eax
   0x7ffa664 <iter_hook+32>:    ret    
   0x7ffa665 <iter_hook+33>:    leave  
   0x7ffa666 <iter_hook+34>:    pop    %edx
   0x7ffa667 <iter_hook+35>:    ret

Before jumping into iter_hook, the trampoline pushes a pointer to the
enclosing function context, but as we can see from disassembly, iter_hook does
not pop that pointer at all (and it seems to refer to it wrongly). It seems
that this routine is not the only one for which wrong trampoline is generated,
but because most of them start with a one-byte push instruction, the resulting
stack pointer misadjustments cancel out. This one does not, but it
resynchronises with the correct instruction stream quite quickly:

   0x7ffa645 <iter_hook+1>:     jp     0x7ffa652 <iter_hook+14>
   0x7ffa647 <iter_hook+3>:     or     %dh,0x18(%ebp)
   0x7ffa64a <iter_hook+6>:     push   %esi
   0x7ffa64b <iter_hook+7>:     push   %ebp
   0x7ffa64c <iter_hook+8>:     mov    %esp,%ebp

Compiling with gcc version 4.7.0 20120505 (prerelease), on
x86_64-unknown-linux-gnu, targeting i386-pc.

Interestingly, when manually fixing the return address, or when using the
x86_64-efi version, GRUB tells me that "filesystem `fat' does not support
labels"; and the grub-probe tool (on x86_64) prints "(nil)" as the filesystem
label. So the compiler bug may be not the only one here, or at least not just
on i386.





    _______________________________________________________

Reply to this item at:

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

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


_______________________________________________
Bug-grub mailing list
Bug-grub@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-grub

Reply via email to