summaryrefslogtreecommitdiffstats
path: root/libs/binder
diff options
context:
space:
mode:
Diffstat (limited to 'libs/binder')
-rw-r--r--libs/binder/Android.mk2
-rw-r--r--libs/binder/IMemory.cpp53
-rw-r--r--libs/binder/MemoryHeapBase.cpp15
-rw-r--r--libs/binder/Permission.cpp88
-rw-r--r--libs/binder/PermissionCache.cpp113
-rw-r--r--libs/binder/ProcessState.cpp51
6 files changed, 168 insertions, 154 deletions
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
index f9d9f25..3a12e96 100644
--- a/libs/binder/Android.mk
+++ b/libs/binder/Android.mk
@@ -27,7 +27,7 @@ sources := \
MemoryHeapBase.cpp \
MemoryHeapPmem.cpp \
Parcel.cpp \
- Permission.cpp \
+ PermissionCache.cpp \
ProcessState.cpp \
Static.cpp
diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp
index bc8c412..1ace8f8 100644
--- a/libs/binder/IMemory.cpp
+++ b/libs/binder/IMemory.cpp
@@ -42,11 +42,11 @@ class HeapCache : public IBinder::DeathRecipient
public:
HeapCache();
virtual ~HeapCache();
-
+
virtual void binderDied(const wp<IBinder>& who);
- sp<IMemoryHeap> find_heap(const sp<IBinder>& binder);
- void free_heap(const sp<IBinder>& binder);
+ sp<IMemoryHeap> find_heap(const sp<IBinder>& binder);
+ void free_heap(const sp<IBinder>& binder);
sp<IMemoryHeap> get_heap(const sp<IBinder>& binder);
void dump_heaps();
@@ -57,7 +57,7 @@ private:
int32_t count;
};
- void free_heap(const wp<IBinder>& binder);
+ void free_heap(const wp<IBinder>& binder);
Mutex mHeapCacheLock;
KeyedVector< wp<IBinder>, heap_info_t > mHeapCache;
@@ -81,11 +81,12 @@ public:
virtual void* getBase() const;
virtual size_t getSize() const;
virtual uint32_t getFlags() const;
+ virtual uint32_t getOffset() const;
private:
friend class IMemory;
friend class HeapCache;
-
+
// for debugging in this module
static inline sp<IMemoryHeap> find_heap(const sp<IBinder>& binder) {
return gHeapCache->find_heap(binder);
@@ -97,7 +98,7 @@ private:
return gHeapCache->get_heap(binder);
}
static inline void dump_heaps() {
- gHeapCache->dump_heaps();
+ gHeapCache->dump_heaps();
}
void assertMapped() const;
@@ -107,6 +108,7 @@ private:
mutable void* mBase;
mutable size_t mSize;
mutable uint32_t mFlags;
+ mutable uint32_t mOffset;
mutable bool mRealHeap;
mutable Mutex mLock;
};
@@ -123,7 +125,7 @@ public:
BpMemory(const sp<IBinder>& impl);
virtual ~BpMemory();
virtual sp<IMemoryHeap> getMemory(ssize_t* offset=0, size_t* size=0) const;
-
+
private:
mutable sp<IMemoryHeap> mHeap;
mutable ssize_t mOffset;
@@ -203,7 +205,7 @@ IMPLEMENT_META_INTERFACE(Memory, "android.utils.IMemory");
BnMemory::BnMemory() {
}
-BnMemory::~BnMemory() {
+BnMemory::~BnMemory() {
}
status_t BnMemory::onTransact(
@@ -229,7 +231,7 @@ status_t BnMemory::onTransact(
BpMemoryHeap::BpMemoryHeap(const sp<IBinder>& impl)
: BpInterface<IMemoryHeap>(impl),
- mHeapId(-1), mBase(MAP_FAILED), mSize(0), mFlags(0), mRealHeap(false)
+ mHeapId(-1), mBase(MAP_FAILED), mSize(0), mFlags(0), mOffset(0), mRealHeap(false)
{
}
@@ -242,7 +244,7 @@ BpMemoryHeap::~BpMemoryHeap() {
sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder();
if (VERBOSE) {
- LOGD("UNMAPPING binder=%p, heap=%p, size=%d, fd=%d",
+ LOGD("UNMAPPING binder=%p, heap=%p, size=%d, fd=%d",
binder.get(), this, mSize, mHeapId);
CallStack stack;
stack.update();
@@ -270,6 +272,7 @@ void BpMemoryHeap::assertMapped() const
if (mHeapId == -1) {
mBase = heap->mBase;
mSize = heap->mSize;
+ mOffset = heap->mOffset;
android_atomic_write( dup( heap->mHeapId ), &mHeapId );
}
} else {
@@ -286,13 +289,14 @@ void BpMemoryHeap::assertReallyMapped() const
// remote call without mLock held, worse case scenario, we end up
// calling transact() from multiple threads, but that's not a problem,
// only mmap below must be in the critical section.
-
+
Parcel data, reply;
data.writeInterfaceToken(IMemoryHeap::getInterfaceDescriptor());
status_t err = remote()->transact(HEAP_ID, data, &reply);
int parcel_fd = reply.readFileDescriptor();
ssize_t size = reply.readInt32();
uint32_t flags = reply.readInt32();
+ uint32_t offset = reply.readInt32();
LOGE_IF(err, "binder=%p transaction failed fd=%d, size=%ld, err=%d (%s)",
asBinder().get(), parcel_fd, size, err, strerror(-err));
@@ -309,7 +313,7 @@ void BpMemoryHeap::assertReallyMapped() const
Mutex::Autolock _l(mLock);
if (mHeapId == -1) {
mRealHeap = true;
- mBase = mmap(0, size, access, MAP_SHARED, fd, 0);
+ mBase = mmap(0, size, access, MAP_SHARED, fd, offset);
if (mBase == MAP_FAILED) {
LOGE("cannot map BpMemoryHeap (binder=%p), size=%ld, fd=%d (%s)",
asBinder().get(), size, fd, strerror(errno));
@@ -317,6 +321,7 @@ void BpMemoryHeap::assertReallyMapped() const
} else {
mSize = size;
mFlags = flags;
+ mOffset = offset;
android_atomic_write(fd, &mHeapId);
}
}
@@ -343,14 +348,19 @@ uint32_t BpMemoryHeap::getFlags() const {
return mFlags;
}
+uint32_t BpMemoryHeap::getOffset() const {
+ assertMapped();
+ return mOffset;
+}
+
// ---------------------------------------------------------------------------
IMPLEMENT_META_INTERFACE(MemoryHeap, "android.utils.IMemoryHeap");
-BnMemoryHeap::BnMemoryHeap() {
+BnMemoryHeap::BnMemoryHeap() {
}
-BnMemoryHeap::~BnMemoryHeap() {
+BnMemoryHeap::~BnMemoryHeap() {
}
status_t BnMemoryHeap::onTransact(
@@ -362,6 +372,7 @@ status_t BnMemoryHeap::onTransact(
reply->writeFileDescriptor(getHeapID());
reply->writeInt32(getSize());
reply->writeInt32(getFlags());
+ reply->writeInt32(getOffset());
return NO_ERROR;
} break;
default:
@@ -383,17 +394,17 @@ HeapCache::~HeapCache()
void HeapCache::binderDied(const wp<IBinder>& binder)
{
//LOGD("binderDied binder=%p", binder.unsafe_get());
- free_heap(binder);
+ free_heap(binder);
}
-sp<IMemoryHeap> HeapCache::find_heap(const sp<IBinder>& binder)
+sp<IMemoryHeap> HeapCache::find_heap(const sp<IBinder>& binder)
{
Mutex::Autolock _l(mHeapCacheLock);
ssize_t i = mHeapCache.indexOfKey(binder);
if (i>=0) {
heap_info_t& info = mHeapCache.editValueAt(i);
LOGD_IF(VERBOSE,
- "found binder=%p, heap=%p, size=%d, fd=%d, count=%d",
+ "found binder=%p, heap=%p, size=%d, fd=%d, count=%d",
binder.get(), info.heap.get(),
static_cast<BpMemoryHeap*>(info.heap.get())->mSize,
static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId,
@@ -415,7 +426,7 @@ void HeapCache::free_heap(const sp<IBinder>& binder) {
free_heap( wp<IBinder>(binder) );
}
-void HeapCache::free_heap(const wp<IBinder>& binder)
+void HeapCache::free_heap(const wp<IBinder>& binder)
{
sp<IMemoryHeap> rel;
{
@@ -426,7 +437,7 @@ void HeapCache::free_heap(const wp<IBinder>& binder)
int32_t c = android_atomic_dec(&info.count);
if (c == 1) {
LOGD_IF(VERBOSE,
- "removing binder=%p, heap=%p, size=%d, fd=%d, count=%d",
+ "removing binder=%p, heap=%p, size=%d, fd=%d, count=%d",
binder.unsafe_get(), info.heap.get(),
static_cast<BpMemoryHeap*>(info.heap.get())->mSize,
static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId,
@@ -450,7 +461,7 @@ sp<IMemoryHeap> HeapCache::get_heap(const sp<IBinder>& binder)
return realHeap;
}
-void HeapCache::dump_heaps()
+void HeapCache::dump_heaps()
{
Mutex::Autolock _l(mHeapCacheLock);
int c = mHeapCache.size();
@@ -459,7 +470,7 @@ void HeapCache::dump_heaps()
BpMemoryHeap const* h(static_cast<BpMemoryHeap const *>(info.heap.get()));
LOGD("hey=%p, heap=%p, count=%d, (fd=%d, base=%p, size=%d)",
mHeapCache.keyAt(i).unsafe_get(),
- info.heap.get(), info.count,
+ info.heap.get(), info.count,
h->mHeapId, h->mBase, h->mSize);
}
}
diff --git a/libs/binder/MemoryHeapBase.cpp b/libs/binder/MemoryHeapBase.cpp
index 9f501e2..bf4a73f 100644
--- a/libs/binder/MemoryHeapBase.cpp
+++ b/libs/binder/MemoryHeapBase.cpp
@@ -40,15 +40,15 @@ namespace android {
// ---------------------------------------------------------------------------
-MemoryHeapBase::MemoryHeapBase()
+MemoryHeapBase::MemoryHeapBase()
: mFD(-1), mSize(0), mBase(MAP_FAILED),
- mDevice(NULL), mNeedUnmap(false)
+ mDevice(NULL), mNeedUnmap(false), mOffset(0)
{
}
MemoryHeapBase::MemoryHeapBase(size_t size, uint32_t flags, char const * name)
: mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
- mDevice(0), mNeedUnmap(false)
+ mDevice(0), mNeedUnmap(false), mOffset(0)
{
const size_t pagesize = getpagesize();
size = ((size + pagesize-1) & ~(pagesize-1));
@@ -65,7 +65,7 @@ MemoryHeapBase::MemoryHeapBase(size_t size, uint32_t flags, char const * name)
MemoryHeapBase::MemoryHeapBase(const char* device, size_t size, uint32_t flags)
: mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
- mDevice(0), mNeedUnmap(false)
+ mDevice(0), mNeedUnmap(false), mOffset(0)
{
int open_flags = O_RDWR;
if (flags & NO_CACHING)
@@ -84,7 +84,7 @@ MemoryHeapBase::MemoryHeapBase(const char* device, size_t size, uint32_t flags)
MemoryHeapBase::MemoryHeapBase(int fd, size_t size, uint32_t flags, uint32_t offset)
: mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
- mDevice(0), mNeedUnmap(false)
+ mDevice(0), mNeedUnmap(false), mOffset(0)
{
const size_t pagesize = getpagesize();
size = ((size + pagesize-1) & ~(pagesize-1));
@@ -141,6 +141,7 @@ status_t MemoryHeapBase::mapfd(int fd, size_t size, uint32_t offset)
}
mFD = fd;
mSize = size;
+ mOffset = offset;
return NO_ERROR;
}
@@ -183,5 +184,9 @@ const char* MemoryHeapBase::getDevice() const {
return mDevice;
}
+uint32_t MemoryHeapBase::getOffset() const {
+ return mOffset;
+}
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/libs/binder/Permission.cpp b/libs/binder/Permission.cpp
deleted file mode 100644
index fd8fe69..0000000
--- a/libs/binder/Permission.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdint.h>
-#include <utils/Log.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/Permission.h>
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-Permission::Permission(char const* name)
- : mPermissionName(name), mPid(getpid())
-{
-}
-
-Permission::Permission(const String16& name)
- : mPermissionName(name), mPid(getpid())
-{
-}
-
-Permission::Permission(const Permission& rhs)
- : mPermissionName(rhs.mPermissionName),
- mGranted(rhs.mGranted),
- mPid(rhs.mPid)
-{
-}
-
-Permission::~Permission()
-{
-}
-
-bool Permission::operator < (const Permission& rhs) const
-{
- return mPermissionName < rhs.mPermissionName;
-}
-
-bool Permission::checkCalling() const
-{
- IPCThreadState* ipcState = IPCThreadState::self();
- pid_t pid = ipcState->getCallingPid();
- uid_t uid = ipcState->getCallingUid();
- return doCheckPermission(pid, uid);
-}
-
-bool Permission::check(pid_t pid, uid_t uid) const
-{
- return doCheckPermission(pid, uid);
-}
-
-bool Permission::doCheckPermission(pid_t pid, uid_t uid) const
-{
- if ((uid == 0) || (pid == mPid)) {
- // root and ourselves is always okay
- return true;
- } else {
- // see if we already granted this permission for this uid
- Mutex::Autolock _l(mLock);
- if (mGranted.indexOf(uid) >= 0)
- return true;
- }
-
- bool granted = checkPermission(mPermissionName, pid, uid);
- if (granted) {
- Mutex::Autolock _l(mLock);
- // no need to check again, the old item will be replaced if it is
- // already there.
- mGranted.add(uid);
- }
- return granted;
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/binder/PermissionCache.cpp b/libs/binder/PermissionCache.cpp
new file mode 100644
index 0000000..7278187
--- /dev/null
+++ b/libs/binder/PermissionCache.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "PermissionCache"
+
+#include <stdint.h>
+#include <utils/Log.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/PermissionCache.h>
+#include <utils/String8.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+ANDROID_SINGLETON_STATIC_INSTANCE(PermissionCache) ;
+
+// ----------------------------------------------------------------------------
+
+PermissionCache::PermissionCache() {
+}
+
+status_t PermissionCache::check(bool* granted,
+ const String16& permission, uid_t uid) const {
+ Mutex::Autolock _l(mLock);
+ Entry e;
+ e.name = permission;
+ e.uid = uid;
+ ssize_t index = mCache.indexOf(e);
+ if (index >= 0) {
+ *granted = mCache.itemAt(index).granted;
+ return NO_ERROR;
+ }
+ return NAME_NOT_FOUND;
+}
+
+void PermissionCache::cache(const String16& permission,
+ uid_t uid, bool granted) {
+ Mutex::Autolock _l(mLock);
+ Entry e;
+ ssize_t index = mPermissionNamesPool.indexOf(permission);
+ if (index > 0) {
+ e.name = mPermissionNamesPool.itemAt(index);
+ } else {
+ mPermissionNamesPool.add(permission);
+ e.name = permission;
+ }
+ // note, we don't need to store the pid, which is not actually used in
+ // permission checks
+ e.uid = uid;
+ e.granted = granted;
+ index = mCache.indexOf(e);
+ if (index < 0) {
+ mCache.add(e);
+ }
+}
+
+void PermissionCache::purge() {
+ Mutex::Autolock _l(mLock);
+ mCache.clear();
+}
+
+bool PermissionCache::checkCallingPermission(const String16& permission) {
+ return PermissionCache::checkCallingPermission(permission, NULL, NULL);
+}
+
+bool PermissionCache::checkCallingPermission(
+ const String16& permission, int32_t* outPid, int32_t* outUid) {
+ IPCThreadState* ipcState = IPCThreadState::self();
+ pid_t pid = ipcState->getCallingPid();
+ uid_t uid = ipcState->getCallingUid();
+ if (outPid) *outPid = pid;
+ if (outUid) *outUid = uid;
+ return PermissionCache::checkPermission(permission, pid, uid);
+}
+
+bool PermissionCache::checkPermission(
+ const String16& permission, pid_t pid, uid_t uid) {
+ if ((uid == 0) || (pid == getpid())) {
+ // root and ourselves is always okay
+ return true;
+ }
+
+ PermissionCache& pc(PermissionCache::getInstance());
+ bool granted = false;
+ if (pc.check(&granted, permission, uid) != NO_ERROR) {
+ nsecs_t t = -systemTime();
+ granted = android::checkPermission(permission, pid, uid);
+ t += systemTime();
+ LOGD("checking %s for uid=%d => %s (%d us)",
+ String8(permission).string(), uid,
+ granted?"granted":"denied", (int)ns2us(t));
+ pc.cache(permission, uid, granted);
+ }
+ return granted;
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 2d4e10d..7264ac4 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -43,8 +43,6 @@
#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
-static bool gSingleProcess = false;
-
// ---------------------------------------------------------------------------
@@ -82,12 +80,6 @@ sp<ProcessState> ProcessState::self()
return gProcess;
}
-void ProcessState::setSingleProcess(bool singleProcess)
-{
- gSingleProcess = singleProcess;
-}
-
-
void ProcessState::setContextObject(const sp<IBinder>& object)
{
setContextObject(object, String16("default"));
@@ -95,11 +87,7 @@ void ProcessState::setContextObject(const sp<IBinder>& object)
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
{
- if (supportsProcesses()) {
- return getStrongProxyForHandle(0);
- } else {
- return getContextObject(String16("default"), caller);
- }
+ return getStrongProxyForHandle(0);
}
void ProcessState::setContextObject(const sp<IBinder>& object, const String16& name)
@@ -144,11 +132,6 @@ sp<IBinder> ProcessState::getContextObject(const String16& name, const sp<IBinde
return object;
}
-bool ProcessState::supportsProcesses() const
-{
- return mDriverFD >= 0;
-}
-
void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
@@ -169,24 +152,19 @@ bool ProcessState::becomeContextManager(context_check_func checkFunc, void* user
AutoMutex _l(mLock);
mBinderContextCheckFunc = checkFunc;
mBinderContextUserData = userData;
- if (mDriverFD >= 0) {
- int dummy = 0;
+
+ int dummy = 0;
#if defined(HAVE_ANDROID_OS)
- status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
+ status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
#else
- status_t result = INVALID_OPERATION;
+ status_t result = INVALID_OPERATION;
#endif
- if (result == 0) {
- mManagesContexts = true;
- } else if (result == -1) {
- mBinderContextCheckFunc = NULL;
- mBinderContextUserData = NULL;
- LOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
- }
- } else {
- // If there is no driver, our only world is the local
- // process so we can always become the context manager there.
+ if (result == 0) {
mManagesContexts = true;
+ } else if (result == -1) {
+ mBinderContextCheckFunc = NULL;
+ mBinderContextUserData = NULL;
+ LOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
}
}
return mManagesContexts;
@@ -322,10 +300,6 @@ void ProcessState::spawnPooledThread(bool isMain)
static int open_driver()
{
- if (gSingleProcess) {
- return -1;
- }
-
int fd = open("/dev/binder", O_RDWR);
if (fd >= 0) {
fcntl(fd, F_SETFD, FD_CLOEXEC);
@@ -386,9 +360,8 @@ ProcessState::ProcessState()
mDriverFD = -1;
#endif
}
- if (mDriverFD < 0) {
- // Need to run without the driver, starting our own thread pool.
- }
+
+ LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating.");
}
ProcessState::~ProcessState()