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
runtime/internal/atomic: on Linux/ARM, support kernel without CONFIG_KUSER_HELPERS? #23792
Comments
The documentation for |
Thanks, @aclements. I agree. Closing. We can reopen if there is any problem. |
@aclements, @cherrymui, the documentation for
Taken from here: https://cateee.net/lkddb/web-lkddb/KUSER_HELPERS.html |
CONFIG_KUSER_HELPERS is controlled by GRKERNSEC_OLD_ARM_USERLAND, which I have explicitly disable precisely because of the exploit possibility that @Risca mentions. I have found that the protobuffer project had a similar issue with dependency on CONFIG_KUSER_HELPERS; and that redhat issued a patch to remove that dependency: https://gist.github.com/BennettSmith/7111094 Perhaps you would reconsider your decision to close this issue? I am very interested in running golang programs with a kernel that has been secured by disabling CONFIG_KUSER_HELPERS. |
Related pull request for protobuf: protocolbuffers/protobuf#2301 |
Has the C toolchain (gcc/clang and libc in particular) moved away from using these helpers? There are good technical reasons for using these helpers: because of the myriad subtleties around the support for, performance of, and lack of forward-compatibility of ARM memory barriers, the kernel is in the best position to figure out what the right barriers are. We aren't simply using them out of convenience. But, if the C toolchain has figured out a good way to handle the barriers in user space, we could see what it's doing. |
@aclements: I see, thanks for this information. I do not know if the toolchain uses the helpers or not. |
@aclements, you cannot have
So, in order for us to use grsecurity and golang, we would need to enable I don't know the state of C toolchains regarding this. I wish I had the time to keep up. I fully understand that there is a really valid use case for the kernel user helpers. Unfortunately for us, it also creates an incompatibility. |
It's all in assembly, so no compiler option. A build tag might be more appropriate, if we end up with it (but I hope not). If we go this way, would it be enough if we only do this on ARMv7? As @aclements mentioned, a good reason to use the kernel helper is not to dealing with the complexity of various incompatible memory barriers. If we do it on ARMv7 only, I think it is more feasible. |
I am mainly interested in ARM7. |
For what it's worth, I checked what GCC does. It looks like if GCC is compiled with _Bool f(int *p, int old, int new) {
return __atomic_compare_exchange_n(p, &old, new, 0, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
} In principle we could check at run time which type of processor we were on, and select the compare-and-exchange implementation accordingly. But of course we would prefer to avoid that because it is more complex. I don't think we should use build tags. I don't see any good solution here. At least not until we can assume a sufficiently new ARM processor. |
Let me change that a bit; I am only interested in ARM7. So if there is a resonable way to do this for ARM7, I would be very happy if you would consider it. |
I think we can do this for ARMv7, by just testing |
Change https://golang.org/cl/94076 mentions this issue: |
+1 for issuing native instructions.
This seems to be in line with the behavior in GCC @ianlancetaylor described. |
@frepe360, or anyone interested, could you try CL https://golang.org/cl/94076 (which depends on CL https://golang.org/cl/93637), to make sure it works on ARMv7 machines without the kernel helpers? I don't have the environment to test. Thanks. |
@cherrymui, of course, no problem. But I don't have access to it for a few days. Until then; I understand that this is patch, correct? I have no experience in building a golang compiler. Can you explain what I need to do in order to test these changes? |
@frepe360 thank you! The easiest way is probably:
Find the "DOWNLOAD" button on the webpage https://golang.org/cl/94076, click and copy the first command (currently as below), this will check out the patch.
Set up the bootstrap Go, if not already done (assuming you have Go installed on the machine):
Then build and test:
The last step will probably take a while (hopefully). |
@cherrymui Ok, that's not going to be a problem. |
@cherrymui, just to be perfectly clear; I build this compiler according to your instructions. Then I compile a helloworld.go program with my homebuilt compiler, and then I try to run the resulting helloworld program on an ARM7 with my specific kernel configuration. Correct? |
@frepe360 the instruction above was to build natively on ARM machine. It will also work for cross-compilation. Once you build the compiler as above, just do
If you could try some programs more than a helloworld, that will be great. Thanks! |
Unfortunately, I get a build error here.... git clone https://go.googlesource.com/go ... gives me this: Building Go cmd/dist using /usr/lib/go-1.6. Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1. Testing packages.ok archive/tar 0.786s |
(This was done on an ARM7, a raspberry pi. It does not have my "special" kernel.) |
I guess they are OOM'd, or timeout (which is possible on raspberry pi). Anyway, these are just tests, now you should already have the compiler built. You can use this new Go toolchain to build helloworld and run on the device with the special kernel. Thanks! |
Ok, no problem. I'll let you know on monday. |
The helloworld built with the compiler that I build according to your instructions, does NOT segfault on my kernel. The helloworld built with the regular compiler, DOES segfault:
I assume that this is progress? |
Thanks, @frepe360! This is great. |
On Linux/ARM, we use the atomic operations provided by the kernel. (https://github.com/torvalds/linux/blob/master/arch/arm/kernel/entry-armv.S#L941)
This can be configured with
CONFIG_KUSER_HELPERS
in the kernel. On some machine, this option may not be enabled.Should we support machines without this option enabled? Maybe only on GOARM=7, where the machine has atomic instructions? And keep relying on kernel helpers on older machines?
See also issue #23787.
cc @rsc @minux @davecheney
The text was updated successfully, but these errors were encountered: