Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 92fd3caf authored by Tri Vo's avatar Tri Vo
Browse files

libcutils: route to /dev/ashmem<boot_id> instead of ashmemd

Having libcutils ask ashmemd for ashmem fds results in unsatisfactory
performance/memory overhead. Introduce a duplicate of /dev/ashmem and
route to it instead.

Our goal remains as before, namely, use SELinux to phase out usage of
ashmem that doesn't go through libcutils.

Bug: 139855428
Test: boot aosp_crosshatch, browse internet, use camera
Change-Id: I02260a9042acb412571b11f1f4c1d8608483064a
parent ff89b8d8
Loading
Loading
Loading
Loading
+19 −50
Original line number Diff line number Diff line
@@ -23,9 +23,6 @@
 */
#define LOG_TAG "ashmem"

#ifndef __ANDROID_VNDK__
#include <dlfcn.h>
#endif
#include <errno.h>
#include <fcntl.h>
#include <linux/ashmem.h>
@@ -42,11 +39,11 @@
#include <sys/types.h>
#include <unistd.h>

#include <android-base/file.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>

#define ASHMEM_DEVICE "/dev/ashmem"

/* Will be added to UAPI once upstream change is merged */
#define F_SEAL_FUTURE_WRITE 0x0010

@@ -65,32 +62,6 @@ static dev_t __ashmem_rdev;
 */
static pthread_mutex_t __ashmem_lock = PTHREAD_MUTEX_INITIALIZER;

/*
 * We use ashmemd to enforce that apps don't open /dev/ashmem directly. Vendor
 * code can't access system aidl services per Treble requirements. So we limit
 * ashmemd access to the system variant of libcutils.
 */
#ifndef __ANDROID_VNDK__
using openFdType = int (*)();

static openFdType openFd;

openFdType initOpenAshmemFd() {
    openFdType openFd = nullptr;
    void* handle = dlopen("libashmemd_client.so", RTLD_NOW);
    if (!handle) {
        ALOGE("Failed to dlopen() libashmemd_client.so: %s", dlerror());
        return openFd;
    }

    openFd = reinterpret_cast<openFdType>(dlsym(handle, "openAshmemdFd"));
    if (!openFd) {
        ALOGE("Failed to dlsym() openAshmemdFd() function: %s", dlerror());
    }
    return openFd;
}
#endif

/*
 * has_memfd_support() determines if the device can use memfd. memfd support
 * has been there for long time, but certain things in it may be missing.  We
@@ -215,25 +186,31 @@ static bool has_memfd_support() {
    return memfd_supported;
}

static std::string get_ashmem_device_path() {
    static const std::string boot_id_path = "/proc/sys/kernel/random/boot_id";
    std::string boot_id;
    if (!android::base::ReadFileToString(boot_id_path, &boot_id)) {
        ALOGE("Failed to read %s: %s.\n", boot_id_path.c_str(), strerror(errno));
        return "";
    };
    boot_id = android::base::Trim(boot_id);

    return "/dev/ashmem" + boot_id;
}

/* logistics of getting file descriptor for ashmem */
static int __ashmem_open_locked()
{
    static const std::string ashmem_device_path = get_ashmem_device_path();

    int ret;
    struct stat st;

    int fd = -1;
#ifndef __ANDROID_VNDK__
    if (!openFd) {
        openFd = initOpenAshmemFd();
    if (ashmem_device_path.empty()) {
        return -1;
    }

    if (openFd) {
        fd = openFd();
    }
#endif
    if (fd < 0) {
        fd = TEMP_FAILURE_RETRY(open(ASHMEM_DEVICE, O_RDWR | O_CLOEXEC));
    }
    int fd = TEMP_FAILURE_RETRY(open(ashmem_device_path.c_str(), O_RDWR | O_CLOEXEC));
    if (fd < 0) {
        return fd;
    }
@@ -485,11 +462,3 @@ int ashmem_get_size_region(int fd)

    return __ashmem_check_failure(fd, TEMP_FAILURE_RETRY(ioctl(fd, ASHMEM_GET_SIZE, NULL)));
}

void ashmem_init() {
#ifndef __ANDROID_VNDK__
    pthread_mutex_lock(&__ashmem_lock);
    openFd = initOpenAshmemFd();
    pthread_mutex_unlock(&__ashmem_lock);
#endif  //__ANDROID_VNDK__
}
+0 −2
Original line number Diff line number Diff line
@@ -94,5 +94,3 @@ int ashmem_get_size_region(int fd)

    return buf.st_size;
}

void ashmem_init() {}
+0 −1
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ int ashmem_set_prot_region(int fd, int prot);
int ashmem_pin_region(int fd, size_t offset, size_t len);
int ashmem_unpin_region(int fd, size_t offset, size_t len);
int ashmem_get_size_region(int fd);
void ashmem_init();

#ifdef __cplusplus
}