tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: PAX mprotect and JIT



> Date: Mon, 27 Feb 2017 03:17:15 +0000 (UTC)
> From: christos%astron.com@localhost (Christos Zoulas)
> 
> In article <20170226213704.DED726038D%jupiter.mumble.net@localhost>,
> Taylor R Campbell  <campbell+netbsd-tech-kern%mumble.net@localhost> wrote:
> >
> >The idiom I imagine is something like:
> >
> >	void *buf = mmap(NULL, len, PROT_READ|PROT_WRITE|PROT_EXEC,
> >	    MAP_ANON|MAP_REMAPDUP, -1, 0);
> 
> This is never allowed (rwx).

What I meant is that mmap(..., maxprot, ...|MAP_REMAPDUP, ...) would

(a) enable the backing object to be dupable,

(b) allow any dup'd mapping to use at most the bits in maxprot, and

(c) return a mapping using only as many bits of maxprot as are allowed
for a mapping under W^X, preferring PROT_WRITE over PROT_EXEC -- if
maxprot includes PROT_WRITE|PROT_EXEC, then this mapping would allow
only PROT_WRITE.

Thus, the first call to mmap(PROT_READ|PROT_WRITE|PROT_EXEC) would
return a mapping with PROT_READ|PROT_WRITE, which you can dup and
mprotect to be any of 0, PROT_READ, PROT_READ|PROT_EXEC, or PROT_EXEC.
To get an executable mapping we mremap it to get a dup'd mapping and
mprotect the dup'd mapping to PROT_EXEC.

> Why not:
> 
> 	void *buf = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0);
> 	void *ip = mmap(buf, len, PROT_READ|PROT_EXEC, MAP_DUP, -1, 0);
> 	/* update buf with modified instructions */

I don't think the mapping should be dup'able unless you specify that
up front, and I'm inclined to think that as joerg suggested dup'd
mappings should not be allowed to have prot bits beyond what were
specified for the original mapping.

Certainly mprotect refuses to add prot bits that were not included in
the original call to mmap.

Here are the desiderata I am suggesting:

1. Semantics and attack surface of existing uses of mmap should not
change: should not enable dup, should not enable mprotect upgrades,
&c.  Any new features should depend on explicitly setting MAP_REMAPDUP
in the original call to mmap for any mapping.

2. User should be able to specify maxprot of the mapping and all dup'd
mappings in the original call to mmap.  Thus, a user can specify,
e.g., PROT_READ|PROT_WRITE as maxprot for a mapping from the
beginning, and neither that mapping nor any dup'd one can have
PROT_EXEC added.


Home | Main Index | Thread Index | Old Index