Dave Voutila <dv@sisu.io> wrote:
> Have you considered a libexec approach instead? If the goal is to keep a
> child process having only the executable pages it needs for operations,
> why not split up the program design instead of mucking with ELF stuff?
> That surely has to be even more portable.
I have. There are other reasons for preferring a single static binary. I
agree that playing with ELF sections is problematic. But, on most
systems I use, this works. It's no worse than assumptions made for GC,
dynamic code generation, or fibers on most platforms. Of course, like
each of these assumptions, it's not guaranteed and, as with what
happened with 7.3, is likely to go away at any time.
It's fine. I have plenty of kernel patches I use on most OSes. I'll
probably just flesh this one out with its own system call and
alternative mode for ld.so. I just figured it was useful to point out
that at least one person is using this pattern.
- Justin
On Fri, Jun 30, 2023 at 8:03 AM Dave Voutila <dv@sisu.io> wrote:
>
>
> Justin Handville <nanolith@gmail.com> writes:
>
> > I'm assuming that misc@ is probably the best place for this e-mail,
> > although it gets a bit in the tech@ weeds. I upgraded to 7.3 not so
> > long ago, and I noticed that a daemon I had written was no longer
> > working properly. For reasons that are probably too much to get into
> > here, I statically link the daemon. It's a single binary that makes use
> > of pledge / unveil, and privilege separation. This all works fine. It
> > also has another trick, which unfortunately no longer works in 7.3.
> >
> > To reduce the code footprint of this daemon as well as the potential
> > gadget attack surface, I have it drop any code that it will no longer
> > execute. This happens after fork / exec on a child, and also after
> > initialization code executes before the child process enters its steady
> > state. This is trivially done by grouping functions into custom page
> > aligned sections in the ELF binary, and running mprotect on these
> > sections with PROT_NONE. I considered munmap as well as other tricks,
> > but so far, this seems to be the most portable way to handle this trick
> > that I could think of between BSD and Linux. I'm sure others are more
> > clever. It's a cheap defense in depth protection that simplifies my use
> > case.
>
> Have you considered a libexec approach instead? If the goal is to keep a
> child process having only the executable pages it needs for operations,
> why not split up the program design instead of mucking with ELF stuff?
> That surely has to be even more portable.
>
> >
> > As of OpenBSD 7.3, when the immutable flag entered mainstream, this
> > trick no longer works. Given that my trick is a total hack, I'm not too
> > broken up about it. Of course, this change led me to doing some poking
> > around.
> >
> > I noticed that in sys/uvm/uvm_map.c, an exception was granted to allow
> > Chrome to drop the write flag for a region for userland compatibility.
> > That makes sense as a temporary measure. I'm wondering, however, if it
> > might not make sense to think about this functionality differently.
> > Instead of immutable memory regions, why can't we consider a more
> > pledge-like ratcheting for memory regions, where bits can be removed,
> > but never added back? How does this impact the gadget attack surface
> > that led to the immutable flag being considered to begin with?
> >
> > For the time being, I extended the exception in uvm_map.c on my own
> > OpenBSD systems to allow immutable regions to be stripped of all
> > protection flags with a call to mprotect. So, in addition to allowing RW
> > to R, if the region is any combination of PROT_READ, PROT_WRITE, or
> > PROT_EXEC, then it can be reduced to PROT_NONE. This seemed the safer
> > option for patching for now. Of course, this further breaks the
> > definition of "immutable", but at least immutable regions can only have
> > protection bits removed.
> >
> > My reason for mailing misc@ is just to bring up this data point from a
> > single user. I'm certain that the OpenBSD developers have reasons for
> > preferring a pure immutable flag, but having a mechanism for ratcheting
> > down protections is useful at least for me, and is apparently useful
> > enough in userland going from RW to R, that an exception was carved out
> > for now. Of course, I'm more than happy to work with the developers to
> > come up with a plan for upstreaming this feature if it's something
> > useful. If not, I have no problem adding it to my personal list of
> > patches I maintain that I doubt anyone else would want or need.
> >
> > - Justin
No comments:
Post a Comment