summaryrefslogtreecommitdiff
path: root/libs/binder/Parcel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/binder/Parcel.cpp')
-rw-r--r--libs/binder/Parcel.cpp88
1 files changed, 58 insertions, 30 deletions
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 333b95badc..19f3606bfa 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -1063,12 +1063,22 @@ status_t Parcel::writeCString(const char* str)
status_t Parcel::writeString8(const String8& str)
{
- status_t err = writeInt32(str.bytes());
- // only write string if its length is more than zero characters,
- // as readString8 will only read if the length field is non-zero.
- // this is slightly different from how writeString16 works.
- if (str.bytes() > 0 && err == NO_ERROR) {
- err = write(str.string(), str.bytes()+1);
+ return writeString8(str.string(), str.size());
+}
+
+status_t Parcel::writeString8(const char* str, size_t len)
+{
+ if (str == nullptr) return writeInt32(-1);
+
+ status_t err = writeInt32(len);
+ if (err == NO_ERROR) {
+ uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char));
+ if (data) {
+ memcpy(data, str, len);
+ *reinterpret_cast<char*>(data+len) = 0;
+ return NO_ERROR;
+ }
+ err = mError;
}
return err;
}
@@ -2023,37 +2033,39 @@ const char* Parcel::readCString() const
String8 Parcel::readString8() const
{
- String8 retString;
- status_t status = readString8(&retString);
- if (status != OK) {
- // We don't care about errors here, so just return an empty string.
- return String8();
- }
- return retString;
+ size_t len;
+ const char* str = readString8Inplace(&len);
+ if (str) return String8(str, len);
+ ALOGE("Reading a NULL string not supported here.");
+ return String8();
}
status_t Parcel::readString8(String8* pArg) const
{
- int32_t size;
- status_t status = readInt32(&size);
- if (status != OK) {
- return status;
- }
- // watch for potential int overflow from size+1
- if (size < 0 || size >= INT32_MAX) {
- return BAD_VALUE;
- }
- // |writeString8| writes nothing for empty string.
- if (size == 0) {
+ size_t len;
+ const char* str = readString8Inplace(&len);
+ if (str) {
+ pArg->setTo(str, len);
+ return 0;
+ } else {
*pArg = String8();
- return OK;
+ return UNEXPECTED_NULL;
}
- const char* str = (const char*)readInplace(size + 1);
- if (str == nullptr) {
- return BAD_VALUE;
+}
+
+const char* Parcel::readString8Inplace(size_t* outLen) const
+{
+ int32_t size = readInt32();
+ // watch for potential int overflow from size+1
+ if (size >= 0 && size < INT32_MAX) {
+ *outLen = size;
+ const char* str = (const char*)readInplace(size+1);
+ if (str != nullptr) {
+ return str;
+ }
}
- pArg->setTo(str, size);
- return OK;
+ *outLen = 0;
+ return nullptr;
}
String16 Parcel::readString16() const
@@ -2515,6 +2527,22 @@ void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
mObjectsSize = 0;
break;
}
+ const flat_binder_object* flat
+ = reinterpret_cast<const flat_binder_object*>(mData + offset);
+ uint32_t type = flat->hdr.type;
+ if (!(type == BINDER_TYPE_BINDER || type == BINDER_TYPE_HANDLE ||
+ type == BINDER_TYPE_FD)) {
+ // We should never receive other types (eg BINDER_TYPE_FDA) as long as we don't support
+ // them in libbinder. If we do receive them, it probably means a kernel bug; try to
+ // recover gracefully by clearing out the objects, and releasing the objects we do
+ // know about.
+ android_errorWriteLog(0x534e4554, "135930648");
+ ALOGE("%s: unsupported type object (%" PRIu32 ") at offset %" PRIu64 "\n",
+ __func__, type, (uint64_t)offset);
+ releaseObjects();
+ mObjectsSize = 0;
+ break;
+ }
minOffset = offset + sizeof(flat_binder_object);
}
scanForFds();