-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/ld: add PAX header #47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Owner changed to [email protected]. Status changed to Accepted. |
See http://code.google.com/p/go/source/detail?r=6bfe1e03b36c8284bcf471f4b5ec3a4a33703e50 The magic command is # setsebool -P allow_execstack 1 make.bash: detect and warn about SELinux policy that crashes us. The default SELinux policy on Fedora 12 (at least) disallows stack pages to be +x. This causes all binaries written by 6g/6l to segfault immedately. The 'true' way to fix this issue is to mark binaries with the correct type. However, that assumes that 6l is going to detect SELinux, figure out the correct type for the current distribution and set the type (without libselinux). For now we'll warn users and point them towards the way to enable execstack for the whole system. https://golang.org/issue/47 R=rsc CC=golang-dev http://codereview.prom.corp.google.com/1026041 |
Enabling an executable stack is the wrong way to fix the issue. It's going to be a problem for almost all selinux enabled distros. I'm guessing that it will fail RHEL 5.x as well. Here's a discussion of the general problem. http://people.redhat.com/drepper/selinux-mem.html |
Thanks for the pointer. I know it's not ideal. Drepper is suggesting creating an anonymous file and mapping it twice: once W and once X. We're not going to do that. The best answer may be a policy change to make it so that the output files of 6l are correctly typed so that they can execmem. |
The gc implementation is going to continue to depend on W+X memory. Gccgo does too, though work on gcc may provide an answer later. The so-called security protections here are trying to guard against badly written C programs. There's no good reason to force these restrictions onto a safe language like Go. If someone wants to do the work to make 6l generate binaries that are blessed enough to do W+X mappings, patches welcome. But I think this is a bug in SELinux and its ilk more than in Go. Owner changed to [email protected]. Status changed to WorkingAsIntended. |
Issue #1669 has been merged into this issue. |
This patch needed to compile and run go on amd64 Hardened Gentoo Linux. Probably it should be modified to work both on amd64 and x86. Attachments:
|
Updated patch to fix broken Go compile on Hardened Gentoo (actually, on kernel with PaX patch) and force Go linker to generate paxmarked binaries. Support both x86 and amd64. Attachments:
|
@RSC: I am the developer for gentoo linux who is working to get the go language into our distribution. I could condissionally apply the patch in comment 12. But, I would like your opinion as well. Is something like this a safe temporary fix until 6l/8l are fixed to write the binaries correctly? Thanks much, William |
I am considering extending it so that it would be activated from the command line of make.bash as follows: make.bash --pax-kernel or with a similar switch. That way it could always be applied instead of being condissionally applied. If we do that, is there a chance this would be accepted into the repository? |
Some ways to detect PaX kernel are listed at https://bugs.gentoo.org/show_bug.cgi?id=342505#c67 Other ways may be as simple as checking for paxctl existence on target system. Also, in this case make sure paxctl also will be used while building go itself. |
> What does paxctl do that 6l or 8l cannot? I think go linkers may do the same paxctl does, but in case there are subtle issues you'd better ask PaX developer [email protected] |
Hi Russ, In the wrappers, we use the -c and -m flags for paxctl. According to the man page, these do the following: -c creates the PT_PAX_FLAGS program header if it does not exist by converting the PT_GNU_STACK program header if it exists. -m does not enforce secure memory protections (NOMPROTECT) In otherwords, I think you would want to add a PT_PAX_FLAGS header to the binaries with the NOMPROTECT setting. I'm not an expert on how to do this sort of thing, but I don't know why 6l/8l (and maybe even the arm linker) couldn't do this. William |
> Of course it is also possible that the non-PaX Linux systems will reject such binaries. I don't think so. Paxmarked binaries works just fine with vanilla kernels. Also, paxctl can both convert PT_GNU_STACK into PT_PAX_FLAGS (with -c option) and just add PT_PAX_FLAGS (with -C option). In practice, only real difference between these was for skype binary (which has it's own protection against unauthorized modification of skype binary) - using paxctl -c will break skype protection, while using paxctl -C won't break it and so it's only way to paxmark skype. |
powerman@home ~ $ paxctl -v hello PaX control v0.7 Copyright 2004,2005,2006,2007,2009,2010,2011,2012 PaX Team <[email protected]> - PaX flags: -------x-e-- [hello] RANDEXEC is disabled EMUTRAMP is disabled powerman@home ~ $ paxctl -v hello_paxmarked PaX control v0.7 Copyright 2004,2005,2006,2007,2009,2010,2011,2012 PaX Team <[email protected]> - PaX flags: -----m-x-e-- [hello_paxmarked] MPROTECT is disabled RANDEXEC is disabled EMUTRAMP is disabled Attachments:
|
Thank you for your note on this bug. I would be happy to add the PT_PAX program header to all our Linux ELF binaries. I just need to know what the format is so that the linker can write it out itself, instead of depending on the presence of the paxctl binary. Can you please point me at the spec for what a PT_PAX program header should contain? Thanks again. Russ |
The format is straightforward. It's a program segment with type PT_PAX_FLAGS == 0x65041580. The p_flags field is set to a bitmask of: #define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */ #define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */ #define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */ #define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */ #define PF_MPROTECT (1U << 8) /* Enable MPROTECT */ #define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */ #define PF_RANDEXEC (1U << 10) /* Enable RANDEXEC */ #define PF_NORANDEXEC (1U << 11) /* Disable RANDEXEC */ #define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */ #define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */ #define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */ #define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */ The PF_X, PF_W, and PF_R fields are for the stack. For Go we will want to set PF_EMUTRAMP. I'm not sure what else what we need. |
Comment 29 by anthony.g.basile: here's a link to a patch against binutils-2.19. its a bit dated, but it answers the question of what a PT_PAX phdr should contain: http://pax.grsecurity.net/binutils-2.19-pt-pax-flags-200811041810.patch |
Can you please try http://golang.org/cl/6326054 ? It is my attempt to add the PAX headers. |
Hi Russ, I have applied your patch to go-1.0.2 in the gentoo distribution. I can verify via readelf -l that the generated binaries contain the PaX headers. Also, they run fine with a normal kernel (I do not run PaX). Now we need to make sure that things work correctly under a PaX kernel. Anthony, can you add your observations wrt our version of go-1.0.2 in gentoo since it now has this patch applied? Thanks, William |
This issue was closed by revision 3f34248. Status changed to Fixed. |
Issue #3329 has been merged into this issue. |
Issue #5223 has been merged into this issue. |
Issue #5223 has been merged into this issue. |
by jameshubbard:
The text was updated successfully, but these errors were encountered: