system_server BINDER_TYPE_FD driver ashmem accessors

check if device matches the ashmem rdev, before calling
ashmem_get_size_region. This eliminates making this call
when associated with other driver file descriptors.

Bug: 26374183
Bug: 26918423
Bug: 26871259
Change-Id: I1f88c2c93ea35a73c8e14125f3d1a6c67fa4f15b
This commit is contained in:
Mark Salyzyn 2016-02-02 10:27:03 -08:00 committed by Steve Kondik
parent d70043eaf4
commit 839f0dd964

View File

@ -18,6 +18,8 @@
//#define LOG_NDEBUG 0 //#define LOG_NDEBUG 0
#include <binder/Parcel.h> #include <binder/Parcel.h>
#include <fcntl.h>
#include <pthread.h>
#include <binder/IPCThreadState.h> #include <binder/IPCThreadState.h>
#include <binder/Binder.h> #include <binder/Binder.h>
@ -98,6 +100,32 @@ enum {
BLOB_ASHMEM_MUTABLE = 2, BLOB_ASHMEM_MUTABLE = 2,
}; };
static dev_t ashmem_rdev()
{
static dev_t __ashmem_rdev;
static pthread_mutex_t __ashmem_rdev_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&__ashmem_rdev_lock);
dev_t rdev = __ashmem_rdev;
if (!rdev) {
int fd = TEMP_FAILURE_RETRY(open("/dev/ashmem", O_RDONLY));
if (fd >= 0) {
struct stat st;
int ret = TEMP_FAILURE_RETRY(fstat(fd, &st));
close(fd);
if ((ret >= 0) && S_ISCHR(st.st_mode)) {
rdev = __ashmem_rdev = st.st_rdev;
}
}
}
pthread_mutex_unlock(&__ashmem_rdev_lock);
return rdev;
}
void acquire_object(const sp<ProcessState>& proc, void acquire_object(const sp<ProcessState>& proc,
const flat_binder_object& obj, const void* who, size_t* outAshmemSize) const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
{ {
@ -129,7 +157,7 @@ void acquire_object(const sp<ProcessState>& proc,
if ((obj.cookie != 0) && (outAshmemSize != NULL)) { if ((obj.cookie != 0) && (outAshmemSize != NULL)) {
struct stat st; struct stat st;
int ret = fstat(obj.handle, &st); int ret = fstat(obj.handle, &st);
if (!ret && S_ISCHR(st.st_mode)) { if (!ret && S_ISCHR(st.st_mode) && (st.st_rdev == ashmem_rdev())) {
// If we own an ashmem fd, keep track of how much memory it refers to. // If we own an ashmem fd, keep track of how much memory it refers to.
int size = ashmem_get_size_region(obj.handle); int size = ashmem_get_size_region(obj.handle);
if (size > 0) { if (size > 0) {
@ -182,7 +210,7 @@ static void release_object(const sp<ProcessState>& proc,
if (outAshmemSize != NULL) { if (outAshmemSize != NULL) {
struct stat st; struct stat st;
int ret = fstat(obj.handle, &st); int ret = fstat(obj.handle, &st);
if (!ret && S_ISCHR(st.st_mode)) { if (!ret && S_ISCHR(st.st_mode) && (st.st_rdev == ashmem_rdev())) {
int size = ashmem_get_size_region(obj.handle); int size = ashmem_get_size_region(obj.handle);
if (size > 0) { if (size > 0) {
*outAshmemSize -= size; *outAshmemSize -= size;