From: Baoquan He <bhe@redhat.com>
To: Kees Cook <keescook@chromium.org>
Cc: Dave Jiang <dave.jiang@intel.com>,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
linux-nvdimm <linux-nvdimm@ml01.01.org>,
"x86@kernel.org" <x86@kernel.org>,
Dave Chinner <david@fromorbit.com>,
LKML <linux-kernel@vger.kernel.org>,
Dan Williams <dan.j.williams@intel.com>
Subject: Re: [PATCH v5] x86: fix kaslr and memmap collision
Date: Sat, 7 Jan 2017 18:48:49 +0800 [thread overview]
Message-ID: <20170107104849.GI6937@x1> (raw)
In-Reply-To: <CAGXu5jJbOQZfmydoWLXeNc3ZKgZkgO9003PzdKi85JfkZJcYGA@mail.gmail.com>
On 01/06/17 at 01:16pm, Kees Cook wrote:
> On Thu, Jan 5, 2017 at 6:44 PM, Baoquan He <bhe@redhat.com> wrote:
> >> > +static int mem_avoid_memmap(void)
> >> > +{
> >> > + char arg[128];
> >> > + int rc = 0;
> >> > +
> >> > + /* see if we have any memmap areas */
> >> > + if (cmdline_find_option("memmap", arg, sizeof(arg)) > 0) {
> >> > + int i = 0;
> >> > + char *str = arg;
> >> > +
> >> > + while (str && (i < MAX_MEMMAP_REGIONS)) {
> >> > + unsigned long long start, size;
> >> > + char *k = strchr(str, ',');
> >> > +
> >> > + if (k)
> >> > + *k++ = 0;
> >> > +
> >> > + rc = parse_memmap(str, &start, &size);
> >> > + if (rc < 0)
> >> > + break;
> >> > + str = k;
> >> > + /* a usable region that should not be skipped */
> >> > + if (size == 0)
> >> > + continue;
> >> > +
> >> > + mem_avoid[MEM_AVOID_MEMMAP_BEGIN + i].start = start;
> >> > + mem_avoid[MEM_AVOID_MEMMAP_BEGIN + i].size = size;
> >> > + i++;
> >> > + }
> >> > +
> >> > + /* more than 4 memmaps, fail kaslr */
> >> > + if ((i >= MAX_MEMMAP_REGIONS) && str)
> >> > + rc = -EINVAL;
> >> > + }
> >> > +
> >> > + return rc;
> >> > +}
> >> > +
> >> > /*
> >> > * In theory, KASLR can put the kernel anywhere in the range of [16M, 64T).
> >> > * The mem_avoid array is used to store the ranges that need to be avoided
> >> > @@ -438,6 +559,12 @@ void choose_random_location(unsigned long input,
> >> > return;
> >> > }
> >> >
> >> > + /* Mark the memmap regions we need to avoid */
> >> > + if (mem_avoid_memmap()) {
> >> > + warn("KASLR disabled: memmap exceeds limit of 4, giving up.");
> >> > + return;
> >> > + }
> >>
> >> theoretically, mem_avoid_memmap is doing the mem_avoid initialization
> >> job, should be called inside mem_avoid_init(). The reason you put it
> >> here is you want to make it cancel kaslr, both physical and virtual
> >> address randomization, right?
> >>
> >> In choose_random_location(), the physical and virtual random are done
> >> separately. You can see that later when find_random_phys_addr failed to
> >> find a suitable random slot, it just prints a warning, virtual
> >> randomization is still be done with calling find_random_virt_addr().
> >> Avoiding memmap reserved region should be physical ram issue, should we
> >> stop the kernel virtual address randomization either?
> >>
> >> Kees, what do you think about this?
>
> Yeah, good catch. mem_avoid_memmap() should be called from
> mem_avoid_init(). I think likely the cleanest approach to dealing with
> the >4 case would be to set a global flag, similar to slot_area_index,
> that is checked in find_random_phys_addr().
>
> Maybe something like:
>
> static bool memmap_too_large;
Yes, this is better.
>
> static int mem_avoid_memmap(void)
> {
> ...
> /* more than 4 memmaps, fail kaslr */
> if ((i >= MAX_MEMMAP_REGIONS) && str) {
> memmap_too_large = true;
> rc = -EINVAL;
> }
> ...
> }
> ...
> static unsigned long find_random_phys_addr(unsigned long minimum,
> unsigned long image_size)
> {
> int i;
> unsigned long addr;
>
> /* Check if we had too many memmaps. */
> if (memmap_too_large) {
> debug_putstr("Aborted e820 scan (more than 4 memmap=
> arguments)!\n");
> return 0;
> }
>
> /* Make sure minimum is aligned. */
> minimum = ALIGN(minimum, CONFIG_PHYSICAL_ALIGN);
> ...
>
>
> And we should likely adjust this warning:
>
> if (!random_addr) {
> warn("KASLR disabled: could not find suitable E820 region!");
>
> to something like:
>
> if (!random_addr) {
> warn("Physical KASLR disabled: no suitable memory region!");
>
>
> -Kees
>
> >>
> >> > +
> >> > boot_params->hdr.loadflags |= KASLR_FLAG;
> >> >
> >> > /* Prepare to add new identity pagetables on demand. */
prev parent reply other threads:[~2017-01-07 10:49 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-04 18:29 [PATCH v5] x86: fix kaslr and memmap collision Dave Jiang
2017-01-05 9:21 ` Baoquan He
2017-01-06 2:44 ` Baoquan He
2017-01-06 21:16 ` Kees Cook
2017-01-07 10:48 ` Baoquan He [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170107104849.GI6937@x1 \
--to=bhe@redhat.com \
--cc=dan.j.williams@intel.com \
--cc=dave.jiang@intel.com \
--cc=david@fromorbit.com \
--cc=hpa@zytor.com \
--cc=keescook@chromium.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nvdimm@ml01.01.org \
--cc=mingo@redhat.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox