Index | Thread | Search

From:
Stuart Henderson <stu@spacehopper.org>
Subject:
Re: lang/polyml: fix (stupid because needless) W^X violation
To:
Daniel Dickman <didickman@gmail.com>
Cc:
ports@openbsd.org
Date:
Wed, 16 Jul 2025 02:46:15 +0100

Download raw body.

Thread
On 2025/07/15 20:51, Daniel Dickman wrote:
> 
> 
> On Wed, 16 Jul 2025, Stuart Henderson wrote:
> 
> > On 2025/07/15 19:35, Daniel Dickman wrote:
> > > Should ports not even try to do a runtime check in the first place?
> > 
> > I think these runtime checks are mainly for OS where the binary might
> > be compiled on a system with no W^X protection and then run on a system
> > with a kernel which enforces it (as long as it wasn't opted-out for the
> > binary..) and they don't seem to make much sense for OpenBSD to me.
> > 
> > On OpenBSD the possibilities (where a program deliberately tries to
> > make a W+X mapping and checks the return code like this) are:
> > 
> > - port forces W+X to be permitted (USE_WXNEEDED); binary run from
> >   wxallowed partition: test will succeed, program uses W+X and runs
> > 
> > - port forces W+X to be permitted (USE_WXNEEDED); binary run from
> >   !wxallowed partition: test will fail, program avoids W+X and runs
> > 
> > - port leaves W^X protection enabled; run with kern.wxabort=0; test
> >   will fail, program avoids W+X and runs
> > 
> > - port leaves W^X protection enabled; run with kern.wxabort=1; crash
> > 
> 
> I don't agree.
> 
> I could be wrong but I suspect most ports have support for only one 
> code-path not both. So it makes sense to use USE_WXNEEDED in those 
> other cases.
> 
> But this port includes support for running under either codepath:
> - W^X enabled
> - W^X disabled
> 
> The user's policy is detected at runtime and then the appropriate code 
> path is used.
> 
> Now we could hard-code this for PolyML at compile time and insist that all 
> PolyML users must ONLY run the W^X enabled code-path, even if they do not 
> have W^X set system-wide, but this seems like an odd choice so long as W^X 
> is not mandatory on OpenBSD.
> 
> > For a port which does not set USE_WXNEEDED 
> 
> We shouldn't set USE_WXNEEDED because we don't know until runtime what the 
> user's policy is.

Unless the binary is tagged as allowing W+X mappings (i.e. it has an
OPENBSD_WXNEEDED program header, as requested via '-z wxneeded' linker
flags, which is what USE_WXNEEDED sets), whatever the user sets
kern.wxabort to, and whether it's on a wxallowed filesystem or not,
they will not be using W+X.

If you want to give the user of packages a choice then you need to set
USE_WXNEEDED, and the majority of our users will then not be using W^X
for that binary (because the default is /usr/local wxallowed, as needed
for chromium etc).

> > then avoiding the runtime
> > check gives the most useful behaviour under both possibilities.
> 
> Avoiding the runtime check simply hard-codes one of the 2 supported code 
> paths.
> 
> Again, this is fine if we think that when a port supports both paths, we 
> should force the W^X path and not give the user an option.
> 
> I'll leave it to others to make a call on this because it's not really 
> something I care too much about. I'll only be running the port with W^X 
> enabled (which the current port correctly checks at run-time and goes down 
> the appropriate code path).

Upstream may support both paths, but it's not something where the port
can really give the user a choice (unless we want it to default to
disabling W^X and allow W+X mappings, and then the only way they can
choose at runtime is by removing wxallowed from the mount).

fwiw, we '#if 0'-out the similar test in libffi. Maybe others too.