Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

Started by Andres Freundover 4 years ago34 messageshackers
Jump to latest
#1Andres Freund
andres@anarazel.de

Hi,

When testing EXEC_BACKEND on linux I see occasional test failures as long as I
don't disable ASLR. There's a code comment to that effect:

* If testing EXEC_BACKEND on Linux, you should run this as root before
* starting the postmaster:
*
* echo 0 >/proc/sys/kernel/randomize_va_space

but I don't like doing that on a system wide basis.

Linux allows disabling ASLR on a per-process basis using
personality(ADDR_NO_RANDOMIZE). There's a wrapper binary to do that as well,
setarch --addr-no-randomize.

I was wondering if we should have postmaster do personality(ADDR_NO_RANDOMIZE)
for EXEC_BACKEND builds? It seems nicer to make it automatically work than
have people remember that they need to call "setarch --addr-no-randomize make check".

Not that it actually matters for EXEC_BACKEND, but theoretically doing
personality(ADDR_NO_RANDOMIZE) in postmaster is a tad more secure than doing
it via setarch, as in the personality() case postmaster's layout itself is
still randomized...

Or perhaps we should just add a comment mentioning setarch.

Greetings,

Andres Freund

#2Andrew Dunstan
andrew@dunslane.net
In reply to: Andres Freund (#1)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

On 8/5/21 11:29 PM, Andres Freund wrote:

Hi,

When testing EXEC_BACKEND on linux I see occasional test failures as long as I
don't disable ASLR. There's a code comment to that effect:

* If testing EXEC_BACKEND on Linux, you should run this as root before
* starting the postmaster:
*
* echo 0 >/proc/sys/kernel/randomize_va_space

but I don't like doing that on a system wide basis.

Linux allows disabling ASLR on a per-process basis using
personality(ADDR_NO_RANDOMIZE). There's a wrapper binary to do that as well,
setarch --addr-no-randomize.

I was wondering if we should have postmaster do personality(ADDR_NO_RANDOMIZE)
for EXEC_BACKEND builds? It seems nicer to make it automatically work than
have people remember that they need to call "setarch --addr-no-randomize make check".

Not that it actually matters for EXEC_BACKEND, but theoretically doing
personality(ADDR_NO_RANDOMIZE) in postmaster is a tad more secure than doing
it via setarch, as in the personality() case postmaster's layout itself is
still randomized...

Or perhaps we should just add a comment mentioning setarch.

If we can set it conveniently then that seems worth doing.

(Thinks: do we have non-Windows buildfarm members doing EXEC_BACKEND?)

cheers

andrew

--
Andrew Dunstan
EDB: https://www.enterprisedb.com

#3Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Andrew Dunstan (#2)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

On 2021-Aug-06, Andrew Dunstan wrote:

On 8/5/21 11:29 PM, Andres Freund wrote:

I was wondering if we should have postmaster do personality(ADDR_NO_RANDOMIZE)
for EXEC_BACKEND builds? It seems nicer to make it automatically work than
have people remember that they need to call "setarch --addr-no-randomize make check".

How common is to get a failure? I know I've run tests under
EXEC_BACKEND and not seen any failures. Not many runs though.

Not that it actually matters for EXEC_BACKEND, but theoretically doing
personality(ADDR_NO_RANDOMIZE) in postmaster is a tad more secure than doing
it via setarch, as in the personality() case postmaster's layout itself is
still randomized...

True. I think the security aspect is not critically important, since
hopefully nobody should be using such builds for production.

(Thinks: do we have non-Windows buildfarm members doing EXEC_BACKEND?)

culicidae does that.

--
Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/
"Pido que me den el Nobel por razones humanitarias" (Nicanor Parra)

#4Robert Haas
robertmhaas@gmail.com
In reply to: Alvaro Herrera (#3)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

On Mon, Aug 9, 2021 at 1:30 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:

How common is to get a failure? I know I've run tests under
EXEC_BACKEND and not seen any failures. Not many runs though.

On macOS, failures are extremely common. Sometimes I have to run
simple tests many times to get even one success. The proposal on the
table won't help with that problem since it's Linux-specific, but if
there's any way to do something similar on macOS it would be a _huge_
help.

--
Robert Haas
EDB: http://www.enterprisedb.com

#5Andres Freund
andres@anarazel.de
In reply to: Robert Haas (#4)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

Hi,

On 2021-08-09 13:43:03 -0400, Robert Haas wrote:

On Mon, Aug 9, 2021 at 1:30 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:

How common is to get a failure? I know I've run tests under
EXEC_BACKEND and not seen any failures. Not many runs though.

I get check-world failures in about 1/2-1/3 of the runs, and a plain check
fails in maybe 1/4 of the cases. It's pretty annoying because it often isn't
trivial to distinguish whether I've broken something or whether it's
randomization related...

The frequency of failures isn't stable over time, making it a bit harder to
know what's going on.

On macOS, failures are extremely common. Sometimes I have to run
simple tests many times to get even one success. The proposal on the
table won't help with that problem since it's Linux-specific, but if
there's any way to do something similar on macOS it would be a _huge_
help.

There does seem to be a way of doing so, because I found blog posts talking
about how to get e.g. lldb to *enable* ASLR, which it disables by default...

Greetings,

Andres Freund

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#5)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

Andres Freund <andres@anarazel.de> writes:

On 2021-08-09 13:43:03 -0400, Robert Haas wrote:

On Mon, Aug 9, 2021 at 1:30 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:

How common is to get a failure? I know I've run tests under
EXEC_BACKEND and not seen any failures. Not many runs though.

I get check-world failures in about 1/2-1/3 of the runs, and a plain check
fails in maybe 1/4 of the cases. It's pretty annoying because it often isn't
trivial to distinguish whether I've broken something or whether it's
randomization related...

I don't have numbers, but I do know that on Linux EXEC_BACKEND builds fail
often enough to be annoying if you don't disable ASLR. If we can do
something not-too-invasive about that, it'd be great.

regards, tom lane

#7Andres Freund
andres@anarazel.de
In reply to: Tom Lane (#6)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

Hi,

On 2021-08-09 13:54:25 -0400, Tom Lane wrote:

Andres Freund <andres@anarazel.de> writes:

On 2021-08-09 13:43:03 -0400, Robert Haas wrote:

On Mon, Aug 9, 2021 at 1:30 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:

How common is to get a failure? I know I've run tests under
EXEC_BACKEND and not seen any failures. Not many runs though.

I get check-world failures in about 1/2-1/3 of the runs, and a plain check
fails in maybe 1/4 of the cases. It's pretty annoying because it often isn't
trivial to distinguish whether I've broken something or whether it's
randomization related...

I don't have numbers, but I do know that on Linux EXEC_BACKEND builds fail
often enough to be annoying if you don't disable ASLR. If we can do
something not-too-invasive about that, it'd be great.

I now not sure if personality(NO_RANDOMIZE) in postmaster is actually
sufficient. It does seem to drastically reduce the frequency of issues, but
there's still conceivable failures where postmaster's layout would class with
the non-randomized children - obviously personality(NO_RANDOMIZE) cannot
retroactively change the layout of the already running binary.

So maybe we should put it into pg_ctl?

Greetings,

Andres Freund

#8Thomas Munro
thomas.munro@gmail.com
In reply to: Robert Haas (#4)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

On Tue, Aug 10, 2021 at 5:43 AM Robert Haas <robertmhaas@gmail.com> wrote:

On Mon, Aug 9, 2021 at 1:30 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:

How common is to get a failure? I know I've run tests under
EXEC_BACKEND and not seen any failures. Not many runs though.

On macOS, failures are extremely common. Sometimes I have to run
simple tests many times to get even one success. The proposal on the
table won't help with that problem since it's Linux-specific, but if
there's any way to do something similar on macOS it would be a _huge_
help.

Yeah, make check always fails for me on macOS 11. With the attached
experimental hack, it fails only occasionally (1 in 8 runs or so). I
don't know why.

Attachments:

0001-Try-to-make-EXEC_BACKEND-more-convenient-on-macOS.patchapplication/x-patch; name=0001-Try-to-make-EXEC_BACKEND-more-convenient-on-macOS.patchDownload+83-3
#9Andres Freund
andres@anarazel.de
In reply to: Thomas Munro (#8)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

Hi,

On Tue, Aug 10, 2021, at 15:19, Thomas Munro wrote:

On Tue, Aug 10, 2021 at 5:43 AM Robert Haas <robertmhaas@gmail.com> wrote:

On Mon, Aug 9, 2021 at 1:30 PM Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:

How common is to get a failure? I know I've run tests under
EXEC_BACKEND and not seen any failures. Not many runs though.

On macOS, failures are extremely common. Sometimes I have to run
simple tests many times to get even one success. The proposal on the
table won't help with that problem since it's Linux-specific, but if
there's any way to do something similar on macOS it would be a _huge_
help.

Yeah, make check always fails for me on macOS 11. With the attached
experimental hack, it fails only occasionally (1 in 8 runs or so). I
don't know why.

I suspect you'd need to use the hack in pg_ctl to make it reliable. The layout of normally stayed position independent postmaster can be incompatible with the non ASLR spawned child.

Andres

#10Thomas Munro
thomas.munro@gmail.com
In reply to: Andres Freund (#9)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

On Wed, Aug 11, 2021 at 2:12 AM Andres Freund <andres@anarazel.de> wrote:

On Tue, Aug 10, 2021, at 15:19, Thomas Munro wrote:

Yeah, make check always fails for me on macOS 11. With the attached
experimental hack, it fails only occasionally (1 in 8 runs or so). I
don't know why.

I suspect you'd need to use the hack in pg_ctl to make it reliable. The layout of normally stayed position independent postmaster can be incompatible with the non ASLR spawned child.

Yeah, but the patch already changes both pg_ctl.c and postmaster.c.

#11Thomas Munro
thomas.munro@gmail.com
In reply to: Thomas Munro (#10)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

On Wed, Aug 11, 2021 at 7:07 AM Thomas Munro <thomas.munro@gmail.com> wrote:

On Wed, Aug 11, 2021 at 2:12 AM Andres Freund <andres@anarazel.de> wrote:

On Tue, Aug 10, 2021, at 15:19, Thomas Munro wrote:

Yeah, make check always fails for me on macOS 11. With the attached
experimental hack, it fails only occasionally (1 in 8 runs or so). I
don't know why.

I suspect you'd need to use the hack in pg_ctl to make it reliable. The layout of normally stayed position independent postmaster can be incompatible with the non ASLR spawned child.

Yeah, but the patch already changes both pg_ctl.c and postmaster.c.

/me stares at vmmap output for a while

Oooh. It's working perfectly (for example if you export
PATH=binarys:$PATH, pg_ctl -D pgdata start, make installcheck), but
pg_regress.c has its own separate fork/exec to launch the temporary
cluster that needs to be similarly hacked. Unfortunately I have to
give this Macintosh back and go and do some real work on a different
computer now. That does seem to be a working solution to the problem,
though, and could be polished into proposable form.

I saw claims that you can also link with -Wl,-no_pie or toggle the PIE
bit on your executable and libraries, but that didn't work for me on
11, Intel (no effect) or ARM (linker option gone).

#12Andrew Dunstan
andrew@dunslane.net
In reply to: Thomas Munro (#11)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

On 8/10/21 7:59 PM, Thomas Munro wrote:

On Wed, Aug 11, 2021 at 7:07 AM Thomas Munro <thomas.munro@gmail.com> wrote:

On Wed, Aug 11, 2021 at 2:12 AM Andres Freund <andres@anarazel.de> wrote:

On Tue, Aug 10, 2021, at 15:19, Thomas Munro wrote:

Yeah, make check always fails for me on macOS 11. With the attached
experimental hack, it fails only occasionally (1 in 8 runs or so). I
don't know why.

I suspect you'd need to use the hack in pg_ctl to make it reliable. The layout of normally stayed position independent postmaster can be incompatible with the non ASLR spawned child.

Yeah, but the patch already changes both pg_ctl.c and postmaster.c.

/me stares at vmmap output for a while

Oooh. It's working perfectly (for example if you export
PATH=binarys:$PATH, pg_ctl -D pgdata start, make installcheck), but
pg_regress.c has its own separate fork/exec to launch the temporary
cluster that needs to be similarly hacked.

initdb also runs postgres a bunch of times via system(), similarly to
pg_regress but without the "exec". Does it also need adjusting?

cheers

andrew

--
Andrew Dunstan
EDB: https://www.enterprisedb.com

#13Robert Haas
robertmhaas@gmail.com
In reply to: Thomas Munro (#11)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

On Tue, Aug 10, 2021 at 7:59 PM Thomas Munro <thomas.munro@gmail.com> wrote:

I saw claims that you can also link with -Wl,-no_pie or toggle the PIE
bit on your executable and libraries, but that didn't work for me on
11, Intel (no effect) or ARM (linker option gone).

I think that worked for me on older macOS releases, and then it
stopped working at some point after some update or reinstall or
something. Unfortunately I don't know any more precisely than that,
but it does seem like we have to find some other approach to work on
modern systems.

Hopefully they don't keep whacking this around...

--
Robert Haas
EDB: http://www.enterprisedb.com

#14Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#12)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

Andrew Dunstan <andrew@dunslane.net> writes:

initdb also runs postgres a bunch of times via system(), similarly to
pg_regress but without the "exec". Does it also need adjusting?

That shouldn't be an issue, because we're only running the single
"standalone backend" process, not a cluster.

regards, tom lane

#15Thomas Munro
thomas.munro@gmail.com
In reply to: Robert Haas (#13)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

On Thu, Aug 12, 2021 at 1:45 AM Robert Haas <robertmhaas@gmail.com> wrote:

I think that worked for me on older macOS releases, and then it
stopped working at some point after some update or reinstall or
something. Unfortunately I don't know any more precisely than that,
but it does seem like we have to find some other approach to work on
modern systems.

I gave up on trying to make that work once I realised that
/usr/lib/dyld doesn't seem to obey the flag, so although other
segments become deterministic and the success rate is fairly high,
there's still a 600kb wrecking ball swinging around. I wondered what
the "slide" range could be... it appears to be fairly small
(vm_map_get_max_aslr_slide_pages() seems to be the place that's
determined and it's a 16MB or 256MB window, depending on architecture,
if I read that right). Given that, the death of 32 bit processes
since Catalina, and the typical layout we see, I think just doing
something like (/me rolls dice) export PG_SHMEM_ADDR=0x80000000000 is
a good candidate for something that works on both architectures, being
many TB away from everything else (above everything on ARM, between
heap etc and libs on Intel but with 8TB of space below it and 120TB
above). That gets the tests passing consistently with unpatched
master, -DEXEC_BACKEND, on both flavours of silicon.

#16Robert Haas
robertmhaas@gmail.com
In reply to: Thomas Munro (#15)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

On Wed, Aug 11, 2021 at 6:24 PM Thomas Munro <thomas.munro@gmail.com> wrote:

On Thu, Aug 12, 2021 at 1:45 AM Robert Haas <robertmhaas@gmail.com> wrote:

I think that worked for me on older macOS releases, and then it
stopped working at some point after some update or reinstall or
something. Unfortunately I don't know any more precisely than that,
but it does seem like we have to find some other approach to work on
modern systems.

I gave up on trying to make that work once I realised that
/usr/lib/dyld doesn't seem to obey the flag, so although other
segments become deterministic and the success rate is fairly high,
there's still a 600kb wrecking ball swinging around. I wondered what
the "slide" range could be... it appears to be fairly small
(vm_map_get_max_aslr_slide_pages() seems to be the place that's
determined and it's a 16MB or 256MB window, depending on architecture,
if I read that right). Given that, the death of 32 bit processes
since Catalina, and the typical layout we see, I think just doing
something like (/me rolls dice) export PG_SHMEM_ADDR=0x80000000000 is
a good candidate for something that works on both architectures, being
many TB away from everything else (above everything on ARM, between
heap etc and libs on Intel but with 8TB of space below it and 120TB
above). That gets the tests passing consistently with unpatched
master, -DEXEC_BACKEND, on both flavours of silicon.

Ugh, OK. So, is there a way that we can get an "easy button" committed
to the tree?

--
Robert Haas
EDB: http://www.enterprisedb.com

#17Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#16)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

Robert Haas <robertmhaas@gmail.com> writes:

On Wed, Aug 11, 2021 at 6:24 PM Thomas Munro <thomas.munro@gmail.com> wrote:

... I think just doing
something like (/me rolls dice) export PG_SHMEM_ADDR=0x80000000000 is
a good candidate for something that works on both architectures, being
many TB away from everything else (above everything on ARM, between
heap etc and libs on Intel but with 8TB of space below it and 120TB
above). That gets the tests passing consistently with unpatched
master, -DEXEC_BACKEND, on both flavours of silicon.

Ugh, OK. So, is there a way that we can get an "easy button" committed
to the tree?

I don't see why that approach couldn't be incorporated into pg_ctl,
or the postmaster itself. Given Andres' point that Linux ASLR
disable probably has to happen in pg_ctl, it seems like doing it
in pg_ctl in all cases is the way to move forward.

regards, tom lane

#18Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#17)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

On Fri, Aug 13, 2021 at 3:13 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Robert Haas <robertmhaas@gmail.com> writes:

Ugh, OK. So, is there a way that we can get an "easy button" committed
to the tree?

I don't see why that approach couldn't be incorporated into pg_ctl,
or the postmaster itself. Given Andres' point that Linux ASLR
disable probably has to happen in pg_ctl, it seems like doing it
in pg_ctl in all cases is the way to move forward.

I think doing it in the postmaster is best, since otherwise you have
to put code into pg_regress.c and pg_ctl.c. Here's a patch like that.

Attachments:

0001-Make-EXEC_BACKEND-more-convenient-on-macOS.patchapplication/octet-stream; name=0001-Make-EXEC_BACKEND-more-convenient-on-macOS.patchDownload+10-3
#19Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#18)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

Thomas Munro <thomas.munro@gmail.com> writes:

On Fri, Aug 13, 2021 at 3:13 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

I don't see why that approach couldn't be incorporated into pg_ctl,
or the postmaster itself. Given Andres' point that Linux ASLR
disable probably has to happen in pg_ctl, it seems like doing it
in pg_ctl in all cases is the way to move forward.

I think doing it in the postmaster is best, since otherwise you have
to put code into pg_regress.c and pg_ctl.c. Here's a patch like that.

Hmm, ok. Small thought: it might be better to put the #if inside
the "else { .... }". That way it scales easily to allow other
platform-specific defaults if we find anything useful. As-is,
the obvious extension would end up with multiple else-blocks,
which seems likely to confuse pgindent if nothing else.

regards, tom lane

#20Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#19)
Re: Worth using personality(ADDR_NO_RANDOMIZE) for EXEC_BACKEND on linux?

On Fri, Aug 13, 2021 at 9:59 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Hmm, ok. Small thought: it might be better to put the #if inside
the "else { .... }". That way it scales easily to allow other
platform-specific defaults if we find anything useful. As-is,
the obvious extension would end up with multiple else-blocks,
which seems likely to confuse pgindent if nothing else.

True. Thanks. Pushed to all live branches.

Obviously the address may have to be adjusted if Apple moves stuff
around, or if the initial layout and ASLR slide range turn out to be
less constrained than I inferred by nosing around the source code and
testing on a couple of systems.

#21Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thomas Munro (#20)
#22Thomas Munro
thomas.munro@gmail.com
In reply to: Tom Lane (#21)
#23Nathan Bossart
nathandbossart@gmail.com
In reply to: Thomas Munro (#22)
#24Thomas Munro
thomas.munro@gmail.com
In reply to: Nathan Bossart (#23)
#25Michael Paquier
michael@paquier.xyz
In reply to: Thomas Munro (#24)
#26Tom Lane
tgl@sss.pgh.pa.us
In reply to: Michael Paquier (#25)
#27Michael Paquier
michael@paquier.xyz
In reply to: Tom Lane (#26)
#28Thomas Munro
thomas.munro@gmail.com
In reply to: Michael Paquier (#27)
#29Michael Paquier
michael@paquier.xyz
In reply to: Thomas Munro (#28)
#30Michael Paquier
michael@paquier.xyz
In reply to: Michael Paquier (#29)
#31Michael Paquier
michael@paquier.xyz
In reply to: Michael Paquier (#30)
#32Andres Freund
andres@anarazel.de
In reply to: Michael Paquier (#31)
#33Thomas Munro
thomas.munro@gmail.com
In reply to: Michael Paquier (#31)
#34Michael Paquier
michael@paquier.xyz
In reply to: Thomas Munro (#33)