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