qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: Jack Schwartz <jack.schwartz@oracle.com>
Cc: qemu-devel@nongnu.org, qemu-stable@nongnu.org,
	anatol.pomozov@gmail.com, ppandit@redhat.com
Subject: Re: [Qemu-devel] [PATCH 1/5] multiboot: Reject kernels exceeding the address space
Date: Thu, 15 Mar 2018 18:18:11 +0100	[thread overview]
Message-ID: <20180315171811.GF3876@localhost.localdomain> (raw)
In-Reply-To: <821bfa6e-9ad5-f486-49a1-f306696992ec@oracle.com>

Am 15.03.2018 um 17:55 hat Jack Schwartz geschrieben:
> On 03/15/18 08:54, Kevin Wolf wrote:
> > Am 15.03.2018 um 06:19 hat Jack Schwartz geschrieben:
> > > Hi Kevin.
> > > 
> > > My comments are inline...
> > > 
> > > On 2018-03-14 10:32, Kevin Wolf wrote:
> > > > The code path with a manually set mh_load_addr in the Multiboot header
> > > > checks that load_end_addr <= load_addr, but the path where load_end_addr
> > > > is automatically detected if 0 is given in the header misses the
> > > > corresponding check.
> > > 1) The code checks that load_end_addr >= load_addr (before letting it
> > > through).
> > > 
> > > 2) load_end_addr is used only when it is read in as non-zero, so no check is
> > > needed if zero.  (It gets debug-printed even when zero, but is used only to
> > > calculate mb_load_size and only when non-zero.)
> > Oops, good point. I'll change the start of the commit message as follows:
> > 
> >      The code path with a manually set mh_load_end_addr in the Multiboot
> >      header checks that mh_load_end_addr >= mh_load_addr, but the path where
> >      mh_load_end_addr is 0 in the header and therefore automatically
> >      calculated from the file size misses the corresponding check.
> > 
> > Does this look better?
> 
> mb_load_size is calculated from the file size, not mh_load_end_addr, so
> I think you mean mb_load_size rather than mh_load_end_addr.  Do you intend
> to say:
> 
>   The code path where mh_load_end_addr is non-zero in the Multiboot
>   header checks that mh_load_end_addr >= mh_load_addr and so
>   mb_load_size ischecked.  However, mb_load_size is not checked when
>   calculated from thefile size, when mh_load_end_addr is 0.

Ok, technically that's more accurate.

> Also, if this is what you intend to say, would the following code change be
> more ofwhat you want:
> 
> Remove this:
> 
>             mb_load_size = kernel_file_size - mb_kernel_text_offset;
>         }
> -       if (mb_load_size > UINT32_MAX - mh_load_addr) {
> -           error_report("kernel does not fit in address space");
> -           exit(1);
> -       }
>         if (mh_bss_end_addr) {
> 
> and instead do this a few lines further down:
> 
>            mb_kernel_size = mh_bss_end_addr - mh_load_addr;
>         } else {
>             mb_kernel_size = mb_load_size;
>         }
> 
> +       if (mb_kernel_size > UINT32_MAX - mh_load_addr) {
> +           error_report("kernel does not fit in address space");
> +           exit(1);
> +       }
> 
>         mb_debug("multiboot: header_addr = %#x", mh_header_addr);
>         mb_debug("multiboot: load_addr = %#x", mh_load_addr);
> 
> The reason would be to include the bss area in the calculation, when
> mh_bss_end_addr is non-zero.

Ultimately, mb_load_size > mb_kernel_size is what kills us, so maybe we
could add an assertion for that.

But the reason why this condition could ever be true is the integer
overflow in this line:

    if (mh_bss_end_addr < (mh_load_addr + mb_load_size))

It's generally better to check for integer overflows before they happen
than trying to infer them from the result. In fact, your condition
wouldn't catch the error of test scenario 9:

    kernel_file_size        = 0x2035
    mh_header_addr          = 0xfffff000
    mh_load_addr            = 0xfffff000
    mh_load_end_addr        = 0
    mh_bss_end_addr         = 0xfffff001

    mb_kernel_text_offset   = i - (mh_header_addr - mh_load_addr)
                            = 0

    mb_load_size            = kernel_file_size - mb_kernel_text_offset
                            = 0x2035
                            > UINT32_MAX - mh_load_addr

    mb_kernel_size          = mh_bss_end_addr - mh_load_addr
                            = 1
                            < UINT32_MAX - mh_load_addr

Kevin

  reply	other threads:[~2018-03-15 17:18 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-14 17:32 [Qemu-devel] [PATCH 0/5] multiboot: Fix buffer overflow on invalid kernels Kevin Wolf
2018-03-14 17:32 ` [Qemu-devel] [PATCH 1/5] multiboot: Reject kernels exceeding the address space Kevin Wolf
2018-03-15  5:19   ` Jack Schwartz
2018-03-15 15:54     ` Kevin Wolf
2018-03-15 16:55       ` Jack Schwartz
2018-03-15 17:18         ` Kevin Wolf [this message]
2018-03-15 19:50           ` Jack Schwartz
2018-03-14 17:32 ` [Qemu-devel] [PATCH 2/5] multiboot: Check validity of mh_header_addr Kevin Wolf
2018-03-14 17:32 ` [Qemu-devel] [PATCH 3/5] tests/multiboot: Test exit code for every qemu run Kevin Wolf
2018-03-14 17:32 ` [Qemu-devel] [PATCH 4/5] tests/multiboot: Add tests for the a.out kludge Kevin Wolf
2018-03-14 17:32 ` [Qemu-devel] [PATCH 5/5] tests/multiboot: Add .gitignore Kevin Wolf
2018-03-14 17:43   ` Eric Blake
2018-03-14 17:50     ` Eric Blake
2018-03-15  5:19 ` [Qemu-devel] [PATCH 0/5] multiboot: Fix buffer overflow on invalid kernels Jack Schwartz

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=20180315171811.GF3876@localhost.localdomain \
    --to=kwolf@redhat.com \
    --cc=anatol.pomozov@gmail.com \
    --cc=jack.schwartz@oracle.com \
    --cc=ppandit@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-stable@nongnu.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;
as well as URLs for NNTP newsgroup(s).