diff options
author | 2024-08-14 17:50:30 +0800 | |
---|---|---|
committer | 2024-08-27 01:29:44 +0000 | |
commit | edee03a7be38a0327b108fc02bd947c641351c47 (patch) | |
tree | a039d93bc5df57e80eccd71c0b23c75b254ecf77 | |
parent | a3dba622d541aa7aaf530cbe531a7d003b12ac49 (diff) |
[Binder][XIAOMI][Bugfix] Skip appops header in native parcel. [2/2]
Fix parse fail between native and java binder.
The same way as strict mode header.
Bug: 359692915
Test: atest binderUnitTest
Change-Id: I6a488e4a98159baf79018dc90adf1c64969b5b85
-rw-r--r-- | libs/binder/Status.cpp | 52 | ||||
-rw-r--r-- | libs/binder/include/binder/Status.h | 5 |
2 files changed, 43 insertions, 14 deletions
diff --git a/libs/binder/Status.cpp b/libs/binder/Status.cpp index dba65878fb..9a98097af8 100644 --- a/libs/binder/Status.cpp +++ b/libs/binder/Status.cpp @@ -99,27 +99,28 @@ status_t Status::readFromParcel(const Parcel& parcel) { return status; } - // Skip over fat response headers. Not used (or propagated) in native code. - if (mException == EX_HAS_REPLY_HEADER) { - // Note that the header size includes the 4 byte size field. - const size_t header_start = parcel.dataPosition(); - // Get available size before reading more - const size_t header_avail = parcel.dataAvail(); - - int32_t header_size; - status = parcel.readInt32(&header_size); + if (mException == EX_HAS_NOTED_APPOPS_REPLY_HEADER) { + status = skipUnusedHeader(parcel); + if (status != OK) { + setFromStatusT(status); + return status; + } + // Read next exception code. + status = parcel.readInt32(&mException); if (status != OK) { setFromStatusT(status); return status; } + } - if (header_size < 0 || static_cast<size_t>(header_size) > header_avail) { - android_errorWriteLog(0x534e4554, "132650049"); - setFromStatusT(UNKNOWN_ERROR); - return UNKNOWN_ERROR; + // Skip over fat response headers. Not used (or propagated) in native code. + if (mException == EX_HAS_REPLY_HEADER) { + status = skipUnusedHeader(parcel); + if (status != OK) { + setFromStatusT(status); + return status; } - parcel.setDataPosition(header_start + header_size); // And fat response headers are currently only used when there are no // exceptions, so act like there was no error. mException = EX_NONE; @@ -257,5 +258,28 @@ String8 Status::toString8() const { return ret; } +status_t Status::skipUnusedHeader(const Parcel& parcel) { + // Note that the header size includes the 4 byte size field. + const size_t header_start = parcel.dataPosition(); + // Get available size before reading more + const size_t header_avail = parcel.dataAvail(); + + int32_t header_size; + status_t status = parcel.readInt32(&header_size); + ALOGD("Skip unused header. exception code: %d, start: %zu, size: %d.", + mException, header_start, header_size); + if (status != OK) { + return status; + } + + if (header_size < 0 || static_cast<size_t>(header_size) > header_avail) { + android_errorWriteLog(0x534e4554, "132650049"); + return UNKNOWN_ERROR; + } + + parcel.setDataPosition(header_start + header_size); + return OK; +} + } // namespace binder } // namespace android diff --git a/libs/binder/include/binder/Status.h b/libs/binder/include/binder/Status.h index 49ccf7c36c..d69f662891 100644 --- a/libs/binder/include/binder/Status.h +++ b/libs/binder/include/binder/Status.h @@ -67,6 +67,9 @@ public: EX_SERVICE_SPECIFIC = -8, EX_PARCELABLE = -9, + // See android/os/Parcel.java. We need to handle this in native code. + EX_HAS_NOTED_APPOPS_REPLY_HEADER = -127, + // This is special and Java specific; see Parcel.java. EX_HAS_REPLY_HEADER = -128, // This is special, and indicates to C++ binder proxies that the @@ -150,6 +153,8 @@ private: Status(int32_t exceptionCode, int32_t errorCode); Status(int32_t exceptionCode, int32_t errorCode, const String8& message); + status_t skipUnusedHeader(const Parcel& parcel); + // If |mException| == EX_TRANSACTION_FAILED, generated code will return // |mErrorCode| as the result of the transaction rather than write an // exception to the reply parcel. |