bugGNU GRUB - Bugs: bug #38800, x86-64: overflowing relocation...

 
 

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

bug #38800: x86-64: overflowing relocation crashes GRUB

Submitter:  <qwertial>
Submitted:  Mon 22 Apr 2013 05:46:08 AM UTC
   
 
Category:  None Severity:  Major
Priority:  5 - Normal Item Group:  None
Status:  Fixed Privacy:  Public
Assigned to:  None Originator Name: 
Open/Closed:  Closed Release:  Bazaar - trunk
Release:  Reproducibility:  Every Time
Planned Release:  None

Sat 04 May 2013 09:26:49 PM UTC, comment #5: 

/usr/lib/grub is ro to user while the sceript improperly assumes the module directory to be writable. It's a problem with script. As for ->mod I'm puzzled as to why it works on my system as-is.

Vladimir Serbinenko <phcoder>
Group administrator
Sat 04 May 2013 07:11:12 PM UTC, comment #4: 

Ugh, Savannah ate my comment. (Though it is readable in the mailing list.) Anyway, it's because of this change:

http://bzr.savannah.gnu.org/lh/grub/trunk/grub/revision/2445/kern/dl.c

The module list (to which grub_dl_head points) used to be implemented by two structures. The above change moved the "->next" pointer directly into the grub_dl structure and eliminated the other one.

(Also, the auto-attach-to-QEMU commands might be removed, as they are actually counterproductive when debugging grub-emu, and maybe the /usr/lib/grub/platform path prepended to module paths in gdb_grub.in and gmodule.pl.in... but that is another story.)

Has the original issue been addressed (pardon the pun) well enough to close this? There are no more crashes, by default at least.

<qwertial>
Tue 30 Apr 2013 02:43:21 AM UTC, comment #3: 

grub-core/kern/dl.c:

grub_dl_t grub_dl_head = 0;
-verbatim+

include/grub/dl.h:
+verbatim+
#ifndef GRUB_UTIL
struct grub_dl
{
  char *name;
  int ref_count;
  grub_dl_dep_t dep;
  grub_dl_segment_t segment;
  Elf_Sym *symtab;
  void (*init) (struct grub_dl *mod);
  void (*fini) (void);
#if defined (__ia64__) || defined (__powerpc__)
  void *got;
  void *tramp;
#endif
  void *base;
  grub_size_t sz;
  struct grub_dl *next;
};
#endif
typedef struct grub_dl *grub_dl_t;


...r-right?

<qwertial>
Mon 29 Apr 2013 05:19:22 PM UTC, comment #2: 

Why do you need to remove ->mod ?

Vladimir Serbinenko <phcoder>
Group administrator
Mon 22 Apr 2013 06:06:44 PM UTC, comment #1: 

Some other random things discovered by the way:

0. grub-core/gdb_grub needs a correction for 64-bit pointers and data structures change:


--- grub-core/gdb_grub.in
+++ grub-core/gdb_grub.in
@@ -22,7 +22,7 @@
         printf "%s", $mod->name
         set $segment = $mod->segment
         while ($segment)
-                printf " %i 0x%x", $segment->section, $segment->addr
+                printf " %i 0x%lx", $segment->section, $segment->addr
                 set $segment = $segment->next
         end
         printf "\n"
@@ -61,7 +61,7 @@
 define load_all_modules
         set $this = grub_dl_head
         while ($this != 0)
-                dump_module_sections $this->mod
+                dump_module_sections $this
                 set $this = $this->next
         end
         match_and_load_symbols


1. FOR_LIST_ELEMENTS_SAFE is not as safe as it says: it will dereference the final NULL pointer after assigning it to var. Which is mostly harmless without memory protection, but crashes grub-emu running the help command.

2. Speaking of which, running "help help" crashes because the help command was registered with a 0 pointer for the parser argument. The NULL check in grub_arg_show_help() happens too late. This does not seem to do much on real hardware, though it may access some bogus data.

<qwertial>
Mon 22 Apr 2013 05:46:08 AM UTC, original submission:  

The x86-64 version of grub_arch_dl_relocate_symbols() does not check whether an R_X86_64_PC32 relocation fits into 32 bits. This makes grub-emu-lite crash (with default compiler options) when trying to execute the module, since module code is loaded above 0x7ffff0000000, while grub-emu-lite code is loaded around 0x400000.

Possible solutions:

0. Add an overflow check to grub_arch_dl_relocate_symbols().
1. Try to allocate module code near core code.
2. Use the system's dlopen() and dlsym() calls for loading modules in grub-emu-lite instead of the built-in loader.
3. Compile with -mcmodel=large, which makes 32-bit relocations disappear.

<qwertial>

 

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

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by phcoder (Posted a comment)
  • -email is unavailable- added by qwertial (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 2 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2013-05-04 phcoder StatusNone Fixed
        Open/ClosedOpen Closed

    Back to the top

    Powered by Savane 3.13-3230.
    Corresponding source code