1

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?

Nullptr
  • 11
  • 1

0 Answers0