Merge "Limit the number of keys read by KeyCharacterMaps."
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index 3ada1e9..7b80dd9 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_PARCEL_H
#define ANDROID_PARCEL_H
+#include <vector>
+
#include <cutils/native_handle.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
@@ -108,6 +110,18 @@
status_t writeWeakBinder(const wp<IBinder>& val);
status_t writeInt32Array(size_t len, const int32_t *val);
status_t writeByteArray(size_t len, const uint8_t *val);
+ status_t writeBool(bool val);
+ status_t writeChar(char16_t val);
+ status_t writeByte(int8_t val);
+
+ status_t writeByteVector(const std::vector<int8_t>& val);
+ status_t writeInt32Vector(const std::vector<int32_t>& val);
+ status_t writeInt64Vector(const std::vector<int64_t>& val);
+ status_t writeFloatVector(const std::vector<float>& val);
+ status_t writeDoubleVector(const std::vector<double>& val);
+ status_t writeBoolVector(const std::vector<bool>& val);
+ status_t writeCharVector(const std::vector<char16_t>& val);
+ status_t writeString16Vector(const std::vector<String16>& val);
template<typename T>
status_t write(const Flattenable<T>& val);
@@ -118,7 +132,7 @@
// Place a native_handle into the parcel (the native_handle's file-
// descriptors are dup'ed, so it is safe to delete the native_handle
- // when this function returns).
+ // when this function returns).
// Doesn't take ownership of the native_handle.
status_t writeNativeHandle(const native_handle* handle);
@@ -169,14 +183,30 @@
status_t readDouble(double *pArg) const;
intptr_t readIntPtr() const;
status_t readIntPtr(intptr_t *pArg) const;
+ bool readBool() const;
+ status_t readBool(bool *pArg) const;
+ char16_t readChar() const;
+ status_t readChar(char16_t *pArg) const;
+ int8_t readByte() const;
+ status_t readByte(int8_t *pArg) const;
const char* readCString() const;
String8 readString8() const;
String16 readString16() const;
+ status_t readString16(String16* pArg) const;
const char16_t* readString16Inplace(size_t* outLen) const;
sp<IBinder> readStrongBinder() const;
wp<IBinder> readWeakBinder() const;
+ status_t readByteVector(std::vector<int8_t>* val) const;
+ status_t readInt32Vector(std::vector<int32_t>* val) const;
+ status_t readInt64Vector(std::vector<int64_t>* val) const;
+ status_t readFloatVector(std::vector<float>* val) const;
+ status_t readDoubleVector(std::vector<double>* val) const;
+ status_t readBoolVector(std::vector<bool>* val) const;
+ status_t readCharVector(std::vector<char16_t>* val) const;
+ status_t readString16Vector(std::vector<String16>* val) const;
+
template<typename T>
status_t read(Flattenable<T>& val) const;
@@ -342,9 +372,11 @@
private:
size_t mBlobAshmemSize;
+ size_t mOpenAshmemSize;
public:
size_t getBlobAshmemSize() const;
+ size_t getOpenAshmemSize() const;
};
// ---------------------------------------------------------------------------
@@ -412,9 +444,9 @@
// Generic acquire and release of objects.
void acquire_object(const sp<ProcessState>& proc,
- const flat_binder_object& obj, const void* who);
+ const flat_binder_object& obj, const void* who, size_t* outAshmemSize);
void release_object(const sp<ProcessState>& proc,
- const flat_binder_object& obj, const void* who);
+ const flat_binder_object& obj, const void* who, size_t* outAshmemSize);
void flatten_binder(const sp<ProcessState>& proc,
const sp<IBinder>& binder, flat_binder_object* out);
diff --git a/libs/binder/Debug.cpp b/libs/binder/Debug.cpp
index bdb7182..a8f2da5 100644
--- a/libs/binder/Debug.cpp
+++ b/libs/binder/Debug.cpp
@@ -138,7 +138,7 @@
*pos = 0;
return pos;
}
-
+
if( fullContext ) {
*pos++ = '0';
*pos++ = 'x';
@@ -167,21 +167,21 @@
if (func == NULL) func = defaultPrintFunc;
size_t offset;
-
+
unsigned char *pos = (unsigned char *)buf;
-
+
if (pos == NULL) {
if (singleLineBytesCutoff < 0) func(cookie, "\n");
func(cookie, "(NULL)");
return;
}
-
+
if (length == 0) {
if (singleLineBytesCutoff < 0) func(cookie, "\n");
func(cookie, "(empty)");
return;
}
-
+
if ((int32_t)length < 0) {
if (singleLineBytesCutoff < 0) func(cookie, "\n");
char buf[64];
@@ -189,12 +189,12 @@
func(cookie, buf);
return;
}
-
+
char buffer[256];
static const size_t maxBytesPerLine = (sizeof(buffer)-1-11-4)/(3+1);
-
+
if (bytesPerLine > maxBytesPerLine) bytesPerLine = maxBytesPerLine;
-
+
const bool oneLine = (int32_t)length <= singleLineBytesCutoff;
bool newLine = false;
if (cStyle) {
@@ -205,7 +205,7 @@
func(cookie, "\n");
newLine = true;
}
-
+
for (offset = 0; ; offset += bytesPerLine, pos += bytesPerLine) {
long remain = length;
@@ -217,21 +217,20 @@
size_t index;
size_t word;
-
+
for (word = 0; word < bytesPerLine; ) {
const size_t startIndex = word+(alignment-(alignment?1:0));
- const ssize_t dir = -1;
for (index = 0; index < alignment || (alignment == 0 && index < bytesPerLine); index++) {
-
+
if (!cStyle) {
if (index == 0 && word > 0 && alignment > 0) {
*c++ = ' ';
}
-
+
if (remain-- > 0) {
- const unsigned char val = *(pos+startIndex+(index*dir));
+ const unsigned char val = *(pos+startIndex-index);
*c++ = makehexdigit(val>>4);
*c++ = makehexdigit(val);
} else if (!oneLine) {
@@ -248,14 +247,14 @@
*c++ = '0';
*c++ = 'x';
}
- const unsigned char val = *(pos+startIndex+(index*dir));
+ const unsigned char val = *(pos+startIndex-index);
*c++ = makehexdigit(val>>4);
*c++ = makehexdigit(val);
remain--;
}
}
}
-
+
word += index;
}
@@ -272,7 +271,7 @@
*c++ = ' ';
}
}
-
+
*c++ = '\'';
if (length > bytesPerLine) *c++ = '\n';
} else {
@@ -284,7 +283,7 @@
*c = 0;
func(cookie, buffer);
newLine = true;
-
+
if (length <= bytesPerLine) break;
length -= bytesPerLine;
}
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 134aadc..61f24d6 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -33,7 +33,7 @@
sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
-
+
{
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == NULL) {
@@ -43,7 +43,7 @@
sleep(1);
}
}
-
+
return gDefaultServiceManager;
}
@@ -67,11 +67,16 @@
bool checkPermission(const String16& permission, pid_t pid, uid_t uid)
{
+#ifdef __BRILLO__
+ // Brillo doesn't currently run ActivityManager or support framework permissions.
+ return true;
+#endif
+
sp<IPermissionController> pc;
gDefaultServiceManagerLock.lock();
pc = gPermissionController;
gDefaultServiceManagerLock.unlock();
-
+
int64_t startTime = 0;
while (true) {
@@ -85,14 +90,14 @@
}
return res;
}
-
+
// Is this a permission failure, or did the controller go away?
if (IInterface::asBinder(pc)->isBinderAlive()) {
ALOGW("Permission failure: %s from uid=%d pid=%d",
String8(permission).string(), uid, pid);
return false;
}
-
+
// Object is dead!
gDefaultServiceManagerLock.lock();
if (gPermissionController == pc) {
@@ -100,7 +105,7 @@
}
gDefaultServiceManagerLock.unlock();
}
-
+
// Need to retrieve the permission controller.
sp<IBinder> binder = defaultServiceManager()->checkService(_permission);
if (binder == NULL) {
@@ -113,7 +118,7 @@
sleep(1);
} else {
pc = interface_cast<IPermissionController>(binder);
- // Install the new permission controller, and try again.
+ // Install the new permission controller, and try again.
gDefaultServiceManagerLock.lock();
gPermissionController = pc;
gDefaultServiceManagerLock.unlock();
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 8315c58..5a62fce 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -96,7 +96,7 @@
};
void acquire_object(const sp<ProcessState>& proc,
- const flat_binder_object& obj, const void* who)
+ const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
{
switch (obj.type) {
case BINDER_TYPE_BINDER:
@@ -123,8 +123,13 @@
return;
}
case BINDER_TYPE_FD: {
- // intentionally blank -- nothing to do to acquire this, but we do
- // recognize it as a legitimate object type.
+ if (obj.cookie != 0) {
+ // If we own an ashmem fd, keep track of how much memory it refers to.
+ int size = ashmem_get_size_region(obj.handle);
+ if (size > 0) {
+ *outAshmemSize += size;
+ }
+ }
return;
}
}
@@ -133,7 +138,7 @@
}
void release_object(const sp<ProcessState>& proc,
- const flat_binder_object& obj, const void* who)
+ const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
{
switch (obj.type) {
case BINDER_TYPE_BINDER:
@@ -160,7 +165,14 @@
return;
}
case BINDER_TYPE_FD: {
- if (obj.cookie != 0) close(obj.handle);
+ if (obj.cookie != 0) {
+ int size = ashmem_get_size_region(obj.handle);
+ if (size > 0) {
+ *outAshmemSize -= size;
+ }
+
+ close(obj.handle);
+ }
return;
}
}
@@ -502,7 +514,7 @@
flat_binder_object* flat
= reinterpret_cast<flat_binder_object*>(mData + off);
- acquire_object(proc, *flat, this);
+ acquire_object(proc, *flat, this, &mOpenAshmemSize);
if (flat->type == BINDER_TYPE_FD) {
// If this is a file descriptor, we need to dup it so the
@@ -715,6 +727,190 @@
return NULL;
}
+status_t Parcel::writeByteVector(const std::vector<int8_t>& val)
+{
+ if (val.size() > std::numeric_limits<int32_t>::max()) {
+ return BAD_VALUE;
+ }
+
+ status_t status = writeInt32(val.size());
+
+ if (status != OK) {
+ return status;
+ }
+
+ for (const auto& item : val) {
+ status = writeByte(item);
+
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ return OK;
+}
+
+status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val)
+{
+ if (val.size() > std::numeric_limits<int32_t>::max()) {
+ return BAD_VALUE;
+ }
+
+ status_t status = writeInt32(val.size());
+
+ if (status != OK) {
+ return status;
+ }
+
+ for (const auto& item : val) {
+ status = writeInt32(item);
+
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ return OK;
+}
+
+status_t Parcel::writeInt64Vector(const std::vector<int64_t>& val)
+{
+ if (val.size() > std::numeric_limits<int32_t>::max()) {
+ return BAD_VALUE;
+ }
+
+ status_t status = writeInt32(val.size());
+
+ if (status != OK) {
+ return status;
+ }
+
+ for (const auto& item : val) {
+ status = writeInt64(item);
+
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ return OK;
+}
+
+status_t Parcel::writeFloatVector(const std::vector<float>& val)
+{
+ if (val.size() > std::numeric_limits<int32_t>::max()) {
+ return BAD_VALUE;
+ }
+
+ status_t status = writeInt32(val.size());
+
+ if (status != OK) {
+ return status;
+ }
+
+ for (const auto& item : val) {
+ status = writeFloat(item);
+
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ return OK;
+}
+
+status_t Parcel::writeDoubleVector(const std::vector<double>& val)
+{
+ if (val.size() > std::numeric_limits<int32_t>::max()) {
+ return BAD_VALUE;
+ }
+
+ status_t status = writeInt32(val.size());
+
+ if (status != OK) {
+ return status;
+ }
+
+ for (const auto& item : val) {
+ status = writeDouble(item);
+
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ return OK;
+}
+
+status_t Parcel::writeBoolVector(const std::vector<bool>& val)
+{
+ if (val.size() > std::numeric_limits<int32_t>::max()) {
+ return BAD_VALUE;
+ }
+
+ status_t status = writeInt32(val.size());
+
+ if (status != OK) {
+ return status;
+ }
+
+ for (const auto& item : val) {
+ status = writeBool(item);
+
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ return OK;
+}
+
+status_t Parcel::writeCharVector(const std::vector<char16_t>& val)
+{
+ if (val.size() > std::numeric_limits<int32_t>::max()) {
+ return BAD_VALUE;
+ }
+
+ status_t status = writeInt32(val.size());
+
+ if (status != OK) {
+ return status;
+ }
+
+ for (const auto& item : val) {
+ status = writeChar(item);
+
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ return OK;
+}
+
+status_t Parcel::writeString16Vector(const std::vector<String16>& val)
+{
+ if (val.size() > std::numeric_limits<int32_t>::max()) {
+ return BAD_VALUE;
+ }
+
+ status_t status = writeInt32(val.size());
+
+ if (status != OK) {
+ return status;
+ }
+
+ for (const auto& item : val) {
+ status = writeString16(item);
+
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ return OK;
+}
+
status_t Parcel::writeInt32(int32_t val)
{
return writeAligned(val);
@@ -758,6 +954,21 @@
return ret;
}
+status_t Parcel::writeBool(bool val)
+{
+ return writeInt32(int32_t(val));
+}
+
+status_t Parcel::writeChar(char16_t val)
+{
+ return writeInt32(int32_t(val));
+}
+
+status_t Parcel::writeByte(int8_t val)
+{
+ return writeInt32(int32_t(val));
+}
+
status_t Parcel::writeInt64(int64_t val)
{
return writeAligned(val);
@@ -1024,7 +1235,7 @@
// Need to write meta-data?
if (nullMetaData || val.binder != 0) {
mObjects[mObjectsSize] = mDataPos;
- acquire_object(ProcessState::self(), val, this);
+ acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize);
mObjectsSize++;
}
@@ -1132,6 +1343,232 @@
return err;
}
+status_t Parcel::readByteVector(std::vector<int8_t>* val) const {
+ val->clear();
+
+ int32_t size;
+ status_t status = readInt32(&size);
+
+ if (status != OK) {
+ return status;
+ }
+
+ if (size < 0) {
+ return BAD_VALUE;
+ }
+
+ val->resize(size);
+
+ for (auto& v : *val) {
+ status = readByte(&v);
+
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ return OK;
+}
+
+status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
+ val->clear();
+
+ int32_t size;
+ status_t status = readInt32(&size);
+
+ if (status != OK) {
+ return status;
+ }
+
+ if (size < 0) {
+ return BAD_VALUE;
+ }
+
+ val->resize(size);
+
+ for (auto& v: *val) {
+ status = readInt32(&v);
+
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ return OK;
+}
+
+status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const {
+ val->clear();
+
+ int32_t size;
+ status_t status = readInt32(&size);
+
+ if (status != OK) {
+ return status;
+ }
+
+ if (size < 0) {
+ return BAD_VALUE;
+ }
+
+ val->resize(size);
+
+ for (auto& v : *val) {
+ status = readInt64(&v);
+
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ return OK;
+}
+
+status_t Parcel::readFloatVector(std::vector<float>* val) const {
+ val->clear();
+
+ int32_t size;
+ status_t status = readInt32(&size);
+
+ if (status != OK) {
+ return status;
+ }
+
+ if (size < 0) {
+ return BAD_VALUE;
+ }
+
+ val->resize(size);
+
+ for (auto& v : *val) {
+ status = readFloat(&v);
+
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ return OK;
+}
+
+status_t Parcel::readDoubleVector(std::vector<double>* val) const {
+ val->clear();
+
+ int32_t size;
+ status_t status = readInt32(&size);
+
+ if (status != OK) {
+ return status;
+ }
+
+ if (size < 0) {
+ return BAD_VALUE;
+ }
+
+ val->resize(size);
+
+ for (auto& v : *val) {
+ status = readDouble(&v);
+
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ return OK;
+}
+
+status_t Parcel::readBoolVector(std::vector<bool>* val) const {
+ val->clear();
+
+ int32_t size;
+ status_t status = readInt32(&size);
+
+ if (status != OK) {
+ return status;
+ }
+
+ if (size < 0) {
+ return BAD_VALUE;
+ }
+
+ val->resize(size);
+
+ /* C++ bool handling means a vector of bools isn't necessarily addressable
+ * (we might use individual bits)
+ */
+ for (int32_t i = 0; i < size; size++) {
+ bool data;
+ status = readBool(&data);
+ (*val)[i] = data;
+
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ return OK;
+}
+
+status_t Parcel::readCharVector(std::vector<char16_t>* val) const {
+ val->clear();
+
+ int32_t size;
+ status_t status = readInt32(&size);
+
+ if (status != OK) {
+ return status;
+ }
+
+ if (size < 0) {
+ return BAD_VALUE;
+ }
+
+ val->resize(size);
+
+ for (auto& v : *val) {
+ status = readChar(&v);
+
+ if (status != OK) {
+ return status;
+ }
+ }
+
+ return OK;
+}
+
+status_t Parcel::readString16Vector(std::vector<String16>* val) const {
+ val->clear();
+
+ int32_t size;
+ status_t status = readInt32(&size);
+
+ if (status != OK) {
+ return status;
+ }
+
+ if (size < 0) {
+ return BAD_VALUE;
+ }
+
+ val->reserve(size);
+
+ while (size-- > 0) {
+ const char16_t *data;
+ size_t size;
+ data = readString16Inplace(&size);
+
+ if (data == nullptr) {
+ return UNKNOWN_ERROR;
+ }
+
+ val->emplace_back(data, size);
+ }
+
+ return OK;
+}
+
+
status_t Parcel::readInt32(int32_t *pArg) const
{
return readAligned(pArg);
@@ -1250,6 +1687,44 @@
return readAligned<intptr_t>();
}
+status_t Parcel::readBool(bool *pArg) const
+{
+ int32_t tmp;
+ status_t ret = readInt32(&tmp);
+ *pArg = (tmp != 0);
+ return ret;
+}
+
+bool Parcel::readBool() const
+{
+ return readInt32() != 0;
+}
+
+status_t Parcel::readChar(char16_t *pArg) const
+{
+ int32_t tmp;
+ status_t ret = readInt32(&tmp);
+ *pArg = char16_t(tmp);
+ return ret;
+}
+
+char16_t Parcel::readChar() const
+{
+ return char16_t(readInt32());
+}
+
+status_t Parcel::readByte(int8_t *pArg) const
+{
+ int32_t tmp;
+ status_t ret = readInt32(&tmp);
+ *pArg = int8_t(tmp);
+ return ret;
+}
+
+int8_t Parcel::readByte() const
+{
+ return int8_t(readInt32());
+}
const char* Parcel::readCString() const
{
@@ -1288,6 +1763,19 @@
return String16();
}
+status_t Parcel::readString16(String16* pArg) const
+{
+ size_t len;
+ const char16_t* str = readString16Inplace(&len);
+ if (str) {
+ pArg->setTo(str, len);
+ return 0;
+ } else {
+ *pArg = String16();
+ return UNKNOWN_ERROR;
+ }
+}
+
const char16_t* Parcel::readString16Inplace(size_t* outLen) const
{
int32_t size = readInt32();
@@ -1607,7 +2095,7 @@
i--;
const flat_binder_object* flat
= reinterpret_cast<flat_binder_object*>(data+objects[i]);
- release_object(proc, *flat, this);
+ release_object(proc, *flat, this, &mOpenAshmemSize);
}
}
@@ -1621,7 +2109,7 @@
i--;
const flat_binder_object* flat
= reinterpret_cast<flat_binder_object*>(data+objects[i]);
- acquire_object(proc, *flat, this);
+ acquire_object(proc, *flat, this, &mOpenAshmemSize);
}
}
@@ -1809,7 +2297,7 @@
// will need to rescan because we may have lopped off the only FDs
mFdsKnown = false;
}
- release_object(proc, *flat, this);
+ release_object(proc, *flat, this, &mOpenAshmemSize);
}
binder_size_t* objects =
(binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
@@ -1896,6 +2384,7 @@
mAllowFds = true;
mOwner = NULL;
mBlobAshmemSize = 0;
+ mOpenAshmemSize = 0;
}
void Parcel::scanForFds() const
@@ -1918,6 +2407,11 @@
return mBlobAshmemSize;
}
+size_t Parcel::getOpenAshmemSize() const
+{
+ return mOpenAshmemSize;
+}
+
// --- Parcel::Blob ---
Parcel::Blob::Blob() :