All of lore.kernel.org
 help / color / mirror / Atom feed
From: Baoquan He <bhe@redhat.com>
To: Kees Cook <keescook@chromium.org>
Cc: Ingo Molnar <mingo@kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Dave Young <dyoung@redhat.com>,
	douly.fnst@cn.fujitsu.com,
	Dan Williams <dan.j.williams@intel.com>,
	"H. Peter Anvin" <hpa@zytor.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	"x86@kernel.org" <x86@kernel.org>
Subject: Re: [PATCH v4 2/3] KASLR: Handle memory limit specified by memmap and mem option
Date: Wed, 10 May 2017 08:35:00 +0800	[thread overview]
Message-ID: <20170510003500.GE21870@x1> (raw)
In-Reply-To: <CAGXu5jLE-yAKPFJzD+Hi4dSmuSaDPybJd=iBe3Q05oXwoq7-Lg@mail.gmail.com>

On 05/09/17 at 10:39am, Kees Cook wrote:
> On Mon, May 8, 2017 at 10:57 PM, Baoquan He <bhe@redhat.com> wrote:
> > Option mem= will limit the max address a system can use and any memory
> > region above the limit will be removed.
> >
> > Furthermore, memmap=nn[KMG] which has no offset specified has the same
> > behaviour as mem=.
> >
> > KASLR needs to consider this when choosing the random position for
> > decompressing the kernel.
> >
> > This patch implements that.
> >
> > Signed-off-by: Baoquan He <bhe@redhat.com>
> > ---
> >  arch/x86/boot/compressed/kaslr.c | 69 +++++++++++++++++++++++++++++-----------
> >  1 file changed, 51 insertions(+), 18 deletions(-)
> >
> > diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
> > index 106e13b..0637e85 100644
> > --- a/arch/x86/boot/compressed/kaslr.c
> > +++ b/arch/x86/boot/compressed/kaslr.c
> > @@ -88,6 +88,10 @@ struct mem_vector {
> >  static bool memmap_too_large;
> >
> >
> > +/* Store memory limit specified by "mem=nn[KMG]" or "memmap=nn[KMG]" */
> > +unsigned long long mem_limit = ULLONG_MAX;
> > +
> > +
> >  enum mem_avoid_index {
> >         MEM_AVOID_ZO_RANGE = 0,
> >         MEM_AVOID_INITRD,
> > @@ -138,16 +142,24 @@ parse_memmap(char *p, unsigned long long *start, unsigned long long *size)
> >                 return -EINVAL;
> >
> >         switch (*p) {
> > -       case '@':
> > -               /* Skip this region, usable */
> > -               *start = 0;
> > -               *size = 0;
> > -               return 0;
> >         case '#':
> >         case '$':
> >         case '!':
> >                 *start = memparse(p + 1, &p);
> >                 return 0;
> > +       case '@':       /* Fall through: */
> > +               /*
> > +                * memmap=nn@ss specifies usable region, should be skipped
> > +                */
> > +               *size = 0;
> 
> The "fall through" comment should go here (where the break is "missing").

Ah, OK, will change and repost after patch 1/3 reviewing. Thanks a lot!

> 
> > +       default:
> > +               /*
> > +                * If w/o offset, only size specified, memmap=nn[KMG] has the
> > +                * same behaviour as mem=nn[KMG]. It limits the max address
> > +                * system can use. Region above the limit should be avoided.
> > +                */
> > +               *start = 0;
> > +               return 0;
> >         }
> >
> >         return -EINVAL;
> > @@ -173,9 +185,14 @@ static void mem_avoid_memmap(char *str)
> >                 if (rc < 0)
> >                         break;
> >                 str = k;
> > -               /* A usable region that should not be skipped */
> > -               if (size == 0)
> > +
> > +               if (start == 0) {
> > +                       /* Store the specified memory limit if size > 0 */
> > +                       if (size > 0)
> > +                               mem_limit = size;
> > +
> >                         continue;
> > +               }
> >
> >                 mem_avoid[MEM_AVOID_MEMMAP_BEGIN + i].start = start;
> >                 mem_avoid[MEM_AVOID_MEMMAP_BEGIN + i].size = size;
> > @@ -187,19 +204,15 @@ static void mem_avoid_memmap(char *str)
> >                 memmap_too_large = true;
> >  }
> >
> > -
> > -/*
> > - * handle_mem_memmap will also cover 'mem=' issue in next patch. Will remove
> > - * this note later.
> > - */
> >  static int handle_mem_memmap(void)
> >  {
> >         char *args = (char *)get_cmd_line_ptr();
> >         size_t len = strlen((char *)args);
> >         char *tmp_cmdline;
> >         char *param, *val;
> > +       u64 mem_size;
> >
> > -       if (!strstr(args, "memmap="))
> > +       if (!strstr(args, "memmap=") && !strstr(args, "mem="))
> >                 return 0;
> >
> >         tmp_cmdline = malloc(len + 1);
> > @@ -222,8 +235,20 @@ static int handle_mem_memmap(void)
> >                         return -1;
> >                 }
> >
> > -               if (!strcmp(param, "memmap"))
> > +               if (!strcmp(param, "memmap")) {
> >                         mem_avoid_memmap(val);
> > +               } else if (!strcmp(param, "mem")) {
> > +                       char *p = val;
> > +
> > +                       if (!strcmp(p, "nopentium"))
> > +                               continue;
> > +                       mem_size = memparse(p, &p);
> > +                       if (mem_size == 0) {
> > +                               free(tmp_cmdline);
> > +                               return -EINVAL;
> > +                       }
> > +                       mem_limit = mem_size;
> > +               }
> >         }
> >
> >         free(tmp_cmdline);
> > @@ -460,7 +485,8 @@ static void process_e820_entry(struct boot_e820_entry *entry,
> >  {
> >         struct mem_vector region, overlap;
> >         struct slot_area slot_area;
> > -       unsigned long start_orig;
> > +       unsigned long start_orig, end;
> > +       struct boot_e820_entry cur_entry;
> >
> >         /* Skip non-RAM entries. */
> >         if (entry->type != E820_TYPE_RAM)
> > @@ -474,8 +500,15 @@ static void process_e820_entry(struct boot_e820_entry *entry,
> >         if (entry->addr + entry->size < minimum)
> >                 return;
> >
> > -       region.start = entry->addr;
> > -       region.size = entry->size;
> > +       /* Ignore entries above memory limit */
> > +       end = min(entry->size + entry->addr, mem_limit);
> > +       if (entry->addr >= end)
> > +               return;
> > +       cur_entry.addr = entry->addr;
> > +       cur_entry.size = end - entry->addr;
> > +
> > +       region.start = cur_entry.addr;
> > +       region.size = cur_entry.size;
> >
> >         /* Give up if slot area array is full. */
> >         while (slot_area_index < MAX_SLOT_AREA) {
> > @@ -489,7 +522,7 @@ static void process_e820_entry(struct boot_e820_entry *entry,
> >                 region.start = ALIGN(region.start, CONFIG_PHYSICAL_ALIGN);
> >
> >                 /* Did we raise the address above this e820 region? */
> > -               if (region.start > entry->addr + entry->size)
> > +               if (region.start > cur_entry.addr + cur_entry.size)
> >                         return;
> >
> >                 /* Reduce size by any delta from the original address. */
> > --
> > 2.5.5
> >
> 
> Otherwise looks fine to me!
> 
> -Kees
> 
> -- 
> Kees Cook
> Pixel Security

  reply	other threads:[~2017-05-10  0:35 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-09  5:57 [PATCH v4 0/3] Handle memmap and mem kernel options in boot stage kaslr Baoquan He
2017-05-09  5:57 ` [PATCH v4 1/3] KASLR: Parse all memmap entries in cmdline Baoquan He
2017-05-10 12:29   ` Thomas Gleixner
2017-05-10 13:11     ` Baoquan He
2017-05-09  5:57 ` [PATCH v4 2/3] KASLR: Handle memory limit specified by memmap and mem option Baoquan He
2017-05-09 17:39   ` Kees Cook
2017-05-10  0:35     ` Baoquan He [this message]
2017-05-12  4:15   ` Masayoshi Mizuma
2017-05-12  5:06     ` Baoquan He
2017-05-09  5:57 ` [PATCH v4 3/3] Documentation/kernel-parameters.txt: Update 'memmap=' option description Baoquan He

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=20170510003500.GE21870@x1 \
    --to=bhe@redhat.com \
    --cc=dan.j.williams@intel.com \
    --cc=douly.fnst@cn.fujitsu.com \
    --cc=dyoung@redhat.com \
    --cc=hpa@zytor.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.