I am trying to get a memfd on Android. When I do this all things seem to be okay:
int getFd() {
...
int fd = syscall(__NR_memfd_create, "none", MFD_CLOEXEC | MFD_ALLOW_SEALING);
errno = 0;
write(fd, str.c_str(), str.length());
logi(strerror(errno));
lseek(fd, SEEK_SET, SEEK_SET);
return fd;
}
But memfd_create syscall doesn't exist on older Android version. So I am trying to call ashmem_create_region in libcutils.so instead. (Not using ASharedMemory_create because the minSDK 26 is still too high)
First I inject into zygote to dlsym the symbols.
// Should call in zygote through Riru
void initMemoryTools() {
void *handle = dlopen("/system/lib/libcutils.so", RTLD_LAZY);
#define DLSYM(symbol, type) symbol = reinterpret_cast<type>(dlsym(handle, #symbol))
DLSYM(ashmem_valid, int (*)(int));
DLSYM(ashmem_create_region, int (*)(const char *, size_t));
DLSYM(ashmem_set_prot_region, int (*)(int, int));
DLSYM(ashmem_pin_region, int (*)(int, size_t, size_t));
DLSYM(ashmem_unpin_region, int (*)(int, size_t, size_t));
DLSYM(ashmem_get_size_region, int (*)(int));
#undef DLSYM
}
Then I replace memfd_create for ashmem_create_region.
int getFd() {
...
int fd = ashmem_create_region("none", sizeof(char) * str.length());
errno = 0;
write(fd, str.c_str(), str.length());
logi(strerror(errno));
lseek(fd, SEEK_SET, SEEK_SET);
return fd;
}
I successfully get a fd (not -1), but write() throws EINVAL, also encounter EBADF when trying to read from this fd. Now I wonder why this happens and what should I do to get a memfd on Android 7 ~ 11?