Fix support for named mmap usage on Android

Using a memfd name to annotate swiftshader_jit allocations is quite clever, but it doesn't work on Android because memfds can be shared and so writing to mappings of them promotes CoW/shared, which is classified by selinux as 'execmod' permission. Android prohibits 'execmod' permission for new app processes, because this is usually a sign the app relies on shared text relocations, which are insecure. In this case, that isn't actually happening, but we are subject to the same blanket ban :) Fortunately, Android has a longtime non-upstreamed prctl() to allow private mappings to be named as well, PR_SET_VMA_ANON_NAME. As this isn't generally available for Linux, wrap it in checks for __ANDROID__. This enables the naming without tripping the 'execmod' permission check. Bug: b/171498948 Bug: b/174801963 Change-Id: Ic4375bc4407e21ecdafb42a7cec651dc3b2ad13e Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/52669Reviewed-by: 's avatarJason Macnak <natsu@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Presubmit-Ready: Jason Macnak <natsu@google.com> Tested-by: 's avatarJason Macnak <natsu@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com> Commit-Queue: Jason Macnak <natsu@google.com>
parent bb04803b
......@@ -33,6 +33,10 @@
# include <unistd.h>
#endif
#if defined(__ANDROID__)
# include <sys/prctl.h>
#endif
#include <memory.h>
#undef allocate
......@@ -132,29 +136,30 @@ int permissionsToMmapProt(int permissions)
#endif // !defined(_WIN32) && !defined(__Fuchsia__)
#if defined(__linux__) && defined(REACTOR_ANONYMOUS_MMAP_NAME)
# if !defined(__ANDROID__)
// Create a file descriptor for anonymous memory with the given
// name. Returns -1 on failure.
// TODO: remove once libc wrapper exists.
static int memfd_create(const char *name, unsigned int flags)
{
# if __aarch64__
# define __NR_memfd_create 279
# elif __arm__
# define __NR_memfd_create 279
# elif __powerpc64__
# define __NR_memfd_create 360
# elif __i386__
# define __NR_memfd_create 356
# elif __x86_64__
# define __NR_memfd_create 319
# endif /* __NR_memfd_create__ */
# ifdef __NR_memfd_create
# if __aarch64__
# define __NR_memfd_create 279
# elif __arm__
# define __NR_memfd_create 279
# elif __powerpc64__
# define __NR_memfd_create 360
# elif __i386__
# define __NR_memfd_create 356
# elif __x86_64__
# define __NR_memfd_create 319
# endif /* __NR_memfd_create__ */
# ifdef __NR_memfd_create
// In the event of no system call this returns -1 with errno set
// as ENOSYS.
return syscall(__NR_memfd_create, name, flags);
# else
# else
return -1;
# endif
# endif
}
// Returns a file descriptor for use with an anonymous mmap, if
......@@ -165,6 +170,12 @@ int anonymousFd()
static int fd = memfd_create(MACRO_STRINGIFY(REACTOR_ANONYMOUS_MMAP_NAME), 0);
return fd;
}
# else // defined(__ANDROID__)
int anonymousFd()
{
return -1;
}
# endif // defined(__ANDROID__)
// Ensure there is enough space in the "anonymous" fd for length.
void ensureAnonFileSize(int anonFd, size_t length)
......@@ -278,6 +289,17 @@ void *allocateMemoryPages(size_t bytes, int permissions, bool need_exec)
{
mapping = nullptr;
}
# if defined(__ANDROID__)
else
{
// On Android, prefer to use a non-standard prctl called
// PR_SET_VMA_ANON_NAME to set the name of a private anonymous
// mapping, as Android restricts EXECUTE permission on
// CoW/shared anonymous mappings with sepolicy neverallows.
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, mapping, length,
MACRO_STRINGIFY(REACTOR_ANONYMOUS_MMAP_NAME));
}
# endif // __ANDROID__
#elif defined(__Fuchsia__)
zx_handle_t vmo;
if(zx_vmo_create(length, 0, &vmo) != ZX_OK)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment