diff options
| author | 2021-05-14 19:50:52 +0000 | |
|---|---|---|
| committer | 2021-05-15 02:10:52 +0000 | |
| commit | d4f73fbf0f41d12dc744f3397f75a01e6dd0e516 (patch) | |
| tree | 7439951d47c2f4609ee87360855abe171f5eac75 /libs/binder/Parcel.cpp | |
| parent | 06e367beaa56d75c103bbb38d19d9b97713b6881 (diff) | |
libbinder: resizeOutVector size check
Like the other functions, but with a much higher limit since we can't
actually know the size of a vector that will be returned. Likely this
value could be scoped down incrementally.
Bug: 131868573
Test: binder_parcel_fuzzer
Change-Id: I8a73fd51bf25b66fb1398f9715891bbb5d6f0857
Diffstat (limited to 'libs/binder/Parcel.cpp')
| -rw-r--r-- | libs/binder/Parcel.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index e4dfa52189..9795348a0c 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -1466,6 +1466,29 @@ const void* Parcel::readInplace(size_t len) const return nullptr; } +status_t Parcel::readOutVectorSizeWithCheck(size_t elmSize, int32_t* size) const { + if (status_t status = readInt32(size); status != OK) return status; + if (*size < 0) return OK; // may be null, client to handle + + LOG_ALWAYS_FATAL_IF(elmSize > INT32_MAX, "Cannot have element as big as %zu", elmSize); + + // approximation, can't know max element size (e.g. if it makes heap + // allocations) + static_assert(sizeof(int) == sizeof(int32_t), "Android is LP64"); + int32_t allocationSize; + if (__builtin_smul_overflow(elmSize, *size, &allocationSize)) return NO_MEMORY; + + // High limit of 1MB since something this big could never be returned. Could + // probably scope this down, but might impact very specific usecases. + constexpr int32_t kMaxAllocationSize = 1 * 1000 * 1000; + + if (allocationSize >= kMaxAllocationSize) { + return NO_MEMORY; + } + + return OK; +} + template<class T> status_t Parcel::readAligned(T *pArg) const { static_assert(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T)); |