Skip to content
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

x/mobile/app: cannot open /proc/self/auxv: Permission denied #9229

Closed
gen2brain opened this issue Dec 9, 2014 · 9 comments
Closed

x/mobile/app: cannot open /proc/self/auxv: Permission denied #9229

gen2brain opened this issue Dec 9, 2014 · 9 comments

Comments

@gen2brain
Copy link

When debug apk is built all works fine, but in release mode /proc/self/auxv is not readable and app crashes.

go version 1.4rc2 linux/amd64

@crawshaw crawshaw self-assigned this Dec 9, 2014
@crawshaw
Copy link
Member

crawshaw commented Dec 9, 2014

Ah, yes. It does not work on some platforms some of the time, as noted here:
https://android-review.googlesource.com/#/c/51271/1/sources/android/cpufeatures/cpu-features.c

/* IMPORTANT:

  • Accessing /proc/self/auxv doesn't work anymore on all
  • platform versions. More specifically, when running inside
  • a regular application process, most of /proc/self/ will be
  • non-readable, including /proc/self/auxv. This doesn't
  • happen however if the application is debuggable, or when
  • running under the "shell" UID, which is why this was not
  • detected appropriately.
    */

I'll try and find another way.

@minux
Copy link
Member

minux commented Dec 9, 2014

The Go runtime needs the following items from AUXV on linux:

  • _AT_RANDOM: we can read from /dev/urandom, at the cost of 3 extra syscalls, or use getrandom on newer kernels, one syscall, or use sysctl(uuid) trick.
  • _AT_PLATFORM: only on ARM. I think we can get the same information by parsing /proc/cpuinfo.
  • _AT_HWCAP: again, only on ARM. Android has its own way of querying the hardware capabilities, the mobile/app package could synthesis an entry for the runtime.
  • _AT_SYSINFO: only on 386, we need this to use vdso. Android port needs some way to get this pointer from libc or we can always use INT 0x80 on android.
  • _AT_SYSINFO_EHDR: only on amd64. we need this for vdso. We can either fallback to syscall or find some way to query the information.

For Android/ARM port, I think the way to go is to make mobile/app synthesize the needed auxv entries.
I will just describe how to deal with _AT_PLATFORM and _AT_HWCAP here.
we query android_getCpuFeatures() and then translate:

  • if ANDROID_CPU_ARM_FEATURE_ARMv7 and ANDROID_CPU_ARM_FEATURE_VFPv3 are set, we set _AT_PLATFORM="v7l" and _AT_HWCAP = _HWCAP_VFPv3;
  • else if ANDROID_CPU_ARM_FEATURE_LDREX_STREX and any of ANDROID_CPU_ARM_FEATURE_VFP* flags are set, we set _AT_PLATFORM="v6l" and _AT_HWCAP=_HWCAP_VFP;
  • else set _AT_PLATFORM="v5l", _AT_HWCAP=0

Of course, the _AT_HWCAP set here is the bare minimum needed by the Go runtime. Ideally, we should translate as many bits of android cpufeatures to hwcaps as possible.

I'm not sure how to deal with _AT_SYSINFO and _AT_SYSINFO_EHDR yet, but in the worse case we simply pass 0 and let the runtime fallback to int 0x80/syscall.
(for _AT_SYSINFO_EHDR, we can parse /proc/self/maps and looks for "[vsyscall]", but I'm not sure if we can read that file if even the seemingly harmless auxv is not readable.)

@crawshaw
Copy link
Member

crawshaw commented Dec 9, 2014

Yep, I've already got a patch synthesizing auxv for arm, it's easy enough. Interestingly it seems to work, and then panic randomly later in my program in debug mode, when it usually passes when reading from /proc/self/auxv. I've verified with printstring that everythin in os_linux_arm.go is getting the right value, so it must be something else. Still investigating.

x86/amd64 is a problem for another day. First up is getting the builder working in debug mode.

@aclements
Copy link
Member

I assume platform init is handled by bionic before the Go runtime inits. If so, can we use getauxval from libc (or even just use __libc_auxv directly)?

@crawshaw
Copy link
Member

bionic is a minimal libc. While there is a getauxval (and __libc_auxv!), it is private:

https://android.googlesource.com/platform/bionic.git/+/master/libc/private/bionic_auxv.h

This means it is not exported in the supported .h files that ship with the NDK and its use is strongly discouraged by the android team. I have agreed not to use any private interfaces in our Go packages.

@aclements
Copy link
Member

You're right, __libc_auxv is definitely private. But getauxval is in sys/auxv.h. Surely that's not off limits? Or is that excluded by the NDK? (Sorry, I know the libc side of this, but not the NDK side.)

@crawshaw
Copy link
Member

So it does! It shipped in android-21, and I was grepping over an older version. (My method for determining what's private or not is to search all the headers that ship with the NDK, and I usually stick to android-9.)

I don't want to introduce a dependency on the latest release yet, but we should switch to it eventually.

@crawshaw
Copy link
Member

Fixed (at least for now) in golang/mobile@32030f7. Looks like commits to other Go repositories does not close issues here.

@dmitshur
Copy link
Contributor

@crawshaw, to refer to an issue in another repo, you need to use the username/repository#issue_number form. :)

See https://help.github.com/articles/closing-issues-via-commit-messages/ for full details.

@mikioh mikioh changed the title golang.org/x/mobile/app: cannot open /proc/self/auxv: Permission denied x/mobile/app: cannot open /proc/self/auxv: Permission denied Aug 5, 2015
@golang golang locked and limited conversation to collaborators Aug 5, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants