grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

loadee relocation (Re: loader modules jumping back to kernel)


From: Robert Millan
Subject: loadee relocation (Re: loader modules jumping back to kernel)
Date: Wed, 30 Jul 2008 21:15:10 +0200
User-agent: Mutt/1.5.13 (2006-08-11)

On Sun, Jul 27, 2008 at 11:39:49PM +0200, Robert Millan wrote:
> On Sun, Jul 20, 2008 at 11:09:02AM +0200, Yoshinori K. Okuji wrote:
> > > IIRC this causes trouble when the loadee chose an address that precisely
> > > overwrites the loader, which is garanteed to happen when GRUB is loading
> > > itself, AFAICT.
> > 
> > Sure. My recommendation is, in case where you might overwrite that part, 
> > that 
> > you should write relocatable code (which is rather easy for simple code on 
> > i386) at anywhere (it could be in the startup), find out a safe region when 
> > loading an OS image, copy the code to the safe region, and finalize the 
> > bootstrap in that code (e.g. relocating the OS image, initializing 
> > registers, 
> > and jumping to it). On i386, we have a reserved region to temporarily load 
> > an 
> > OS image for the very reason, so this is not difficult.
> 
> Ok.  I've been looking at grub_multiboot_load_elf32() which contains the
> bound checks that make loading abort in first place;  It seems that bounds
> are checked for every segment in the ELF image, in:
> 
>    /* Load every loadable segment in memory.  */
>    for (i = 0; i < ehdr->e_phnum; i++)
> 
> so I'm wondering if it is safe to assume the segments are going to occupy
> a single block of memory (which can be relocated in one run) or it is allowed
> for them to be scattered.
> 
> As for the safe region, AFAICT the OS load area is our only choice, or maybe
> the heap, but in both cases overlaps are a problem, as we don't want the
> relocator code to overwrite itself.  In case of the OS load area, we could
> abort on situations where payload requested region overlaps with our area,
> and in case of the heap, we could play some ugly tricks in order to obtain
> a non-overlapped region from malloc.
> 
> TBH I don't like either of the options.  Do you have any other suggestions?

Let's try to revive this discussion.  Here's a patch I made a while ago that
implements support for loading at any address.  It works by having a "special"
version of malloc() that is told to allocate a chunk of memory that does
_not_ overlap with a specific region.  It does so by iteratively reserving
memory (and keeping track of what was reserved, of course).

Then we use this function to allocate the asm relocator code in heap, asking
it to garantee that it won't overlap with our final destination.  Finally,
our loadee can be put anywhere (e.g. in heap), and we just jump to the
relocator which will jump to the loadee.

But I really find the approach really ugly.  What do you think?  If we agree
that this is the way to go, I can do some cleanup & update it to current svn
for a merge.

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."

Attachment: loader_relocation.diff
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]