diff --git a/third_party/ashmem/ashmem-dev.c b/third_party/ashmem/ashmem-dev.c index d419c775a0d41..8a1ee6218aed6 100644 --- a/third_party/ashmem/ashmem-dev.c +++ b/third_party/ashmem/ashmem-dev.c @@ -118,7 +118,7 @@ static AshmemStatus ashmem_get_status(void) { /* Returns true iff the ashmem device ioctl should be used for a given fd. * NOTE: Try not to use fstat() when possible to avoid performance issues. */ -static int ashmem_dev_fd_check(int fd) { +static int is_ashmem_fd(int fd) { if (device_api_level() <= __ANDROID_API_O_MR1__) return 1; if (ashmem_get_status() == ASHMEM_STATUS_SUPPORTED) { @@ -188,13 +188,13 @@ static size_t ashmem_dev_get_size_region(int fd) { // or newer, in which case, use memfd directly instead of // the ASharedMemory API. typedef int(*ASharedMemory_createFunc)(const char*, size_t); -typedef size_t(*ASharedMemory_getSizeFunc)(int fd); +// ASharedMemory_setProtFunc() is typically invoked in conjunction with ASharedMemory_createFunc(), +// so it's okay for setProt to implicitly assume the type of fd it needs to work with. typedef int(*ASharedMemory_setProtFunc)(int fd, int prot); // Function pointers to shared memory functions. typedef struct { ASharedMemory_createFunc create; - ASharedMemory_getSizeFunc getSize; ASharedMemory_setProtFunc setProt; } ASharedMemoryFuncs; @@ -227,16 +227,6 @@ error: return ret; } -static int memfd_get_size_region(int fd) { - struct stat sb; - if (fstat(fd, &sb) == -1) { - LOG_E("memfd_get_size_region(%d): fstat failed: %m", fd); - return -1; - } - - return sb.st_size; -} - static int memfd_set_prot_region(int fd, int prot) { int seals = fcntl(fd, F_GET_SEALS); if (seals == -1) { @@ -299,13 +289,10 @@ static void ashmem_init_funcs() { } funcs->create = (ASharedMemory_createFunc)dlsym(lib, "ASharedMemory_create"); - funcs->getSize = - (ASharedMemory_getSizeFunc)dlsym(lib, "ASharedMemory_getSize"); funcs->setProt = (ASharedMemory_setProtFunc)dlsym(lib, "ASharedMemory_setProt"); } else { funcs->create = &ashmem_dev_create_region; - funcs->getSize = &ashmem_dev_get_size_region; funcs->setProt = &ashmem_dev_set_prot_region; } } @@ -329,34 +316,30 @@ int ashmem_set_prot_region(int fd, int prot) { return ashmem_get_funcs()->setProt(fd, prot); } +static bool is_memfd_fd(int fd) { + if (fcntl(fd, F_GET_SEALS, 0) == -1) + return false; + return true; +} + int ashmem_get_prot_region(int fd) { - if (s_use_memfd) + if (is_memfd_fd(fd)) return memfd_get_prot_region(fd); - else if (ashmem_dev_fd_check(fd)) + + if (is_ashmem_fd(fd)) return ashmem_dev_get_prot_region(fd); - /* There are only two practical values to return here: either - * PROT_READ|PROT_WRITE or just PROT_READ, so try to determine - * the flags by trying to mmap() the region read-write first. - */ - int result = PROT_READ; - const size_t page_size = (size_t)sysconf(_SC_PAGESIZE); - void* m = mmap(NULL, page_size, PROT_READ|PROT_WRITE, - MAP_SHARED, fd, 0); - if (m != MAP_FAILED) { - munmap(m, page_size); - result = PROT_READ|PROT_WRITE; - } - return result; + + return -1; } int ashmem_pin_region(int fd, size_t offset, size_t len) { - if (ashmem_dev_fd_check(fd)) + if (is_ashmem_fd(fd)) return ashmem_dev_pin_region(fd, offset, len); return ASHMEM_NOT_PURGED; } int ashmem_unpin_region(int fd, size_t offset, size_t len) { - if (ashmem_dev_fd_check(fd)) + if (is_ashmem_fd(fd)) return ashmem_dev_unpin_region(fd, offset, len); /* NOTE: It is not possible to use madvise() here because it requires a * memory address. This could be done in the caller though, instead of @@ -365,11 +348,16 @@ int ashmem_unpin_region(int fd, size_t offset, size_t len) { } int ashmem_get_size_region(int fd) { - if (s_use_memfd) - return memfd_get_size_region(fd); + if (is_ashmem_fd(fd)) + return ashmem_dev_get_size_region(fd); - /* NOTE: Original API returns an int. Avoid breaking it. */ - return (int)ashmem_get_funcs()->getSize(fd); + struct stat sb; + if (fstat(fd, &sb) == -1) { + LOG_E("fstat(%d) failed: %m", fd); + return -1; + } + + return sb.st_size; } int ashmem_device_is_supported(void) {