-
-
Notifications
You must be signed in to change notification settings - Fork 249
Use PROT_MPROTECT for NetBSD mprotect restrictions #185
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
Conversation
NetBSD's mprotect seems to be more restrictive than other OSes, where it does not allow less restrictive mappings than the original mmap, and can be subject to PaX restrictions. According to NetBSD documentation, there is a PROT_MPROTECT macro to define allowed protections for later uses of mprotect, without granting the permissions immediately in mmap. This can be used to ensure that the full range of protections blink could make in the course of execution are permitted.
|
What NetBSD architecture? I don't get this behavior on x86-64. |
|
I get this on both x86_64 and aarch64, NetBSD 10.0 running in VMs |
|
My setup: Building the latest code from master with |
|
Try writing a C program locally on the system to confirm. Something like: TEST(mprotect, loosenRestriction) {
char *p;
ASSERT_NE(MAP_FAILED, (p = mmap(0, 1, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)));
ASSERT_SYS(0, 0, mprotect(p, 1, PROT_READ | PROT_EXEC));
ASSERT_SYS(0, 0, munmap(p, 1));
} |
|
I converted the test into a standalone program: #include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
int main(void) {
char *p = mmap(0, 1, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (p == MAP_FAILED) {
perror("mmap failed");
return EXIT_FAILURE;
}
if (mprotect(p, 1, PROT_READ | PROT_EXEC) != 0) {
perror("mprotect failed");
munmap(p, 1);
return EXIT_FAILURE;
}
if (munmap(p, 1) != 0) {
perror("munmap failed");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}Then: Changing to the following line allows this to succeed: |
|
This is probably relevant: |
|
Disabling PaX mprotect allows the original test to succeed |
|
Is PaX enabled by default in the stock installation these days? |
|
According to NetBSD 8.0's release notes, PaX mprotect is enabled by default on x86_64 and arm64: https://www.netbsd.org/releases/formal-8/NetBSD-8.0.html |
|
It appears that PaX mprotect can be disabled on binaries with paxctl: https://man.netbsd.org/paxctl.8 |
|
For my use case, running |
|
Thanks for the update. I'd rather not make it default to RWX memory on NetBSD because it has a WIN32-like memory restriction feature. Since there'll probably be another feature lurking in NetBSD somewhere that demands a W^X invariant. Appreciate you taking the time to send the change though! Glad you're unblocked. |
|
Actually on second thought, having just noticed the comment that PAX is enabled by default in the stock install, what would you recommend? Would it be possible to configure the Blink build system to set the flag on the binary automatically for our users? |
|
I think a short-term fix would be to add |
jart
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right that we should respect the security blankets each platform
puts in place. This change does a better job at that, since it disables
PAX surgically, whereas paxctl -m would disable PAX systemically.
since it could, as a VM, be used to run untrusted x86_64 binaries
Stock open source Blink shouldn't be thought of as a security layer for
untrusted binaries. Blink aims to ensure programs work above all, so
that people have a good experience using the software. That means Blink
lets your programs do what they want to do. However Blink is designed
with the security use case in mind. It should take minimal eng effort to
modify blink/syscall.c to enforce whatever security policy you want. If
you do that, then Blink can potentially offer you a much stronger layer
of hardware/system isolation than alternatives like KVM, gVisor, etc.
Especially if you disable JIT and have a SECCOMP policy too. We also
really should add soft floating point to make it even more extreme.
NetBSD's mprotect seems to be more restrictive than other OSes, where it does not allow less restrictive mappings than the original mmap, and can be subject to PaX restrictions. According to NetBSD documentation, there is a PROT_MPROTECT macro to define allowed protections for later uses of mprotect, without granting the permissions immediately in mmap. This can be used to ensure that the full range of protections blink could make in the course of execution are permitted.