Re: [PATCH 0/2] make kASLR vs hibernation boot-time selectable

From: Rafael J. Wysocki
Date: Fri Jun 13 2014 - 17:57:13 EST


On Friday, June 13, 2014 10:32:56 AM Kees Cook wrote:
> On Fri, Jun 13, 2014 at 3:51 AM, Pavel Machek <pavel@xxxxxx> wrote:
> > Hi!
> >
> >
> >> >>> Any way we can make them work together instead?
> >> >>
> >> >> I'm sure there is, but I don't know the solution. :)
> >> >>
> >> >> At the very least this gets us one step closer (we can build them together).
> >> >>
> >> >
> >> > But it is really invasive.
> >>
> >> Well, I don't agree there. I actually would like to be able to turn
> >> off hibernation support on distro kernels regardless of kASLR, so I
> >> think this is really killing two birds with one stone.
> >>
> >> > I have to admit to being somewhat fuzzy on what the core problem with
> >> > hibernation and kASLR is... in both cases there is a set of pages that
> >> > need to be installed, some of which will overlap the loader kernel.
> >> > What am I missing?
> >>
> >> I don't know how resume works, but I have assumed that the newly
> >> loaded kernel stays in memory and pulls in the vmalloc, kmalloc,
> >> modules, and userspace memory maps from disk. Since these things can
> >> easily contain references to kernel text, if the newly loaded kernel
> >> has moved with regard to the hibernated image, everything breaks.
> >> IIUC, this is similar why you can't rebuild your kernel and resume
> >> from a different version.
> >
> > x86-64 can resume from different kernel that did the suspend. kASLR
> > should not be too different from that. (You just include kernel text
> > in the hibernation image. It is small enough to do that.)
>
> Oooh, that's very exciting! How does that work (what happens to the
> kernel that booted first, etc)? I assume physical memory layout can't
> change between hibernation and resume? Or, where should I be reading
> code that does this?

I guess it would help if you were a bit less sarcastic, but perhaps that's
just me.

Anyway, the core hibernation code actually works with page frames rather
than with virtual addresses. Essentially, it creates a bitmap where each
page frame is represented by a single bit and the bits representing free
page frames are unset. It then allocates as many new pages as there are
set bits in the bitmap and copies the entire contents of the page frames
represented by those bits to new pages it's just allocated. That covers
the entire kernel with its data and all process memory and is saved to
disk storage along with the PFNs of the page frames whose contents have
been copied.

During resume it simply restores the contents of the saved page frames
into those same page frames if they are available at that time. For the
page frames that aren't free then it allocates memory to store their
contents temporarily and creates a list of PFNs where that contents should
be moved eventually. Then, it quiesces all activity of the system and
jumps to arch-specific code that copies data from the temporary memory to
the target page frames (that generally overwrites the boot kernel, so there's
no way back from it). Finally, it jumps to a specific address where the
hibernated kernel trampoline code should be present.

I think what fails with kASLR is that last step, because everything else
should be entirely agnostic to the way the virtual addresses are laid out.
I'm not sure how to fix that at the moment, but it should be fixable at
least on x86_64.

Rafael

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/