blob: ba44c66020a22b70fcf870447de7e5efc0d91408 [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>
Mark Salyzyn70f36652016-02-02 10:27:03 -080023#include <pthread.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080024#include <stdint.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <sys/mman.h>
Mark Salyzyneab2afc2016-01-27 08:02:48 -080028#include <sys/stat.h>
29#include <sys/types.h>
Christopher Tatee4e0ae82016-03-24 16:03:44 -070030#include <sys/resource.h>
Mark Salyzyneab2afc2016-01-27 08:02:48 -080031#include <unistd.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070032
Mathias Agopianc5b2c0b2009-05-19 19:08:10 -070033#include <binder/Binder.h>
34#include <binder/BpBinder.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080035#include <binder/IPCThreadState.h>
36#include <binder/Parcel.h>
Mathias Agopianc5b2c0b2009-05-19 19:08:10 -070037#include <binder/ProcessState.h>
Christopher Wiley09eb7492015-11-09 15:06:15 -080038#include <binder/Status.h>
Mathias Agopian002e1e52013-05-06 20:20:50 -070039#include <binder/TextOutput.h>
40
Mark Salyzynabed7f72016-01-27 08:02:48 -080041#include <cutils/ashmem.h>
Mathias Agopian002e1e52013-05-06 20:20:50 -070042#include <utils/Debug.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080043#include <utils/Flattenable.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070044#include <utils/Log.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080045#include <utils/misc.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070046#include <utils/String8.h>
47#include <utils/String16.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070048
Mathias Agopian208059f2009-05-18 15:08:03 -070049#include <private/binder/binder_module.h>
Steven Morelanda4853cd2019-07-12 15:44:37 -070050#include "Static.h"
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070051
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070052#ifndef INT32_MAX
53#define INT32_MAX ((int32_t)(2147483647))
54#endif
55
56#define LOG_REFS(...)
Mark Salyzyne93390b2016-01-27 08:02:48 -080057//#define LOG_REFS(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
Dianne Hackborn7e790af2014-11-11 12:22:53 -080058#define LOG_ALLOC(...)
Mark Salyzyne93390b2016-01-27 08:02:48 -080059//#define LOG_ALLOC(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070060
61// ---------------------------------------------------------------------------
62
Nick Kralevichb6b14232015-04-02 09:36:02 -070063// This macro should never be used at runtime, as a too large value
64// of s could cause an integer overflow. Instead, you should always
65// use the wrapper function pad_size()
66#define PAD_SIZE_UNSAFE(s) (((s)+3)&~3)
67
68static size_t pad_size(size_t s) {
69 if (s > (SIZE_T_MAX - 3)) {
70 abort();
71 }
72 return PAD_SIZE_UNSAFE(s);
73}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070074
Brad Fitzpatricka877cd82010-07-07 16:06:39 -070075// Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
Jeff Sharkey05827be2018-06-26 10:52:38 -060076#define STRICT_MODE_PENALTY_GATHER (1 << 31)
Brad Fitzpatricka877cd82010-07-07 16:06:39 -070077
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070078namespace android {
79
Steven Moreland7b102262019-08-01 15:48:43 -070080// many things compile this into prebuilts on the stack
81static_assert(sizeof(Parcel) == 60 || sizeof(Parcel) == 120);
82
Dianne Hackborna4cff882014-11-13 17:07:40 -080083static pthread_mutex_t gParcelGlobalAllocSizeLock = PTHREAD_MUTEX_INITIALIZER;
84static size_t gParcelGlobalAllocSize = 0;
85static size_t gParcelGlobalAllocCount = 0;
86
Christopher Tatee4e0ae82016-03-24 16:03:44 -070087static size_t gMaxFds = 0;
88
Jeff Brown13b16042014-11-11 16:44:25 -080089// Maximum size of a blob to transfer in-place.
90static const size_t BLOB_INPLACE_LIMIT = 16 * 1024;
91
92enum {
93 BLOB_INPLACE = 0,
94 BLOB_ASHMEM_IMMUTABLE = 1,
95 BLOB_ASHMEM_MUTABLE = 2,
96};
97
Steven Morelandb1c81202019-04-05 18:49:55 -070098static void acquire_object(const sp<ProcessState>& proc,
Adrian Rooscbf37262015-10-22 16:12:53 -070099 const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700100{
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700101 switch (obj.hdr.type) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700102 case BINDER_TYPE_BINDER:
103 if (obj.binder) {
104 LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800105 reinterpret_cast<IBinder*>(obj.cookie)->incStrong(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700106 }
107 return;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700108 case BINDER_TYPE_HANDLE: {
109 const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
Yi Kong91635562018-06-07 14:38:36 -0700110 if (b != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700111 LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
112 b->incStrong(who);
113 }
114 return;
115 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700116 case BINDER_TYPE_FD: {
Jorim Jaggi150b4ef2018-07-13 11:18:30 +0000117 if ((obj.cookie != 0) && (outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
Mark Salyzyn80589362016-08-23 16:15:04 -0700118 // If we own an ashmem fd, keep track of how much memory it refers to.
119 int size = ashmem_get_size_region(obj.handle);
120 if (size > 0) {
121 *outAshmemSize += size;
Adrian Rooscbf37262015-10-22 16:12:53 -0700122 }
123 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700124 return;
125 }
126 }
127
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700128 ALOGD("Invalid object type 0x%08x", obj.hdr.type);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700129}
130
Adrian Roos6bb31142015-10-22 16:46:12 -0700131static void release_object(const sp<ProcessState>& proc,
Adrian Rooscbf37262015-10-22 16:12:53 -0700132 const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700133{
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700134 switch (obj.hdr.type) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700135 case BINDER_TYPE_BINDER:
136 if (obj.binder) {
137 LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800138 reinterpret_cast<IBinder*>(obj.cookie)->decStrong(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700139 }
140 return;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700141 case BINDER_TYPE_HANDLE: {
142 const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
Yi Kong91635562018-06-07 14:38:36 -0700143 if (b != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700144 LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
145 b->decStrong(who);
146 }
147 return;
148 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700149 case BINDER_TYPE_FD: {
Mark Salyzynb454d8f2016-01-27 08:02:48 -0800150 if (obj.cookie != 0) { // owned
Jorim Jaggi150b4ef2018-07-13 11:18:30 +0000151 if ((outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
Mark Salyzyn80589362016-08-23 16:15:04 -0700152 int size = ashmem_get_size_region(obj.handle);
153 if (size > 0) {
Tri Voaa6e1112019-01-29 13:23:46 -0800154 // ashmem size might have changed since last time it was accounted for, e.g.
155 // in acquire_object(). Value of *outAshmemSize is not critical since we are
156 // releasing the object anyway. Check for integer overflow condition.
157 *outAshmemSize -= std::min(*outAshmemSize, static_cast<size_t>(size));
Adrian Roos6bb31142015-10-22 16:46:12 -0700158 }
Adrian Roos6bb31142015-10-22 16:46:12 -0700159 }
Mark Salyzynb454d8f2016-01-27 08:02:48 -0800160
161 close(obj.handle);
Adrian Rooscbf37262015-10-22 16:12:53 -0700162 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700163 return;
164 }
165 }
166
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700167 ALOGE("Invalid object type 0x%08x", obj.hdr.type);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700168}
169
Steven Morelanda86a3562019-08-01 23:28:34 +0000170status_t Parcel::finishFlattenBinder(
171 const sp<IBinder>& binder, const flat_binder_object& flat)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700172{
Steven Morelanda86a3562019-08-01 23:28:34 +0000173 status_t status = writeObject(flat, false);
174 if (status != OK) return status;
175
176 return writeInt32(internal::Stability::get(binder.get()));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700177}
178
Steven Morelanda86a3562019-08-01 23:28:34 +0000179status_t Parcel::finishUnflattenBinder(
180 const sp<IBinder>& binder, sp<IBinder>* out) const
181{
182 int32_t stability;
183 status_t status = readInt32(&stability);
184 if (status != OK) return status;
185
186 if (!internal::Stability::check(stability, mRequiredStability)) {
187 return BAD_TYPE;
188 }
189
190 status = internal::Stability::set(binder.get(), stability);
191 if (status != OK) return status;
192
193 *out = binder;
194 return OK;
195}
196
197status_t Parcel::flattenBinder(const sp<IBinder>& binder)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700198{
199 flat_binder_object obj;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700200
Martijn Coenen2b631742017-05-05 11:16:59 -0700201 if (IPCThreadState::self()->backgroundSchedulingDisabled()) {
202 /* minimum priority for all nodes is nice 0 */
203 obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;
204 } else {
205 /* minimum priority for all nodes is MAX_NICE(19) */
206 obj.flags = 0x13 | FLAT_BINDER_FLAG_ACCEPTS_FDS;
207 }
208
Yi Kong91635562018-06-07 14:38:36 -0700209 if (binder != nullptr) {
Steven Morelandf0212002018-12-26 13:59:23 -0800210 BBinder *local = binder->localBinder();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700211 if (!local) {
212 BpBinder *proxy = binder->remoteBinder();
Yi Kong91635562018-06-07 14:38:36 -0700213 if (proxy == nullptr) {
Steve Blocke6f43dd2012-01-06 19:20:56 +0000214 ALOGE("null proxy");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700215 }
216 const int32_t handle = proxy ? proxy->handle() : 0;
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700217 obj.hdr.type = BINDER_TYPE_HANDLE;
Arve Hjønnevåg07fd0f12014-02-18 21:10:29 -0800218 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700219 obj.handle = handle;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800220 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700221 } else {
Steven Morelandf0212002018-12-26 13:59:23 -0800222 if (local->isRequestingSid()) {
223 obj.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
224 }
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700225 obj.hdr.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800226 obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
227 obj.cookie = reinterpret_cast<uintptr_t>(local);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700228 }
229 } else {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700230 obj.hdr.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800231 obj.binder = 0;
232 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700233 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700234
Steven Morelanda86a3562019-08-01 23:28:34 +0000235 return finishFlattenBinder(binder, obj);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700236}
237
Steven Morelanda86a3562019-08-01 23:28:34 +0000238status_t Parcel::unflattenBinder(sp<IBinder>* out) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700239{
Steven Morelanda86a3562019-08-01 23:28:34 +0000240 const flat_binder_object* flat = readObject(false);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700241
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700242 if (flat) {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700243 switch (flat->hdr.type) {
Steven Morelanda86a3562019-08-01 23:28:34 +0000244 case BINDER_TYPE_BINDER: {
245 sp<IBinder> binder = reinterpret_cast<IBinder*>(flat->cookie);
246 return finishUnflattenBinder(binder, out);
247 }
248 case BINDER_TYPE_HANDLE: {
249 sp<IBinder> binder =
250 ProcessState::self()->getStrongProxyForHandle(flat->handle);
251 return finishUnflattenBinder(binder, out);
252 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700253 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700254 }
255 return BAD_TYPE;
256}
257
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700258// ---------------------------------------------------------------------------
259
260Parcel::Parcel()
261{
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800262 LOG_ALLOC("Parcel %p: constructing", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700263 initState();
264}
265
266Parcel::~Parcel()
267{
268 freeDataNoInit();
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800269 LOG_ALLOC("Parcel %p: destroyed", this);
270}
271
272size_t Parcel::getGlobalAllocSize() {
Dianne Hackborna4cff882014-11-13 17:07:40 -0800273 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
274 size_t size = gParcelGlobalAllocSize;
275 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
276 return size;
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800277}
278
279size_t Parcel::getGlobalAllocCount() {
Dianne Hackborna4cff882014-11-13 17:07:40 -0800280 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
281 size_t count = gParcelGlobalAllocCount;
282 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
283 return count;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700284}
285
286const uint8_t* Parcel::data() const
287{
288 return mData;
289}
290
291size_t Parcel::dataSize() const
292{
293 return (mDataSize > mDataPos ? mDataSize : mDataPos);
294}
295
296size_t Parcel::dataAvail() const
297{
Nick Kralevichcfe27de2015-09-16 09:49:15 -0700298 size_t result = dataSize() - dataPosition();
299 if (result > INT32_MAX) {
300 abort();
301 }
302 return result;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700303}
304
305size_t Parcel::dataPosition() const
306{
307 return mDataPos;
308}
309
310size_t Parcel::dataCapacity() const
311{
312 return mDataCapacity;
313}
314
315status_t Parcel::setDataSize(size_t size)
316{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700317 if (size > INT32_MAX) {
318 // don't accept size_t values which may have come from an
319 // inadvertent conversion from a negative int.
320 return BAD_VALUE;
321 }
322
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700323 status_t err;
324 err = continueWrite(size);
325 if (err == NO_ERROR) {
326 mDataSize = size;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700327 ALOGV("setDataSize Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700328 }
329 return err;
330}
331
332void Parcel::setDataPosition(size_t pos) const
333{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700334 if (pos > INT32_MAX) {
335 // don't accept size_t values which may have come from an
336 // inadvertent conversion from a negative int.
337 abort();
338 }
339
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700340 mDataPos = pos;
341 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -0800342 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700343}
344
345status_t Parcel::setDataCapacity(size_t size)
346{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700347 if (size > INT32_MAX) {
348 // don't accept size_t values which may have come from an
349 // inadvertent conversion from a negative int.
350 return BAD_VALUE;
351 }
352
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -0700353 if (size > mDataCapacity) return continueWrite(size);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700354 return NO_ERROR;
355}
356
Steven Morelanda86a3562019-08-01 23:28:34 +0000357void Parcel::setTransactingBinder(const sp<IBinder>& binder) const {
358 mRequiredStability = internal::Stability::get(binder.get());
359}
360
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700361status_t Parcel::setData(const uint8_t* buffer, size_t len)
362{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700363 if (len > INT32_MAX) {
364 // don't accept size_t values which may have come from an
365 // inadvertent conversion from a negative int.
366 return BAD_VALUE;
367 }
368
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700369 status_t err = restartWrite(len);
370 if (err == NO_ERROR) {
371 memcpy(const_cast<uint8_t*>(data()), buffer, len);
372 mDataSize = len;
373 mFdsKnown = false;
374 }
375 return err;
376}
377
Andreas Huber51faf462011-04-13 10:21:56 -0700378status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700379{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700380 status_t err;
Andreas Huber51faf462011-04-13 10:21:56 -0700381 const uint8_t *data = parcel->mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800382 const binder_size_t *objects = parcel->mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700383 size_t size = parcel->mObjectsSize;
384 int startPos = mDataPos;
385 int firstIndex = -1, lastIndex = -2;
386
387 if (len == 0) {
388 return NO_ERROR;
389 }
390
Nick Kralevichb6b14232015-04-02 09:36:02 -0700391 if (len > INT32_MAX) {
392 // don't accept size_t values which may have come from an
393 // inadvertent conversion from a negative int.
394 return BAD_VALUE;
395 }
396
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700397 // range checks against the source parcel size
398 if ((offset > parcel->mDataSize)
399 || (len > parcel->mDataSize)
400 || (offset + len > parcel->mDataSize)) {
401 return BAD_VALUE;
402 }
403
404 // Count objects in range
405 for (int i = 0; i < (int) size; i++) {
406 size_t off = objects[i];
Christopher Tate27182be2015-05-27 17:53:02 -0700407 if ((off >= offset) && (off + sizeof(flat_binder_object) <= offset + len)) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700408 if (firstIndex == -1) {
409 firstIndex = i;
410 }
411 lastIndex = i;
412 }
413 }
414 int numObjects = lastIndex - firstIndex + 1;
415
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -0700416 if ((mDataSize+len) > mDataCapacity) {
417 // grow data
418 err = growData(len);
419 if (err != NO_ERROR) {
420 return err;
421 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700422 }
423
424 // append data
425 memcpy(mData + mDataPos, data + offset, len);
426 mDataPos += len;
427 mDataSize += len;
428
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400429 err = NO_ERROR;
430
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700431 if (numObjects > 0) {
Martijn Coenen69390d42018-10-22 15:18:10 +0200432 const sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700433 // grow objects
434 if (mObjectsCapacity < mObjectsSize + numObjects) {
Christopher Tateed7a50c2015-06-08 14:45:14 -0700435 size_t newSize = ((mObjectsSize + numObjects)*3)/2;
Christopher Tate44235112016-11-03 13:32:41 -0700436 if (newSize*sizeof(binder_size_t) < mObjectsSize) return NO_MEMORY; // overflow
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800437 binder_size_t *objects =
438 (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
Yi Kong91635562018-06-07 14:38:36 -0700439 if (objects == (binder_size_t*)nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700440 return NO_MEMORY;
441 }
442 mObjects = objects;
443 mObjectsCapacity = newSize;
444 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700445
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700446 // append and acquire objects
447 int idx = mObjectsSize;
448 for (int i = firstIndex; i <= lastIndex; i++) {
449 size_t off = objects[i] - offset + startPos;
450 mObjects[idx++] = off;
451 mObjectsSize++;
452
Dianne Hackborn8af0f822009-05-22 13:20:23 -0700453 flat_binder_object* flat
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700454 = reinterpret_cast<flat_binder_object*>(mData + off);
Adrian Rooscbf37262015-10-22 16:12:53 -0700455 acquire_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700456
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700457 if (flat->hdr.type == BINDER_TYPE_FD) {
Dianne Hackborn8af0f822009-05-22 13:20:23 -0700458 // If this is a file descriptor, we need to dup it so the
459 // new Parcel now owns its own fd, and can declare that we
460 // officially know we have fds.
Nick Kralevichec9ec7d2016-12-17 19:47:27 -0800461 flat->handle = fcntl(flat->handle, F_DUPFD_CLOEXEC, 0);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800462 flat->cookie = 1;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700463 mHasFds = mFdsKnown = true;
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400464 if (!mAllowFds) {
465 err = FDS_NOT_ALLOWED;
466 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700467 }
468 }
469 }
470
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400471 return err;
472}
473
Dianne Hackborn15feb9b2017-04-10 15:34:35 -0700474int Parcel::compareData(const Parcel& other) {
475 size_t size = dataSize();
476 if (size != other.dataSize()) {
477 return size < other.dataSize() ? -1 : 1;
478 }
479 return memcmp(data(), other.data(), size);
480}
481
Jeff Brown13b16042014-11-11 16:44:25 -0800482bool Parcel::allowFds() const
483{
484 return mAllowFds;
485}
486
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700487bool Parcel::pushAllowFds(bool allowFds)
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400488{
489 const bool origValue = mAllowFds;
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700490 if (!allowFds) {
491 mAllowFds = false;
492 }
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400493 return origValue;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700494}
495
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700496void Parcel::restoreAllowFds(bool lastValue)
497{
498 mAllowFds = lastValue;
499}
500
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700501bool Parcel::hasFileDescriptors() const
502{
503 if (!mFdsKnown) {
504 scanForFds();
505 }
506 return mHasFds;
507}
508
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000509void Parcel::updateWorkSourceRequestHeaderPosition() const {
510 // Only update the request headers once. We only want to point
511 // to the first headers read/written.
512 if (!mRequestHeaderPresent) {
513 mWorkSourceRequestHeaderPosition = dataPosition();
514 mRequestHeaderPresent = true;
515 }
516}
517
Steven Morelandd70160f2019-07-23 10:20:38 -0700518#ifdef __ANDROID_VNDK__
519constexpr int32_t kHeader = B_PACK_CHARS('V', 'N', 'D', 'R');
520#else
521constexpr int32_t kHeader = B_PACK_CHARS('S', 'Y', 'S', 'T');
522#endif
523
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700524// Write RPC headers. (previously just the interface token)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700525status_t Parcel::writeInterfaceToken(const String16& interface)
526{
Olivier Gaillard91a04802018-11-14 17:32:41 +0000527 const IPCThreadState* threadState = IPCThreadState::self();
528 writeInt32(threadState->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER);
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000529 updateWorkSourceRequestHeaderPosition();
Olivier Gaillard91a04802018-11-14 17:32:41 +0000530 writeInt32(threadState->shouldPropagateWorkSource() ?
531 threadState->getCallingWorkSourceUid() : IPCThreadState::kUnsetWorkSource);
Steven Morelandd70160f2019-07-23 10:20:38 -0700532 writeInt32(kHeader);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700533 // currently the interface identification token is just its name as a string
534 return writeString16(interface);
535}
536
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000537bool Parcel::replaceCallingWorkSourceUid(uid_t uid)
538{
539 if (!mRequestHeaderPresent) {
540 return false;
541 }
542
543 const size_t initialPosition = dataPosition();
544 setDataPosition(mWorkSourceRequestHeaderPosition);
545 status_t err = writeInt32(uid);
546 setDataPosition(initialPosition);
547 return err == NO_ERROR;
548}
549
550uid_t Parcel::readCallingWorkSourceUid()
551{
552 if (!mRequestHeaderPresent) {
553 return IPCThreadState::kUnsetWorkSource;
554 }
555
556 const size_t initialPosition = dataPosition();
557 setDataPosition(mWorkSourceRequestHeaderPosition);
558 uid_t uid = readInt32();
559 setDataPosition(initialPosition);
560 return uid;
561}
562
Mathias Agopian83c04462009-05-22 19:00:22 -0700563bool Parcel::checkInterface(IBinder* binder) const
564{
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700565 return enforceInterface(binder->getInterfaceDescriptor());
Mathias Agopian83c04462009-05-22 19:00:22 -0700566}
567
Brad Fitzpatricka877cd82010-07-07 16:06:39 -0700568bool Parcel::enforceInterface(const String16& interface,
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700569 IPCThreadState* threadState) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700570{
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100571 // StrictModePolicy.
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700572 int32_t strictPolicy = readInt32();
Yi Kong91635562018-06-07 14:38:36 -0700573 if (threadState == nullptr) {
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700574 threadState = IPCThreadState::self();
Brad Fitzpatricka877cd82010-07-07 16:06:39 -0700575 }
Brad Fitzpatrick52736032010-08-30 16:01:16 -0700576 if ((threadState->getLastTransactionBinderFlags() &
577 IBinder::FLAG_ONEWAY) != 0) {
578 // For one-way calls, the callee is running entirely
579 // disconnected from the caller, so disable StrictMode entirely.
580 // Not only does disk/network usage not impact the caller, but
581 // there's no way to commuicate back any violations anyway.
582 threadState->setStrictModePolicy(0);
583 } else {
584 threadState->setStrictModePolicy(strictPolicy);
585 }
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100586 // WorkSource.
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000587 updateWorkSourceRequestHeaderPosition();
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100588 int32_t workSource = readInt32();
Olivier Gaillard91a04802018-11-14 17:32:41 +0000589 threadState->setCallingWorkSourceUidWithoutPropagation(workSource);
Steven Morelandd70160f2019-07-23 10:20:38 -0700590 // vendor header
591 int32_t header = readInt32();
592 if (header != kHeader) {
593 ALOGE("Expecting header 0x%x but found 0x%x. Mixing copies of libbinder?", kHeader, header);
594 return false;
595 }
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100596 // Interface descriptor.
Mathias Agopian83c04462009-05-22 19:00:22 -0700597 const String16 str(readString16());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700598 if (str == interface) {
599 return true;
600 } else {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700601 ALOGW("**** enforceInterface() expected '%s' but read '%s'",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700602 String8(interface).string(), String8(str).string());
603 return false;
604 }
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700605}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700606
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700607size_t Parcel::objectsCount() const
608{
609 return mObjectsSize;
610}
611
612status_t Parcel::errorCheck() const
613{
614 return mError;
615}
616
617void Parcel::setError(status_t err)
618{
619 mError = err;
620}
621
622status_t Parcel::finishWrite(size_t len)
623{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700624 if (len > INT32_MAX) {
625 // don't accept size_t values which may have come from an
626 // inadvertent conversion from a negative int.
627 return BAD_VALUE;
628 }
629
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700630 //printf("Finish write of %d\n", len);
631 mDataPos += len;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700632 ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700633 if (mDataPos > mDataSize) {
634 mDataSize = mDataPos;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700635 ALOGV("finishWrite Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700636 }
637 //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
638 return NO_ERROR;
639}
640
641status_t Parcel::writeUnpadded(const void* data, size_t len)
642{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700643 if (len > INT32_MAX) {
644 // don't accept size_t values which may have come from an
645 // inadvertent conversion from a negative int.
646 return BAD_VALUE;
647 }
648
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700649 size_t end = mDataPos + len;
650 if (end < mDataPos) {
651 // integer overflow
652 return BAD_VALUE;
653 }
654
655 if (end <= mDataCapacity) {
656restart_write:
657 memcpy(mData+mDataPos, data, len);
658 return finishWrite(len);
659 }
660
661 status_t err = growData(len);
662 if (err == NO_ERROR) goto restart_write;
663 return err;
664}
665
666status_t Parcel::write(const void* data, size_t len)
667{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700668 if (len > INT32_MAX) {
669 // don't accept size_t values which may have come from an
670 // inadvertent conversion from a negative int.
671 return BAD_VALUE;
672 }
673
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700674 void* const d = writeInplace(len);
675 if (d) {
676 memcpy(d, data, len);
677 return NO_ERROR;
678 }
679 return mError;
680}
681
682void* Parcel::writeInplace(size_t len)
683{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700684 if (len > INT32_MAX) {
685 // don't accept size_t values which may have come from an
686 // inadvertent conversion from a negative int.
Yi Kong91635562018-06-07 14:38:36 -0700687 return nullptr;
Nick Kralevichb6b14232015-04-02 09:36:02 -0700688 }
689
690 const size_t padded = pad_size(len);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700691
692 // sanity check for integer overflow
693 if (mDataPos+padded < mDataPos) {
Yi Kong91635562018-06-07 14:38:36 -0700694 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700695 }
696
697 if ((mDataPos+padded) <= mDataCapacity) {
698restart_write:
699 //printf("Writing %ld bytes, padded to %ld\n", len, padded);
700 uint8_t* const data = mData+mDataPos;
701
702 // Need to pad at end?
703 if (padded != len) {
704#if BYTE_ORDER == BIG_ENDIAN
705 static const uint32_t mask[4] = {
706 0x00000000, 0xffffff00, 0xffff0000, 0xff000000
707 };
708#endif
709#if BYTE_ORDER == LITTLE_ENDIAN
710 static const uint32_t mask[4] = {
711 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
712 };
713#endif
714 //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
715 // *reinterpret_cast<void**>(data+padded-4));
716 *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
717 }
718
719 finishWrite(padded);
720 return data;
721 }
722
723 status_t err = growData(padded);
724 if (err == NO_ERROR) goto restart_write;
Yi Kong91635562018-06-07 14:38:36 -0700725 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700726}
727
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800728status_t Parcel::writeUtf8AsUtf16(const std::string& str) {
729 const uint8_t* strData = (uint8_t*)str.data();
730 const size_t strLen= str.length();
731 const ssize_t utf16Len = utf8_to_utf16_length(strData, strLen);
Sergio Girof4607432016-07-21 14:46:35 +0100732 if (utf16Len < 0 || utf16Len > std::numeric_limits<int32_t>::max()) {
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800733 return BAD_VALUE;
734 }
735
736 status_t err = writeInt32(utf16Len);
737 if (err) {
738 return err;
739 }
740
741 // Allocate enough bytes to hold our converted string and its terminating NULL.
742 void* dst = writeInplace((utf16Len + 1) * sizeof(char16_t));
743 if (!dst) {
744 return NO_MEMORY;
745 }
746
Sergio Girof4607432016-07-21 14:46:35 +0100747 utf8_to_utf16(strData, strLen, (char16_t*)dst, (size_t) utf16Len + 1);
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800748
749 return NO_ERROR;
750}
751
752status_t Parcel::writeUtf8AsUtf16(const std::unique_ptr<std::string>& str) {
753 if (!str) {
754 return writeInt32(-1);
755 }
756 return writeUtf8AsUtf16(*str);
757}
758
Casey Dahlin185d3442016-02-09 11:08:35 -0800759namespace {
Casey Dahlinb9872622015-11-25 15:09:45 -0800760
Casey Dahlin185d3442016-02-09 11:08:35 -0800761template<typename T>
762status_t writeByteVectorInternal(Parcel* parcel, const std::vector<T>& val)
Casey Dahlin451ff582015-10-19 18:12:18 -0700763{
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700764 status_t status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700765 if (val.size() > std::numeric_limits<int32_t>::max()) {
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700766 status = BAD_VALUE;
767 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700768 }
769
Casey Dahlin185d3442016-02-09 11:08:35 -0800770 status = parcel->writeInt32(val.size());
Casey Dahlin451ff582015-10-19 18:12:18 -0700771 if (status != OK) {
772 return status;
773 }
774
Casey Dahlin185d3442016-02-09 11:08:35 -0800775 void* data = parcel->writeInplace(val.size());
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700776 if (!data) {
777 status = BAD_VALUE;
778 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700779 }
780
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700781 memcpy(data, val.data(), val.size());
782 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700783}
784
Casey Dahlin185d3442016-02-09 11:08:35 -0800785template<typename T>
786status_t writeByteVectorInternalPtr(Parcel* parcel,
787 const std::unique_ptr<std::vector<T>>& val)
788{
789 if (!val) {
790 return parcel->writeInt32(-1);
791 }
792
793 return writeByteVectorInternal(parcel, *val);
794}
795
796} // namespace
797
798status_t Parcel::writeByteVector(const std::vector<int8_t>& val) {
799 return writeByteVectorInternal(this, val);
800}
801
802status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val)
803{
804 return writeByteVectorInternalPtr(this, val);
805}
806
807status_t Parcel::writeByteVector(const std::vector<uint8_t>& val) {
808 return writeByteVectorInternal(this, val);
809}
810
811status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val)
812{
813 return writeByteVectorInternalPtr(this, val);
814}
815
Casey Dahlin451ff582015-10-19 18:12:18 -0700816status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val)
817{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800818 return writeTypedVector(val, &Parcel::writeInt32);
Casey Dahlin451ff582015-10-19 18:12:18 -0700819}
820
Casey Dahlinb9872622015-11-25 15:09:45 -0800821status_t Parcel::writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val)
822{
823 return writeNullableTypedVector(val, &Parcel::writeInt32);
824}
825
Casey Dahlin451ff582015-10-19 18:12:18 -0700826status_t Parcel::writeInt64Vector(const std::vector<int64_t>& val)
827{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800828 return writeTypedVector(val, &Parcel::writeInt64);
Casey Dahlin451ff582015-10-19 18:12:18 -0700829}
830
Casey Dahlinb9872622015-11-25 15:09:45 -0800831status_t Parcel::writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val)
832{
833 return writeNullableTypedVector(val, &Parcel::writeInt64);
834}
835
Kevin DuBois2f82d5b2018-12-05 12:56:10 -0800836status_t Parcel::writeUint64Vector(const std::vector<uint64_t>& val)
837{
838 return writeTypedVector(val, &Parcel::writeUint64);
839}
840
841status_t Parcel::writeUint64Vector(const std::unique_ptr<std::vector<uint64_t>>& val)
842{
843 return writeNullableTypedVector(val, &Parcel::writeUint64);
844}
845
Casey Dahlin451ff582015-10-19 18:12:18 -0700846status_t Parcel::writeFloatVector(const std::vector<float>& val)
847{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800848 return writeTypedVector(val, &Parcel::writeFloat);
Casey Dahlin451ff582015-10-19 18:12:18 -0700849}
850
Casey Dahlinb9872622015-11-25 15:09:45 -0800851status_t Parcel::writeFloatVector(const std::unique_ptr<std::vector<float>>& val)
852{
853 return writeNullableTypedVector(val, &Parcel::writeFloat);
854}
855
Casey Dahlin451ff582015-10-19 18:12:18 -0700856status_t Parcel::writeDoubleVector(const std::vector<double>& val)
857{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800858 return writeTypedVector(val, &Parcel::writeDouble);
Casey Dahlin451ff582015-10-19 18:12:18 -0700859}
860
Casey Dahlinb9872622015-11-25 15:09:45 -0800861status_t Parcel::writeDoubleVector(const std::unique_ptr<std::vector<double>>& val)
862{
863 return writeNullableTypedVector(val, &Parcel::writeDouble);
864}
865
Casey Dahlin451ff582015-10-19 18:12:18 -0700866status_t Parcel::writeBoolVector(const std::vector<bool>& val)
867{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800868 return writeTypedVector(val, &Parcel::writeBool);
Casey Dahlin451ff582015-10-19 18:12:18 -0700869}
870
Casey Dahlinb9872622015-11-25 15:09:45 -0800871status_t Parcel::writeBoolVector(const std::unique_ptr<std::vector<bool>>& val)
872{
873 return writeNullableTypedVector(val, &Parcel::writeBool);
874}
875
Casey Dahlin451ff582015-10-19 18:12:18 -0700876status_t Parcel::writeCharVector(const std::vector<char16_t>& val)
877{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800878 return writeTypedVector(val, &Parcel::writeChar);
Casey Dahlin451ff582015-10-19 18:12:18 -0700879}
880
Casey Dahlinb9872622015-11-25 15:09:45 -0800881status_t Parcel::writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val)
882{
883 return writeNullableTypedVector(val, &Parcel::writeChar);
884}
885
Casey Dahlin451ff582015-10-19 18:12:18 -0700886status_t Parcel::writeString16Vector(const std::vector<String16>& val)
887{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800888 return writeTypedVector(val, &Parcel::writeString16);
Casey Dahlin451ff582015-10-19 18:12:18 -0700889}
890
Casey Dahlinb9872622015-11-25 15:09:45 -0800891status_t Parcel::writeString16Vector(
892 const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val)
893{
894 return writeNullableTypedVector(val, &Parcel::writeString16);
895}
896
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800897status_t Parcel::writeUtf8VectorAsUtf16Vector(
898 const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val) {
899 return writeNullableTypedVector(val, &Parcel::writeUtf8AsUtf16);
900}
901
902status_t Parcel::writeUtf8VectorAsUtf16Vector(const std::vector<std::string>& val) {
903 return writeTypedVector(val, &Parcel::writeUtf8AsUtf16);
904}
905
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700906status_t Parcel::writeInt32(int32_t val)
907{
Andreas Huber84a6d042009-08-17 13:33:27 -0700908 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700909}
Dan Stoza41a0f2f2014-12-01 10:01:10 -0800910
911status_t Parcel::writeUint32(uint32_t val)
912{
913 return writeAligned(val);
914}
915
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700916status_t Parcel::writeInt32Array(size_t len, const int32_t *val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -0700917 if (len > INT32_MAX) {
918 // don't accept size_t values which may have come from an
919 // inadvertent conversion from a negative int.
920 return BAD_VALUE;
921 }
922
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700923 if (!val) {
Chad Brubakere59cb432015-06-30 14:03:55 -0700924 return writeInt32(-1);
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700925 }
Chad Brubakere59cb432015-06-30 14:03:55 -0700926 status_t ret = writeInt32(static_cast<uint32_t>(len));
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700927 if (ret == NO_ERROR) {
928 ret = write(val, len * sizeof(*val));
929 }
930 return ret;
931}
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700932status_t Parcel::writeByteArray(size_t len, const uint8_t *val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -0700933 if (len > INT32_MAX) {
934 // don't accept size_t values which may have come from an
935 // inadvertent conversion from a negative int.
936 return BAD_VALUE;
937 }
938
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700939 if (!val) {
Chad Brubakere59cb432015-06-30 14:03:55 -0700940 return writeInt32(-1);
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700941 }
Chad Brubakere59cb432015-06-30 14:03:55 -0700942 status_t ret = writeInt32(static_cast<uint32_t>(len));
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700943 if (ret == NO_ERROR) {
944 ret = write(val, len * sizeof(*val));
945 }
946 return ret;
947}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700948
Casey Dahlind6848f52015-10-15 15:44:59 -0700949status_t Parcel::writeBool(bool val)
950{
951 return writeInt32(int32_t(val));
952}
953
954status_t Parcel::writeChar(char16_t val)
955{
956 return writeInt32(int32_t(val));
957}
958
959status_t Parcel::writeByte(int8_t val)
960{
961 return writeInt32(int32_t(val));
962}
963
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700964status_t Parcel::writeInt64(int64_t val)
965{
Andreas Huber84a6d042009-08-17 13:33:27 -0700966 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700967}
968
Ronghua Wu2d13afd2015-03-16 11:11:07 -0700969status_t Parcel::writeUint64(uint64_t val)
970{
971 return writeAligned(val);
972}
973
Serban Constantinescuf683e012013-11-05 16:53:55 +0000974status_t Parcel::writePointer(uintptr_t val)
975{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800976 return writeAligned<binder_uintptr_t>(val);
Serban Constantinescuf683e012013-11-05 16:53:55 +0000977}
978
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700979status_t Parcel::writeFloat(float val)
980{
Andreas Huber84a6d042009-08-17 13:33:27 -0700981 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700982}
983
Douglas Leungcc1a4bb2013-01-11 15:00:55 -0800984#if defined(__mips__) && defined(__mips_hard_float)
985
986status_t Parcel::writeDouble(double val)
987{
988 union {
989 double d;
990 unsigned long long ll;
991 } u;
992 u.d = val;
993 return writeAligned(u.ll);
994}
995
996#else
997
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700998status_t Parcel::writeDouble(double val)
999{
Andreas Huber84a6d042009-08-17 13:33:27 -07001000 return writeAligned(val);
1001}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001002
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001003#endif
1004
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001005status_t Parcel::writeCString(const char* str)
1006{
1007 return write(str, strlen(str)+1);
1008}
1009
1010status_t Parcel::writeString8(const String8& str)
1011{
1012 status_t err = writeInt32(str.bytes());
Pravat Dalbeherad1dff8d2010-12-15 08:40:00 +01001013 // only write string if its length is more than zero characters,
1014 // as readString8 will only read if the length field is non-zero.
1015 // this is slightly different from how writeString16 works.
1016 if (str.bytes() > 0 && err == NO_ERROR) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001017 err = write(str.string(), str.bytes()+1);
1018 }
1019 return err;
1020}
1021
Casey Dahlinb9872622015-11-25 15:09:45 -08001022status_t Parcel::writeString16(const std::unique_ptr<String16>& str)
1023{
1024 if (!str) {
1025 return writeInt32(-1);
1026 }
1027
1028 return writeString16(*str);
1029}
1030
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001031status_t Parcel::writeString16(const String16& str)
1032{
1033 return writeString16(str.string(), str.size());
1034}
1035
1036status_t Parcel::writeString16(const char16_t* str, size_t len)
1037{
Yi Kong91635562018-06-07 14:38:36 -07001038 if (str == nullptr) return writeInt32(-1);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001039
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001040 status_t err = writeInt32(len);
1041 if (err == NO_ERROR) {
1042 len *= sizeof(char16_t);
1043 uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
1044 if (data) {
1045 memcpy(data, str, len);
1046 *reinterpret_cast<char16_t*>(data+len) = 0;
1047 return NO_ERROR;
1048 }
1049 err = mError;
1050 }
1051 return err;
1052}
1053
1054status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
1055{
Steven Morelanda86a3562019-08-01 23:28:34 +00001056 return flattenBinder(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001057}
1058
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001059status_t Parcel::writeStrongBinderVector(const std::vector<sp<IBinder>>& val)
1060{
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001061 return writeTypedVector(val, &Parcel::writeStrongBinder);
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001062}
1063
Casey Dahlinb9872622015-11-25 15:09:45 -08001064status_t Parcel::writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val)
1065{
1066 return writeNullableTypedVector(val, &Parcel::writeStrongBinder);
1067}
1068
1069status_t Parcel::readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const {
Christopher Wiley35d77ca2016-03-08 10:49:51 -08001070 return readNullableTypedVector(val, &Parcel::readNullableStrongBinder);
Casey Dahlinb9872622015-11-25 15:09:45 -08001071}
1072
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001073status_t Parcel::readStrongBinderVector(std::vector<sp<IBinder>>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001074 return readTypedVector(val, &Parcel::readStrongBinder);
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001075}
1076
Casey Dahlinb9872622015-11-25 15:09:45 -08001077status_t Parcel::writeRawNullableParcelable(const Parcelable* parcelable) {
1078 if (!parcelable) {
1079 return writeInt32(0);
1080 }
1081
1082 return writeParcelable(*parcelable);
1083}
1084
Christopher Wiley97f048d2015-11-19 06:49:05 -08001085status_t Parcel::writeParcelable(const Parcelable& parcelable) {
1086 status_t status = writeInt32(1); // parcelable is not null.
1087 if (status != OK) {
1088 return status;
1089 }
1090 return parcelable.writeToParcel(this);
1091}
1092
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001093status_t Parcel::writeNativeHandle(const native_handle* handle)
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001094{
Mathias Agopian1d0a95b2009-07-31 16:12:13 -07001095 if (!handle || handle->version != sizeof(native_handle))
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001096 return BAD_TYPE;
1097
1098 status_t err;
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001099 err = writeInt32(handle->numFds);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001100 if (err != NO_ERROR) return err;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001101
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001102 err = writeInt32(handle->numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001103 if (err != NO_ERROR) return err;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001104
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001105 for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)
1106 err = writeDupFileDescriptor(handle->data[i]);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001107
1108 if (err != NO_ERROR) {
Steve Block9d453682011-12-20 16:23:08 +00001109 ALOGD("write native handle, write dup fd failed");
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001110 return err;
1111 }
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001112 err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001113 return err;
1114}
1115
Jeff Brown93ff1f92011-11-04 19:01:44 -07001116status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001117{
1118 flat_binder_object obj;
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07001119 obj.hdr.type = BINDER_TYPE_FD;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001120 obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
Arve Hjønnevåg07fd0f12014-02-18 21:10:29 -08001121 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001122 obj.handle = fd;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001123 obj.cookie = takeOwnership ? 1 : 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001124 return writeObject(obj, true);
1125}
1126
1127status_t Parcel::writeDupFileDescriptor(int fd)
1128{
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08001129 int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
Jeff Brownd341c712011-11-04 20:19:33 -07001130 if (dupFd < 0) {
1131 return -errno;
1132 }
1133 status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/);
Casey Dahlin06673e32015-11-23 13:24:23 -08001134 if (err != OK) {
Jeff Brownd341c712011-11-04 20:19:33 -07001135 close(dupFd);
1136 }
1137 return err;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001138}
1139
Dianne Hackborn1941a402016-08-29 12:30:43 -07001140status_t Parcel::writeParcelFileDescriptor(int fd, bool takeOwnership)
1141{
1142 writeInt32(0);
1143 return writeFileDescriptor(fd, takeOwnership);
1144}
1145
Ryo Hashimotobf551892018-05-31 16:58:35 +09001146status_t Parcel::writeDupParcelFileDescriptor(int fd)
1147{
1148 int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
1149 if (dupFd < 0) {
1150 return -errno;
1151 }
1152 status_t err = writeParcelFileDescriptor(dupFd, true /*takeOwnership*/);
1153 if (err != OK) {
1154 close(dupFd);
1155 }
1156 return err;
1157}
1158
Christopher Wiley2cf19952016-04-11 11:09:37 -07001159status_t Parcel::writeUniqueFileDescriptor(const base::unique_fd& fd) {
Casey Dahlin06673e32015-11-23 13:24:23 -08001160 return writeDupFileDescriptor(fd.get());
1161}
1162
Christopher Wiley2cf19952016-04-11 11:09:37 -07001163status_t Parcel::writeUniqueFileDescriptorVector(const std::vector<base::unique_fd>& val) {
Casey Dahlin06673e32015-11-23 13:24:23 -08001164 return writeTypedVector(val, &Parcel::writeUniqueFileDescriptor);
1165}
1166
Christopher Wiley2cf19952016-04-11 11:09:37 -07001167status_t Parcel::writeUniqueFileDescriptorVector(const std::unique_ptr<std::vector<base::unique_fd>>& val) {
Casey Dahlinb9872622015-11-25 15:09:45 -08001168 return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
1169}
1170
Jeff Brown13b16042014-11-11 16:44:25 -08001171status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob)
Jeff Brown5707dbf2011-09-23 21:17:56 -07001172{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001173 if (len > INT32_MAX) {
1174 // don't accept size_t values which may have come from an
1175 // inadvertent conversion from a negative int.
1176 return BAD_VALUE;
1177 }
1178
Jeff Brown13b16042014-11-11 16:44:25 -08001179 status_t status;
1180 if (!mAllowFds || len <= BLOB_INPLACE_LIMIT) {
Steve Block6807e592011-10-20 11:56:00 +01001181 ALOGV("writeBlob: write in place");
Jeff Brown13b16042014-11-11 16:44:25 -08001182 status = writeInt32(BLOB_INPLACE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001183 if (status) return status;
1184
1185 void* ptr = writeInplace(len);
1186 if (!ptr) return NO_MEMORY;
1187
Jeff Brown13b16042014-11-11 16:44:25 -08001188 outBlob->init(-1, ptr, len, false);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001189 return NO_ERROR;
1190 }
1191
Steve Block6807e592011-10-20 11:56:00 +01001192 ALOGV("writeBlob: write to ashmem");
Jeff Brown5707dbf2011-09-23 21:17:56 -07001193 int fd = ashmem_create_region("Parcel Blob", len);
1194 if (fd < 0) return NO_MEMORY;
1195
1196 int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
1197 if (result < 0) {
Jeff Brownec4e0062011-10-10 14:50:10 -07001198 status = result;
Jeff Brown5707dbf2011-09-23 21:17:56 -07001199 } else {
Yi Kong91635562018-06-07 14:38:36 -07001200 void* ptr = ::mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001201 if (ptr == MAP_FAILED) {
1202 status = -errno;
1203 } else {
Jeff Brown13b16042014-11-11 16:44:25 -08001204 if (!mutableCopy) {
1205 result = ashmem_set_prot_region(fd, PROT_READ);
1206 }
Jeff Brown5707dbf2011-09-23 21:17:56 -07001207 if (result < 0) {
Jeff Brownec4e0062011-10-10 14:50:10 -07001208 status = result;
Jeff Brown5707dbf2011-09-23 21:17:56 -07001209 } else {
Jeff Brown13b16042014-11-11 16:44:25 -08001210 status = writeInt32(mutableCopy ? BLOB_ASHMEM_MUTABLE : BLOB_ASHMEM_IMMUTABLE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001211 if (!status) {
Jeff Brown93ff1f92011-11-04 19:01:44 -07001212 status = writeFileDescriptor(fd, true /*takeOwnership*/);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001213 if (!status) {
Jeff Brown13b16042014-11-11 16:44:25 -08001214 outBlob->init(fd, ptr, len, mutableCopy);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001215 return NO_ERROR;
1216 }
1217 }
1218 }
1219 }
1220 ::munmap(ptr, len);
1221 }
1222 ::close(fd);
1223 return status;
1224}
1225
Jeff Brown13b16042014-11-11 16:44:25 -08001226status_t Parcel::writeDupImmutableBlobFileDescriptor(int fd)
1227{
1228 // Must match up with what's done in writeBlob.
1229 if (!mAllowFds) return FDS_NOT_ALLOWED;
1230 status_t status = writeInt32(BLOB_ASHMEM_IMMUTABLE);
1231 if (status) return status;
1232 return writeDupFileDescriptor(fd);
1233}
1234
Mathias Agopiane1424282013-07-29 21:24:40 -07001235status_t Parcel::write(const FlattenableHelperInterface& val)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001236{
1237 status_t err;
1238
1239 // size if needed
Mathias Agopiane1424282013-07-29 21:24:40 -07001240 const size_t len = val.getFlattenedSize();
1241 const size_t fd_count = val.getFdCount();
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001242
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001243 if ((len > INT32_MAX) || (fd_count >= gMaxFds)) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001244 // don't accept size_t values which may have come from an
1245 // inadvertent conversion from a negative int.
1246 return BAD_VALUE;
1247 }
1248
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001249 err = this->writeInt32(len);
1250 if (err) return err;
1251
1252 err = this->writeInt32(fd_count);
1253 if (err) return err;
1254
1255 // payload
Martijn Coenenf8542382018-04-04 11:46:56 +02001256 void* const buf = this->writeInplace(len);
Yi Kong91635562018-06-07 14:38:36 -07001257 if (buf == nullptr)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001258 return BAD_VALUE;
1259
Yi Kong91635562018-06-07 14:38:36 -07001260 int* fds = nullptr;
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001261 if (fd_count) {
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001262 fds = new (std::nothrow) int[fd_count];
1263 if (fds == nullptr) {
1264 ALOGE("write: failed to allocate requested %zu fds", fd_count);
1265 return BAD_VALUE;
1266 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001267 }
1268
1269 err = val.flatten(buf, len, fds, fd_count);
1270 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
1271 err = this->writeDupFileDescriptor( fds[i] );
1272 }
1273
1274 if (fd_count) {
1275 delete [] fds;
1276 }
1277
1278 return err;
1279}
1280
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001281status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
1282{
1283 const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
1284 const bool enoughObjects = mObjectsSize < mObjectsCapacity;
1285 if (enoughData && enoughObjects) {
1286restart_write:
1287 *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001288
Christopher Tate98e67d32015-06-03 18:44:15 -07001289 // remember if it's a file descriptor
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07001290 if (val.hdr.type == BINDER_TYPE_FD) {
Christopher Tate98e67d32015-06-03 18:44:15 -07001291 if (!mAllowFds) {
1292 // fail before modifying our object index
1293 return FDS_NOT_ALLOWED;
1294 }
1295 mHasFds = mFdsKnown = true;
1296 }
1297
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001298 // Need to write meta-data?
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001299 if (nullMetaData || val.binder != 0) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001300 mObjects[mObjectsSize] = mDataPos;
Adrian Rooscbf37262015-10-22 16:12:53 -07001301 acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001302 mObjectsSize++;
1303 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001304
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001305 return finishWrite(sizeof(flat_binder_object));
1306 }
1307
1308 if (!enoughData) {
1309 const status_t err = growData(sizeof(val));
1310 if (err != NO_ERROR) return err;
1311 }
1312 if (!enoughObjects) {
1313 size_t newSize = ((mObjectsSize+2)*3)/2;
Christopher Tate44235112016-11-03 13:32:41 -07001314 if (newSize*sizeof(binder_size_t) < mObjectsSize) return NO_MEMORY; // overflow
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001315 binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
Yi Kong91635562018-06-07 14:38:36 -07001316 if (objects == nullptr) return NO_MEMORY;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001317 mObjects = objects;
1318 mObjectsCapacity = newSize;
1319 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001320
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001321 goto restart_write;
1322}
1323
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07001324status_t Parcel::writeNoException()
1325{
Christopher Wiley09eb7492015-11-09 15:06:15 -08001326 binder::Status status;
1327 return status.writeToParcel(this);
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07001328}
1329
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001330status_t Parcel::validateReadData(size_t upperBound) const
1331{
1332 // Don't allow non-object reads on object data
1333 if (mObjectsSorted || mObjectsSize <= 1) {
1334data_sorted:
1335 // Expect to check only against the next object
1336 if (mNextObjectHint < mObjectsSize && upperBound > mObjects[mNextObjectHint]) {
1337 // For some reason the current read position is greater than the next object
1338 // hint. Iterate until we find the right object
1339 size_t nextObject = mNextObjectHint;
1340 do {
1341 if (mDataPos < mObjects[nextObject] + sizeof(flat_binder_object)) {
1342 // Requested info overlaps with an object
1343 ALOGE("Attempt to read from protected data in Parcel %p", this);
1344 return PERMISSION_DENIED;
1345 }
1346 nextObject++;
1347 } while (nextObject < mObjectsSize && upperBound > mObjects[nextObject]);
1348 mNextObjectHint = nextObject;
1349 }
1350 return NO_ERROR;
1351 }
1352 // Quickly determine if mObjects is sorted.
1353 binder_size_t* currObj = mObjects + mObjectsSize - 1;
1354 binder_size_t* prevObj = currObj;
1355 while (currObj > mObjects) {
1356 prevObj--;
1357 if(*prevObj > *currObj) {
1358 goto data_unsorted;
1359 }
1360 currObj--;
1361 }
1362 mObjectsSorted = true;
1363 goto data_sorted;
1364
1365data_unsorted:
1366 // Insertion Sort mObjects
1367 // Great for mostly sorted lists. If randomly sorted or reverse ordered mObjects become common,
1368 // switch to std::sort(mObjects, mObjects + mObjectsSize);
1369 for (binder_size_t* iter0 = mObjects + 1; iter0 < mObjects + mObjectsSize; iter0++) {
1370 binder_size_t temp = *iter0;
1371 binder_size_t* iter1 = iter0 - 1;
1372 while (iter1 >= mObjects && *iter1 > temp) {
1373 *(iter1 + 1) = *iter1;
1374 iter1--;
1375 }
1376 *(iter1 + 1) = temp;
1377 }
1378 mNextObjectHint = 0;
1379 mObjectsSorted = true;
1380 goto data_sorted;
1381}
1382
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001383status_t Parcel::read(void* outData, size_t len) const
1384{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001385 if (len > INT32_MAX) {
1386 // don't accept size_t values which may have come from an
1387 // inadvertent conversion from a negative int.
1388 return BAD_VALUE;
1389 }
1390
1391 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1392 && len <= pad_size(len)) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001393 if (mObjectsSize > 0) {
1394 status_t err = validateReadData(mDataPos + pad_size(len));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001395 if(err != NO_ERROR) {
1396 // Still increment the data position by the expected length
1397 mDataPos += pad_size(len);
1398 ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
1399 return err;
1400 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001401 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001402 memcpy(outData, mData+mDataPos, len);
Nick Kralevichb6b14232015-04-02 09:36:02 -07001403 mDataPos += pad_size(len);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001404 ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001405 return NO_ERROR;
1406 }
1407 return NOT_ENOUGH_DATA;
1408}
1409
1410const void* Parcel::readInplace(size_t len) const
1411{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001412 if (len > INT32_MAX) {
1413 // don't accept size_t values which may have come from an
1414 // inadvertent conversion from a negative int.
Yi Kong91635562018-06-07 14:38:36 -07001415 return nullptr;
Nick Kralevichb6b14232015-04-02 09:36:02 -07001416 }
1417
1418 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1419 && len <= pad_size(len)) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001420 if (mObjectsSize > 0) {
1421 status_t err = validateReadData(mDataPos + pad_size(len));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001422 if(err != NO_ERROR) {
1423 // Still increment the data position by the expected length
1424 mDataPos += pad_size(len);
1425 ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
Yi Kong91635562018-06-07 14:38:36 -07001426 return nullptr;
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001427 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001428 }
1429
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001430 const void* data = mData+mDataPos;
Nick Kralevichb6b14232015-04-02 09:36:02 -07001431 mDataPos += pad_size(len);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001432 ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001433 return data;
1434 }
Yi Kong91635562018-06-07 14:38:36 -07001435 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001436}
1437
Andreas Huber84a6d042009-08-17 13:33:27 -07001438template<class T>
1439status_t Parcel::readAligned(T *pArg) const {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001440 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
Andreas Huber84a6d042009-08-17 13:33:27 -07001441
1442 if ((mDataPos+sizeof(T)) <= mDataSize) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001443 if (mObjectsSize > 0) {
1444 status_t err = validateReadData(mDataPos + sizeof(T));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001445 if(err != NO_ERROR) {
1446 // Still increment the data position by the expected length
1447 mDataPos += sizeof(T);
1448 return err;
1449 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001450 }
1451
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001452 const void* data = mData+mDataPos;
Andreas Huber84a6d042009-08-17 13:33:27 -07001453 mDataPos += sizeof(T);
1454 *pArg = *reinterpret_cast<const T*>(data);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001455 return NO_ERROR;
1456 } else {
1457 return NOT_ENOUGH_DATA;
1458 }
1459}
1460
Andreas Huber84a6d042009-08-17 13:33:27 -07001461template<class T>
1462T Parcel::readAligned() const {
1463 T result;
1464 if (readAligned(&result) != NO_ERROR) {
1465 result = 0;
1466 }
1467
1468 return result;
1469}
1470
1471template<class T>
1472status_t Parcel::writeAligned(T val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001473 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
Andreas Huber84a6d042009-08-17 13:33:27 -07001474
1475 if ((mDataPos+sizeof(val)) <= mDataCapacity) {
1476restart_write:
1477 *reinterpret_cast<T*>(mData+mDataPos) = val;
1478 return finishWrite(sizeof(val));
1479 }
1480
1481 status_t err = growData(sizeof(val));
1482 if (err == NO_ERROR) goto restart_write;
1483 return err;
1484}
1485
Casey Dahlin185d3442016-02-09 11:08:35 -08001486namespace {
1487
1488template<typename T>
1489status_t readByteVectorInternal(const Parcel* parcel,
1490 std::vector<T>* val) {
Casey Dahlin451ff582015-10-19 18:12:18 -07001491 val->clear();
1492
1493 int32_t size;
Casey Dahlin185d3442016-02-09 11:08:35 -08001494 status_t status = parcel->readInt32(&size);
Casey Dahlin451ff582015-10-19 18:12:18 -07001495
1496 if (status != OK) {
1497 return status;
1498 }
1499
Christopher Wiley4db672d2015-11-10 09:44:30 -08001500 if (size < 0) {
1501 status = UNEXPECTED_NULL;
1502 return status;
1503 }
Casey Dahlin185d3442016-02-09 11:08:35 -08001504 if (size_t(size) > parcel->dataAvail()) {
Christopher Wileyf0fc52b2015-10-31 13:22:15 -07001505 status = BAD_VALUE;
1506 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -07001507 }
Christopher Wiley4db672d2015-11-10 09:44:30 -08001508
Paul Lietar433e87b2016-09-16 10:39:32 -07001509 T* data = const_cast<T*>(reinterpret_cast<const T*>(parcel->readInplace(size)));
Christopher Wileyf0fc52b2015-10-31 13:22:15 -07001510 if (!data) {
1511 status = BAD_VALUE;
1512 return status;
1513 }
Paul Lietar433e87b2016-09-16 10:39:32 -07001514 val->reserve(size);
1515 val->insert(val->end(), data, data + size);
Casey Dahlin451ff582015-10-19 18:12:18 -07001516
Christopher Wileyf0fc52b2015-10-31 13:22:15 -07001517 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -07001518}
1519
Casey Dahlin185d3442016-02-09 11:08:35 -08001520template<typename T>
1521status_t readByteVectorInternalPtr(
1522 const Parcel* parcel,
1523 std::unique_ptr<std::vector<T>>* val) {
1524 const int32_t start = parcel->dataPosition();
Casey Dahlinb9872622015-11-25 15:09:45 -08001525 int32_t size;
Casey Dahlin185d3442016-02-09 11:08:35 -08001526 status_t status = parcel->readInt32(&size);
Casey Dahlinb9872622015-11-25 15:09:45 -08001527 val->reset();
1528
1529 if (status != OK || size < 0) {
1530 return status;
1531 }
1532
Casey Dahlin185d3442016-02-09 11:08:35 -08001533 parcel->setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001534 val->reset(new (std::nothrow) std::vector<T>());
Casey Dahlinb9872622015-11-25 15:09:45 -08001535
Casey Dahlin185d3442016-02-09 11:08:35 -08001536 status = readByteVectorInternal(parcel, val->get());
Casey Dahlinb9872622015-11-25 15:09:45 -08001537
1538 if (status != OK) {
1539 val->reset();
1540 }
1541
1542 return status;
1543}
1544
Casey Dahlin185d3442016-02-09 11:08:35 -08001545} // namespace
1546
1547status_t Parcel::readByteVector(std::vector<int8_t>* val) const {
1548 return readByteVectorInternal(this, val);
1549}
1550
1551status_t Parcel::readByteVector(std::vector<uint8_t>* val) const {
1552 return readByteVectorInternal(this, val);
1553}
1554
1555status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const {
1556 return readByteVectorInternalPtr(this, val);
1557}
1558
1559status_t Parcel::readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const {
1560 return readByteVectorInternalPtr(this, val);
1561}
1562
Casey Dahlinb9872622015-11-25 15:09:45 -08001563status_t Parcel::readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const {
1564 return readNullableTypedVector(val, &Parcel::readInt32);
1565}
1566
Casey Dahlin451ff582015-10-19 18:12:18 -07001567status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001568 return readTypedVector(val, &Parcel::readInt32);
Casey Dahlin451ff582015-10-19 18:12:18 -07001569}
1570
Casey Dahlinb9872622015-11-25 15:09:45 -08001571status_t Parcel::readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const {
1572 return readNullableTypedVector(val, &Parcel::readInt64);
1573}
1574
Casey Dahlin451ff582015-10-19 18:12:18 -07001575status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001576 return readTypedVector(val, &Parcel::readInt64);
Casey Dahlin451ff582015-10-19 18:12:18 -07001577}
1578
Kevin DuBois2f82d5b2018-12-05 12:56:10 -08001579status_t Parcel::readUint64Vector(std::unique_ptr<std::vector<uint64_t>>* val) const {
1580 return readNullableTypedVector(val, &Parcel::readUint64);
1581}
1582
1583status_t Parcel::readUint64Vector(std::vector<uint64_t>* val) const {
1584 return readTypedVector(val, &Parcel::readUint64);
1585}
1586
Casey Dahlinb9872622015-11-25 15:09:45 -08001587status_t Parcel::readFloatVector(std::unique_ptr<std::vector<float>>* val) const {
1588 return readNullableTypedVector(val, &Parcel::readFloat);
1589}
1590
Casey Dahlin451ff582015-10-19 18:12:18 -07001591status_t Parcel::readFloatVector(std::vector<float>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001592 return readTypedVector(val, &Parcel::readFloat);
Casey Dahlin451ff582015-10-19 18:12:18 -07001593}
1594
Casey Dahlinb9872622015-11-25 15:09:45 -08001595status_t Parcel::readDoubleVector(std::unique_ptr<std::vector<double>>* val) const {
1596 return readNullableTypedVector(val, &Parcel::readDouble);
1597}
1598
Casey Dahlin451ff582015-10-19 18:12:18 -07001599status_t Parcel::readDoubleVector(std::vector<double>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001600 return readTypedVector(val, &Parcel::readDouble);
Casey Dahlin451ff582015-10-19 18:12:18 -07001601}
1602
Casey Dahlinb9872622015-11-25 15:09:45 -08001603status_t Parcel::readBoolVector(std::unique_ptr<std::vector<bool>>* val) const {
1604 const int32_t start = dataPosition();
1605 int32_t size;
1606 status_t status = readInt32(&size);
1607 val->reset();
Casey Dahlin451ff582015-10-19 18:12:18 -07001608
Casey Dahlinb9872622015-11-25 15:09:45 -08001609 if (status != OK || size < 0) {
1610 return status;
1611 }
1612
1613 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001614 val->reset(new (std::nothrow) std::vector<bool>());
Casey Dahlinb9872622015-11-25 15:09:45 -08001615
1616 status = readBoolVector(val->get());
1617
1618 if (status != OK) {
1619 val->reset();
1620 }
1621
1622 return status;
1623}
1624
1625status_t Parcel::readBoolVector(std::vector<bool>* val) const {
Casey Dahlin451ff582015-10-19 18:12:18 -07001626 int32_t size;
1627 status_t status = readInt32(&size);
1628
1629 if (status != OK) {
1630 return status;
1631 }
1632
1633 if (size < 0) {
Christopher Wiley4db672d2015-11-10 09:44:30 -08001634 return UNEXPECTED_NULL;
Casey Dahlin451ff582015-10-19 18:12:18 -07001635 }
1636
1637 val->resize(size);
1638
1639 /* C++ bool handling means a vector of bools isn't necessarily addressable
1640 * (we might use individual bits)
1641 */
Christopher Wiley97887982015-10-27 16:33:47 -07001642 bool data;
1643 for (int32_t i = 0; i < size; ++i) {
Casey Dahlin451ff582015-10-19 18:12:18 -07001644 status = readBool(&data);
1645 (*val)[i] = data;
1646
1647 if (status != OK) {
1648 return status;
1649 }
1650 }
1651
1652 return OK;
1653}
1654
Casey Dahlinb9872622015-11-25 15:09:45 -08001655status_t Parcel::readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const {
1656 return readNullableTypedVector(val, &Parcel::readChar);
1657}
1658
Casey Dahlin451ff582015-10-19 18:12:18 -07001659status_t Parcel::readCharVector(std::vector<char16_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001660 return readTypedVector(val, &Parcel::readChar);
Casey Dahlin451ff582015-10-19 18:12:18 -07001661}
1662
Casey Dahlinb9872622015-11-25 15:09:45 -08001663status_t Parcel::readString16Vector(
1664 std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const {
1665 return readNullableTypedVector(val, &Parcel::readString16);
1666}
1667
Casey Dahlin451ff582015-10-19 18:12:18 -07001668status_t Parcel::readString16Vector(std::vector<String16>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001669 return readTypedVector(val, &Parcel::readString16);
Casey Dahlin451ff582015-10-19 18:12:18 -07001670}
1671
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001672status_t Parcel::readUtf8VectorFromUtf16Vector(
1673 std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const {
1674 return readNullableTypedVector(val, &Parcel::readUtf8FromUtf16);
1675}
1676
1677status_t Parcel::readUtf8VectorFromUtf16Vector(std::vector<std::string>* val) const {
1678 return readTypedVector(val, &Parcel::readUtf8FromUtf16);
1679}
Casey Dahlin451ff582015-10-19 18:12:18 -07001680
Andreas Huber84a6d042009-08-17 13:33:27 -07001681status_t Parcel::readInt32(int32_t *pArg) const
1682{
1683 return readAligned(pArg);
1684}
1685
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001686int32_t Parcel::readInt32() const
1687{
Andreas Huber84a6d042009-08-17 13:33:27 -07001688 return readAligned<int32_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001689}
1690
Dan Stoza41a0f2f2014-12-01 10:01:10 -08001691status_t Parcel::readUint32(uint32_t *pArg) const
1692{
1693 return readAligned(pArg);
1694}
1695
1696uint32_t Parcel::readUint32() const
1697{
1698 return readAligned<uint32_t>();
1699}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001700
1701status_t Parcel::readInt64(int64_t *pArg) const
1702{
Andreas Huber84a6d042009-08-17 13:33:27 -07001703 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001704}
1705
1706
1707int64_t Parcel::readInt64() const
1708{
Andreas Huber84a6d042009-08-17 13:33:27 -07001709 return readAligned<int64_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001710}
1711
Ronghua Wu2d13afd2015-03-16 11:11:07 -07001712status_t Parcel::readUint64(uint64_t *pArg) const
1713{
1714 return readAligned(pArg);
1715}
1716
1717uint64_t Parcel::readUint64() const
1718{
1719 return readAligned<uint64_t>();
1720}
1721
Serban Constantinescuf683e012013-11-05 16:53:55 +00001722status_t Parcel::readPointer(uintptr_t *pArg) const
1723{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001724 status_t ret;
1725 binder_uintptr_t ptr;
1726 ret = readAligned(&ptr);
1727 if (!ret)
1728 *pArg = ptr;
1729 return ret;
Serban Constantinescuf683e012013-11-05 16:53:55 +00001730}
1731
1732uintptr_t Parcel::readPointer() const
1733{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001734 return readAligned<binder_uintptr_t>();
Serban Constantinescuf683e012013-11-05 16:53:55 +00001735}
1736
1737
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001738status_t Parcel::readFloat(float *pArg) const
1739{
Andreas Huber84a6d042009-08-17 13:33:27 -07001740 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001741}
1742
1743
1744float Parcel::readFloat() const
1745{
Andreas Huber84a6d042009-08-17 13:33:27 -07001746 return readAligned<float>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001747}
1748
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001749#if defined(__mips__) && defined(__mips_hard_float)
1750
1751status_t Parcel::readDouble(double *pArg) const
1752{
1753 union {
1754 double d;
1755 unsigned long long ll;
1756 } u;
Narayan Kamath2c68d382014-06-04 15:04:29 +01001757 u.d = 0;
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001758 status_t status;
1759 status = readAligned(&u.ll);
1760 *pArg = u.d;
1761 return status;
1762}
1763
1764double Parcel::readDouble() const
1765{
1766 union {
1767 double d;
1768 unsigned long long ll;
1769 } u;
1770 u.ll = readAligned<unsigned long long>();
1771 return u.d;
1772}
1773
1774#else
1775
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001776status_t Parcel::readDouble(double *pArg) const
1777{
Andreas Huber84a6d042009-08-17 13:33:27 -07001778 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001779}
1780
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001781double Parcel::readDouble() const
1782{
Andreas Huber84a6d042009-08-17 13:33:27 -07001783 return readAligned<double>();
1784}
1785
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001786#endif
1787
Andreas Huber84a6d042009-08-17 13:33:27 -07001788status_t Parcel::readIntPtr(intptr_t *pArg) const
1789{
1790 return readAligned(pArg);
1791}
1792
1793
1794intptr_t Parcel::readIntPtr() const
1795{
1796 return readAligned<intptr_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001797}
1798
Casey Dahlind6848f52015-10-15 15:44:59 -07001799status_t Parcel::readBool(bool *pArg) const
1800{
Manoj Gupta6eb62052017-07-12 10:29:15 -07001801 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07001802 status_t ret = readInt32(&tmp);
1803 *pArg = (tmp != 0);
1804 return ret;
1805}
1806
1807bool Parcel::readBool() const
1808{
1809 return readInt32() != 0;
1810}
1811
1812status_t Parcel::readChar(char16_t *pArg) const
1813{
Manoj Gupta6eb62052017-07-12 10:29:15 -07001814 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07001815 status_t ret = readInt32(&tmp);
1816 *pArg = char16_t(tmp);
1817 return ret;
1818}
1819
1820char16_t Parcel::readChar() const
1821{
1822 return char16_t(readInt32());
1823}
1824
1825status_t Parcel::readByte(int8_t *pArg) const
1826{
Manoj Gupta6eb62052017-07-12 10:29:15 -07001827 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07001828 status_t ret = readInt32(&tmp);
1829 *pArg = int8_t(tmp);
1830 return ret;
1831}
1832
1833int8_t Parcel::readByte() const
1834{
1835 return int8_t(readInt32());
1836}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001837
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001838status_t Parcel::readUtf8FromUtf16(std::string* str) const {
1839 size_t utf16Size = 0;
1840 const char16_t* src = readString16Inplace(&utf16Size);
1841 if (!src) {
1842 return UNEXPECTED_NULL;
1843 }
1844
1845 // Save ourselves the trouble, we're done.
1846 if (utf16Size == 0u) {
1847 str->clear();
1848 return NO_ERROR;
1849 }
1850
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001851 // Allow for closing '\0'
1852 ssize_t utf8Size = utf16_to_utf8_length(src, utf16Size) + 1;
1853 if (utf8Size < 1) {
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001854 return BAD_VALUE;
1855 }
1856 // Note that while it is probably safe to assume string::resize keeps a
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001857 // spare byte around for the trailing null, we still pass the size including the trailing null
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001858 str->resize(utf8Size);
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001859 utf16_to_utf8(src, utf16Size, &((*str)[0]), utf8Size);
1860 str->resize(utf8Size - 1);
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001861 return NO_ERROR;
1862}
1863
1864status_t Parcel::readUtf8FromUtf16(std::unique_ptr<std::string>* str) const {
1865 const int32_t start = dataPosition();
1866 int32_t size;
1867 status_t status = readInt32(&size);
1868 str->reset();
1869
1870 if (status != OK || size < 0) {
1871 return status;
1872 }
1873
1874 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001875 str->reset(new (std::nothrow) std::string());
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001876 return readUtf8FromUtf16(str->get());
1877}
1878
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001879const char* Parcel::readCString() const
1880{
Steven Morelandd0d4b582019-05-17 13:14:06 -07001881 if (mDataPos < mDataSize) {
1882 const size_t avail = mDataSize-mDataPos;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001883 const char* str = reinterpret_cast<const char*>(mData+mDataPos);
1884 // is the string's trailing NUL within the parcel's valid bounds?
1885 const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
1886 if (eos) {
1887 const size_t len = eos - str;
Nick Kralevichb6b14232015-04-02 09:36:02 -07001888 mDataPos += pad_size(len+1);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001889 ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001890 return str;
1891 }
1892 }
Yi Kong91635562018-06-07 14:38:36 -07001893 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001894}
1895
1896String8 Parcel::readString8() const
1897{
Roshan Pius87b64d22016-07-18 12:51:02 -07001898 String8 retString;
1899 status_t status = readString8(&retString);
1900 if (status != OK) {
1901 // We don't care about errors here, so just return an empty string.
1902 return String8();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001903 }
Roshan Pius87b64d22016-07-18 12:51:02 -07001904 return retString;
1905}
1906
1907status_t Parcel::readString8(String8* pArg) const
1908{
1909 int32_t size;
1910 status_t status = readInt32(&size);
1911 if (status != OK) {
1912 return status;
1913 }
1914 // watch for potential int overflow from size+1
1915 if (size < 0 || size >= INT32_MAX) {
1916 return BAD_VALUE;
1917 }
1918 // |writeString8| writes nothing for empty string.
1919 if (size == 0) {
1920 *pArg = String8();
1921 return OK;
1922 }
1923 const char* str = (const char*)readInplace(size + 1);
Yi Kong91635562018-06-07 14:38:36 -07001924 if (str == nullptr) {
Roshan Pius87b64d22016-07-18 12:51:02 -07001925 return BAD_VALUE;
1926 }
1927 pArg->setTo(str, size);
1928 return OK;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001929}
1930
1931String16 Parcel::readString16() const
1932{
1933 size_t len;
1934 const char16_t* str = readString16Inplace(&len);
1935 if (str) return String16(str, len);
Steve Blocke6f43dd2012-01-06 19:20:56 +00001936 ALOGE("Reading a NULL string not supported here.");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001937 return String16();
1938}
1939
Casey Dahlinb9872622015-11-25 15:09:45 -08001940status_t Parcel::readString16(std::unique_ptr<String16>* pArg) const
1941{
1942 const int32_t start = dataPosition();
1943 int32_t size;
1944 status_t status = readInt32(&size);
1945 pArg->reset();
1946
1947 if (status != OK || size < 0) {
1948 return status;
1949 }
1950
1951 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001952 pArg->reset(new (std::nothrow) String16());
Casey Dahlinb9872622015-11-25 15:09:45 -08001953
1954 status = readString16(pArg->get());
1955
1956 if (status != OK) {
1957 pArg->reset();
1958 }
1959
1960 return status;
1961}
1962
Casey Dahlin451ff582015-10-19 18:12:18 -07001963status_t Parcel::readString16(String16* pArg) const
1964{
1965 size_t len;
1966 const char16_t* str = readString16Inplace(&len);
1967 if (str) {
Casey Dahlin1515ea12015-10-20 16:26:23 -07001968 pArg->setTo(str, len);
Casey Dahlin451ff582015-10-19 18:12:18 -07001969 return 0;
1970 } else {
1971 *pArg = String16();
Christopher Wiley4db672d2015-11-10 09:44:30 -08001972 return UNEXPECTED_NULL;
Casey Dahlin451ff582015-10-19 18:12:18 -07001973 }
1974}
1975
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001976const char16_t* Parcel::readString16Inplace(size_t* outLen) const
1977{
1978 int32_t size = readInt32();
1979 // watch for potential int overflow from size+1
1980 if (size >= 0 && size < INT32_MAX) {
1981 *outLen = size;
1982 const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
Yi Kong91635562018-06-07 14:38:36 -07001983 if (str != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001984 return str;
1985 }
1986 }
1987 *outLen = 0;
Yi Kong91635562018-06-07 14:38:36 -07001988 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001989}
1990
Casey Dahlinf0c13772015-10-27 18:33:56 -07001991status_t Parcel::readStrongBinder(sp<IBinder>* val) const
1992{
Christopher Wiley35d77ca2016-03-08 10:49:51 -08001993 status_t status = readNullableStrongBinder(val);
1994 if (status == OK && !val->get()) {
1995 status = UNEXPECTED_NULL;
1996 }
1997 return status;
1998}
1999
2000status_t Parcel::readNullableStrongBinder(sp<IBinder>* val) const
2001{
Steven Morelanda86a3562019-08-01 23:28:34 +00002002 return unflattenBinder(val);
Casey Dahlinf0c13772015-10-27 18:33:56 -07002003}
2004
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002005sp<IBinder> Parcel::readStrongBinder() const
2006{
2007 sp<IBinder> val;
Christopher Wiley35d77ca2016-03-08 10:49:51 -08002008 // Note that a lot of code in Android reads binders by hand with this
2009 // method, and that code has historically been ok with getting nullptr
2010 // back (while ignoring error codes).
2011 readNullableStrongBinder(&val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002012 return val;
2013}
2014
Christopher Wiley97f048d2015-11-19 06:49:05 -08002015status_t Parcel::readParcelable(Parcelable* parcelable) const {
2016 int32_t have_parcelable = 0;
2017 status_t status = readInt32(&have_parcelable);
2018 if (status != OK) {
2019 return status;
2020 }
2021 if (!have_parcelable) {
2022 return UNEXPECTED_NULL;
2023 }
2024 return parcelable->readFromParcel(this);
2025}
2026
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07002027int32_t Parcel::readExceptionCode() const
2028{
Christopher Wiley09eb7492015-11-09 15:06:15 -08002029 binder::Status status;
2030 status.readFromParcel(*this);
2031 return status.exceptionCode();
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07002032}
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002033
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002034native_handle* Parcel::readNativeHandle() const
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002035{
2036 int numFds, numInts;
2037 status_t err;
2038 err = readInt32(&numFds);
Yi Kong91635562018-06-07 14:38:36 -07002039 if (err != NO_ERROR) return nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002040 err = readInt32(&numInts);
Yi Kong91635562018-06-07 14:38:36 -07002041 if (err != NO_ERROR) return nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002042
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002043 native_handle* h = native_handle_create(numFds, numInts);
Adam Lesinskieaac99a2015-05-12 17:35:48 -07002044 if (!h) {
Yi Kong91635562018-06-07 14:38:36 -07002045 return nullptr;
Adam Lesinskieaac99a2015-05-12 17:35:48 -07002046 }
2047
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002048 for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002049 h->data[i] = fcntl(readFileDescriptor(), F_DUPFD_CLOEXEC, 0);
Marco Nelissen1de79662016-04-26 08:44:09 -07002050 if (h->data[i] < 0) {
2051 for (int j = 0; j < i; j++) {
2052 close(h->data[j]);
2053 }
2054 native_handle_delete(h);
Yi Kong91635562018-06-07 14:38:36 -07002055 return nullptr;
Marco Nelissen1de79662016-04-26 08:44:09 -07002056 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002057 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002058 err = read(h->data + numFds, sizeof(int)*numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002059 if (err != NO_ERROR) {
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002060 native_handle_close(h);
2061 native_handle_delete(h);
Yi Kong91635562018-06-07 14:38:36 -07002062 h = nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002063 }
2064 return h;
2065}
2066
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002067int Parcel::readFileDescriptor() const
2068{
2069 const flat_binder_object* flat = readObject(true);
Casey Dahlin06673e32015-11-23 13:24:23 -08002070
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002071 if (flat && flat->hdr.type == BINDER_TYPE_FD) {
Casey Dahlin06673e32015-11-23 13:24:23 -08002072 return flat->handle;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002073 }
Casey Dahlin06673e32015-11-23 13:24:23 -08002074
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002075 return BAD_TYPE;
2076}
2077
Dianne Hackborn1941a402016-08-29 12:30:43 -07002078int Parcel::readParcelFileDescriptor() const
2079{
2080 int32_t hasComm = readInt32();
2081 int fd = readFileDescriptor();
2082 if (hasComm != 0) {
Steven Morelandb73806a2018-11-12 19:35:47 -08002083 // detach (owned by the binder driver)
2084 int comm = readFileDescriptor();
2085
2086 // warning: this must be kept in sync with:
2087 // frameworks/base/core/java/android/os/ParcelFileDescriptor.java
2088 enum ParcelFileDescriptorStatus {
2089 DETACHED = 2,
2090 };
2091
2092#if BYTE_ORDER == BIG_ENDIAN
2093 const int32_t message = ParcelFileDescriptorStatus::DETACHED;
2094#endif
2095#if BYTE_ORDER == LITTLE_ENDIAN
2096 const int32_t message = __builtin_bswap32(ParcelFileDescriptorStatus::DETACHED);
2097#endif
2098
2099 ssize_t written = TEMP_FAILURE_RETRY(
2100 ::write(comm, &message, sizeof(message)));
2101
2102 if (written == -1 || written != sizeof(message)) {
2103 ALOGW("Failed to detach ParcelFileDescriptor written: %zd err: %s",
2104 written, strerror(errno));
2105 return BAD_TYPE;
2106 }
Dianne Hackborn1941a402016-08-29 12:30:43 -07002107 }
2108 return fd;
2109}
2110
Christopher Wiley2cf19952016-04-11 11:09:37 -07002111status_t Parcel::readUniqueFileDescriptor(base::unique_fd* val) const
Casey Dahlin06673e32015-11-23 13:24:23 -08002112{
2113 int got = readFileDescriptor();
2114
2115 if (got == BAD_TYPE) {
2116 return BAD_TYPE;
2117 }
2118
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002119 val->reset(fcntl(got, F_DUPFD_CLOEXEC, 0));
Casey Dahlin06673e32015-11-23 13:24:23 -08002120
2121 if (val->get() < 0) {
2122 return BAD_VALUE;
2123 }
2124
2125 return OK;
2126}
2127
Ryo Hashimotobf551892018-05-31 16:58:35 +09002128status_t Parcel::readUniqueParcelFileDescriptor(base::unique_fd* val) const
2129{
2130 int got = readParcelFileDescriptor();
2131
2132 if (got == BAD_TYPE) {
2133 return BAD_TYPE;
2134 }
2135
2136 val->reset(fcntl(got, F_DUPFD_CLOEXEC, 0));
2137
2138 if (val->get() < 0) {
2139 return BAD_VALUE;
2140 }
2141
2142 return OK;
2143}
Casey Dahlin06673e32015-11-23 13:24:23 -08002144
Christopher Wiley2cf19952016-04-11 11:09:37 -07002145status_t Parcel::readUniqueFileDescriptorVector(std::unique_ptr<std::vector<base::unique_fd>>* val) const {
Casey Dahlinb9872622015-11-25 15:09:45 -08002146 return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
2147}
2148
Christopher Wiley2cf19952016-04-11 11:09:37 -07002149status_t Parcel::readUniqueFileDescriptorVector(std::vector<base::unique_fd>* val) const {
Casey Dahlin06673e32015-11-23 13:24:23 -08002150 return readTypedVector(val, &Parcel::readUniqueFileDescriptor);
2151}
2152
Jeff Brown5707dbf2011-09-23 21:17:56 -07002153status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
2154{
Jeff Brown13b16042014-11-11 16:44:25 -08002155 int32_t blobType;
2156 status_t status = readInt32(&blobType);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002157 if (status) return status;
2158
Jeff Brown13b16042014-11-11 16:44:25 -08002159 if (blobType == BLOB_INPLACE) {
Steve Block6807e592011-10-20 11:56:00 +01002160 ALOGV("readBlob: read in place");
Jeff Brown5707dbf2011-09-23 21:17:56 -07002161 const void* ptr = readInplace(len);
2162 if (!ptr) return BAD_VALUE;
2163
Jeff Brown13b16042014-11-11 16:44:25 -08002164 outBlob->init(-1, const_cast<void*>(ptr), len, false);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002165 return NO_ERROR;
2166 }
2167
Steve Block6807e592011-10-20 11:56:00 +01002168 ALOGV("readBlob: read from ashmem");
Jeff Brown13b16042014-11-11 16:44:25 -08002169 bool isMutable = (blobType == BLOB_ASHMEM_MUTABLE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002170 int fd = readFileDescriptor();
2171 if (fd == int(BAD_TYPE)) return BAD_VALUE;
2172
Jorim Jaggi150b4ef2018-07-13 11:18:30 +00002173 if (!ashmem_valid(fd)) {
2174 ALOGE("invalid fd");
2175 return BAD_VALUE;
2176 }
Marco Nelissen7a96ec42018-06-06 07:37:46 -07002177 int size = ashmem_get_size_region(fd);
2178 if (size < 0 || size_t(size) < len) {
Jorim Jaggi150b4ef2018-07-13 11:18:30 +00002179 ALOGE("request size %zu does not match fd size %d", len, size);
Marco Nelissen7a96ec42018-06-06 07:37:46 -07002180 return BAD_VALUE;
2181 }
Yi Kong91635562018-06-07 14:38:36 -07002182 void* ptr = ::mmap(nullptr, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ,
Jeff Brown13b16042014-11-11 16:44:25 -08002183 MAP_SHARED, fd, 0);
Narayan Kamath9ea09752014-10-08 17:35:45 +01002184 if (ptr == MAP_FAILED) return NO_MEMORY;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002185
Jeff Brown13b16042014-11-11 16:44:25 -08002186 outBlob->init(fd, ptr, len, isMutable);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002187 return NO_ERROR;
2188}
2189
Mathias Agopiane1424282013-07-29 21:24:40 -07002190status_t Parcel::read(FlattenableHelperInterface& val) const
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002191{
2192 // size
2193 const size_t len = this->readInt32();
2194 const size_t fd_count = this->readInt32();
2195
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002196 if ((len > INT32_MAX) || (fd_count >= gMaxFds)) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07002197 // don't accept size_t values which may have come from an
2198 // inadvertent conversion from a negative int.
2199 return BAD_VALUE;
2200 }
2201
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002202 // payload
Nick Kralevichb6b14232015-04-02 09:36:02 -07002203 void const* const buf = this->readInplace(pad_size(len));
Yi Kong91635562018-06-07 14:38:36 -07002204 if (buf == nullptr)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002205 return BAD_VALUE;
2206
Yi Kong91635562018-06-07 14:38:36 -07002207 int* fds = nullptr;
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002208 if (fd_count) {
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002209 fds = new (std::nothrow) int[fd_count];
2210 if (fds == nullptr) {
2211 ALOGE("read: failed to allocate requested %zu fds", fd_count);
2212 return BAD_VALUE;
2213 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002214 }
2215
2216 status_t err = NO_ERROR;
2217 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
Fabien Sanglardd84ff312016-10-21 10:58:26 -07002218 int fd = this->readFileDescriptor();
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002219 if (fd < 0 || ((fds[i] = fcntl(fd, F_DUPFD_CLOEXEC, 0)) < 0)) {
Jun Jiangabf8a2c2014-04-29 14:22:10 +08002220 err = BAD_VALUE;
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002221 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 -07002222 i, fds[i], fd_count, strerror(fd < 0 ? -fd : errno));
2223 // Close all the file descriptors that were dup-ed.
2224 for (size_t j=0; j<i ;j++) {
2225 close(fds[j]);
2226 }
Jun Jiangabf8a2c2014-04-29 14:22:10 +08002227 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002228 }
2229
2230 if (err == NO_ERROR) {
2231 err = val.unflatten(buf, len, fds, fd_count);
2232 }
2233
2234 if (fd_count) {
2235 delete [] fds;
2236 }
2237
2238 return err;
2239}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002240const flat_binder_object* Parcel::readObject(bool nullMetaData) const
2241{
2242 const size_t DPOS = mDataPos;
2243 if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
2244 const flat_binder_object* obj
2245 = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
2246 mDataPos = DPOS + sizeof(flat_binder_object);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002247 if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) {
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002248 // When transferring a NULL object, we don't write it into
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002249 // the object list, so we don't want to check for it when
2250 // reading.
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002251 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002252 return obj;
2253 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002254
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002255 // Ensure that this object is valid...
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002256 binder_size_t* const OBJS = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002257 const size_t N = mObjectsSize;
2258 size_t opos = mNextObjectHint;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002259
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002260 if (N > 0) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002261 ALOGV("Parcel %p looking for obj at %zu, hint=%zu",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002262 this, DPOS, opos);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002263
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002264 // Start at the current hint position, looking for an object at
2265 // the current data position.
2266 if (opos < N) {
2267 while (opos < (N-1) && OBJS[opos] < DPOS) {
2268 opos++;
2269 }
2270 } else {
2271 opos = N-1;
2272 }
2273 if (OBJS[opos] == DPOS) {
2274 // Found it!
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002275 ALOGV("Parcel %p found obj %zu at index %zu with forward search",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002276 this, DPOS, opos);
2277 mNextObjectHint = opos+1;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002278 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002279 return obj;
2280 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002281
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002282 // Look backwards for it...
2283 while (opos > 0 && OBJS[opos] > DPOS) {
2284 opos--;
2285 }
2286 if (OBJS[opos] == DPOS) {
2287 // Found it!
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002288 ALOGV("Parcel %p found obj %zu at index %zu with backward search",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002289 this, DPOS, opos);
2290 mNextObjectHint = opos+1;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002291 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002292 return obj;
2293 }
2294 }
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002295 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 -07002296 this, DPOS);
2297 }
Yi Kong91635562018-06-07 14:38:36 -07002298 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002299}
2300
2301void Parcel::closeFileDescriptors()
2302{
2303 size_t i = mObjectsSize;
2304 if (i > 0) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002305 //ALOGI("Closing file descriptors for %zu objects...", i);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002306 }
2307 while (i > 0) {
2308 i--;
2309 const flat_binder_object* flat
2310 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002311 if (flat->hdr.type == BINDER_TYPE_FD) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002312 //ALOGI("Closing fd: %ld", flat->handle);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002313 close(flat->handle);
2314 }
2315 }
2316}
2317
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002318uintptr_t Parcel::ipcData() const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002319{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002320 return reinterpret_cast<uintptr_t>(mData);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002321}
2322
2323size_t Parcel::ipcDataSize() const
2324{
2325 return (mDataSize > mDataPos ? mDataSize : mDataPos);
2326}
2327
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002328uintptr_t Parcel::ipcObjects() const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002329{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002330 return reinterpret_cast<uintptr_t>(mObjects);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002331}
2332
2333size_t Parcel::ipcObjectsCount() const
2334{
2335 return mObjectsSize;
2336}
2337
2338void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002339 const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002340{
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002341 binder_size_t minOffset = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002342 freeDataNoInit();
2343 mError = NO_ERROR;
2344 mData = const_cast<uint8_t*>(data);
2345 mDataSize = mDataCapacity = dataSize;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002346 //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)", this, mDataSize, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002347 mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002348 ALOGV("setDataReference Setting data pos of %p to %zu", this, mDataPos);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002349 mObjects = const_cast<binder_size_t*>(objects);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002350 mObjectsSize = mObjectsCapacity = objectsCount;
2351 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002352 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002353 mOwner = relFunc;
2354 mOwnerCookie = relCookie;
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002355 for (size_t i = 0; i < mObjectsSize; i++) {
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002356 binder_size_t offset = mObjects[i];
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002357 if (offset < minOffset) {
Dan Albert3bdc5b82014-11-20 11:50:23 -08002358 ALOGE("%s: bad object offset %" PRIu64 " < %" PRIu64 "\n",
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002359 __func__, (uint64_t)offset, (uint64_t)minOffset);
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002360 mObjectsSize = 0;
2361 break;
2362 }
2363 minOffset = offset + sizeof(flat_binder_object);
2364 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002365 scanForFds();
2366}
2367
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002368void Parcel::print(TextOutput& to, uint32_t /*flags*/) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002369{
2370 to << "Parcel(";
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002371
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002372 if (errorCheck() != NO_ERROR) {
2373 const status_t err = errorCheck();
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002374 to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\"";
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002375 } else if (dataSize() > 0) {
2376 const uint8_t* DATA = data();
2377 to << indent << HexDump(DATA, dataSize()) << dedent;
Steven Moreland8bd01352019-07-15 16:36:14 -07002378 const binder_size_t* OBJS = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002379 const size_t N = objectsCount();
2380 for (size_t i=0; i<N; i++) {
2381 const flat_binder_object* flat
2382 = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
2383 to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002384 << TypeCode(flat->hdr.type & 0x7f7f7f00)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002385 << " = " << flat->binder;
2386 }
2387 } else {
2388 to << "NULL";
2389 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002390
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002391 to << ")";
2392}
2393
2394void Parcel::releaseObjects()
2395{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002396 size_t i = mObjectsSize;
Martijn Coenen69390d42018-10-22 15:18:10 +02002397 if (i == 0) {
2398 return;
2399 }
2400 sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002401 uint8_t* const data = mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002402 binder_size_t* const objects = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002403 while (i > 0) {
2404 i--;
2405 const flat_binder_object* flat
2406 = reinterpret_cast<flat_binder_object*>(data+objects[i]);
Adrian Rooscbf37262015-10-22 16:12:53 -07002407 release_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002408 }
2409}
2410
2411void Parcel::acquireObjects()
2412{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002413 size_t i = mObjectsSize;
Martijn Coenen69390d42018-10-22 15:18:10 +02002414 if (i == 0) {
2415 return;
2416 }
2417 const sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002418 uint8_t* const data = mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002419 binder_size_t* const objects = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002420 while (i > 0) {
2421 i--;
2422 const flat_binder_object* flat
2423 = reinterpret_cast<flat_binder_object*>(data+objects[i]);
Adrian Rooscbf37262015-10-22 16:12:53 -07002424 acquire_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002425 }
2426}
2427
2428void Parcel::freeData()
2429{
2430 freeDataNoInit();
2431 initState();
2432}
2433
2434void Parcel::freeDataNoInit()
2435{
2436 if (mOwner) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002437 LOG_ALLOC("Parcel %p: freeing other owner data", this);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002438 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002439 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
2440 } else {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002441 LOG_ALLOC("Parcel %p: freeing allocated data", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002442 releaseObjects();
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002443 if (mData) {
2444 LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002445 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dan Austin48fd7b42015-09-10 13:46:02 -07002446 if (mDataCapacity <= gParcelGlobalAllocSize) {
2447 gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity;
2448 } else {
2449 gParcelGlobalAllocSize = 0;
2450 }
2451 if (gParcelGlobalAllocCount > 0) {
2452 gParcelGlobalAllocCount--;
2453 }
Dianne Hackborna4cff882014-11-13 17:07:40 -08002454 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002455 free(mData);
2456 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002457 if (mObjects) free(mObjects);
2458 }
2459}
2460
2461status_t Parcel::growData(size_t len)
2462{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002463 if (len > INT32_MAX) {
2464 // don't accept size_t values which may have come from an
2465 // inadvertent conversion from a negative int.
2466 return BAD_VALUE;
2467 }
2468
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002469 size_t newSize = ((mDataSize+len)*3)/2;
2470 return (newSize <= mDataSize)
2471 ? (status_t) NO_MEMORY
2472 : continueWrite(newSize);
2473}
2474
2475status_t Parcel::restartWrite(size_t desired)
2476{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002477 if (desired > INT32_MAX) {
2478 // don't accept size_t values which may have come from an
2479 // inadvertent conversion from a negative int.
2480 return BAD_VALUE;
2481 }
2482
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002483 if (mOwner) {
2484 freeData();
2485 return continueWrite(desired);
2486 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002487
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002488 uint8_t* data = (uint8_t*)realloc(mData, desired);
2489 if (!data && desired > mDataCapacity) {
2490 mError = NO_MEMORY;
2491 return NO_MEMORY;
2492 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002493
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002494 releaseObjects();
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002495
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002496 if (data) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002497 LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002498 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002499 gParcelGlobalAllocSize += desired;
2500 gParcelGlobalAllocSize -= mDataCapacity;
Colin Cross83ec65e2015-12-08 17:15:50 -08002501 if (!mData) {
2502 gParcelGlobalAllocCount++;
2503 }
Dianne Hackborna4cff882014-11-13 17:07:40 -08002504 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002505 mData = data;
2506 mDataCapacity = desired;
2507 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002508
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002509 mDataSize = mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002510 ALOGV("restartWrite Setting data size of %p to %zu", this, mDataSize);
2511 ALOGV("restartWrite Setting data pos of %p to %zu", this, mDataPos);
2512
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002513 free(mObjects);
Yi Kong91635562018-06-07 14:38:36 -07002514 mObjects = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002515 mObjectsSize = mObjectsCapacity = 0;
2516 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002517 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002518 mHasFds = false;
2519 mFdsKnown = true;
Dianne Hackborn8938ed22011-09-28 23:19:47 -04002520 mAllowFds = true;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002521
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002522 return NO_ERROR;
2523}
2524
2525status_t Parcel::continueWrite(size_t desired)
2526{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002527 if (desired > INT32_MAX) {
2528 // don't accept size_t values which may have come from an
2529 // inadvertent conversion from a negative int.
2530 return BAD_VALUE;
2531 }
2532
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002533 // If shrinking, first adjust for any objects that appear
2534 // after the new data size.
2535 size_t objectsSize = mObjectsSize;
2536 if (desired < mDataSize) {
2537 if (desired == 0) {
2538 objectsSize = 0;
2539 } else {
2540 while (objectsSize > 0) {
Michael Wachenschwanza6541632017-05-18 22:08:32 +00002541 if (mObjects[objectsSize-1] < desired)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002542 break;
2543 objectsSize--;
2544 }
2545 }
2546 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002547
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002548 if (mOwner) {
2549 // If the size is going to zero, just release the owner's data.
2550 if (desired == 0) {
2551 freeData();
2552 return NO_ERROR;
2553 }
2554
2555 // If there is a different owner, we need to take
2556 // posession.
2557 uint8_t* data = (uint8_t*)malloc(desired);
2558 if (!data) {
2559 mError = NO_MEMORY;
2560 return NO_MEMORY;
2561 }
Yi Kong91635562018-06-07 14:38:36 -07002562 binder_size_t* objects = nullptr;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002563
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002564 if (objectsSize) {
Nick Kraleviche9881a32015-04-28 16:21:30 -07002565 objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002566 if (!objects) {
Hyejin Kim3f727c02013-03-09 11:28:54 +09002567 free(data);
2568
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002569 mError = NO_MEMORY;
2570 return NO_MEMORY;
2571 }
2572
2573 // Little hack to only acquire references on objects
2574 // we will be keeping.
2575 size_t oldObjectsSize = mObjectsSize;
2576 mObjectsSize = objectsSize;
2577 acquireObjects();
2578 mObjectsSize = oldObjectsSize;
2579 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002580
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002581 if (mData) {
2582 memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
2583 }
2584 if (objects && mObjects) {
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002585 memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002586 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002587 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002588 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
Yi Kong91635562018-06-07 14:38:36 -07002589 mOwner = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002590
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002591 LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002592 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002593 gParcelGlobalAllocSize += desired;
2594 gParcelGlobalAllocCount++;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002595 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002596
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002597 mData = data;
2598 mObjects = objects;
2599 mDataSize = (mDataSize < desired) ? mDataSize : desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002600 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002601 mDataCapacity = desired;
2602 mObjectsSize = mObjectsCapacity = objectsSize;
2603 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002604 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002605
2606 } else if (mData) {
2607 if (objectsSize < mObjectsSize) {
2608 // Need to release refs on any objects we are dropping.
2609 const sp<ProcessState> proc(ProcessState::self());
2610 for (size_t i=objectsSize; i<mObjectsSize; i++) {
2611 const flat_binder_object* flat
2612 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002613 if (flat->hdr.type == BINDER_TYPE_FD) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002614 // will need to rescan because we may have lopped off the only FDs
2615 mFdsKnown = false;
2616 }
Adrian Rooscbf37262015-10-22 16:12:53 -07002617 release_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002618 }
Michael Wachenschwanz6af27a82019-06-03 17:24:51 -07002619
2620 if (objectsSize == 0) {
2621 free(mObjects);
2622 mObjects = nullptr;
2623 } else {
2624 binder_size_t* objects =
2625 (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
2626 if (objects) {
2627 mObjects = objects;
2628 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002629 }
2630 mObjectsSize = objectsSize;
2631 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002632 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002633 }
2634
2635 // We own the data, so we can just do a realloc().
2636 if (desired > mDataCapacity) {
2637 uint8_t* data = (uint8_t*)realloc(mData, desired);
2638 if (data) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002639 LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity,
2640 desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002641 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002642 gParcelGlobalAllocSize += desired;
2643 gParcelGlobalAllocSize -= mDataCapacity;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002644 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002645 mData = data;
2646 mDataCapacity = desired;
Ganesh Mahendranade89892017-09-28 16:56:03 +08002647 } else {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002648 mError = NO_MEMORY;
2649 return NO_MEMORY;
2650 }
2651 } else {
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -07002652 if (mDataSize > desired) {
2653 mDataSize = desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002654 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -07002655 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002656 if (mDataPos > desired) {
2657 mDataPos = desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002658 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002659 }
2660 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002661
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002662 } else {
2663 // This is the first data. Easy!
2664 uint8_t* data = (uint8_t*)malloc(desired);
2665 if (!data) {
2666 mError = NO_MEMORY;
2667 return NO_MEMORY;
2668 }
Hyejin Kim3f727c02013-03-09 11:28:54 +09002669
Yi Kong91635562018-06-07 14:38:36 -07002670 if(!(mDataCapacity == 0 && mObjects == nullptr
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002671 && mObjectsCapacity == 0)) {
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002672 ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002673 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002674
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002675 LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002676 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002677 gParcelGlobalAllocSize += desired;
2678 gParcelGlobalAllocCount++;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002679 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002680
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002681 mData = data;
2682 mDataSize = mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002683 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
2684 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002685 mDataCapacity = desired;
2686 }
2687
2688 return NO_ERROR;
2689}
2690
2691void Parcel::initState()
2692{
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002693 LOG_ALLOC("Parcel %p: initState", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002694 mError = NO_ERROR;
Yi Kong91635562018-06-07 14:38:36 -07002695 mData = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002696 mDataSize = 0;
2697 mDataCapacity = 0;
2698 mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002699 ALOGV("initState Setting data size of %p to %zu", this, mDataSize);
2700 ALOGV("initState Setting data pos of %p to %zu", this, mDataPos);
Yi Kong91635562018-06-07 14:38:36 -07002701 mObjects = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002702 mObjectsSize = 0;
2703 mObjectsCapacity = 0;
2704 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002705 mObjectsSorted = false;
Steven Morelanda86a3562019-08-01 23:28:34 +00002706 mAllowFds = true;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002707 mHasFds = false;
2708 mFdsKnown = true;
Steven Morelanda86a3562019-08-01 23:28:34 +00002709 mRequiredStability = internal::Stability::UNDECLARED;
Yi Kong91635562018-06-07 14:38:36 -07002710 mOwner = nullptr;
Adrian Rooscbf37262015-10-22 16:12:53 -07002711 mOpenAshmemSize = 0;
Olivier Gaillarddc848a02019-01-30 17:10:44 +00002712 mWorkSourceRequestHeaderPosition = 0;
2713 mRequestHeaderPresent = false;
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002714
2715 // racing multiple init leads only to multiple identical write
2716 if (gMaxFds == 0) {
2717 struct rlimit result;
2718 if (!getrlimit(RLIMIT_NOFILE, &result)) {
2719 gMaxFds = (size_t)result.rlim_cur;
Christopher Tatebf14e942016-03-25 14:16:24 -07002720 //ALOGI("parcel fd limit set to %zu", gMaxFds);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002721 } else {
2722 ALOGW("Unable to getrlimit: %s", strerror(errno));
2723 gMaxFds = 1024;
2724 }
2725 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002726}
2727
2728void Parcel::scanForFds() const
2729{
2730 bool hasFds = false;
2731 for (size_t i=0; i<mObjectsSize; i++) {
2732 const flat_binder_object* flat
2733 = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002734 if (flat->hdr.type == BINDER_TYPE_FD) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002735 hasFds = true;
2736 break;
2737 }
2738 }
2739 mHasFds = hasFds;
2740 mFdsKnown = true;
2741}
2742
Dan Sandleraa5c2342015-04-10 10:08:45 -04002743size_t Parcel::getBlobAshmemSize() const
2744{
Adrian Roos6bb31142015-10-22 16:46:12 -07002745 // This used to return the size of all blobs that were written to ashmem, now we're returning
2746 // the ashmem currently referenced by this Parcel, which should be equivalent.
2747 // TODO: Remove method once ABI can be changed.
2748 return mOpenAshmemSize;
Dan Sandleraa5c2342015-04-10 10:08:45 -04002749}
2750
Adrian Rooscbf37262015-10-22 16:12:53 -07002751size_t Parcel::getOpenAshmemSize() const
2752{
2753 return mOpenAshmemSize;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002754}
2755
2756// --- Parcel::Blob ---
2757
2758Parcel::Blob::Blob() :
Yi Kong91635562018-06-07 14:38:36 -07002759 mFd(-1), mData(nullptr), mSize(0), mMutable(false) {
Jeff Brown5707dbf2011-09-23 21:17:56 -07002760}
2761
2762Parcel::Blob::~Blob() {
2763 release();
2764}
2765
2766void Parcel::Blob::release() {
Jeff Brown13b16042014-11-11 16:44:25 -08002767 if (mFd != -1 && mData) {
Jeff Brown5707dbf2011-09-23 21:17:56 -07002768 ::munmap(mData, mSize);
2769 }
2770 clear();
2771}
2772
Jeff Brown13b16042014-11-11 16:44:25 -08002773void Parcel::Blob::init(int fd, void* data, size_t size, bool isMutable) {
2774 mFd = fd;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002775 mData = data;
2776 mSize = size;
Jeff Brown13b16042014-11-11 16:44:25 -08002777 mMutable = isMutable;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002778}
2779
2780void Parcel::Blob::clear() {
Jeff Brown13b16042014-11-11 16:44:25 -08002781 mFd = -1;
Yi Kong91635562018-06-07 14:38:36 -07002782 mData = nullptr;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002783 mSize = 0;
Jeff Brown13b16042014-11-11 16:44:25 -08002784 mMutable = false;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002785}
2786
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002787}; // namespace android