blob: 7fb18c5af2566469e00f4340728166de93830f30 [file] [log] [blame]
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001/*
2 * Copyright (C) 2005 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Parcel"
18//#define LOG_NDEBUG 0
19
Mark Salyzynabed7f72016-01-27 08:02:48 -080020#include <errno.h>
Mark Salyzyn70f36652016-02-02 10:27:03 -080021#include <fcntl.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080022#include <inttypes.h>
Steven Morelandbf1915b2020-07-16 22:43:02 +000023#include <linux/sched.h>
Mark Salyzyn70f36652016-02-02 10:27:03 -080024#include <pthread.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080025#include <stdint.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <sys/mman.h>
Mark Salyzyneab2afc2016-01-27 08:02:48 -080029#include <sys/stat.h>
30#include <sys/types.h>
Christopher Tatee4e0ae82016-03-24 16:03:44 -070031#include <sys/resource.h>
Mark Salyzyneab2afc2016-01-27 08:02:48 -080032#include <unistd.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070033
Mathias Agopianc5b2c0b2009-05-19 19:08:10 -070034#include <binder/Binder.h>
35#include <binder/BpBinder.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080036#include <binder/IPCThreadState.h>
37#include <binder/Parcel.h>
Mathias Agopianc5b2c0b2009-05-19 19:08:10 -070038#include <binder/ProcessState.h>
Steven Moreland6e5a7752019-08-05 20:30:14 -070039#include <binder/Stability.h>
Christopher Wiley09eb7492015-11-09 15:06:15 -080040#include <binder/Status.h>
Mathias Agopian002e1e52013-05-06 20:20:50 -070041#include <binder/TextOutput.h>
42
Mark Salyzynabed7f72016-01-27 08:02:48 -080043#include <cutils/ashmem.h>
Mathias Agopian002e1e52013-05-06 20:20:50 -070044#include <utils/Debug.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080045#include <utils/Flattenable.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070046#include <utils/Log.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080047#include <utils/misc.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070048#include <utils/String8.h>
49#include <utils/String16.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070050
Mathias Agopian208059f2009-05-18 15:08:03 -070051#include <private/binder/binder_module.h>
Steven Morelanda4853cd2019-07-12 15:44:37 -070052#include "Static.h"
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070053
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070054#define LOG_REFS(...)
Mark Salyzyne93390b2016-01-27 08:02:48 -080055//#define LOG_REFS(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
Dianne Hackborn7e790af2014-11-11 12:22:53 -080056#define LOG_ALLOC(...)
Mark Salyzyne93390b2016-01-27 08:02:48 -080057//#define LOG_ALLOC(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070058
59// ---------------------------------------------------------------------------
60
Nick Kralevichb6b14232015-04-02 09:36:02 -070061// This macro should never be used at runtime, as a too large value
62// of s could cause an integer overflow. Instead, you should always
63// use the wrapper function pad_size()
64#define PAD_SIZE_UNSAFE(s) (((s)+3)&~3)
65
66static size_t pad_size(size_t s) {
Steven Moreland28723ae2019-04-01 18:52:30 -070067 if (s > (std::numeric_limits<size_t>::max() - 3)) {
Steven Moreland6adf33c2019-09-25 13:18:09 -070068 LOG_ALWAYS_FATAL("pad size too big %zu", s);
Nick Kralevichb6b14232015-04-02 09:36:02 -070069 }
70 return PAD_SIZE_UNSAFE(s);
71}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070072
Brad Fitzpatricka877cd82010-07-07 16:06:39 -070073// Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
Jeff Sharkey05827be2018-06-26 10:52:38 -060074#define STRICT_MODE_PENALTY_GATHER (1 << 31)
Brad Fitzpatricka877cd82010-07-07 16:06:39 -070075
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070076namespace android {
77
Steven Moreland7b102262019-08-01 15:48:43 -070078// many things compile this into prebuilts on the stack
79static_assert(sizeof(Parcel) == 60 || sizeof(Parcel) == 120);
80
Dianne Hackborna4cff882014-11-13 17:07:40 -080081static pthread_mutex_t gParcelGlobalAllocSizeLock = PTHREAD_MUTEX_INITIALIZER;
82static size_t gParcelGlobalAllocSize = 0;
83static size_t gParcelGlobalAllocCount = 0;
84
Christopher Tatee4e0ae82016-03-24 16:03:44 -070085static size_t gMaxFds = 0;
86
Jeff Brown13b16042014-11-11 16:44:25 -080087// Maximum size of a blob to transfer in-place.
88static const size_t BLOB_INPLACE_LIMIT = 16 * 1024;
89
90enum {
91 BLOB_INPLACE = 0,
92 BLOB_ASHMEM_IMMUTABLE = 1,
93 BLOB_ASHMEM_MUTABLE = 2,
94};
95
Steven Morelandb1c81202019-04-05 18:49:55 -070096static void acquire_object(const sp<ProcessState>& proc,
Adrian Rooscbf37262015-10-22 16:12:53 -070097 const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070098{
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -070099 switch (obj.hdr.type) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700100 case BINDER_TYPE_BINDER:
101 if (obj.binder) {
102 LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800103 reinterpret_cast<IBinder*>(obj.cookie)->incStrong(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700104 }
105 return;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700106 case BINDER_TYPE_HANDLE: {
107 const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
Yi Kong91635562018-06-07 14:38:36 -0700108 if (b != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700109 LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
110 b->incStrong(who);
111 }
112 return;
113 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700114 case BINDER_TYPE_FD: {
Jorim Jaggi150b4ef2018-07-13 11:18:30 +0000115 if ((obj.cookie != 0) && (outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
Mark Salyzyn80589362016-08-23 16:15:04 -0700116 // If we own an ashmem fd, keep track of how much memory it refers to.
117 int size = ashmem_get_size_region(obj.handle);
118 if (size > 0) {
119 *outAshmemSize += size;
Adrian Rooscbf37262015-10-22 16:12:53 -0700120 }
121 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700122 return;
123 }
124 }
125
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700126 ALOGD("Invalid object type 0x%08x", obj.hdr.type);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700127}
128
Adrian Roos6bb31142015-10-22 16:46:12 -0700129static void release_object(const sp<ProcessState>& proc,
Adrian Rooscbf37262015-10-22 16:12:53 -0700130 const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700131{
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700132 switch (obj.hdr.type) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700133 case BINDER_TYPE_BINDER:
134 if (obj.binder) {
135 LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800136 reinterpret_cast<IBinder*>(obj.cookie)->decStrong(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700137 }
138 return;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700139 case BINDER_TYPE_HANDLE: {
140 const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
Yi Kong91635562018-06-07 14:38:36 -0700141 if (b != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700142 LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
143 b->decStrong(who);
144 }
145 return;
146 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700147 case BINDER_TYPE_FD: {
Mark Salyzynb454d8f2016-01-27 08:02:48 -0800148 if (obj.cookie != 0) { // owned
Jorim Jaggi150b4ef2018-07-13 11:18:30 +0000149 if ((outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
Mark Salyzyn80589362016-08-23 16:15:04 -0700150 int size = ashmem_get_size_region(obj.handle);
151 if (size > 0) {
Tri Voaa6e1112019-01-29 13:23:46 -0800152 // ashmem size might have changed since last time it was accounted for, e.g.
153 // in acquire_object(). Value of *outAshmemSize is not critical since we are
154 // releasing the object anyway. Check for integer overflow condition.
155 *outAshmemSize -= std::min(*outAshmemSize, static_cast<size_t>(size));
Adrian Roos6bb31142015-10-22 16:46:12 -0700156 }
Adrian Roos6bb31142015-10-22 16:46:12 -0700157 }
Mark Salyzynb454d8f2016-01-27 08:02:48 -0800158
159 close(obj.handle);
Adrian Rooscbf37262015-10-22 16:12:53 -0700160 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700161 return;
162 }
163 }
164
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700165 ALOGE("Invalid object type 0x%08x", obj.hdr.type);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700166}
167
Steven Morelanda86a3562019-08-01 23:28:34 +0000168status_t Parcel::finishFlattenBinder(
169 const sp<IBinder>& binder, const flat_binder_object& flat)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700170{
Steven Morelanda86a3562019-08-01 23:28:34 +0000171 status_t status = writeObject(flat, false);
172 if (status != OK) return status;
173
Steven Moreland6e5a7752019-08-05 20:30:14 -0700174 internal::Stability::tryMarkCompilationUnit(binder.get());
Steven Morelanda86a3562019-08-01 23:28:34 +0000175 return writeInt32(internal::Stability::get(binder.get()));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700176}
177
Steven Morelanda86a3562019-08-01 23:28:34 +0000178status_t Parcel::finishUnflattenBinder(
179 const sp<IBinder>& binder, sp<IBinder>* out) const
180{
181 int32_t stability;
182 status_t status = readInt32(&stability);
183 if (status != OK) return status;
184
Steven Moreland05929552019-07-31 17:51:25 -0700185 status = internal::Stability::set(binder.get(), stability, true /*log*/);
Steven Morelanda86a3562019-08-01 23:28:34 +0000186 if (status != OK) return status;
187
188 *out = binder;
189 return OK;
190}
191
Steven Morelandbf1915b2020-07-16 22:43:02 +0000192static constexpr inline int schedPolicyMask(int policy, int priority) {
193 return (priority & FLAT_BINDER_FLAG_PRIORITY_MASK) | ((policy & 3) << FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT);
194}
195
Steven Morelanda86a3562019-08-01 23:28:34 +0000196status_t Parcel::flattenBinder(const sp<IBinder>& binder)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700197{
198 flat_binder_object obj;
Steven Morelandbf1915b2020-07-16 22:43:02 +0000199 obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700200
Steven Morelandbf1915b2020-07-16 22:43:02 +0000201 int schedBits = 0;
202 if (!IPCThreadState::self()->backgroundSchedulingDisabled()) {
203 schedBits = schedPolicyMask(SCHED_NORMAL, 19);
Martijn Coenen2b631742017-05-05 11:16:59 -0700204 }
205
Yi Kong91635562018-06-07 14:38:36 -0700206 if (binder != nullptr) {
Steven Morelandf0212002018-12-26 13:59:23 -0800207 BBinder *local = binder->localBinder();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700208 if (!local) {
209 BpBinder *proxy = binder->remoteBinder();
Yi Kong91635562018-06-07 14:38:36 -0700210 if (proxy == nullptr) {
Steve Blocke6f43dd2012-01-06 19:20:56 +0000211 ALOGE("null proxy");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700212 }
213 const int32_t handle = proxy ? proxy->handle() : 0;
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700214 obj.hdr.type = BINDER_TYPE_HANDLE;
Arve Hjønnevåg07fd0f12014-02-18 21:10:29 -0800215 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700216 obj.handle = handle;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800217 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700218 } else {
Steven Morelandbf1915b2020-07-16 22:43:02 +0000219 int policy = local->getMinSchedulerPolicy();
220 int priority = local->getMinSchedulerPriority();
221
222 if (policy != 0 || priority != 0) {
223 // override value, since it is set explicitly
224 schedBits = schedPolicyMask(policy, priority);
225 }
Steven Morelandf0212002018-12-26 13:59:23 -0800226 if (local->isRequestingSid()) {
227 obj.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
228 }
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700229 obj.hdr.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800230 obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
231 obj.cookie = reinterpret_cast<uintptr_t>(local);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700232 }
233 } else {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700234 obj.hdr.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800235 obj.binder = 0;
236 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700237 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700238
Steven Morelandbf1915b2020-07-16 22:43:02 +0000239 obj.flags |= schedBits;
240
Steven Morelanda86a3562019-08-01 23:28:34 +0000241 return finishFlattenBinder(binder, obj);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700242}
243
Steven Morelanda86a3562019-08-01 23:28:34 +0000244status_t Parcel::unflattenBinder(sp<IBinder>* out) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700245{
Steven Morelanda86a3562019-08-01 23:28:34 +0000246 const flat_binder_object* flat = readObject(false);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700247
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700248 if (flat) {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700249 switch (flat->hdr.type) {
Steven Morelanda86a3562019-08-01 23:28:34 +0000250 case BINDER_TYPE_BINDER: {
251 sp<IBinder> binder = reinterpret_cast<IBinder*>(flat->cookie);
252 return finishUnflattenBinder(binder, out);
253 }
254 case BINDER_TYPE_HANDLE: {
255 sp<IBinder> binder =
256 ProcessState::self()->getStrongProxyForHandle(flat->handle);
257 return finishUnflattenBinder(binder, out);
258 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700259 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700260 }
261 return BAD_TYPE;
262}
263
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700264// ---------------------------------------------------------------------------
265
266Parcel::Parcel()
267{
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800268 LOG_ALLOC("Parcel %p: constructing", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700269 initState();
270}
271
272Parcel::~Parcel()
273{
274 freeDataNoInit();
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800275 LOG_ALLOC("Parcel %p: destroyed", this);
276}
277
278size_t Parcel::getGlobalAllocSize() {
Dianne Hackborna4cff882014-11-13 17:07:40 -0800279 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
280 size_t size = gParcelGlobalAllocSize;
281 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
282 return size;
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800283}
284
285size_t Parcel::getGlobalAllocCount() {
Dianne Hackborna4cff882014-11-13 17:07:40 -0800286 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
287 size_t count = gParcelGlobalAllocCount;
288 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
289 return count;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700290}
291
292const uint8_t* Parcel::data() const
293{
294 return mData;
295}
296
297size_t Parcel::dataSize() const
298{
299 return (mDataSize > mDataPos ? mDataSize : mDataPos);
300}
301
302size_t Parcel::dataAvail() const
303{
Nick Kralevichcfe27de2015-09-16 09:49:15 -0700304 size_t result = dataSize() - dataPosition();
305 if (result > INT32_MAX) {
Steven Moreland6adf33c2019-09-25 13:18:09 -0700306 LOG_ALWAYS_FATAL("result too big: %zu", result);
Nick Kralevichcfe27de2015-09-16 09:49:15 -0700307 }
308 return result;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700309}
310
311size_t Parcel::dataPosition() const
312{
313 return mDataPos;
314}
315
316size_t Parcel::dataCapacity() const
317{
318 return mDataCapacity;
319}
320
321status_t Parcel::setDataSize(size_t size)
322{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700323 if (size > INT32_MAX) {
324 // don't accept size_t values which may have come from an
325 // inadvertent conversion from a negative int.
326 return BAD_VALUE;
327 }
328
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700329 status_t err;
330 err = continueWrite(size);
331 if (err == NO_ERROR) {
332 mDataSize = size;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700333 ALOGV("setDataSize Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700334 }
335 return err;
336}
337
338void Parcel::setDataPosition(size_t pos) const
339{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700340 if (pos > INT32_MAX) {
341 // don't accept size_t values which may have come from an
342 // inadvertent conversion from a negative int.
Steven Moreland6adf33c2019-09-25 13:18:09 -0700343 LOG_ALWAYS_FATAL("pos too big: %zu", pos);
Nick Kralevichb6b14232015-04-02 09:36:02 -0700344 }
345
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700346 mDataPos = pos;
347 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -0800348 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700349}
350
351status_t Parcel::setDataCapacity(size_t size)
352{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700353 if (size > INT32_MAX) {
354 // don't accept size_t values which may have come from an
355 // inadvertent conversion from a negative int.
356 return BAD_VALUE;
357 }
358
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -0700359 if (size > mDataCapacity) return continueWrite(size);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700360 return NO_ERROR;
361}
362
363status_t Parcel::setData(const uint8_t* buffer, size_t len)
364{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700365 if (len > INT32_MAX) {
366 // don't accept size_t values which may have come from an
367 // inadvertent conversion from a negative int.
368 return BAD_VALUE;
369 }
370
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700371 status_t err = restartWrite(len);
372 if (err == NO_ERROR) {
373 memcpy(const_cast<uint8_t*>(data()), buffer, len);
374 mDataSize = len;
375 mFdsKnown = false;
376 }
377 return err;
378}
379
Andreas Huber51faf462011-04-13 10:21:56 -0700380status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700381{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700382 status_t err;
Andreas Huber51faf462011-04-13 10:21:56 -0700383 const uint8_t *data = parcel->mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800384 const binder_size_t *objects = parcel->mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700385 size_t size = parcel->mObjectsSize;
386 int startPos = mDataPos;
387 int firstIndex = -1, lastIndex = -2;
388
389 if (len == 0) {
390 return NO_ERROR;
391 }
392
Nick Kralevichb6b14232015-04-02 09:36:02 -0700393 if (len > INT32_MAX) {
394 // don't accept size_t values which may have come from an
395 // inadvertent conversion from a negative int.
396 return BAD_VALUE;
397 }
398
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700399 // range checks against the source parcel size
400 if ((offset > parcel->mDataSize)
401 || (len > parcel->mDataSize)
402 || (offset + len > parcel->mDataSize)) {
403 return BAD_VALUE;
404 }
405
406 // Count objects in range
407 for (int i = 0; i < (int) size; i++) {
408 size_t off = objects[i];
Christopher Tate27182be2015-05-27 17:53:02 -0700409 if ((off >= offset) && (off + sizeof(flat_binder_object) <= offset + len)) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700410 if (firstIndex == -1) {
411 firstIndex = i;
412 }
413 lastIndex = i;
414 }
415 }
416 int numObjects = lastIndex - firstIndex + 1;
417
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -0700418 if ((mDataSize+len) > mDataCapacity) {
419 // grow data
420 err = growData(len);
421 if (err != NO_ERROR) {
422 return err;
423 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700424 }
425
426 // append data
427 memcpy(mData + mDataPos, data + offset, len);
428 mDataPos += len;
429 mDataSize += len;
430
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400431 err = NO_ERROR;
432
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700433 if (numObjects > 0) {
Martijn Coenen69390d42018-10-22 15:18:10 +0200434 const sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700435 // grow objects
436 if (mObjectsCapacity < mObjectsSize + numObjects) {
Martijn Coenenda2f2fd2020-01-22 10:46:25 +0100437 if ((size_t) numObjects > SIZE_MAX - mObjectsSize) return NO_MEMORY; // overflow
438 if (mObjectsSize + numObjects > SIZE_MAX / 3) return NO_MEMORY; // overflow
Christopher Tateed7a50c2015-06-08 14:45:14 -0700439 size_t newSize = ((mObjectsSize + numObjects)*3)/2;
Martijn Coenenda2f2fd2020-01-22 10:46:25 +0100440 if (newSize > SIZE_MAX / sizeof(binder_size_t)) return NO_MEMORY; // overflow
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800441 binder_size_t *objects =
442 (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
Yi Kong91635562018-06-07 14:38:36 -0700443 if (objects == (binder_size_t*)nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700444 return NO_MEMORY;
445 }
446 mObjects = objects;
447 mObjectsCapacity = newSize;
448 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700449
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700450 // append and acquire objects
451 int idx = mObjectsSize;
452 for (int i = firstIndex; i <= lastIndex; i++) {
453 size_t off = objects[i] - offset + startPos;
454 mObjects[idx++] = off;
455 mObjectsSize++;
456
Dianne Hackborn8af0f822009-05-22 13:20:23 -0700457 flat_binder_object* flat
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700458 = reinterpret_cast<flat_binder_object*>(mData + off);
Adrian Rooscbf37262015-10-22 16:12:53 -0700459 acquire_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700460
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700461 if (flat->hdr.type == BINDER_TYPE_FD) {
Dianne Hackborn8af0f822009-05-22 13:20:23 -0700462 // If this is a file descriptor, we need to dup it so the
463 // new Parcel now owns its own fd, and can declare that we
464 // officially know we have fds.
Nick Kralevichec9ec7d2016-12-17 19:47:27 -0800465 flat->handle = fcntl(flat->handle, F_DUPFD_CLOEXEC, 0);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800466 flat->cookie = 1;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700467 mHasFds = mFdsKnown = true;
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400468 if (!mAllowFds) {
469 err = FDS_NOT_ALLOWED;
470 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700471 }
472 }
473 }
474
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400475 return err;
476}
477
Dianne Hackborn15feb9b2017-04-10 15:34:35 -0700478int Parcel::compareData(const Parcel& other) {
479 size_t size = dataSize();
480 if (size != other.dataSize()) {
481 return size < other.dataSize() ? -1 : 1;
482 }
483 return memcmp(data(), other.data(), size);
484}
485
Jeff Brown13b16042014-11-11 16:44:25 -0800486bool Parcel::allowFds() const
487{
488 return mAllowFds;
489}
490
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700491bool Parcel::pushAllowFds(bool allowFds)
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400492{
493 const bool origValue = mAllowFds;
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700494 if (!allowFds) {
495 mAllowFds = false;
496 }
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400497 return origValue;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700498}
499
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700500void Parcel::restoreAllowFds(bool lastValue)
501{
502 mAllowFds = lastValue;
503}
504
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700505bool Parcel::hasFileDescriptors() const
506{
507 if (!mFdsKnown) {
508 scanForFds();
509 }
510 return mHasFds;
511}
512
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000513void Parcel::updateWorkSourceRequestHeaderPosition() const {
514 // Only update the request headers once. We only want to point
515 // to the first headers read/written.
516 if (!mRequestHeaderPresent) {
517 mWorkSourceRequestHeaderPosition = dataPosition();
518 mRequestHeaderPresent = true;
519 }
520}
521
Steven Moreland8852cc72020-08-18 18:15:03 +0000522#ifdef __ANDROID_APEX__
523#error APEX cannot include libbinder. The wire protocol for libbinder is not\
524 frozen, and including it in an APEX would also require APEX\
525 servicemanagers which is not an options. Use libbinder_ndk instead.
526#endif
527
528#if defined(__ANDROID_VNDK__)
Steven Moreland0f452742019-07-31 15:50:51 +0000529constexpr int32_t kHeader = B_PACK_CHARS('V', 'N', 'D', 'R');
530#else
531constexpr int32_t kHeader = B_PACK_CHARS('S', 'Y', 'S', 'T');
532#endif
533
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700534// Write RPC headers. (previously just the interface token)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700535status_t Parcel::writeInterfaceToken(const String16& interface)
536{
Olivier Gaillard91a04802018-11-14 17:32:41 +0000537 const IPCThreadState* threadState = IPCThreadState::self();
538 writeInt32(threadState->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER);
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000539 updateWorkSourceRequestHeaderPosition();
Olivier Gaillard91a04802018-11-14 17:32:41 +0000540 writeInt32(threadState->shouldPropagateWorkSource() ?
541 threadState->getCallingWorkSourceUid() : IPCThreadState::kUnsetWorkSource);
Steven Moreland0f452742019-07-31 15:50:51 +0000542 writeInt32(kHeader);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700543 // currently the interface identification token is just its name as a string
544 return writeString16(interface);
545}
546
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000547bool Parcel::replaceCallingWorkSourceUid(uid_t uid)
548{
549 if (!mRequestHeaderPresent) {
550 return false;
551 }
552
553 const size_t initialPosition = dataPosition();
554 setDataPosition(mWorkSourceRequestHeaderPosition);
555 status_t err = writeInt32(uid);
556 setDataPosition(initialPosition);
557 return err == NO_ERROR;
558}
559
Steven Moreland0891c9b2019-05-06 15:05:13 -0700560uid_t Parcel::readCallingWorkSourceUid() const
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000561{
562 if (!mRequestHeaderPresent) {
563 return IPCThreadState::kUnsetWorkSource;
564 }
565
566 const size_t initialPosition = dataPosition();
567 setDataPosition(mWorkSourceRequestHeaderPosition);
568 uid_t uid = readInt32();
569 setDataPosition(initialPosition);
570 return uid;
571}
572
Mathias Agopian83c04462009-05-22 19:00:22 -0700573bool Parcel::checkInterface(IBinder* binder) const
574{
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700575 return enforceInterface(binder->getInterfaceDescriptor());
Mathias Agopian83c04462009-05-22 19:00:22 -0700576}
577
Brad Fitzpatricka877cd82010-07-07 16:06:39 -0700578bool Parcel::enforceInterface(const String16& interface,
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700579 IPCThreadState* threadState) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700580{
Daniel Colascione0bb330d2019-10-29 16:44:19 -0700581 return enforceInterface(interface.string(), interface.size(), threadState);
582}
583
584bool Parcel::enforceInterface(const char16_t* interface,
585 size_t len,
586 IPCThreadState* threadState) const
587{
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100588 // StrictModePolicy.
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700589 int32_t strictPolicy = readInt32();
Yi Kong91635562018-06-07 14:38:36 -0700590 if (threadState == nullptr) {
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700591 threadState = IPCThreadState::self();
Brad Fitzpatricka877cd82010-07-07 16:06:39 -0700592 }
Brad Fitzpatrick52736032010-08-30 16:01:16 -0700593 if ((threadState->getLastTransactionBinderFlags() &
594 IBinder::FLAG_ONEWAY) != 0) {
595 // For one-way calls, the callee is running entirely
596 // disconnected from the caller, so disable StrictMode entirely.
597 // Not only does disk/network usage not impact the caller, but
598 // there's no way to commuicate back any violations anyway.
599 threadState->setStrictModePolicy(0);
600 } else {
601 threadState->setStrictModePolicy(strictPolicy);
602 }
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100603 // WorkSource.
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000604 updateWorkSourceRequestHeaderPosition();
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100605 int32_t workSource = readInt32();
Olivier Gaillard91a04802018-11-14 17:32:41 +0000606 threadState->setCallingWorkSourceUidWithoutPropagation(workSource);
Steven Moreland0f452742019-07-31 15:50:51 +0000607 // vendor header
608 int32_t header = readInt32();
609 if (header != kHeader) {
610 ALOGE("Expecting header 0x%x but found 0x%x. Mixing copies of libbinder?", kHeader, header);
611 return false;
612 }
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100613 // Interface descriptor.
Daniel Colascione0bb330d2019-10-29 16:44:19 -0700614 size_t parcel_interface_len;
615 const char16_t* parcel_interface = readString16Inplace(&parcel_interface_len);
616 if (len == parcel_interface_len &&
617 (!len || !memcmp(parcel_interface, interface, len * sizeof (char16_t)))) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700618 return true;
619 } else {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700620 ALOGW("**** enforceInterface() expected '%s' but read '%s'",
Daniel Colascione0bb330d2019-10-29 16:44:19 -0700621 String8(interface, len).string(),
622 String8(parcel_interface, parcel_interface_len).string());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700623 return false;
624 }
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700625}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700626
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700627size_t Parcel::objectsCount() const
628{
629 return mObjectsSize;
630}
631
632status_t Parcel::errorCheck() const
633{
634 return mError;
635}
636
637void Parcel::setError(status_t err)
638{
639 mError = err;
640}
641
642status_t Parcel::finishWrite(size_t len)
643{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700644 if (len > INT32_MAX) {
645 // don't accept size_t values which may have come from an
646 // inadvertent conversion from a negative int.
647 return BAD_VALUE;
648 }
649
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700650 //printf("Finish write of %d\n", len);
651 mDataPos += len;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700652 ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700653 if (mDataPos > mDataSize) {
654 mDataSize = mDataPos;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700655 ALOGV("finishWrite Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700656 }
657 //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
658 return NO_ERROR;
659}
660
661status_t Parcel::writeUnpadded(const void* data, size_t len)
662{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700663 if (len > INT32_MAX) {
664 // don't accept size_t values which may have come from an
665 // inadvertent conversion from a negative int.
666 return BAD_VALUE;
667 }
668
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700669 size_t end = mDataPos + len;
670 if (end < mDataPos) {
671 // integer overflow
672 return BAD_VALUE;
673 }
674
675 if (end <= mDataCapacity) {
676restart_write:
677 memcpy(mData+mDataPos, data, len);
678 return finishWrite(len);
679 }
680
681 status_t err = growData(len);
682 if (err == NO_ERROR) goto restart_write;
683 return err;
684}
685
686status_t Parcel::write(const void* data, size_t len)
687{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700688 if (len > INT32_MAX) {
689 // don't accept size_t values which may have come from an
690 // inadvertent conversion from a negative int.
691 return BAD_VALUE;
692 }
693
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700694 void* const d = writeInplace(len);
695 if (d) {
696 memcpy(d, data, len);
697 return NO_ERROR;
698 }
699 return mError;
700}
701
702void* Parcel::writeInplace(size_t len)
703{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700704 if (len > INT32_MAX) {
705 // don't accept size_t values which may have come from an
706 // inadvertent conversion from a negative int.
Yi Kong91635562018-06-07 14:38:36 -0700707 return nullptr;
Nick Kralevichb6b14232015-04-02 09:36:02 -0700708 }
709
710 const size_t padded = pad_size(len);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700711
712 // sanity check for integer overflow
713 if (mDataPos+padded < mDataPos) {
Yi Kong91635562018-06-07 14:38:36 -0700714 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700715 }
716
717 if ((mDataPos+padded) <= mDataCapacity) {
718restart_write:
719 //printf("Writing %ld bytes, padded to %ld\n", len, padded);
720 uint8_t* const data = mData+mDataPos;
721
722 // Need to pad at end?
723 if (padded != len) {
724#if BYTE_ORDER == BIG_ENDIAN
725 static const uint32_t mask[4] = {
726 0x00000000, 0xffffff00, 0xffff0000, 0xff000000
727 };
728#endif
729#if BYTE_ORDER == LITTLE_ENDIAN
730 static const uint32_t mask[4] = {
731 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
732 };
733#endif
734 //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
735 // *reinterpret_cast<void**>(data+padded-4));
736 *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
737 }
738
739 finishWrite(padded);
740 return data;
741 }
742
743 status_t err = growData(padded);
744 if (err == NO_ERROR) goto restart_write;
Yi Kong91635562018-06-07 14:38:36 -0700745 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700746}
747
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800748status_t Parcel::writeUtf8AsUtf16(const std::string& str) {
749 const uint8_t* strData = (uint8_t*)str.data();
750 const size_t strLen= str.length();
751 const ssize_t utf16Len = utf8_to_utf16_length(strData, strLen);
Sergio Girof4607432016-07-21 14:46:35 +0100752 if (utf16Len < 0 || utf16Len > std::numeric_limits<int32_t>::max()) {
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800753 return BAD_VALUE;
754 }
755
756 status_t err = writeInt32(utf16Len);
757 if (err) {
758 return err;
759 }
760
761 // Allocate enough bytes to hold our converted string and its terminating NULL.
762 void* dst = writeInplace((utf16Len + 1) * sizeof(char16_t));
763 if (!dst) {
764 return NO_MEMORY;
765 }
766
Sergio Girof4607432016-07-21 14:46:35 +0100767 utf8_to_utf16(strData, strLen, (char16_t*)dst, (size_t) utf16Len + 1);
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800768
769 return NO_ERROR;
770}
771
Jooyung Han2d5878e2020-01-23 12:45:10 +0900772status_t Parcel::writeUtf8AsUtf16(const std::optional<std::string>& str) {
773 if (!str) {
774 return writeInt32(-1);
775 }
776 return writeUtf8AsUtf16(*str);
777}
778
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800779status_t Parcel::writeUtf8AsUtf16(const std::unique_ptr<std::string>& str) {
780 if (!str) {
781 return writeInt32(-1);
782 }
783 return writeUtf8AsUtf16(*str);
784}
785
Daniel Normand0337ef2019-09-20 15:46:03 -0700786status_t Parcel::writeByteVectorInternal(const int8_t* data, size_t size) {
787 if (size > std::numeric_limits<int32_t>::max()) {
788 return BAD_VALUE;
Casey Dahlin451ff582015-10-19 18:12:18 -0700789 }
790
Daniel Normand0337ef2019-09-20 15:46:03 -0700791 status_t status = writeInt32(size);
Casey Dahlin451ff582015-10-19 18:12:18 -0700792 if (status != OK) {
793 return status;
794 }
795
Daniel Normand0337ef2019-09-20 15:46:03 -0700796 return write(data, size);
Casey Dahlin451ff582015-10-19 18:12:18 -0700797}
798
Casey Dahlin185d3442016-02-09 11:08:35 -0800799status_t Parcel::writeByteVector(const std::vector<int8_t>& val) {
Daniel Normand0337ef2019-09-20 15:46:03 -0700800 return writeByteVectorInternal(val.data(), val.size());
Casey Dahlin185d3442016-02-09 11:08:35 -0800801}
802
Jooyung Han2d5878e2020-01-23 12:45:10 +0900803status_t Parcel::writeByteVector(const std::optional<std::vector<int8_t>>& val)
804{
805 if (!val) return writeInt32(-1);
806 return writeByteVectorInternal(val->data(), val->size());
807}
808
Casey Dahlin185d3442016-02-09 11:08:35 -0800809status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val)
810{
Daniel Normand0337ef2019-09-20 15:46:03 -0700811 if (!val) return writeInt32(-1);
812 return writeByteVectorInternal(val->data(), val->size());
Casey Dahlin185d3442016-02-09 11:08:35 -0800813}
814
815status_t Parcel::writeByteVector(const std::vector<uint8_t>& val) {
Daniel Normand0337ef2019-09-20 15:46:03 -0700816 return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val.data()), val.size());
Casey Dahlin185d3442016-02-09 11:08:35 -0800817}
818
Jooyung Han2d5878e2020-01-23 12:45:10 +0900819status_t Parcel::writeByteVector(const std::optional<std::vector<uint8_t>>& val)
820{
821 if (!val) return writeInt32(-1);
822 return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size());
823}
824
Casey Dahlin185d3442016-02-09 11:08:35 -0800825status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val)
826{
Daniel Normand0337ef2019-09-20 15:46:03 -0700827 if (!val) return writeInt32(-1);
828 return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size());
Casey Dahlin185d3442016-02-09 11:08:35 -0800829}
830
Casey Dahlin451ff582015-10-19 18:12:18 -0700831status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val)
832{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800833 return writeTypedVector(val, &Parcel::writeInt32);
Casey Dahlin451ff582015-10-19 18:12:18 -0700834}
835
Jooyung Han2d5878e2020-01-23 12:45:10 +0900836status_t Parcel::writeInt32Vector(const std::optional<std::vector<int32_t>>& val)
837{
838 return writeNullableTypedVector(val, &Parcel::writeInt32);
839}
840
Casey Dahlinb9872622015-11-25 15:09:45 -0800841status_t Parcel::writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val)
842{
843 return writeNullableTypedVector(val, &Parcel::writeInt32);
844}
845
Casey Dahlin451ff582015-10-19 18:12:18 -0700846status_t Parcel::writeInt64Vector(const std::vector<int64_t>& val)
847{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800848 return writeTypedVector(val, &Parcel::writeInt64);
Casey Dahlin451ff582015-10-19 18:12:18 -0700849}
850
Jooyung Han2d5878e2020-01-23 12:45:10 +0900851status_t Parcel::writeInt64Vector(const std::optional<std::vector<int64_t>>& val)
852{
853 return writeNullableTypedVector(val, &Parcel::writeInt64);
854}
855
Casey Dahlinb9872622015-11-25 15:09:45 -0800856status_t Parcel::writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val)
857{
858 return writeNullableTypedVector(val, &Parcel::writeInt64);
859}
860
Kevin DuBois2f82d5b2018-12-05 12:56:10 -0800861status_t Parcel::writeUint64Vector(const std::vector<uint64_t>& val)
862{
863 return writeTypedVector(val, &Parcel::writeUint64);
864}
865
Jooyung Han2d5878e2020-01-23 12:45:10 +0900866status_t Parcel::writeUint64Vector(const std::optional<std::vector<uint64_t>>& val)
867{
868 return writeNullableTypedVector(val, &Parcel::writeUint64);
869}
870
Kevin DuBois2f82d5b2018-12-05 12:56:10 -0800871status_t Parcel::writeUint64Vector(const std::unique_ptr<std::vector<uint64_t>>& val)
872{
873 return writeNullableTypedVector(val, &Parcel::writeUint64);
874}
875
Casey Dahlin451ff582015-10-19 18:12:18 -0700876status_t Parcel::writeFloatVector(const std::vector<float>& val)
877{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800878 return writeTypedVector(val, &Parcel::writeFloat);
Casey Dahlin451ff582015-10-19 18:12:18 -0700879}
880
Jooyung Han2d5878e2020-01-23 12:45:10 +0900881status_t Parcel::writeFloatVector(const std::optional<std::vector<float>>& val)
882{
883 return writeNullableTypedVector(val, &Parcel::writeFloat);
884}
885
Casey Dahlinb9872622015-11-25 15:09:45 -0800886status_t Parcel::writeFloatVector(const std::unique_ptr<std::vector<float>>& val)
887{
888 return writeNullableTypedVector(val, &Parcel::writeFloat);
889}
890
Casey Dahlin451ff582015-10-19 18:12:18 -0700891status_t Parcel::writeDoubleVector(const std::vector<double>& val)
892{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800893 return writeTypedVector(val, &Parcel::writeDouble);
Casey Dahlin451ff582015-10-19 18:12:18 -0700894}
895
Jooyung Han2d5878e2020-01-23 12:45:10 +0900896status_t Parcel::writeDoubleVector(const std::optional<std::vector<double>>& val)
897{
898 return writeNullableTypedVector(val, &Parcel::writeDouble);
899}
900
Casey Dahlinb9872622015-11-25 15:09:45 -0800901status_t Parcel::writeDoubleVector(const std::unique_ptr<std::vector<double>>& val)
902{
903 return writeNullableTypedVector(val, &Parcel::writeDouble);
904}
905
Casey Dahlin451ff582015-10-19 18:12:18 -0700906status_t Parcel::writeBoolVector(const std::vector<bool>& val)
907{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800908 return writeTypedVector(val, &Parcel::writeBool);
Casey Dahlin451ff582015-10-19 18:12:18 -0700909}
910
Jooyung Han2d5878e2020-01-23 12:45:10 +0900911status_t Parcel::writeBoolVector(const std::optional<std::vector<bool>>& val)
912{
913 return writeNullableTypedVector(val, &Parcel::writeBool);
914}
915
Casey Dahlinb9872622015-11-25 15:09:45 -0800916status_t Parcel::writeBoolVector(const std::unique_ptr<std::vector<bool>>& val)
917{
918 return writeNullableTypedVector(val, &Parcel::writeBool);
919}
920
Casey Dahlin451ff582015-10-19 18:12:18 -0700921status_t Parcel::writeCharVector(const std::vector<char16_t>& val)
922{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800923 return writeTypedVector(val, &Parcel::writeChar);
Casey Dahlin451ff582015-10-19 18:12:18 -0700924}
925
Jooyung Han2d5878e2020-01-23 12:45:10 +0900926status_t Parcel::writeCharVector(const std::optional<std::vector<char16_t>>& val)
927{
928 return writeNullableTypedVector(val, &Parcel::writeChar);
929}
930
Casey Dahlinb9872622015-11-25 15:09:45 -0800931status_t Parcel::writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val)
932{
933 return writeNullableTypedVector(val, &Parcel::writeChar);
934}
935
Casey Dahlin451ff582015-10-19 18:12:18 -0700936status_t Parcel::writeString16Vector(const std::vector<String16>& val)
937{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800938 return writeTypedVector(val, &Parcel::writeString16);
Casey Dahlin451ff582015-10-19 18:12:18 -0700939}
940
Casey Dahlinb9872622015-11-25 15:09:45 -0800941status_t Parcel::writeString16Vector(
Jooyung Han2d5878e2020-01-23 12:45:10 +0900942 const std::optional<std::vector<std::optional<String16>>>& val)
943{
944 return writeNullableTypedVector(val, &Parcel::writeString16);
945}
946
947status_t Parcel::writeString16Vector(
Casey Dahlinb9872622015-11-25 15:09:45 -0800948 const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val)
949{
950 return writeNullableTypedVector(val, &Parcel::writeString16);
951}
952
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800953status_t Parcel::writeUtf8VectorAsUtf16Vector(
Jooyung Han2d5878e2020-01-23 12:45:10 +0900954 const std::optional<std::vector<std::optional<std::string>>>& val) {
955 return writeNullableTypedVector(val, &Parcel::writeUtf8AsUtf16);
956}
957
958status_t Parcel::writeUtf8VectorAsUtf16Vector(
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800959 const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val) {
960 return writeNullableTypedVector(val, &Parcel::writeUtf8AsUtf16);
961}
962
963status_t Parcel::writeUtf8VectorAsUtf16Vector(const std::vector<std::string>& val) {
964 return writeTypedVector(val, &Parcel::writeUtf8AsUtf16);
965}
966
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700967status_t Parcel::writeInt32(int32_t val)
968{
Andreas Huber84a6d042009-08-17 13:33:27 -0700969 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700970}
Dan Stoza41a0f2f2014-12-01 10:01:10 -0800971
972status_t Parcel::writeUint32(uint32_t val)
973{
974 return writeAligned(val);
975}
976
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700977status_t Parcel::writeInt32Array(size_t len, const int32_t *val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -0700978 if (len > INT32_MAX) {
979 // don't accept size_t values which may have come from an
980 // inadvertent conversion from a negative int.
981 return BAD_VALUE;
982 }
983
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700984 if (!val) {
Chad Brubakere59cb432015-06-30 14:03:55 -0700985 return writeInt32(-1);
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700986 }
Chad Brubakere59cb432015-06-30 14:03:55 -0700987 status_t ret = writeInt32(static_cast<uint32_t>(len));
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700988 if (ret == NO_ERROR) {
989 ret = write(val, len * sizeof(*val));
990 }
991 return ret;
992}
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700993status_t Parcel::writeByteArray(size_t len, const uint8_t *val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -0700994 if (len > INT32_MAX) {
995 // don't accept size_t values which may have come from an
996 // inadvertent conversion from a negative int.
997 return BAD_VALUE;
998 }
999
Marco Nelissenf0190bf2014-03-13 14:17:40 -07001000 if (!val) {
Chad Brubakere59cb432015-06-30 14:03:55 -07001001 return writeInt32(-1);
Marco Nelissenf0190bf2014-03-13 14:17:40 -07001002 }
Chad Brubakere59cb432015-06-30 14:03:55 -07001003 status_t ret = writeInt32(static_cast<uint32_t>(len));
Marco Nelissenf0190bf2014-03-13 14:17:40 -07001004 if (ret == NO_ERROR) {
1005 ret = write(val, len * sizeof(*val));
1006 }
1007 return ret;
1008}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001009
Casey Dahlind6848f52015-10-15 15:44:59 -07001010status_t Parcel::writeBool(bool val)
1011{
1012 return writeInt32(int32_t(val));
1013}
1014
1015status_t Parcel::writeChar(char16_t val)
1016{
1017 return writeInt32(int32_t(val));
1018}
1019
1020status_t Parcel::writeByte(int8_t val)
1021{
1022 return writeInt32(int32_t(val));
1023}
1024
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001025status_t Parcel::writeInt64(int64_t val)
1026{
Andreas Huber84a6d042009-08-17 13:33:27 -07001027 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001028}
1029
Ronghua Wu2d13afd2015-03-16 11:11:07 -07001030status_t Parcel::writeUint64(uint64_t val)
1031{
1032 return writeAligned(val);
1033}
1034
Serban Constantinescuf683e012013-11-05 16:53:55 +00001035status_t Parcel::writePointer(uintptr_t val)
1036{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001037 return writeAligned<binder_uintptr_t>(val);
Serban Constantinescuf683e012013-11-05 16:53:55 +00001038}
1039
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001040status_t Parcel::writeFloat(float val)
1041{
Andreas Huber84a6d042009-08-17 13:33:27 -07001042 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001043}
1044
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001045#if defined(__mips__) && defined(__mips_hard_float)
1046
1047status_t Parcel::writeDouble(double val)
1048{
1049 union {
1050 double d;
1051 unsigned long long ll;
1052 } u;
1053 u.d = val;
1054 return writeAligned(u.ll);
1055}
1056
1057#else
1058
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001059status_t Parcel::writeDouble(double val)
1060{
Andreas Huber84a6d042009-08-17 13:33:27 -07001061 return writeAligned(val);
1062}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001063
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001064#endif
1065
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001066status_t Parcel::writeCString(const char* str)
1067{
1068 return write(str, strlen(str)+1);
1069}
1070
1071status_t Parcel::writeString8(const String8& str)
1072{
Jeff Sharkey2f8bdb52020-04-19 21:41:26 -06001073 return writeString8(str.string(), str.size());
1074}
1075
1076status_t Parcel::writeString8(const char* str, size_t len)
1077{
1078 if (str == nullptr) return writeInt32(-1);
1079
1080 status_t err = writeInt32(len);
1081 if (err == NO_ERROR) {
1082 uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char));
1083 if (data) {
1084 memcpy(data, str, len);
1085 *reinterpret_cast<char*>(data+len) = 0;
1086 return NO_ERROR;
1087 }
1088 err = mError;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001089 }
1090 return err;
1091}
1092
Jooyung Han2d5878e2020-01-23 12:45:10 +09001093status_t Parcel::writeString16(const std::optional<String16>& str)
1094{
1095 if (!str) {
1096 return writeInt32(-1);
1097 }
1098
1099 return writeString16(*str);
1100}
1101
Casey Dahlinb9872622015-11-25 15:09:45 -08001102status_t Parcel::writeString16(const std::unique_ptr<String16>& str)
1103{
1104 if (!str) {
1105 return writeInt32(-1);
1106 }
1107
1108 return writeString16(*str);
1109}
1110
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001111status_t Parcel::writeString16(const String16& str)
1112{
1113 return writeString16(str.string(), str.size());
1114}
1115
1116status_t Parcel::writeString16(const char16_t* str, size_t len)
1117{
Yi Kong91635562018-06-07 14:38:36 -07001118 if (str == nullptr) return writeInt32(-1);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001119
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001120 status_t err = writeInt32(len);
1121 if (err == NO_ERROR) {
1122 len *= sizeof(char16_t);
1123 uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
1124 if (data) {
1125 memcpy(data, str, len);
1126 *reinterpret_cast<char16_t*>(data+len) = 0;
1127 return NO_ERROR;
1128 }
1129 err = mError;
1130 }
1131 return err;
1132}
1133
1134status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
1135{
Steven Morelanda86a3562019-08-01 23:28:34 +00001136 return flattenBinder(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001137}
1138
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001139status_t Parcel::writeStrongBinderVector(const std::vector<sp<IBinder>>& val)
1140{
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001141 return writeTypedVector(val, &Parcel::writeStrongBinder);
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001142}
1143
Jooyung Han2d5878e2020-01-23 12:45:10 +09001144status_t Parcel::writeStrongBinderVector(const std::optional<std::vector<sp<IBinder>>>& val)
1145{
1146 return writeNullableTypedVector(val, &Parcel::writeStrongBinder);
1147}
1148
Casey Dahlinb9872622015-11-25 15:09:45 -08001149status_t Parcel::writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val)
1150{
1151 return writeNullableTypedVector(val, &Parcel::writeStrongBinder);
1152}
1153
Jooyung Han2d5878e2020-01-23 12:45:10 +09001154status_t Parcel::readStrongBinderVector(std::optional<std::vector<sp<IBinder>>>* val) const {
1155 return readNullableTypedVector(val, &Parcel::readNullableStrongBinder);
1156}
1157
Casey Dahlinb9872622015-11-25 15:09:45 -08001158status_t Parcel::readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const {
Christopher Wiley35d77ca2016-03-08 10:49:51 -08001159 return readNullableTypedVector(val, &Parcel::readNullableStrongBinder);
Casey Dahlinb9872622015-11-25 15:09:45 -08001160}
1161
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001162status_t Parcel::readStrongBinderVector(std::vector<sp<IBinder>>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001163 return readTypedVector(val, &Parcel::readStrongBinder);
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001164}
1165
Casey Dahlinb9872622015-11-25 15:09:45 -08001166status_t Parcel::writeRawNullableParcelable(const Parcelable* parcelable) {
1167 if (!parcelable) {
1168 return writeInt32(0);
1169 }
1170
1171 return writeParcelable(*parcelable);
1172}
1173
Christopher Wiley97f048d2015-11-19 06:49:05 -08001174status_t Parcel::writeParcelable(const Parcelable& parcelable) {
1175 status_t status = writeInt32(1); // parcelable is not null.
1176 if (status != OK) {
1177 return status;
1178 }
1179 return parcelable.writeToParcel(this);
1180}
1181
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001182status_t Parcel::writeNativeHandle(const native_handle* handle)
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001183{
Mathias Agopian1d0a95b2009-07-31 16:12:13 -07001184 if (!handle || handle->version != sizeof(native_handle))
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001185 return BAD_TYPE;
1186
1187 status_t err;
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001188 err = writeInt32(handle->numFds);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001189 if (err != NO_ERROR) return err;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001190
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001191 err = writeInt32(handle->numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001192 if (err != NO_ERROR) return err;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001193
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001194 for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)
1195 err = writeDupFileDescriptor(handle->data[i]);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001196
1197 if (err != NO_ERROR) {
Steve Block9d453682011-12-20 16:23:08 +00001198 ALOGD("write native handle, write dup fd failed");
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001199 return err;
1200 }
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001201 err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001202 return err;
1203}
1204
Jeff Brown93ff1f92011-11-04 19:01:44 -07001205status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001206{
1207 flat_binder_object obj;
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07001208 obj.hdr.type = BINDER_TYPE_FD;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001209 obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
Arve Hjønnevåg07fd0f12014-02-18 21:10:29 -08001210 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001211 obj.handle = fd;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001212 obj.cookie = takeOwnership ? 1 : 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001213 return writeObject(obj, true);
1214}
1215
1216status_t Parcel::writeDupFileDescriptor(int fd)
1217{
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08001218 int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
Jeff Brownd341c712011-11-04 20:19:33 -07001219 if (dupFd < 0) {
1220 return -errno;
1221 }
1222 status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/);
Casey Dahlin06673e32015-11-23 13:24:23 -08001223 if (err != OK) {
Jeff Brownd341c712011-11-04 20:19:33 -07001224 close(dupFd);
1225 }
1226 return err;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001227}
1228
Dianne Hackborn1941a402016-08-29 12:30:43 -07001229status_t Parcel::writeParcelFileDescriptor(int fd, bool takeOwnership)
1230{
1231 writeInt32(0);
1232 return writeFileDescriptor(fd, takeOwnership);
1233}
1234
Ryo Hashimotobf551892018-05-31 16:58:35 +09001235status_t Parcel::writeDupParcelFileDescriptor(int fd)
1236{
1237 int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
1238 if (dupFd < 0) {
1239 return -errno;
1240 }
1241 status_t err = writeParcelFileDescriptor(dupFd, true /*takeOwnership*/);
1242 if (err != OK) {
1243 close(dupFd);
1244 }
1245 return err;
1246}
1247
Christopher Wiley2cf19952016-04-11 11:09:37 -07001248status_t Parcel::writeUniqueFileDescriptor(const base::unique_fd& fd) {
Casey Dahlin06673e32015-11-23 13:24:23 -08001249 return writeDupFileDescriptor(fd.get());
1250}
1251
Christopher Wiley2cf19952016-04-11 11:09:37 -07001252status_t Parcel::writeUniqueFileDescriptorVector(const std::vector<base::unique_fd>& val) {
Casey Dahlin06673e32015-11-23 13:24:23 -08001253 return writeTypedVector(val, &Parcel::writeUniqueFileDescriptor);
1254}
1255
Jooyung Han2d5878e2020-01-23 12:45:10 +09001256status_t Parcel::writeUniqueFileDescriptorVector(const std::optional<std::vector<base::unique_fd>>& val) {
1257 return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
1258}
1259
Christopher Wiley2cf19952016-04-11 11:09:37 -07001260status_t Parcel::writeUniqueFileDescriptorVector(const std::unique_ptr<std::vector<base::unique_fd>>& val) {
Casey Dahlinb9872622015-11-25 15:09:45 -08001261 return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
1262}
1263
Jeff Brown13b16042014-11-11 16:44:25 -08001264status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob)
Jeff Brown5707dbf2011-09-23 21:17:56 -07001265{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001266 if (len > INT32_MAX) {
1267 // don't accept size_t values which may have come from an
1268 // inadvertent conversion from a negative int.
1269 return BAD_VALUE;
1270 }
1271
Jeff Brown13b16042014-11-11 16:44:25 -08001272 status_t status;
1273 if (!mAllowFds || len <= BLOB_INPLACE_LIMIT) {
Steve Block6807e592011-10-20 11:56:00 +01001274 ALOGV("writeBlob: write in place");
Jeff Brown13b16042014-11-11 16:44:25 -08001275 status = writeInt32(BLOB_INPLACE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001276 if (status) return status;
1277
1278 void* ptr = writeInplace(len);
1279 if (!ptr) return NO_MEMORY;
1280
Jeff Brown13b16042014-11-11 16:44:25 -08001281 outBlob->init(-1, ptr, len, false);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001282 return NO_ERROR;
1283 }
1284
Steve Block6807e592011-10-20 11:56:00 +01001285 ALOGV("writeBlob: write to ashmem");
Jeff Brown5707dbf2011-09-23 21:17:56 -07001286 int fd = ashmem_create_region("Parcel Blob", len);
1287 if (fd < 0) return NO_MEMORY;
1288
1289 int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
1290 if (result < 0) {
Jeff Brownec4e0062011-10-10 14:50:10 -07001291 status = result;
Jeff Brown5707dbf2011-09-23 21:17:56 -07001292 } else {
Yi Kong91635562018-06-07 14:38:36 -07001293 void* ptr = ::mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001294 if (ptr == MAP_FAILED) {
1295 status = -errno;
1296 } else {
Jeff Brown13b16042014-11-11 16:44:25 -08001297 if (!mutableCopy) {
1298 result = ashmem_set_prot_region(fd, PROT_READ);
1299 }
Jeff Brown5707dbf2011-09-23 21:17:56 -07001300 if (result < 0) {
Jeff Brownec4e0062011-10-10 14:50:10 -07001301 status = result;
Jeff Brown5707dbf2011-09-23 21:17:56 -07001302 } else {
Jeff Brown13b16042014-11-11 16:44:25 -08001303 status = writeInt32(mutableCopy ? BLOB_ASHMEM_MUTABLE : BLOB_ASHMEM_IMMUTABLE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001304 if (!status) {
Jeff Brown93ff1f92011-11-04 19:01:44 -07001305 status = writeFileDescriptor(fd, true /*takeOwnership*/);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001306 if (!status) {
Jeff Brown13b16042014-11-11 16:44:25 -08001307 outBlob->init(fd, ptr, len, mutableCopy);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001308 return NO_ERROR;
1309 }
1310 }
1311 }
1312 }
1313 ::munmap(ptr, len);
1314 }
1315 ::close(fd);
1316 return status;
1317}
1318
Jeff Brown13b16042014-11-11 16:44:25 -08001319status_t Parcel::writeDupImmutableBlobFileDescriptor(int fd)
1320{
1321 // Must match up with what's done in writeBlob.
1322 if (!mAllowFds) return FDS_NOT_ALLOWED;
1323 status_t status = writeInt32(BLOB_ASHMEM_IMMUTABLE);
1324 if (status) return status;
1325 return writeDupFileDescriptor(fd);
1326}
1327
Mathias Agopiane1424282013-07-29 21:24:40 -07001328status_t Parcel::write(const FlattenableHelperInterface& val)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001329{
1330 status_t err;
1331
1332 // size if needed
Mathias Agopiane1424282013-07-29 21:24:40 -07001333 const size_t len = val.getFlattenedSize();
1334 const size_t fd_count = val.getFdCount();
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001335
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001336 if ((len > INT32_MAX) || (fd_count >= gMaxFds)) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001337 // don't accept size_t values which may have come from an
1338 // inadvertent conversion from a negative int.
1339 return BAD_VALUE;
1340 }
1341
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001342 err = this->writeInt32(len);
1343 if (err) return err;
1344
1345 err = this->writeInt32(fd_count);
1346 if (err) return err;
1347
1348 // payload
Martijn Coenenf8542382018-04-04 11:46:56 +02001349 void* const buf = this->writeInplace(len);
Yi Kong91635562018-06-07 14:38:36 -07001350 if (buf == nullptr)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001351 return BAD_VALUE;
1352
Yi Kong91635562018-06-07 14:38:36 -07001353 int* fds = nullptr;
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001354 if (fd_count) {
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001355 fds = new (std::nothrow) int[fd_count];
1356 if (fds == nullptr) {
1357 ALOGE("write: failed to allocate requested %zu fds", fd_count);
1358 return BAD_VALUE;
1359 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001360 }
1361
1362 err = val.flatten(buf, len, fds, fd_count);
1363 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
1364 err = this->writeDupFileDescriptor( fds[i] );
1365 }
1366
1367 if (fd_count) {
1368 delete [] fds;
1369 }
1370
1371 return err;
1372}
1373
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001374status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
1375{
1376 const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
1377 const bool enoughObjects = mObjectsSize < mObjectsCapacity;
1378 if (enoughData && enoughObjects) {
1379restart_write:
1380 *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001381
Christopher Tate98e67d32015-06-03 18:44:15 -07001382 // remember if it's a file descriptor
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07001383 if (val.hdr.type == BINDER_TYPE_FD) {
Christopher Tate98e67d32015-06-03 18:44:15 -07001384 if (!mAllowFds) {
1385 // fail before modifying our object index
1386 return FDS_NOT_ALLOWED;
1387 }
1388 mHasFds = mFdsKnown = true;
1389 }
1390
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001391 // Need to write meta-data?
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001392 if (nullMetaData || val.binder != 0) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001393 mObjects[mObjectsSize] = mDataPos;
Adrian Rooscbf37262015-10-22 16:12:53 -07001394 acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001395 mObjectsSize++;
1396 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001397
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001398 return finishWrite(sizeof(flat_binder_object));
1399 }
1400
1401 if (!enoughData) {
1402 const status_t err = growData(sizeof(val));
1403 if (err != NO_ERROR) return err;
1404 }
1405 if (!enoughObjects) {
Martijn Coenenda2f2fd2020-01-22 10:46:25 +01001406 if (mObjectsSize > SIZE_MAX - 2) return NO_MEMORY; // overflow
1407 if ((mObjectsSize + 2) > SIZE_MAX / 3) return NO_MEMORY; // overflow
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001408 size_t newSize = ((mObjectsSize+2)*3)/2;
Martijn Coenenda2f2fd2020-01-22 10:46:25 +01001409 if (newSize > SIZE_MAX / sizeof(binder_size_t)) return NO_MEMORY; // overflow
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001410 binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
Yi Kong91635562018-06-07 14:38:36 -07001411 if (objects == nullptr) return NO_MEMORY;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001412 mObjects = objects;
1413 mObjectsCapacity = newSize;
1414 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001415
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001416 goto restart_write;
1417}
1418
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07001419status_t Parcel::writeNoException()
1420{
Christopher Wiley09eb7492015-11-09 15:06:15 -08001421 binder::Status status;
1422 return status.writeToParcel(this);
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07001423}
1424
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001425status_t Parcel::validateReadData(size_t upperBound) const
1426{
1427 // Don't allow non-object reads on object data
1428 if (mObjectsSorted || mObjectsSize <= 1) {
1429data_sorted:
1430 // Expect to check only against the next object
1431 if (mNextObjectHint < mObjectsSize && upperBound > mObjects[mNextObjectHint]) {
1432 // For some reason the current read position is greater than the next object
1433 // hint. Iterate until we find the right object
1434 size_t nextObject = mNextObjectHint;
1435 do {
1436 if (mDataPos < mObjects[nextObject] + sizeof(flat_binder_object)) {
1437 // Requested info overlaps with an object
1438 ALOGE("Attempt to read from protected data in Parcel %p", this);
1439 return PERMISSION_DENIED;
1440 }
1441 nextObject++;
1442 } while (nextObject < mObjectsSize && upperBound > mObjects[nextObject]);
1443 mNextObjectHint = nextObject;
1444 }
1445 return NO_ERROR;
1446 }
1447 // Quickly determine if mObjects is sorted.
1448 binder_size_t* currObj = mObjects + mObjectsSize - 1;
1449 binder_size_t* prevObj = currObj;
1450 while (currObj > mObjects) {
1451 prevObj--;
1452 if(*prevObj > *currObj) {
1453 goto data_unsorted;
1454 }
1455 currObj--;
1456 }
1457 mObjectsSorted = true;
1458 goto data_sorted;
1459
1460data_unsorted:
1461 // Insertion Sort mObjects
1462 // Great for mostly sorted lists. If randomly sorted or reverse ordered mObjects become common,
1463 // switch to std::sort(mObjects, mObjects + mObjectsSize);
1464 for (binder_size_t* iter0 = mObjects + 1; iter0 < mObjects + mObjectsSize; iter0++) {
1465 binder_size_t temp = *iter0;
1466 binder_size_t* iter1 = iter0 - 1;
1467 while (iter1 >= mObjects && *iter1 > temp) {
1468 *(iter1 + 1) = *iter1;
1469 iter1--;
1470 }
1471 *(iter1 + 1) = temp;
1472 }
1473 mNextObjectHint = 0;
1474 mObjectsSorted = true;
1475 goto data_sorted;
1476}
1477
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001478status_t Parcel::read(void* outData, size_t len) const
1479{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001480 if (len > INT32_MAX) {
1481 // don't accept size_t values which may have come from an
1482 // inadvertent conversion from a negative int.
1483 return BAD_VALUE;
1484 }
1485
1486 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1487 && len <= pad_size(len)) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001488 if (mObjectsSize > 0) {
1489 status_t err = validateReadData(mDataPos + pad_size(len));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001490 if(err != NO_ERROR) {
1491 // Still increment the data position by the expected length
1492 mDataPos += pad_size(len);
1493 ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
1494 return err;
1495 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001496 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001497 memcpy(outData, mData+mDataPos, len);
Nick Kralevichb6b14232015-04-02 09:36:02 -07001498 mDataPos += pad_size(len);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001499 ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001500 return NO_ERROR;
1501 }
1502 return NOT_ENOUGH_DATA;
1503}
1504
1505const void* Parcel::readInplace(size_t len) const
1506{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001507 if (len > INT32_MAX) {
1508 // don't accept size_t values which may have come from an
1509 // inadvertent conversion from a negative int.
Yi Kong91635562018-06-07 14:38:36 -07001510 return nullptr;
Nick Kralevichb6b14232015-04-02 09:36:02 -07001511 }
1512
1513 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1514 && len <= pad_size(len)) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001515 if (mObjectsSize > 0) {
1516 status_t err = validateReadData(mDataPos + pad_size(len));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001517 if(err != NO_ERROR) {
1518 // Still increment the data position by the expected length
1519 mDataPos += pad_size(len);
1520 ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
Yi Kong91635562018-06-07 14:38:36 -07001521 return nullptr;
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001522 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001523 }
1524
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001525 const void* data = mData+mDataPos;
Nick Kralevichb6b14232015-04-02 09:36:02 -07001526 mDataPos += pad_size(len);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001527 ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001528 return data;
1529 }
Yi Kong91635562018-06-07 14:38:36 -07001530 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001531}
1532
Andreas Huber84a6d042009-08-17 13:33:27 -07001533template<class T>
1534status_t Parcel::readAligned(T *pArg) const {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001535 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
Andreas Huber84a6d042009-08-17 13:33:27 -07001536
1537 if ((mDataPos+sizeof(T)) <= mDataSize) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001538 if (mObjectsSize > 0) {
1539 status_t err = validateReadData(mDataPos + sizeof(T));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001540 if(err != NO_ERROR) {
1541 // Still increment the data position by the expected length
1542 mDataPos += sizeof(T);
1543 return err;
1544 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001545 }
1546
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001547 const void* data = mData+mDataPos;
Andreas Huber84a6d042009-08-17 13:33:27 -07001548 mDataPos += sizeof(T);
1549 *pArg = *reinterpret_cast<const T*>(data);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001550 return NO_ERROR;
1551 } else {
1552 return NOT_ENOUGH_DATA;
1553 }
1554}
1555
Andreas Huber84a6d042009-08-17 13:33:27 -07001556template<class T>
1557T Parcel::readAligned() const {
1558 T result;
1559 if (readAligned(&result) != NO_ERROR) {
1560 result = 0;
1561 }
1562
1563 return result;
1564}
1565
1566template<class T>
1567status_t Parcel::writeAligned(T val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001568 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
Andreas Huber84a6d042009-08-17 13:33:27 -07001569
1570 if ((mDataPos+sizeof(val)) <= mDataCapacity) {
1571restart_write:
1572 *reinterpret_cast<T*>(mData+mDataPos) = val;
1573 return finishWrite(sizeof(val));
1574 }
1575
1576 status_t err = growData(sizeof(val));
1577 if (err == NO_ERROR) goto restart_write;
1578 return err;
1579}
1580
Casey Dahlin185d3442016-02-09 11:08:35 -08001581status_t Parcel::readByteVector(std::vector<int8_t>* val) const {
Daniel Normanc8646c32019-10-30 10:33:22 -07001582 size_t size;
1583 if (status_t status = reserveOutVector(val, &size); status != OK) return status;
1584 return readByteVectorInternal(val, size);
Casey Dahlin185d3442016-02-09 11:08:35 -08001585}
1586
1587status_t Parcel::readByteVector(std::vector<uint8_t>* val) const {
Daniel Normanc8646c32019-10-30 10:33:22 -07001588 size_t size;
1589 if (status_t status = reserveOutVector(val, &size); status != OK) return status;
1590 return readByteVectorInternal(val, size);
Casey Dahlin185d3442016-02-09 11:08:35 -08001591}
1592
Jooyung Han2d5878e2020-01-23 12:45:10 +09001593status_t Parcel::readByteVector(std::optional<std::vector<int8_t>>* val) const {
1594 size_t size;
1595 if (status_t status = reserveOutVector(val, &size); status != OK) return status;
1596 if (!*val) {
1597 // reserveOutVector does not create the out vector if size is < 0.
1598 // This occurs when writing a null byte vector.
1599 return OK;
1600 }
1601 return readByteVectorInternal(&**val, size);
1602}
1603
Casey Dahlin185d3442016-02-09 11:08:35 -08001604status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const {
Daniel Normanc8646c32019-10-30 10:33:22 -07001605 size_t size;
1606 if (status_t status = reserveOutVector(val, &size); status != OK) return status;
Daniel Normand0337ef2019-09-20 15:46:03 -07001607 if (val->get() == nullptr) {
Daniel Normanc8646c32019-10-30 10:33:22 -07001608 // reserveOutVector does not create the out vector if size is < 0.
Daniel Normand0337ef2019-09-20 15:46:03 -07001609 // This occurs when writing a null byte vector.
1610 return OK;
1611 }
Daniel Normanc8646c32019-10-30 10:33:22 -07001612 return readByteVectorInternal(val->get(), size);
Casey Dahlin185d3442016-02-09 11:08:35 -08001613}
1614
Jooyung Han2d5878e2020-01-23 12:45:10 +09001615status_t Parcel::readByteVector(std::optional<std::vector<uint8_t>>* val) const {
1616 size_t size;
1617 if (status_t status = reserveOutVector(val, &size); status != OK) return status;
1618 if (!*val) {
1619 // reserveOutVector does not create the out vector if size is < 0.
1620 // This occurs when writing a null byte vector.
1621 return OK;
1622 }
1623 return readByteVectorInternal(&**val, size);
1624}
1625
Casey Dahlin185d3442016-02-09 11:08:35 -08001626status_t Parcel::readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const {
Daniel Normanc8646c32019-10-30 10:33:22 -07001627 size_t size;
1628 if (status_t status = reserveOutVector(val, &size); status != OK) return status;
Daniel Normand0337ef2019-09-20 15:46:03 -07001629 if (val->get() == nullptr) {
Daniel Normanc8646c32019-10-30 10:33:22 -07001630 // reserveOutVector does not create the out vector if size is < 0.
Daniel Normand0337ef2019-09-20 15:46:03 -07001631 // This occurs when writing a null byte vector.
1632 return OK;
1633 }
Daniel Normanc8646c32019-10-30 10:33:22 -07001634 return readByteVectorInternal(val->get(), size);
Casey Dahlin185d3442016-02-09 11:08:35 -08001635}
1636
Jooyung Han2d5878e2020-01-23 12:45:10 +09001637status_t Parcel::readInt32Vector(std::optional<std::vector<int32_t>>* val) const {
1638 return readNullableTypedVector(val, &Parcel::readInt32);
1639}
1640
Casey Dahlinb9872622015-11-25 15:09:45 -08001641status_t Parcel::readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const {
1642 return readNullableTypedVector(val, &Parcel::readInt32);
1643}
1644
Casey Dahlin451ff582015-10-19 18:12:18 -07001645status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001646 return readTypedVector(val, &Parcel::readInt32);
Casey Dahlin451ff582015-10-19 18:12:18 -07001647}
1648
Jooyung Han2d5878e2020-01-23 12:45:10 +09001649status_t Parcel::readInt64Vector(std::optional<std::vector<int64_t>>* val) const {
1650 return readNullableTypedVector(val, &Parcel::readInt64);
1651}
1652
Casey Dahlinb9872622015-11-25 15:09:45 -08001653status_t Parcel::readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const {
1654 return readNullableTypedVector(val, &Parcel::readInt64);
1655}
1656
Casey Dahlin451ff582015-10-19 18:12:18 -07001657status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001658 return readTypedVector(val, &Parcel::readInt64);
Casey Dahlin451ff582015-10-19 18:12:18 -07001659}
1660
Jooyung Han2d5878e2020-01-23 12:45:10 +09001661status_t Parcel::readUint64Vector(std::optional<std::vector<uint64_t>>* val) const {
1662 return readNullableTypedVector(val, &Parcel::readUint64);
1663}
1664
Kevin DuBois2f82d5b2018-12-05 12:56:10 -08001665status_t Parcel::readUint64Vector(std::unique_ptr<std::vector<uint64_t>>* val) const {
1666 return readNullableTypedVector(val, &Parcel::readUint64);
1667}
1668
1669status_t Parcel::readUint64Vector(std::vector<uint64_t>* val) const {
1670 return readTypedVector(val, &Parcel::readUint64);
1671}
1672
Jooyung Han2d5878e2020-01-23 12:45:10 +09001673status_t Parcel::readFloatVector(std::optional<std::vector<float>>* val) const {
1674 return readNullableTypedVector(val, &Parcel::readFloat);
1675}
1676
Casey Dahlinb9872622015-11-25 15:09:45 -08001677status_t Parcel::readFloatVector(std::unique_ptr<std::vector<float>>* val) const {
1678 return readNullableTypedVector(val, &Parcel::readFloat);
1679}
1680
Casey Dahlin451ff582015-10-19 18:12:18 -07001681status_t Parcel::readFloatVector(std::vector<float>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001682 return readTypedVector(val, &Parcel::readFloat);
Casey Dahlin451ff582015-10-19 18:12:18 -07001683}
1684
Jooyung Han2d5878e2020-01-23 12:45:10 +09001685status_t Parcel::readDoubleVector(std::optional<std::vector<double>>* val) const {
1686 return readNullableTypedVector(val, &Parcel::readDouble);
1687}
1688
Casey Dahlinb9872622015-11-25 15:09:45 -08001689status_t Parcel::readDoubleVector(std::unique_ptr<std::vector<double>>* val) const {
1690 return readNullableTypedVector(val, &Parcel::readDouble);
1691}
1692
Casey Dahlin451ff582015-10-19 18:12:18 -07001693status_t Parcel::readDoubleVector(std::vector<double>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001694 return readTypedVector(val, &Parcel::readDouble);
Casey Dahlin451ff582015-10-19 18:12:18 -07001695}
1696
Jooyung Han2d5878e2020-01-23 12:45:10 +09001697status_t Parcel::readBoolVector(std::optional<std::vector<bool>>* val) const {
1698 const int32_t start = dataPosition();
1699 int32_t size;
1700 status_t status = readInt32(&size);
1701 val->reset();
1702
1703 if (status != OK || size < 0) {
1704 return status;
1705 }
1706
1707 setDataPosition(start);
1708 val->emplace();
1709
1710 status = readBoolVector(&**val);
1711
1712 if (status != OK) {
1713 val->reset();
1714 }
1715
1716 return status;
1717}
1718
Casey Dahlinb9872622015-11-25 15:09:45 -08001719status_t Parcel::readBoolVector(std::unique_ptr<std::vector<bool>>* val) const {
1720 const int32_t start = dataPosition();
1721 int32_t size;
1722 status_t status = readInt32(&size);
1723 val->reset();
Casey Dahlin451ff582015-10-19 18:12:18 -07001724
Casey Dahlinb9872622015-11-25 15:09:45 -08001725 if (status != OK || size < 0) {
1726 return status;
1727 }
1728
1729 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001730 val->reset(new (std::nothrow) std::vector<bool>());
Casey Dahlinb9872622015-11-25 15:09:45 -08001731
1732 status = readBoolVector(val->get());
1733
1734 if (status != OK) {
1735 val->reset();
1736 }
1737
1738 return status;
1739}
1740
1741status_t Parcel::readBoolVector(std::vector<bool>* val) const {
Casey Dahlin451ff582015-10-19 18:12:18 -07001742 int32_t size;
1743 status_t status = readInt32(&size);
1744
1745 if (status != OK) {
1746 return status;
1747 }
1748
1749 if (size < 0) {
Christopher Wiley4db672d2015-11-10 09:44:30 -08001750 return UNEXPECTED_NULL;
Casey Dahlin451ff582015-10-19 18:12:18 -07001751 }
1752
1753 val->resize(size);
1754
1755 /* C++ bool handling means a vector of bools isn't necessarily addressable
1756 * (we might use individual bits)
1757 */
Christopher Wiley97887982015-10-27 16:33:47 -07001758 bool data;
1759 for (int32_t i = 0; i < size; ++i) {
Casey Dahlin451ff582015-10-19 18:12:18 -07001760 status = readBool(&data);
1761 (*val)[i] = data;
1762
1763 if (status != OK) {
1764 return status;
1765 }
1766 }
1767
1768 return OK;
1769}
1770
Jooyung Han2d5878e2020-01-23 12:45:10 +09001771status_t Parcel::readCharVector(std::optional<std::vector<char16_t>>* val) const {
1772 return readNullableTypedVector(val, &Parcel::readChar);
1773}
1774
Casey Dahlinb9872622015-11-25 15:09:45 -08001775status_t Parcel::readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const {
1776 return readNullableTypedVector(val, &Parcel::readChar);
1777}
1778
Casey Dahlin451ff582015-10-19 18:12:18 -07001779status_t Parcel::readCharVector(std::vector<char16_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001780 return readTypedVector(val, &Parcel::readChar);
Casey Dahlin451ff582015-10-19 18:12:18 -07001781}
1782
Casey Dahlinb9872622015-11-25 15:09:45 -08001783status_t Parcel::readString16Vector(
Jooyung Han2d5878e2020-01-23 12:45:10 +09001784 std::optional<std::vector<std::optional<String16>>>* val) const {
1785 return readNullableTypedVector(val, &Parcel::readString16);
1786}
1787
1788status_t Parcel::readString16Vector(
Casey Dahlinb9872622015-11-25 15:09:45 -08001789 std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const {
1790 return readNullableTypedVector(val, &Parcel::readString16);
1791}
1792
Casey Dahlin451ff582015-10-19 18:12:18 -07001793status_t Parcel::readString16Vector(std::vector<String16>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001794 return readTypedVector(val, &Parcel::readString16);
Casey Dahlin451ff582015-10-19 18:12:18 -07001795}
1796
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001797status_t Parcel::readUtf8VectorFromUtf16Vector(
Jooyung Han2d5878e2020-01-23 12:45:10 +09001798 std::optional<std::vector<std::optional<std::string>>>* val) const {
1799 return readNullableTypedVector(val, &Parcel::readUtf8FromUtf16);
1800}
1801
1802status_t Parcel::readUtf8VectorFromUtf16Vector(
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001803 std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const {
1804 return readNullableTypedVector(val, &Parcel::readUtf8FromUtf16);
1805}
1806
1807status_t Parcel::readUtf8VectorFromUtf16Vector(std::vector<std::string>* val) const {
1808 return readTypedVector(val, &Parcel::readUtf8FromUtf16);
1809}
Casey Dahlin451ff582015-10-19 18:12:18 -07001810
Andreas Huber84a6d042009-08-17 13:33:27 -07001811status_t Parcel::readInt32(int32_t *pArg) const
1812{
1813 return readAligned(pArg);
1814}
1815
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001816int32_t Parcel::readInt32() const
1817{
Andreas Huber84a6d042009-08-17 13:33:27 -07001818 return readAligned<int32_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001819}
1820
Dan Stoza41a0f2f2014-12-01 10:01:10 -08001821status_t Parcel::readUint32(uint32_t *pArg) const
1822{
1823 return readAligned(pArg);
1824}
1825
1826uint32_t Parcel::readUint32() const
1827{
1828 return readAligned<uint32_t>();
1829}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001830
1831status_t Parcel::readInt64(int64_t *pArg) const
1832{
Andreas Huber84a6d042009-08-17 13:33:27 -07001833 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001834}
1835
1836
1837int64_t Parcel::readInt64() const
1838{
Andreas Huber84a6d042009-08-17 13:33:27 -07001839 return readAligned<int64_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001840}
1841
Ronghua Wu2d13afd2015-03-16 11:11:07 -07001842status_t Parcel::readUint64(uint64_t *pArg) const
1843{
1844 return readAligned(pArg);
1845}
1846
1847uint64_t Parcel::readUint64() const
1848{
1849 return readAligned<uint64_t>();
1850}
1851
Serban Constantinescuf683e012013-11-05 16:53:55 +00001852status_t Parcel::readPointer(uintptr_t *pArg) const
1853{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001854 status_t ret;
1855 binder_uintptr_t ptr;
1856 ret = readAligned(&ptr);
1857 if (!ret)
1858 *pArg = ptr;
1859 return ret;
Serban Constantinescuf683e012013-11-05 16:53:55 +00001860}
1861
1862uintptr_t Parcel::readPointer() const
1863{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001864 return readAligned<binder_uintptr_t>();
Serban Constantinescuf683e012013-11-05 16:53:55 +00001865}
1866
1867
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001868status_t Parcel::readFloat(float *pArg) const
1869{
Andreas Huber84a6d042009-08-17 13:33:27 -07001870 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001871}
1872
1873
1874float Parcel::readFloat() const
1875{
Andreas Huber84a6d042009-08-17 13:33:27 -07001876 return readAligned<float>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001877}
1878
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001879#if defined(__mips__) && defined(__mips_hard_float)
1880
1881status_t Parcel::readDouble(double *pArg) const
1882{
1883 union {
1884 double d;
1885 unsigned long long ll;
1886 } u;
Narayan Kamath2c68d382014-06-04 15:04:29 +01001887 u.d = 0;
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001888 status_t status;
1889 status = readAligned(&u.ll);
1890 *pArg = u.d;
1891 return status;
1892}
1893
1894double Parcel::readDouble() const
1895{
1896 union {
1897 double d;
1898 unsigned long long ll;
1899 } u;
1900 u.ll = readAligned<unsigned long long>();
1901 return u.d;
1902}
1903
1904#else
1905
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001906status_t Parcel::readDouble(double *pArg) const
1907{
Andreas Huber84a6d042009-08-17 13:33:27 -07001908 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001909}
1910
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001911double Parcel::readDouble() const
1912{
Andreas Huber84a6d042009-08-17 13:33:27 -07001913 return readAligned<double>();
1914}
1915
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001916#endif
1917
Andreas Huber84a6d042009-08-17 13:33:27 -07001918status_t Parcel::readIntPtr(intptr_t *pArg) const
1919{
1920 return readAligned(pArg);
1921}
1922
1923
1924intptr_t Parcel::readIntPtr() const
1925{
1926 return readAligned<intptr_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001927}
1928
Casey Dahlind6848f52015-10-15 15:44:59 -07001929status_t Parcel::readBool(bool *pArg) const
1930{
Manoj Gupta6eb62052017-07-12 10:29:15 -07001931 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07001932 status_t ret = readInt32(&tmp);
1933 *pArg = (tmp != 0);
1934 return ret;
1935}
1936
1937bool Parcel::readBool() const
1938{
1939 return readInt32() != 0;
1940}
1941
1942status_t Parcel::readChar(char16_t *pArg) const
1943{
Manoj Gupta6eb62052017-07-12 10:29:15 -07001944 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07001945 status_t ret = readInt32(&tmp);
1946 *pArg = char16_t(tmp);
1947 return ret;
1948}
1949
1950char16_t Parcel::readChar() const
1951{
1952 return char16_t(readInt32());
1953}
1954
1955status_t Parcel::readByte(int8_t *pArg) const
1956{
Manoj Gupta6eb62052017-07-12 10:29:15 -07001957 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07001958 status_t ret = readInt32(&tmp);
1959 *pArg = int8_t(tmp);
1960 return ret;
1961}
1962
1963int8_t Parcel::readByte() const
1964{
1965 return int8_t(readInt32());
1966}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001967
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001968status_t Parcel::readUtf8FromUtf16(std::string* str) const {
1969 size_t utf16Size = 0;
1970 const char16_t* src = readString16Inplace(&utf16Size);
1971 if (!src) {
1972 return UNEXPECTED_NULL;
1973 }
1974
1975 // Save ourselves the trouble, we're done.
1976 if (utf16Size == 0u) {
1977 str->clear();
1978 return NO_ERROR;
1979 }
1980
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001981 // Allow for closing '\0'
1982 ssize_t utf8Size = utf16_to_utf8_length(src, utf16Size) + 1;
1983 if (utf8Size < 1) {
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001984 return BAD_VALUE;
1985 }
1986 // Note that while it is probably safe to assume string::resize keeps a
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001987 // spare byte around for the trailing null, we still pass the size including the trailing null
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001988 str->resize(utf8Size);
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001989 utf16_to_utf8(src, utf16Size, &((*str)[0]), utf8Size);
1990 str->resize(utf8Size - 1);
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001991 return NO_ERROR;
1992}
1993
Jooyung Han2d5878e2020-01-23 12:45:10 +09001994status_t Parcel::readUtf8FromUtf16(std::optional<std::string>* str) const {
1995 const int32_t start = dataPosition();
1996 int32_t size;
1997 status_t status = readInt32(&size);
1998 str->reset();
1999
2000 if (status != OK || size < 0) {
2001 return status;
2002 }
2003
2004 setDataPosition(start);
2005 str->emplace();
2006 return readUtf8FromUtf16(&**str);
2007}
2008
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08002009status_t Parcel::readUtf8FromUtf16(std::unique_ptr<std::string>* str) const {
2010 const int32_t start = dataPosition();
2011 int32_t size;
2012 status_t status = readInt32(&size);
2013 str->reset();
2014
2015 if (status != OK || size < 0) {
2016 return status;
2017 }
2018
2019 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002020 str->reset(new (std::nothrow) std::string());
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08002021 return readUtf8FromUtf16(str->get());
2022}
2023
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002024const char* Parcel::readCString() const
2025{
Steven Morelandf5e6c7e2019-05-17 13:14:06 -07002026 if (mDataPos < mDataSize) {
2027 const size_t avail = mDataSize-mDataPos;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002028 const char* str = reinterpret_cast<const char*>(mData+mDataPos);
2029 // is the string's trailing NUL within the parcel's valid bounds?
2030 const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
2031 if (eos) {
2032 const size_t len = eos - str;
Nick Kralevichb6b14232015-04-02 09:36:02 -07002033 mDataPos += pad_size(len+1);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002034 ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002035 return str;
2036 }
2037 }
Yi Kong91635562018-06-07 14:38:36 -07002038 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002039}
2040
2041String8 Parcel::readString8() const
2042{
Jeff Sharkey2f8bdb52020-04-19 21:41:26 -06002043 size_t len;
2044 const char* str = readString8Inplace(&len);
2045 if (str) return String8(str, len);
2046 ALOGE("Reading a NULL string not supported here.");
2047 return String8();
Roshan Pius87b64d22016-07-18 12:51:02 -07002048}
2049
2050status_t Parcel::readString8(String8* pArg) const
2051{
Jeff Sharkey2f8bdb52020-04-19 21:41:26 -06002052 size_t len;
2053 const char* str = readString8Inplace(&len);
2054 if (str) {
2055 pArg->setTo(str, len);
2056 return 0;
2057 } else {
Roshan Pius87b64d22016-07-18 12:51:02 -07002058 *pArg = String8();
Jeff Sharkey2f8bdb52020-04-19 21:41:26 -06002059 return UNEXPECTED_NULL;
Roshan Pius87b64d22016-07-18 12:51:02 -07002060 }
Jeff Sharkey2f8bdb52020-04-19 21:41:26 -06002061}
2062
2063const char* Parcel::readString8Inplace(size_t* outLen) const
2064{
2065 int32_t size = readInt32();
2066 // watch for potential int overflow from size+1
2067 if (size >= 0 && size < INT32_MAX) {
2068 *outLen = size;
2069 const char* str = (const char*)readInplace(size+1);
2070 if (str != nullptr) {
2071 return str;
2072 }
Roshan Pius87b64d22016-07-18 12:51:02 -07002073 }
Jeff Sharkey2f8bdb52020-04-19 21:41:26 -06002074 *outLen = 0;
2075 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002076}
2077
2078String16 Parcel::readString16() const
2079{
2080 size_t len;
2081 const char16_t* str = readString16Inplace(&len);
2082 if (str) return String16(str, len);
Steve Blocke6f43dd2012-01-06 19:20:56 +00002083 ALOGE("Reading a NULL string not supported here.");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002084 return String16();
2085}
2086
Jooyung Han2d5878e2020-01-23 12:45:10 +09002087status_t Parcel::readString16(std::optional<String16>* pArg) const
2088{
2089 const int32_t start = dataPosition();
2090 int32_t size;
2091 status_t status = readInt32(&size);
2092 pArg->reset();
2093
2094 if (status != OK || size < 0) {
2095 return status;
2096 }
2097
2098 setDataPosition(start);
2099 pArg->emplace();
2100
2101 status = readString16(&**pArg);
2102
2103 if (status != OK) {
2104 pArg->reset();
2105 }
2106
2107 return status;
2108}
2109
Casey Dahlinb9872622015-11-25 15:09:45 -08002110status_t Parcel::readString16(std::unique_ptr<String16>* pArg) const
2111{
2112 const int32_t start = dataPosition();
2113 int32_t size;
2114 status_t status = readInt32(&size);
2115 pArg->reset();
2116
2117 if (status != OK || size < 0) {
2118 return status;
2119 }
2120
2121 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002122 pArg->reset(new (std::nothrow) String16());
Casey Dahlinb9872622015-11-25 15:09:45 -08002123
2124 status = readString16(pArg->get());
2125
2126 if (status != OK) {
2127 pArg->reset();
2128 }
2129
2130 return status;
2131}
2132
Casey Dahlin451ff582015-10-19 18:12:18 -07002133status_t Parcel::readString16(String16* pArg) const
2134{
2135 size_t len;
2136 const char16_t* str = readString16Inplace(&len);
2137 if (str) {
Casey Dahlin1515ea12015-10-20 16:26:23 -07002138 pArg->setTo(str, len);
Casey Dahlin451ff582015-10-19 18:12:18 -07002139 return 0;
2140 } else {
2141 *pArg = String16();
Christopher Wiley4db672d2015-11-10 09:44:30 -08002142 return UNEXPECTED_NULL;
Casey Dahlin451ff582015-10-19 18:12:18 -07002143 }
2144}
2145
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002146const char16_t* Parcel::readString16Inplace(size_t* outLen) const
2147{
2148 int32_t size = readInt32();
2149 // watch for potential int overflow from size+1
2150 if (size >= 0 && size < INT32_MAX) {
2151 *outLen = size;
2152 const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
Yi Kong91635562018-06-07 14:38:36 -07002153 if (str != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002154 return str;
2155 }
2156 }
2157 *outLen = 0;
Yi Kong91635562018-06-07 14:38:36 -07002158 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002159}
2160
Casey Dahlinf0c13772015-10-27 18:33:56 -07002161status_t Parcel::readStrongBinder(sp<IBinder>* val) const
2162{
Christopher Wiley35d77ca2016-03-08 10:49:51 -08002163 status_t status = readNullableStrongBinder(val);
2164 if (status == OK && !val->get()) {
2165 status = UNEXPECTED_NULL;
2166 }
2167 return status;
2168}
2169
2170status_t Parcel::readNullableStrongBinder(sp<IBinder>* val) const
2171{
Steven Morelanda86a3562019-08-01 23:28:34 +00002172 return unflattenBinder(val);
Casey Dahlinf0c13772015-10-27 18:33:56 -07002173}
2174
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002175sp<IBinder> Parcel::readStrongBinder() const
2176{
2177 sp<IBinder> val;
Christopher Wiley35d77ca2016-03-08 10:49:51 -08002178 // Note that a lot of code in Android reads binders by hand with this
2179 // method, and that code has historically been ok with getting nullptr
2180 // back (while ignoring error codes).
2181 readNullableStrongBinder(&val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002182 return val;
2183}
2184
Christopher Wiley97f048d2015-11-19 06:49:05 -08002185status_t Parcel::readParcelable(Parcelable* parcelable) const {
2186 int32_t have_parcelable = 0;
2187 status_t status = readInt32(&have_parcelable);
2188 if (status != OK) {
2189 return status;
2190 }
2191 if (!have_parcelable) {
2192 return UNEXPECTED_NULL;
2193 }
2194 return parcelable->readFromParcel(this);
2195}
2196
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07002197int32_t Parcel::readExceptionCode() const
2198{
Christopher Wiley09eb7492015-11-09 15:06:15 -08002199 binder::Status status;
2200 status.readFromParcel(*this);
2201 return status.exceptionCode();
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07002202}
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002203
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002204native_handle* Parcel::readNativeHandle() const
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002205{
2206 int numFds, numInts;
2207 status_t err;
2208 err = readInt32(&numFds);
Yi Kong91635562018-06-07 14:38:36 -07002209 if (err != NO_ERROR) return nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002210 err = readInt32(&numInts);
Yi Kong91635562018-06-07 14:38:36 -07002211 if (err != NO_ERROR) return nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002212
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002213 native_handle* h = native_handle_create(numFds, numInts);
Adam Lesinskieaac99a2015-05-12 17:35:48 -07002214 if (!h) {
Yi Kong91635562018-06-07 14:38:36 -07002215 return nullptr;
Adam Lesinskieaac99a2015-05-12 17:35:48 -07002216 }
2217
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002218 for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002219 h->data[i] = fcntl(readFileDescriptor(), F_DUPFD_CLOEXEC, 0);
Marco Nelissen1de79662016-04-26 08:44:09 -07002220 if (h->data[i] < 0) {
2221 for (int j = 0; j < i; j++) {
2222 close(h->data[j]);
2223 }
2224 native_handle_delete(h);
Yi Kong91635562018-06-07 14:38:36 -07002225 return nullptr;
Marco Nelissen1de79662016-04-26 08:44:09 -07002226 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002227 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002228 err = read(h->data + numFds, sizeof(int)*numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002229 if (err != NO_ERROR) {
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002230 native_handle_close(h);
2231 native_handle_delete(h);
Yi Kong91635562018-06-07 14:38:36 -07002232 h = nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002233 }
2234 return h;
2235}
2236
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002237int Parcel::readFileDescriptor() const
2238{
2239 const flat_binder_object* flat = readObject(true);
Casey Dahlin06673e32015-11-23 13:24:23 -08002240
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002241 if (flat && flat->hdr.type == BINDER_TYPE_FD) {
Casey Dahlin06673e32015-11-23 13:24:23 -08002242 return flat->handle;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002243 }
Casey Dahlin06673e32015-11-23 13:24:23 -08002244
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002245 return BAD_TYPE;
2246}
2247
Dianne Hackborn1941a402016-08-29 12:30:43 -07002248int Parcel::readParcelFileDescriptor() const
2249{
2250 int32_t hasComm = readInt32();
2251 int fd = readFileDescriptor();
2252 if (hasComm != 0) {
Steven Morelandb73806a2018-11-12 19:35:47 -08002253 // detach (owned by the binder driver)
2254 int comm = readFileDescriptor();
2255
2256 // warning: this must be kept in sync with:
2257 // frameworks/base/core/java/android/os/ParcelFileDescriptor.java
2258 enum ParcelFileDescriptorStatus {
2259 DETACHED = 2,
2260 };
2261
2262#if BYTE_ORDER == BIG_ENDIAN
2263 const int32_t message = ParcelFileDescriptorStatus::DETACHED;
2264#endif
2265#if BYTE_ORDER == LITTLE_ENDIAN
2266 const int32_t message = __builtin_bswap32(ParcelFileDescriptorStatus::DETACHED);
2267#endif
2268
2269 ssize_t written = TEMP_FAILURE_RETRY(
2270 ::write(comm, &message, sizeof(message)));
2271
2272 if (written == -1 || written != sizeof(message)) {
2273 ALOGW("Failed to detach ParcelFileDescriptor written: %zd err: %s",
2274 written, strerror(errno));
2275 return BAD_TYPE;
2276 }
Dianne Hackborn1941a402016-08-29 12:30:43 -07002277 }
2278 return fd;
2279}
2280
Christopher Wiley2cf19952016-04-11 11:09:37 -07002281status_t Parcel::readUniqueFileDescriptor(base::unique_fd* val) const
Casey Dahlin06673e32015-11-23 13:24:23 -08002282{
2283 int got = readFileDescriptor();
2284
2285 if (got == BAD_TYPE) {
2286 return BAD_TYPE;
2287 }
2288
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002289 val->reset(fcntl(got, F_DUPFD_CLOEXEC, 0));
Casey Dahlin06673e32015-11-23 13:24:23 -08002290
2291 if (val->get() < 0) {
2292 return BAD_VALUE;
2293 }
2294
2295 return OK;
2296}
2297
Ryo Hashimotobf551892018-05-31 16:58:35 +09002298status_t Parcel::readUniqueParcelFileDescriptor(base::unique_fd* val) const
2299{
2300 int got = readParcelFileDescriptor();
2301
2302 if (got == BAD_TYPE) {
2303 return BAD_TYPE;
2304 }
2305
2306 val->reset(fcntl(got, F_DUPFD_CLOEXEC, 0));
2307
2308 if (val->get() < 0) {
2309 return BAD_VALUE;
2310 }
2311
2312 return OK;
2313}
Casey Dahlin06673e32015-11-23 13:24:23 -08002314
Jooyung Han2d5878e2020-01-23 12:45:10 +09002315status_t Parcel::readUniqueFileDescriptorVector(std::optional<std::vector<base::unique_fd>>* val) const {
2316 return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
2317}
2318
Christopher Wiley2cf19952016-04-11 11:09:37 -07002319status_t Parcel::readUniqueFileDescriptorVector(std::unique_ptr<std::vector<base::unique_fd>>* val) const {
Casey Dahlinb9872622015-11-25 15:09:45 -08002320 return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
2321}
2322
Christopher Wiley2cf19952016-04-11 11:09:37 -07002323status_t Parcel::readUniqueFileDescriptorVector(std::vector<base::unique_fd>* val) const {
Casey Dahlin06673e32015-11-23 13:24:23 -08002324 return readTypedVector(val, &Parcel::readUniqueFileDescriptor);
2325}
2326
Jeff Brown5707dbf2011-09-23 21:17:56 -07002327status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
2328{
Jeff Brown13b16042014-11-11 16:44:25 -08002329 int32_t blobType;
2330 status_t status = readInt32(&blobType);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002331 if (status) return status;
2332
Jeff Brown13b16042014-11-11 16:44:25 -08002333 if (blobType == BLOB_INPLACE) {
Steve Block6807e592011-10-20 11:56:00 +01002334 ALOGV("readBlob: read in place");
Jeff Brown5707dbf2011-09-23 21:17:56 -07002335 const void* ptr = readInplace(len);
2336 if (!ptr) return BAD_VALUE;
2337
Jeff Brown13b16042014-11-11 16:44:25 -08002338 outBlob->init(-1, const_cast<void*>(ptr), len, false);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002339 return NO_ERROR;
2340 }
2341
Steve Block6807e592011-10-20 11:56:00 +01002342 ALOGV("readBlob: read from ashmem");
Jeff Brown13b16042014-11-11 16:44:25 -08002343 bool isMutable = (blobType == BLOB_ASHMEM_MUTABLE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002344 int fd = readFileDescriptor();
2345 if (fd == int(BAD_TYPE)) return BAD_VALUE;
2346
Jorim Jaggi150b4ef2018-07-13 11:18:30 +00002347 if (!ashmem_valid(fd)) {
2348 ALOGE("invalid fd");
2349 return BAD_VALUE;
2350 }
Marco Nelissen7a96ec42018-06-06 07:37:46 -07002351 int size = ashmem_get_size_region(fd);
2352 if (size < 0 || size_t(size) < len) {
Jorim Jaggi150b4ef2018-07-13 11:18:30 +00002353 ALOGE("request size %zu does not match fd size %d", len, size);
Marco Nelissen7a96ec42018-06-06 07:37:46 -07002354 return BAD_VALUE;
2355 }
Yi Kong91635562018-06-07 14:38:36 -07002356 void* ptr = ::mmap(nullptr, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ,
Jeff Brown13b16042014-11-11 16:44:25 -08002357 MAP_SHARED, fd, 0);
Narayan Kamath9ea09752014-10-08 17:35:45 +01002358 if (ptr == MAP_FAILED) return NO_MEMORY;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002359
Jeff Brown13b16042014-11-11 16:44:25 -08002360 outBlob->init(fd, ptr, len, isMutable);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002361 return NO_ERROR;
2362}
2363
Mathias Agopiane1424282013-07-29 21:24:40 -07002364status_t Parcel::read(FlattenableHelperInterface& val) const
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002365{
2366 // size
2367 const size_t len = this->readInt32();
2368 const size_t fd_count = this->readInt32();
2369
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002370 if ((len > INT32_MAX) || (fd_count >= gMaxFds)) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07002371 // don't accept size_t values which may have come from an
2372 // inadvertent conversion from a negative int.
2373 return BAD_VALUE;
2374 }
2375
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002376 // payload
Nick Kralevichb6b14232015-04-02 09:36:02 -07002377 void const* const buf = this->readInplace(pad_size(len));
Yi Kong91635562018-06-07 14:38:36 -07002378 if (buf == nullptr)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002379 return BAD_VALUE;
2380
Yi Kong91635562018-06-07 14:38:36 -07002381 int* fds = nullptr;
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002382 if (fd_count) {
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002383 fds = new (std::nothrow) int[fd_count];
2384 if (fds == nullptr) {
2385 ALOGE("read: failed to allocate requested %zu fds", fd_count);
2386 return BAD_VALUE;
2387 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002388 }
2389
2390 status_t err = NO_ERROR;
2391 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
Fabien Sanglardd84ff312016-10-21 10:58:26 -07002392 int fd = this->readFileDescriptor();
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002393 if (fd < 0 || ((fds[i] = fcntl(fd, F_DUPFD_CLOEXEC, 0)) < 0)) {
Jun Jiangabf8a2c2014-04-29 14:22:10 +08002394 err = BAD_VALUE;
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002395 ALOGE("fcntl(F_DUPFD_CLOEXEC) failed in Parcel::read, i is %zu, fds[i] is %d, fd_count is %zu, error: %s",
Fabien Sanglardd84ff312016-10-21 10:58:26 -07002396 i, fds[i], fd_count, strerror(fd < 0 ? -fd : errno));
2397 // Close all the file descriptors that were dup-ed.
2398 for (size_t j=0; j<i ;j++) {
2399 close(fds[j]);
2400 }
Jun Jiangabf8a2c2014-04-29 14:22:10 +08002401 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002402 }
2403
2404 if (err == NO_ERROR) {
2405 err = val.unflatten(buf, len, fds, fd_count);
2406 }
2407
2408 if (fd_count) {
2409 delete [] fds;
2410 }
2411
2412 return err;
2413}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002414const flat_binder_object* Parcel::readObject(bool nullMetaData) const
2415{
2416 const size_t DPOS = mDataPos;
2417 if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
2418 const flat_binder_object* obj
2419 = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
2420 mDataPos = DPOS + sizeof(flat_binder_object);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002421 if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) {
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002422 // When transferring a NULL object, we don't write it into
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002423 // the object list, so we don't want to check for it when
2424 // reading.
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002425 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002426 return obj;
2427 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002428
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002429 // Ensure that this object is valid...
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002430 binder_size_t* const OBJS = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002431 const size_t N = mObjectsSize;
2432 size_t opos = mNextObjectHint;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002433
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002434 if (N > 0) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002435 ALOGV("Parcel %p looking for obj at %zu, hint=%zu",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002436 this, DPOS, opos);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002437
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002438 // Start at the current hint position, looking for an object at
2439 // the current data position.
2440 if (opos < N) {
2441 while (opos < (N-1) && OBJS[opos] < DPOS) {
2442 opos++;
2443 }
2444 } else {
2445 opos = N-1;
2446 }
2447 if (OBJS[opos] == DPOS) {
2448 // Found it!
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002449 ALOGV("Parcel %p found obj %zu at index %zu with forward search",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002450 this, DPOS, opos);
2451 mNextObjectHint = opos+1;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002452 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002453 return obj;
2454 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002455
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002456 // Look backwards for it...
2457 while (opos > 0 && OBJS[opos] > DPOS) {
2458 opos--;
2459 }
2460 if (OBJS[opos] == DPOS) {
2461 // Found it!
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002462 ALOGV("Parcel %p found obj %zu at index %zu with backward search",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002463 this, DPOS, opos);
2464 mNextObjectHint = opos+1;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002465 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002466 return obj;
2467 }
2468 }
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002469 ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object list",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002470 this, DPOS);
2471 }
Yi Kong91635562018-06-07 14:38:36 -07002472 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002473}
2474
2475void Parcel::closeFileDescriptors()
2476{
2477 size_t i = mObjectsSize;
2478 if (i > 0) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002479 //ALOGI("Closing file descriptors for %zu objects...", i);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002480 }
2481 while (i > 0) {
2482 i--;
2483 const flat_binder_object* flat
2484 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002485 if (flat->hdr.type == BINDER_TYPE_FD) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002486 //ALOGI("Closing fd: %ld", flat->handle);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002487 close(flat->handle);
2488 }
2489 }
2490}
2491
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002492uintptr_t Parcel::ipcData() const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002493{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002494 return reinterpret_cast<uintptr_t>(mData);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002495}
2496
2497size_t Parcel::ipcDataSize() const
2498{
2499 return (mDataSize > mDataPos ? mDataSize : mDataPos);
2500}
2501
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002502uintptr_t Parcel::ipcObjects() const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002503{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002504 return reinterpret_cast<uintptr_t>(mObjects);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002505}
2506
2507size_t Parcel::ipcObjectsCount() const
2508{
2509 return mObjectsSize;
2510}
2511
2512void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002513 const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002514{
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002515 binder_size_t minOffset = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002516 freeDataNoInit();
2517 mError = NO_ERROR;
2518 mData = const_cast<uint8_t*>(data);
2519 mDataSize = mDataCapacity = dataSize;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002520 //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)", this, mDataSize, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002521 mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002522 ALOGV("setDataReference Setting data pos of %p to %zu", this, mDataPos);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002523 mObjects = const_cast<binder_size_t*>(objects);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002524 mObjectsSize = mObjectsCapacity = objectsCount;
2525 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002526 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002527 mOwner = relFunc;
2528 mOwnerCookie = relCookie;
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002529 for (size_t i = 0; i < mObjectsSize; i++) {
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002530 binder_size_t offset = mObjects[i];
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002531 if (offset < minOffset) {
Dan Albert3bdc5b82014-11-20 11:50:23 -08002532 ALOGE("%s: bad object offset %" PRIu64 " < %" PRIu64 "\n",
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002533 __func__, (uint64_t)offset, (uint64_t)minOffset);
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002534 mObjectsSize = 0;
2535 break;
2536 }
Martijn Coenen82c75312019-07-24 15:18:30 +02002537 const flat_binder_object* flat
2538 = reinterpret_cast<const flat_binder_object*>(mData + offset);
2539 uint32_t type = flat->hdr.type;
2540 if (!(type == BINDER_TYPE_BINDER || type == BINDER_TYPE_HANDLE ||
2541 type == BINDER_TYPE_FD)) {
2542 // We should never receive other types (eg BINDER_TYPE_FDA) as long as we don't support
2543 // them in libbinder. If we do receive them, it probably means a kernel bug; try to
2544 // recover gracefully by clearing out the objects, and releasing the objects we do
2545 // know about.
2546 android_errorWriteLog(0x534e4554, "135930648");
2547 ALOGE("%s: unsupported type object (%" PRIu32 ") at offset %" PRIu64 "\n",
2548 __func__, type, (uint64_t)offset);
2549 releaseObjects();
2550 mObjectsSize = 0;
2551 break;
2552 }
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002553 minOffset = offset + sizeof(flat_binder_object);
2554 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002555 scanForFds();
2556}
2557
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002558void Parcel::print(TextOutput& to, uint32_t /*flags*/) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002559{
2560 to << "Parcel(";
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002561
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002562 if (errorCheck() != NO_ERROR) {
2563 const status_t err = errorCheck();
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002564 to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\"";
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002565 } else if (dataSize() > 0) {
2566 const uint8_t* DATA = data();
2567 to << indent << HexDump(DATA, dataSize()) << dedent;
Steven Moreland8bd01352019-07-15 16:36:14 -07002568 const binder_size_t* OBJS = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002569 const size_t N = objectsCount();
2570 for (size_t i=0; i<N; i++) {
2571 const flat_binder_object* flat
2572 = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
2573 to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002574 << TypeCode(flat->hdr.type & 0x7f7f7f00)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002575 << " = " << flat->binder;
2576 }
2577 } else {
2578 to << "NULL";
2579 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002580
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002581 to << ")";
2582}
2583
2584void Parcel::releaseObjects()
2585{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002586 size_t i = mObjectsSize;
Martijn Coenen69390d42018-10-22 15:18:10 +02002587 if (i == 0) {
2588 return;
2589 }
2590 sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002591 uint8_t* const data = mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002592 binder_size_t* const objects = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002593 while (i > 0) {
2594 i--;
2595 const flat_binder_object* flat
2596 = reinterpret_cast<flat_binder_object*>(data+objects[i]);
Adrian Rooscbf37262015-10-22 16:12:53 -07002597 release_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002598 }
2599}
2600
2601void Parcel::acquireObjects()
2602{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002603 size_t i = mObjectsSize;
Martijn Coenen69390d42018-10-22 15:18:10 +02002604 if (i == 0) {
2605 return;
2606 }
2607 const sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002608 uint8_t* const data = mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002609 binder_size_t* const objects = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002610 while (i > 0) {
2611 i--;
2612 const flat_binder_object* flat
2613 = reinterpret_cast<flat_binder_object*>(data+objects[i]);
Adrian Rooscbf37262015-10-22 16:12:53 -07002614 acquire_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002615 }
2616}
2617
2618void Parcel::freeData()
2619{
2620 freeDataNoInit();
2621 initState();
2622}
2623
2624void Parcel::freeDataNoInit()
2625{
2626 if (mOwner) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002627 LOG_ALLOC("Parcel %p: freeing other owner data", this);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002628 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002629 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
2630 } else {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002631 LOG_ALLOC("Parcel %p: freeing allocated data", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002632 releaseObjects();
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002633 if (mData) {
2634 LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002635 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dan Austin48fd7b42015-09-10 13:46:02 -07002636 if (mDataCapacity <= gParcelGlobalAllocSize) {
2637 gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity;
2638 } else {
2639 gParcelGlobalAllocSize = 0;
2640 }
2641 if (gParcelGlobalAllocCount > 0) {
2642 gParcelGlobalAllocCount--;
2643 }
Dianne Hackborna4cff882014-11-13 17:07:40 -08002644 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002645 free(mData);
2646 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002647 if (mObjects) free(mObjects);
2648 }
2649}
2650
2651status_t Parcel::growData(size_t len)
2652{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002653 if (len > INT32_MAX) {
2654 // don't accept size_t values which may have come from an
2655 // inadvertent conversion from a negative int.
2656 return BAD_VALUE;
2657 }
2658
Martijn Coenenda2f2fd2020-01-22 10:46:25 +01002659 if (len > SIZE_MAX - mDataSize) return NO_MEMORY; // overflow
2660 if (mDataSize + len > SIZE_MAX / 3) return NO_MEMORY; // overflow
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002661 size_t newSize = ((mDataSize+len)*3)/2;
2662 return (newSize <= mDataSize)
2663 ? (status_t) NO_MEMORY
Steven Moreland042ae822020-05-27 17:45:17 +00002664 : continueWrite(std::max(newSize, (size_t) 128));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002665}
2666
2667status_t Parcel::restartWrite(size_t desired)
2668{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002669 if (desired > INT32_MAX) {
2670 // don't accept size_t values which may have come from an
2671 // inadvertent conversion from a negative int.
2672 return BAD_VALUE;
2673 }
2674
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002675 if (mOwner) {
2676 freeData();
2677 return continueWrite(desired);
2678 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002679
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002680 uint8_t* data = (uint8_t*)realloc(mData, desired);
2681 if (!data && desired > mDataCapacity) {
2682 mError = NO_MEMORY;
2683 return NO_MEMORY;
2684 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002685
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002686 releaseObjects();
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002687
Devin Moore4a0a55e2020-06-04 13:23:10 -07002688 if (data || desired == 0) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002689 LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002690 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002691 gParcelGlobalAllocSize += desired;
2692 gParcelGlobalAllocSize -= mDataCapacity;
Colin Cross83ec65e2015-12-08 17:15:50 -08002693 if (!mData) {
2694 gParcelGlobalAllocCount++;
2695 }
Dianne Hackborna4cff882014-11-13 17:07:40 -08002696 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002697 mData = data;
2698 mDataCapacity = desired;
2699 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002700
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002701 mDataSize = mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002702 ALOGV("restartWrite Setting data size of %p to %zu", this, mDataSize);
2703 ALOGV("restartWrite Setting data pos of %p to %zu", this, mDataPos);
2704
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002705 free(mObjects);
Yi Kong91635562018-06-07 14:38:36 -07002706 mObjects = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002707 mObjectsSize = mObjectsCapacity = 0;
2708 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002709 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002710 mHasFds = false;
2711 mFdsKnown = true;
Dianne Hackborn8938ed22011-09-28 23:19:47 -04002712 mAllowFds = true;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002713
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002714 return NO_ERROR;
2715}
2716
2717status_t Parcel::continueWrite(size_t desired)
2718{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002719 if (desired > INT32_MAX) {
2720 // don't accept size_t values which may have come from an
2721 // inadvertent conversion from a negative int.
2722 return BAD_VALUE;
2723 }
2724
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002725 // If shrinking, first adjust for any objects that appear
2726 // after the new data size.
2727 size_t objectsSize = mObjectsSize;
2728 if (desired < mDataSize) {
2729 if (desired == 0) {
2730 objectsSize = 0;
2731 } else {
2732 while (objectsSize > 0) {
Michael Wachenschwanza6541632017-05-18 22:08:32 +00002733 if (mObjects[objectsSize-1] < desired)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002734 break;
2735 objectsSize--;
2736 }
2737 }
2738 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002739
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002740 if (mOwner) {
2741 // If the size is going to zero, just release the owner's data.
2742 if (desired == 0) {
2743 freeData();
2744 return NO_ERROR;
2745 }
2746
2747 // If there is a different owner, we need to take
2748 // posession.
2749 uint8_t* data = (uint8_t*)malloc(desired);
2750 if (!data) {
2751 mError = NO_MEMORY;
2752 return NO_MEMORY;
2753 }
Yi Kong91635562018-06-07 14:38:36 -07002754 binder_size_t* objects = nullptr;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002755
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002756 if (objectsSize) {
Nick Kraleviche9881a32015-04-28 16:21:30 -07002757 objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002758 if (!objects) {
Hyejin Kim3f727c02013-03-09 11:28:54 +09002759 free(data);
2760
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002761 mError = NO_MEMORY;
2762 return NO_MEMORY;
2763 }
2764
2765 // Little hack to only acquire references on objects
2766 // we will be keeping.
2767 size_t oldObjectsSize = mObjectsSize;
2768 mObjectsSize = objectsSize;
2769 acquireObjects();
2770 mObjectsSize = oldObjectsSize;
2771 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002772
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002773 if (mData) {
2774 memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
2775 }
2776 if (objects && mObjects) {
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002777 memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002778 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002779 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002780 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
Yi Kong91635562018-06-07 14:38:36 -07002781 mOwner = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002782
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002783 LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002784 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002785 gParcelGlobalAllocSize += desired;
2786 gParcelGlobalAllocCount++;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002787 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002788
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002789 mData = data;
2790 mObjects = objects;
2791 mDataSize = (mDataSize < desired) ? mDataSize : desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002792 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002793 mDataCapacity = desired;
2794 mObjectsSize = mObjectsCapacity = objectsSize;
2795 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002796 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002797
2798 } else if (mData) {
2799 if (objectsSize < mObjectsSize) {
2800 // Need to release refs on any objects we are dropping.
2801 const sp<ProcessState> proc(ProcessState::self());
2802 for (size_t i=objectsSize; i<mObjectsSize; i++) {
2803 const flat_binder_object* flat
2804 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002805 if (flat->hdr.type == BINDER_TYPE_FD) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002806 // will need to rescan because we may have lopped off the only FDs
2807 mFdsKnown = false;
2808 }
Adrian Rooscbf37262015-10-22 16:12:53 -07002809 release_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002810 }
Michael Wachenschwanz6af27a82019-06-03 17:24:51 -07002811
2812 if (objectsSize == 0) {
2813 free(mObjects);
2814 mObjects = nullptr;
Michael Wachenschwanzc67d9f32019-10-15 11:49:22 -07002815 mObjectsCapacity = 0;
Michael Wachenschwanz6af27a82019-06-03 17:24:51 -07002816 } else {
2817 binder_size_t* objects =
2818 (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
2819 if (objects) {
2820 mObjects = objects;
Michael Wachenschwanzc67d9f32019-10-15 11:49:22 -07002821 mObjectsCapacity = objectsSize;
Michael Wachenschwanz6af27a82019-06-03 17:24:51 -07002822 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002823 }
2824 mObjectsSize = objectsSize;
2825 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002826 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002827 }
2828
2829 // We own the data, so we can just do a realloc().
2830 if (desired > mDataCapacity) {
2831 uint8_t* data = (uint8_t*)realloc(mData, desired);
2832 if (data) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002833 LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity,
2834 desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002835 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002836 gParcelGlobalAllocSize += desired;
2837 gParcelGlobalAllocSize -= mDataCapacity;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002838 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002839 mData = data;
2840 mDataCapacity = desired;
Ganesh Mahendranade89892017-09-28 16:56:03 +08002841 } else {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002842 mError = NO_MEMORY;
2843 return NO_MEMORY;
2844 }
2845 } else {
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -07002846 if (mDataSize > desired) {
2847 mDataSize = desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002848 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -07002849 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002850 if (mDataPos > desired) {
2851 mDataPos = desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002852 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002853 }
2854 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002855
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002856 } else {
2857 // This is the first data. Easy!
2858 uint8_t* data = (uint8_t*)malloc(desired);
2859 if (!data) {
2860 mError = NO_MEMORY;
2861 return NO_MEMORY;
2862 }
Hyejin Kim3f727c02013-03-09 11:28:54 +09002863
Yi Kong91635562018-06-07 14:38:36 -07002864 if(!(mDataCapacity == 0 && mObjects == nullptr
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002865 && mObjectsCapacity == 0)) {
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002866 ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002867 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002868
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002869 LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002870 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002871 gParcelGlobalAllocSize += desired;
2872 gParcelGlobalAllocCount++;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002873 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002874
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002875 mData = data;
2876 mDataSize = mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002877 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
2878 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002879 mDataCapacity = desired;
2880 }
2881
2882 return NO_ERROR;
2883}
2884
2885void Parcel::initState()
2886{
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002887 LOG_ALLOC("Parcel %p: initState", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002888 mError = NO_ERROR;
Yi Kong91635562018-06-07 14:38:36 -07002889 mData = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002890 mDataSize = 0;
2891 mDataCapacity = 0;
2892 mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002893 ALOGV("initState Setting data size of %p to %zu", this, mDataSize);
2894 ALOGV("initState Setting data pos of %p to %zu", this, mDataPos);
Yi Kong91635562018-06-07 14:38:36 -07002895 mObjects = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002896 mObjectsSize = 0;
2897 mObjectsCapacity = 0;
2898 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002899 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002900 mHasFds = false;
2901 mFdsKnown = true;
Steven Moreland6e5a7752019-08-05 20:30:14 -07002902 mAllowFds = true;
Yi Kong91635562018-06-07 14:38:36 -07002903 mOwner = nullptr;
Adrian Rooscbf37262015-10-22 16:12:53 -07002904 mOpenAshmemSize = 0;
Olivier Gaillarddc848a02019-01-30 17:10:44 +00002905 mWorkSourceRequestHeaderPosition = 0;
2906 mRequestHeaderPresent = false;
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002907
2908 // racing multiple init leads only to multiple identical write
2909 if (gMaxFds == 0) {
2910 struct rlimit result;
2911 if (!getrlimit(RLIMIT_NOFILE, &result)) {
2912 gMaxFds = (size_t)result.rlim_cur;
Christopher Tatebf14e942016-03-25 14:16:24 -07002913 //ALOGI("parcel fd limit set to %zu", gMaxFds);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002914 } else {
2915 ALOGW("Unable to getrlimit: %s", strerror(errno));
2916 gMaxFds = 1024;
2917 }
2918 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002919}
2920
2921void Parcel::scanForFds() const
2922{
2923 bool hasFds = false;
2924 for (size_t i=0; i<mObjectsSize; i++) {
2925 const flat_binder_object* flat
2926 = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002927 if (flat->hdr.type == BINDER_TYPE_FD) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002928 hasFds = true;
2929 break;
2930 }
2931 }
2932 mHasFds = hasFds;
2933 mFdsKnown = true;
2934}
2935
Dan Sandleraa5c2342015-04-10 10:08:45 -04002936size_t Parcel::getBlobAshmemSize() const
2937{
Adrian Roos6bb31142015-10-22 16:46:12 -07002938 // This used to return the size of all blobs that were written to ashmem, now we're returning
2939 // the ashmem currently referenced by this Parcel, which should be equivalent.
2940 // TODO: Remove method once ABI can be changed.
2941 return mOpenAshmemSize;
Dan Sandleraa5c2342015-04-10 10:08:45 -04002942}
2943
Adrian Rooscbf37262015-10-22 16:12:53 -07002944size_t Parcel::getOpenAshmemSize() const
2945{
2946 return mOpenAshmemSize;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002947}
2948
2949// --- Parcel::Blob ---
2950
2951Parcel::Blob::Blob() :
Yi Kong91635562018-06-07 14:38:36 -07002952 mFd(-1), mData(nullptr), mSize(0), mMutable(false) {
Jeff Brown5707dbf2011-09-23 21:17:56 -07002953}
2954
2955Parcel::Blob::~Blob() {
2956 release();
2957}
2958
2959void Parcel::Blob::release() {
Jeff Brown13b16042014-11-11 16:44:25 -08002960 if (mFd != -1 && mData) {
Jeff Brown5707dbf2011-09-23 21:17:56 -07002961 ::munmap(mData, mSize);
2962 }
2963 clear();
2964}
2965
Jeff Brown13b16042014-11-11 16:44:25 -08002966void Parcel::Blob::init(int fd, void* data, size_t size, bool isMutable) {
2967 mFd = fd;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002968 mData = data;
2969 mSize = size;
Jeff Brown13b16042014-11-11 16:44:25 -08002970 mMutable = isMutable;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002971}
2972
2973void Parcel::Blob::clear() {
Jeff Brown13b16042014-11-11 16:44:25 -08002974 mFd = -1;
Yi Kong91635562018-06-07 14:38:36 -07002975 mData = nullptr;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002976 mSize = 0;
Jeff Brown13b16042014-11-11 16:44:25 -08002977 mMutable = false;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002978}
2979
Steven Moreland6511af52019-09-26 16:05:45 -07002980} // namespace android