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

Does Android 8.0 support the getrandom syscall? #852

Closed
briansmith opened this issue Jun 18, 2019 · 4 comments
Closed

Does Android 8.0 support the getrandom syscall? #852

briansmith opened this issue Jun 18, 2019 · 4 comments

Comments

@briansmith
Copy link
Owner

In ring 0.14 and earlier, Android always used /dev/urandom and never used the getrandom syscall. The current code in the ring master branch always uses the getrandom syscall. Is this new behavior too aggressive?

In the absence of any reason to do otherwise, ring's minimum supported version of Android is the same as Google Play's minimum version of Android. From https://developer.android.com/distribute/best-practices/develop/target-sdk: Google Play requires that [...] app updates target Android 9.0 starting November 1, 2019. Until then, Android 8.0 is the minimum supported version.

  • Android 8.0 = API level 26 = Android O (Oreo)
  • Android 9.0 = API level 28 = Android P (Pie)

I know that bionic libc only adds a getrandom() wrapper around the syscall starting in API level 28 according to https://android.googlesource.com/platform/bionic/+/android-9.0.0_r22/docs/status.md#libc.

However, it is not clear whether the syscall available for use through syscall(SYS_getrandom) in Android 8.0. If not, we need to enable the fallback to /dev/urandom. If so, then the current code is correct.

@josephlr Can you find an authoritative answer to this question?

@briansmith briansmith changed the title Does Android 8.0 support the getrandom() syscall Does Android 8.0 support the getrandom() syscall? Jun 18, 2019
@briansmith briansmith changed the title Does Android 8.0 support the getrandom() syscall? Does Android 8.0 support the getrandom syscall? Jun 18, 2019
@josephlr
Copy link
Contributor

TL;DR; We need to have a /dev/urandom fallback and will need it at least until the 3.16 kernel ends LTS support in mid 2020.

An Android app has two values that matter when talking about versions. For more info see this article.

  • minSdkVersion - The minimum version your app supports, for Rust this is 14 (Andorid 4.0, Ice Cream Sandwich) on 32-bit and 21 (Android 5.0, Lollipop) on 64-bit as determined by their CI.
  • targetSdkVersion - The SDK's whose behavior changes your app has opted into. This allows Android to break backwards compatibility and then have apps opt into this breakage (not unlike Rust editions). This is the value that must increase by a certain date.

This repo is a good example. Their minSdkVersion is 16 and targetSdkVersion is 28, so this app could be submitted to the Play Store today. Given the distribution of Andorid releases developers generally have a tradeoff to consider where setting a higher minSdkVersion means being installable on a smaller number of devices.

The getrandom() syscall was introduced in v3.17, and the earliest ASOP kernel that brings in those changes is Andoird 6.0 Marshmallow = API level 23. So it's on about 75% of Android devices. Of course vendors have kernel patches on top of ASOP, but it's unlikely many added or removed an entire syscall.

So we should determine what ring's minSdkVersion should be, Google uses Andorid 4.4 KitKat = API level 19 for most of our key apps (Youtube and Gmail), which gets you 95% of installed users. So I think 16 or 19 is a reasonable cutoff. We should keep the /dev/urandom fallback for now. We can revisit this when all supported mainline kernel versions have the syscall (April 2020), then it might make sense to remove the fallback for Linux and Android.

@jmgao
Copy link

jmgao commented Jun 23, 2019

There are definitely devices running Android O that do not support getrandom (e.g. Nexus Player). Strictly speaking, even devices with Q don't have to support getrandom via syscall being invoked directly: the thing that's tested is the libc getrandom wrapper, and an OEM could implement that themselves however they wished. There isn't even a requirement that you're running on top of Linux.

In reality, though, I'd expect that the vast majority of devices running O have getrandom, and every device that officially supports P or newer has getrandom.

@briansmith
Copy link
Owner Author

Thanks for the info. Maybe at some point we should consider calling getrandom() instead of syscall() if the minimum supported Android version is at least Android P. In the meantime, I think it makes sense to do things the way we are currently doing things, especially since BoringSSL does it this way too (BoringSSL: ret = syscall(__NR_getrandom, buf, buf_len, flags);).

@briansmith
Copy link
Owner Author

From the new README.md:

ring for ARMv7 Android is built in CI using SDK version 26 targeting API level 18 (Android 4.3+); it is tested in the emulator using the corresponding system image. ring for AArch64 Android is built in CI using SDK version 26 targeting API level 21 (Android 5.0).

getauxval, not getrandom, is what is forces the minimum API level as of now.

See commits d041b73, 1897790, and 904cad6.

Thanks for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants