public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
From: "Kaz Kylheku (libffi)" <382-725-6798@kylheku.com>
To: DJ Delorie <dj@redhat.com>
Cc: Jay K <jayk123@hotmail.com>,
	libffi-discuss@sourceware.org,
	Libffi-discuss
	<libffi-discuss-bounces+382-725-6798=kylheku.com@sourceware.org>
Subject: Re: is fork() supported?
Date: Tue, 24 Aug 2021 14:12:07 -0700	[thread overview]
Message-ID: <09e0d2b62f62482b2fa1c29120a43078@mail.kylheku.com> (raw)
In-Reply-To: <xnczq24r6x.fsf@greed.delorie.com>

On 2021-08-24 11:45, DJ Delorie via Libffi-discuss wrote:
> Jay K <jayk123@hotmail.com> writes:
>> 1 Sorry, I assumed mail from DJ was about djgpp, and that context was
>> lacking in libffi. My mistake.
> 
> Ha!  Yeah, not about djgpp, which I think "just works" ;-)
> 
>> 3 So libffi no longer has read/write/execute memory, or turns
>> read/write into execute, correct?
> 
> The problem case is when libffi can't mmap a chunk of write+exec 
> memory,
> and resorts to writing to a file and mapping the file read+exec, which
> happens in Linux with certain selinux security profiles.

Isn't there some way way set up two anonymous, virtual regions such that
they alias to the same frames? One can be read+exec, and the other 
write.

I could easily write code in the kernel to take some user space pages
of the calling process and make them also appear somewhere else in
the address space.

I don't see anything like that in the Linux mmap among any of the flags
and whatnot.

It would be a useful extension.

Imagine a MAP_ALIAS flag, which requires the void *addr argument to be
present. addr, normally used with MAP_FIXED, in this case would specify
the virtual address of the target range to be aliased by the returned
mapping.

Being able to obtain a writable alias of executable space is
a security risk though: the risk that an attacker can inject a mmap
call to create an writable alias of executable space.
Some new PROT_* bit could help mitigate: the read+exec mapping would 
have
this bit to indicate that such aliasing of it is permitted.
Mappings like shared libs and executables would not have this bit,
only libffi's closure buffer.

(Attackers who can call mmap to obtain a writable mapping could
arguably perpetrate the same workaround as libffi: write to a file
and then read+exec map it. So why worry about this too much.)

Summary:

   /* new flags + kernel support */
   #define MAP_ALIAS        ...
   #define PROT_ALIAS_OK ...

   void *closures = mmap(NULL, len,
                         PROT_READ | PROT_EXEC | PROT_ALIAS_OK,
                         MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);

   void *write_closures = mmap(closures, len,
                               PROT_WRITE,
                               MAP_ALIAS | MAP_PRIVATE, -1, 0);


Write closures through write_closures pointer, execute via
closures pointer.

The kernel code for MAP_ALIAS has to ensure that fork
observes this linkage. That is tricky. The child process gets
its own copy of this memory, and the two aliased views of it.
The views cannot just be subject to independent COW because
their aliasing relationship will break.

One more detail: mprotect should disallow PROT_ALIAS_OK.
Only the original mmap must be able to specify PROT_ALIAS_OK,
which is then a mapping's immutable flag.

  reply	other threads:[~2021-08-24 21:12 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-04 20:00 DJ Delorie
2021-08-05  8:17 ` Andrew Haley
2021-08-05  8:27   ` Florian Weimer
2021-08-24 18:15     ` DJ Delorie
2021-08-24 18:27       ` Jay K
2021-08-24 18:45         ` DJ Delorie
2021-08-24 21:12           ` Kaz Kylheku (libffi) [this message]
2021-08-24 21:58             ` Jay K
2021-08-25  9:27               ` Andrew Haley
2021-08-25 15:58                 ` Jay K
2021-08-25 16:59                 ` Kaz Kylheku (libffi)
2021-08-25 21:17                   ` Andrew Haley
2021-08-05 18:13   ` DJ Delorie
2021-08-05 21:21     ` Jay K
2021-08-06  8:32       ` Andrew Haley

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=09e0d2b62f62482b2fa1c29120a43078@mail.kylheku.com \
    --to=382-725-6798@kylheku.com \
    --cc=dj@redhat.com \
    --cc=jayk123@hotmail.com \
    --cc=libffi-discuss-bounces+382-725-6798=kylheku.com@sourceware.org \
    --cc=libffi-discuss@sourceware.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 read-only IMAP folder(s) and NNTP newsgroup(s).