kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Eric Blake <eblake@redhat.com>
To: Warner Losh <imp@bsdimp.com>
Cc: "Philippe Mathieu-Daudé" <philmd@redhat.com>,
	kvm-devel <kvm@vger.kernel.org>,
	"Kyle Evans" <kevans@freebsd.org>,
	"QEMU Developers" <qemu-devel@nongnu.org>,
	qemu-arm <qemu-arm@nongnu.org>, qemu-ppc <qemu-ppc@nongnu.org>,
	"Gerd Hoffmann" <kraxel@redhat.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Alex Bennée" <alex.bennee@linaro.org>
Subject: Re: [PATCH v2 4/9] bsd-user/syscall: Replace alloca() by g_new()
Date: Thu, 6 May 2021 10:12:27 -0500	[thread overview]
Message-ID: <7a96d45e-2bdc-f699-96f7-3fbf607cb06b@redhat.com> (raw)
In-Reply-To: <CANCZdfqW0XTa18F+JxuSnhpictWxVJUsu87c=yAwMp6YT60FMg@mail.gmail.com>

On 5/6/21 9:55 AM, Warner Losh wrote:

>>> Where is this freed? Also, alloca just moves a stack pointer, where
>> malloc
>>> has complex interactions. Are you sure that's a safe change here?
>>
>> It's freed any time the g_autofree variable goes out of scope (that's
>> what the g_autofree macro is for).  Yes, the change is safe, although
>> you are right that switching to malloc is going to be a bit more
>> heavyweight than what alloca used.  What's more, it adds safety: if
>> count was under user control, a user could pass a value that could cause
>> alloca to allocate more than 4k and accidentally mess up stack guard
>> pages, while malloc() uses the heap and therefore cannot cause stack bugs.
>>
> 
> I'm not sure I understand that argument, since we're not compiling bsd-user
> with the stack-smash-protection stuff enabled, so there's no guard pages
> involved. The stack can grow quite large and the unmapped page at
> the end of the stack would catch any overflows. Since these allocations
> are on the top of the stack, they won't overflow into any other frames
> and subsequent calls are made with them already in place.

With alloca() on user-controlled size, the user can set up the size to
be larger than the unmapped guard page, at which point you CANNOT catch
the stack overflow because the alloca can skip the guard page and wrap
into other valid memory.  Compiling with stack-smash-protection stuff
enabled will catch such a bad alloca(); but the issue at hand here is
not when stack-smash-protection is enabled, but the more common case
when it is disabled (at which point the only protection you have is the
guard page, but improper use of alloca() can bypass the guard page).
Not all alloca() arguments are under user control, but it is easier as a
matter of policy to blindly avoid alloca() than it is to audit which
calls have safe sizes and therefore will not risk user control bypassing
stack guards.

> 
> malloc, on the other hand, involves taking out a number of mutexes
> and similar things to obtain the memory, which may not necessarily
> be safe in all the contexts system calls can be called from. System
> calls are, typically, async safe and can be called from signal handlers.
> alloca() is async safe, while malloc() is not. So changing the calls
> from alloca to malloc makes calls to system calls in signal handlers
> unsafe and potentially introducing buggy behavior as a result.

Correct, use of malloc() is not safe within signal handlers. But these
calls are not within signal handlers - or am _I_ missing something?  Is
the point of *-user code to emulate syscalls that are reachable from
code installed in a signal handler, at which point introducing an
async-unsafe call to malloc in our emulation is indeed putting the
application at risk of a malloc deadlock?

Ultimately, we're trading one maintenance headache (determining which
alloca() size calls might be under user control) for another
(determining that malloca() calls are not in a signal context), but the
latter is far more common such that we can use existing tooling to make
that conversion safely (both in the fact that the compiler has flags to
warn about alloca() usage, and in the fact that Coverity is good at
flagging improper uses of malloc() such as within a function reachable
from something installed in a signal handler).  But I'm not familiar
enough with the bsd/linux-user code to know if your point about having
to use only async-safe functionalities is a valid limitation on our
emulation.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org


  parent reply	other threads:[~2021-05-06 15:12 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-06 13:37 [PATCH v2 0/9] misc: Replace alloca() by g_malloc() Philippe Mathieu-Daudé
2021-05-06 13:37 ` [PATCH v2 1/9] audio/alsaaudio: Replace ALSA alloca() by malloc() equivalent Philippe Mathieu-Daudé
2021-05-06 13:37 ` [PATCH v2 2/9] backends/tpm: Replace qemu_mutex_lock calls with QEMU_LOCK_GUARD Philippe Mathieu-Daudé
2021-05-06 14:46   ` Stefan Berger
2021-05-06 15:07   ` Christophe de Dinechin
2021-05-06 13:37 ` [PATCH v2 3/9] backends/tpm: Replace g_alloca() by g_malloc() Philippe Mathieu-Daudé
2021-05-06 14:46   ` Stefan Berger
2021-05-06 13:37 ` [PATCH v2 4/9] bsd-user/syscall: Replace alloca() by g_new() Philippe Mathieu-Daudé
     [not found]   ` <CANCZdfoJWEbPFvZ0605riUfnpVRAeC6Feem5_ahC7FUfO71-AA@mail.gmail.com>
2021-05-06 14:20     ` Peter Maydell
     [not found]       ` <CANCZdfpXjDECHmZq55zP43g32OVhnfjf9W+ERtPMFeDs2MmvXQ@mail.gmail.com>
2021-05-06 14:57         ` Philippe Mathieu-Daudé
2021-05-06 14:25     ` Eric Blake
     [not found]       ` <CANCZdfqW0XTa18F+JxuSnhpictWxVJUsu87c=yAwMp6YT60FMg@mail.gmail.com>
2021-05-06 15:12         ` Eric Blake [this message]
     [not found]           ` <CANCZdfrcv9ZUcBv7z+z3JPCjy0uzzY07VLmC4dqr5r8ba_QPLw@mail.gmail.com>
2021-05-06 15:42             ` Eric Blake
2021-05-06 16:03               ` Peter Maydell
2021-05-06 15:58         ` Peter Maydell
2021-05-06 13:37 ` [PATCH v2 5/9] gdbstub: Constify GdbCmdParseEntry Philippe Mathieu-Daudé
2021-05-06 13:37 ` [PATCH v2 6/9] gdbstub: Only call cmd_parse_params() with non-NULL command schema Philippe Mathieu-Daudé
2021-05-06 19:21   ` Alex Bennée
2021-05-06 13:37 ` [PATCH v2 7/9] gdbstub: Replace alloca() + memset(0) by g_new0() Philippe Mathieu-Daudé
2021-05-06 19:22   ` Alex Bennée
2021-05-06 13:37 ` [PATCH v2 8/9] hw/misc/pca9552: Replace g_newa() by g_new() Philippe Mathieu-Daudé
2021-05-06 13:37 ` [PATCH v2 9/9] target/ppc/kvm: Replace alloca() by g_malloc() Philippe Mathieu-Daudé
2021-05-06 14:45   ` Greg Kurz
2021-05-07  1:05   ` David Gibson
     [not found] ` <CANCZdfqiHxQoG+g3bq_KL01yWCHUbF5qxJWN=sD37h7UJFMZ7g@mail.gmail.com>
2021-05-06 14:28   ` [PATCH v2 0/9] misc: " Eric Blake

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=7a96d45e-2bdc-f699-96f7-3fbf607cb06b@redhat.com \
    --to=eblake@redhat.com \
    --cc=alex.bennee@linaro.org \
    --cc=imp@bsdimp.com \
    --cc=kevans@freebsd.org \
    --cc=kraxel@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=philmd@redhat.com \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@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).