blob: 0b9849ab118c82aa6c9b09006b8c44ac5fc45220 [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
Dianne Hackborna4cff882014-11-13 17:07:40 -080080static pthread_mutex_t gParcelGlobalAllocSizeLock = PTHREAD_MUTEX_INITIALIZER;
81static size_t gParcelGlobalAllocSize = 0;
82static size_t gParcelGlobalAllocCount = 0;
83
Christopher Tatee4e0ae82016-03-24 16:03:44 -070084static size_t gMaxFds = 0;
85
Jeff Brown13b16042014-11-11 16:44:25 -080086// Maximum size of a blob to transfer in-place.
87static const size_t BLOB_INPLACE_LIMIT = 16 * 1024;
88
89enum {
90 BLOB_INPLACE = 0,
91 BLOB_ASHMEM_IMMUTABLE = 1,
92 BLOB_ASHMEM_MUTABLE = 2,
93};
94
Steven Morelandb1c81202019-04-05 18:49:55 -070095static void acquire_object(const sp<ProcessState>& proc,
Adrian Rooscbf37262015-10-22 16:12:53 -070096 const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070097{
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -070098 switch (obj.hdr.type) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070099 case BINDER_TYPE_BINDER:
100 if (obj.binder) {
101 LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800102 reinterpret_cast<IBinder*>(obj.cookie)->incStrong(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700103 }
104 return;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700105 case BINDER_TYPE_HANDLE: {
106 const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
Yi Kong91635562018-06-07 14:38:36 -0700107 if (b != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700108 LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
109 b->incStrong(who);
110 }
111 return;
112 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700113 case BINDER_TYPE_FD: {
Jorim Jaggi150b4ef2018-07-13 11:18:30 +0000114 if ((obj.cookie != 0) && (outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
Mark Salyzyn80589362016-08-23 16:15:04 -0700115 // If we own an ashmem fd, keep track of how much memory it refers to.
116 int size = ashmem_get_size_region(obj.handle);
117 if (size > 0) {
118 *outAshmemSize += size;
Adrian Rooscbf37262015-10-22 16:12:53 -0700119 }
120 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700121 return;
122 }
123 }
124
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700125 ALOGD("Invalid object type 0x%08x", obj.hdr.type);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700126}
127
Adrian Roos6bb31142015-10-22 16:46:12 -0700128static void release_object(const sp<ProcessState>& proc,
Adrian Rooscbf37262015-10-22 16:12:53 -0700129 const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700130{
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700131 switch (obj.hdr.type) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700132 case BINDER_TYPE_BINDER:
133 if (obj.binder) {
134 LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800135 reinterpret_cast<IBinder*>(obj.cookie)->decStrong(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700136 }
137 return;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700138 case BINDER_TYPE_HANDLE: {
139 const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
Yi Kong91635562018-06-07 14:38:36 -0700140 if (b != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700141 LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
142 b->decStrong(who);
143 }
144 return;
145 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700146 case BINDER_TYPE_FD: {
Mark Salyzynb454d8f2016-01-27 08:02:48 -0800147 if (obj.cookie != 0) { // owned
Jorim Jaggi150b4ef2018-07-13 11:18:30 +0000148 if ((outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
Mark Salyzyn80589362016-08-23 16:15:04 -0700149 int size = ashmem_get_size_region(obj.handle);
150 if (size > 0) {
Tri Voaa6e1112019-01-29 13:23:46 -0800151 // ashmem size might have changed since last time it was accounted for, e.g.
152 // in acquire_object(). Value of *outAshmemSize is not critical since we are
153 // releasing the object anyway. Check for integer overflow condition.
154 *outAshmemSize -= std::min(*outAshmemSize, static_cast<size_t>(size));
Adrian Roos6bb31142015-10-22 16:46:12 -0700155 }
Adrian Roos6bb31142015-10-22 16:46:12 -0700156 }
Mark Salyzynb454d8f2016-01-27 08:02:48 -0800157
158 close(obj.handle);
Adrian Rooscbf37262015-10-22 16:12:53 -0700159 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700160 return;
161 }
162 }
163
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700164 ALOGE("Invalid object type 0x%08x", obj.hdr.type);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700165}
166
Steven Morelanda86a3562019-08-01 23:28:34 +0000167status_t Parcel::finishFlattenBinder(
168 const sp<IBinder>& binder, const flat_binder_object& flat)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700169{
Steven Morelanda86a3562019-08-01 23:28:34 +0000170 status_t status = writeObject(flat, false);
171 if (status != OK) return status;
172
173 return writeInt32(internal::Stability::get(binder.get()));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700174}
175
Steven Morelanda86a3562019-08-01 23:28:34 +0000176status_t Parcel::finishUnflattenBinder(
177 const sp<IBinder>& binder, sp<IBinder>* out) const
178{
179 int32_t stability;
180 status_t status = readInt32(&stability);
181 if (status != OK) return status;
182
183 if (!internal::Stability::check(stability, mRequiredStability)) {
184 return BAD_TYPE;
185 }
186
187 status = internal::Stability::set(binder.get(), stability);
188 if (status != OK) return status;
189
190 *out = binder;
191 return OK;
192}
193
194status_t Parcel::flattenBinder(const sp<IBinder>& binder)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700195{
196 flat_binder_object obj;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700197
Martijn Coenen2b631742017-05-05 11:16:59 -0700198 if (IPCThreadState::self()->backgroundSchedulingDisabled()) {
199 /* minimum priority for all nodes is nice 0 */
200 obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;
201 } else {
202 /* minimum priority for all nodes is MAX_NICE(19) */
203 obj.flags = 0x13 | FLAT_BINDER_FLAG_ACCEPTS_FDS;
204 }
205
Yi Kong91635562018-06-07 14:38:36 -0700206 if (binder != nullptr) {
Steven Morelandf0212002018-12-26 13:59:23 -0800207 BBinder *local = binder->localBinder();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700208 if (!local) {
209 BpBinder *proxy = binder->remoteBinder();
Yi Kong91635562018-06-07 14:38:36 -0700210 if (proxy == nullptr) {
Steve Blocke6f43dd2012-01-06 19:20:56 +0000211 ALOGE("null proxy");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700212 }
213 const int32_t handle = proxy ? proxy->handle() : 0;
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700214 obj.hdr.type = BINDER_TYPE_HANDLE;
Arve Hjønnevåg07fd0f12014-02-18 21:10:29 -0800215 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700216 obj.handle = handle;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800217 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700218 } else {
Steven Morelandf0212002018-12-26 13:59:23 -0800219 if (local->isRequestingSid()) {
220 obj.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
221 }
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700222 obj.hdr.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800223 obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
224 obj.cookie = reinterpret_cast<uintptr_t>(local);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700225 }
226 } else {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700227 obj.hdr.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800228 obj.binder = 0;
229 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700230 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700231
Steven Morelanda86a3562019-08-01 23:28:34 +0000232 return finishFlattenBinder(binder, obj);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700233}
234
Steven Morelanda86a3562019-08-01 23:28:34 +0000235status_t Parcel::unflattenBinder(sp<IBinder>* out) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700236{
Steven Morelanda86a3562019-08-01 23:28:34 +0000237 const flat_binder_object* flat = readObject(false);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700238
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700239 if (flat) {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700240 switch (flat->hdr.type) {
Steven Morelanda86a3562019-08-01 23:28:34 +0000241 case BINDER_TYPE_BINDER: {
242 sp<IBinder> binder = reinterpret_cast<IBinder*>(flat->cookie);
243 return finishUnflattenBinder(binder, out);
244 }
245 case BINDER_TYPE_HANDLE: {
246 sp<IBinder> binder =
247 ProcessState::self()->getStrongProxyForHandle(flat->handle);
248 return finishUnflattenBinder(binder, out);
249 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700250 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700251 }
252 return BAD_TYPE;
253}
254
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700255// ---------------------------------------------------------------------------
256
257Parcel::Parcel()
258{
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800259 LOG_ALLOC("Parcel %p: constructing", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700260 initState();
261}
262
263Parcel::~Parcel()
264{
265 freeDataNoInit();
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800266 LOG_ALLOC("Parcel %p: destroyed", this);
267}
268
269size_t Parcel::getGlobalAllocSize() {
Dianne Hackborna4cff882014-11-13 17:07:40 -0800270 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
271 size_t size = gParcelGlobalAllocSize;
272 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
273 return size;
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800274}
275
276size_t Parcel::getGlobalAllocCount() {
Dianne Hackborna4cff882014-11-13 17:07:40 -0800277 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
278 size_t count = gParcelGlobalAllocCount;
279 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
280 return count;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700281}
282
283const uint8_t* Parcel::data() const
284{
285 return mData;
286}
287
288size_t Parcel::dataSize() const
289{
290 return (mDataSize > mDataPos ? mDataSize : mDataPos);
291}
292
293size_t Parcel::dataAvail() const
294{
Nick Kralevichcfe27de2015-09-16 09:49:15 -0700295 size_t result = dataSize() - dataPosition();
296 if (result > INT32_MAX) {
297 abort();
298 }
299 return result;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700300}
301
302size_t Parcel::dataPosition() const
303{
304 return mDataPos;
305}
306
307size_t Parcel::dataCapacity() const
308{
309 return mDataCapacity;
310}
311
312status_t Parcel::setDataSize(size_t size)
313{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700314 if (size > INT32_MAX) {
315 // don't accept size_t values which may have come from an
316 // inadvertent conversion from a negative int.
317 return BAD_VALUE;
318 }
319
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700320 status_t err;
321 err = continueWrite(size);
322 if (err == NO_ERROR) {
323 mDataSize = size;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700324 ALOGV("setDataSize Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700325 }
326 return err;
327}
328
329void Parcel::setDataPosition(size_t pos) const
330{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700331 if (pos > INT32_MAX) {
332 // don't accept size_t values which may have come from an
333 // inadvertent conversion from a negative int.
334 abort();
335 }
336
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700337 mDataPos = pos;
338 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -0800339 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700340}
341
342status_t Parcel::setDataCapacity(size_t size)
343{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700344 if (size > INT32_MAX) {
345 // don't accept size_t values which may have come from an
346 // inadvertent conversion from a negative int.
347 return BAD_VALUE;
348 }
349
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -0700350 if (size > mDataCapacity) return continueWrite(size);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700351 return NO_ERROR;
352}
353
Steven Morelanda86a3562019-08-01 23:28:34 +0000354void Parcel::setTransactingBinder(const sp<IBinder>& binder) const {
355 mRequiredStability = internal::Stability::get(binder.get());
356}
357
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700358status_t Parcel::setData(const uint8_t* buffer, size_t len)
359{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700360 if (len > INT32_MAX) {
361 // don't accept size_t values which may have come from an
362 // inadvertent conversion from a negative int.
363 return BAD_VALUE;
364 }
365
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700366 status_t err = restartWrite(len);
367 if (err == NO_ERROR) {
368 memcpy(const_cast<uint8_t*>(data()), buffer, len);
369 mDataSize = len;
370 mFdsKnown = false;
371 }
372 return err;
373}
374
Andreas Huber51faf462011-04-13 10:21:56 -0700375status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700376{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700377 status_t err;
Andreas Huber51faf462011-04-13 10:21:56 -0700378 const uint8_t *data = parcel->mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800379 const binder_size_t *objects = parcel->mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700380 size_t size = parcel->mObjectsSize;
381 int startPos = mDataPos;
382 int firstIndex = -1, lastIndex = -2;
383
384 if (len == 0) {
385 return NO_ERROR;
386 }
387
Nick Kralevichb6b14232015-04-02 09:36:02 -0700388 if (len > INT32_MAX) {
389 // don't accept size_t values which may have come from an
390 // inadvertent conversion from a negative int.
391 return BAD_VALUE;
392 }
393
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700394 // range checks against the source parcel size
395 if ((offset > parcel->mDataSize)
396 || (len > parcel->mDataSize)
397 || (offset + len > parcel->mDataSize)) {
398 return BAD_VALUE;
399 }
400
401 // Count objects in range
402 for (int i = 0; i < (int) size; i++) {
403 size_t off = objects[i];
Christopher Tate27182be2015-05-27 17:53:02 -0700404 if ((off >= offset) && (off + sizeof(flat_binder_object) <= offset + len)) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700405 if (firstIndex == -1) {
406 firstIndex = i;
407 }
408 lastIndex = i;
409 }
410 }
411 int numObjects = lastIndex - firstIndex + 1;
412
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -0700413 if ((mDataSize+len) > mDataCapacity) {
414 // grow data
415 err = growData(len);
416 if (err != NO_ERROR) {
417 return err;
418 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700419 }
420
421 // append data
422 memcpy(mData + mDataPos, data + offset, len);
423 mDataPos += len;
424 mDataSize += len;
425
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400426 err = NO_ERROR;
427
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700428 if (numObjects > 0) {
Martijn Coenen69390d42018-10-22 15:18:10 +0200429 const sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700430 // grow objects
431 if (mObjectsCapacity < mObjectsSize + numObjects) {
Christopher Tateed7a50c2015-06-08 14:45:14 -0700432 size_t newSize = ((mObjectsSize + numObjects)*3)/2;
Christopher Tate44235112016-11-03 13:32:41 -0700433 if (newSize*sizeof(binder_size_t) < mObjectsSize) return NO_MEMORY; // overflow
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800434 binder_size_t *objects =
435 (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
Yi Kong91635562018-06-07 14:38:36 -0700436 if (objects == (binder_size_t*)nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700437 return NO_MEMORY;
438 }
439 mObjects = objects;
440 mObjectsCapacity = newSize;
441 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700442
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700443 // append and acquire objects
444 int idx = mObjectsSize;
445 for (int i = firstIndex; i <= lastIndex; i++) {
446 size_t off = objects[i] - offset + startPos;
447 mObjects[idx++] = off;
448 mObjectsSize++;
449
Dianne Hackborn8af0f822009-05-22 13:20:23 -0700450 flat_binder_object* flat
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700451 = reinterpret_cast<flat_binder_object*>(mData + off);
Adrian Rooscbf37262015-10-22 16:12:53 -0700452 acquire_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700453
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700454 if (flat->hdr.type == BINDER_TYPE_FD) {
Dianne Hackborn8af0f822009-05-22 13:20:23 -0700455 // If this is a file descriptor, we need to dup it so the
456 // new Parcel now owns its own fd, and can declare that we
457 // officially know we have fds.
Nick Kralevichec9ec7d2016-12-17 19:47:27 -0800458 flat->handle = fcntl(flat->handle, F_DUPFD_CLOEXEC, 0);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800459 flat->cookie = 1;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700460 mHasFds = mFdsKnown = true;
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400461 if (!mAllowFds) {
462 err = FDS_NOT_ALLOWED;
463 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700464 }
465 }
466 }
467
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400468 return err;
469}
470
Dianne Hackborn15feb9b2017-04-10 15:34:35 -0700471int Parcel::compareData(const Parcel& other) {
472 size_t size = dataSize();
473 if (size != other.dataSize()) {
474 return size < other.dataSize() ? -1 : 1;
475 }
476 return memcmp(data(), other.data(), size);
477}
478
Jeff Brown13b16042014-11-11 16:44:25 -0800479bool Parcel::allowFds() const
480{
481 return mAllowFds;
482}
483
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700484bool Parcel::pushAllowFds(bool allowFds)
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400485{
486 const bool origValue = mAllowFds;
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700487 if (!allowFds) {
488 mAllowFds = false;
489 }
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400490 return origValue;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700491}
492
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700493void Parcel::restoreAllowFds(bool lastValue)
494{
495 mAllowFds = lastValue;
496}
497
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700498bool Parcel::hasFileDescriptors() const
499{
500 if (!mFdsKnown) {
501 scanForFds();
502 }
503 return mHasFds;
504}
505
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000506void Parcel::updateWorkSourceRequestHeaderPosition() const {
507 // Only update the request headers once. We only want to point
508 // to the first headers read/written.
509 if (!mRequestHeaderPresent) {
510 mWorkSourceRequestHeaderPosition = dataPosition();
511 mRequestHeaderPresent = true;
512 }
513}
514
Steven Morelandd70160f2019-07-23 10:20:38 -0700515#ifdef __ANDROID_VNDK__
516constexpr int32_t kHeader = B_PACK_CHARS('V', 'N', 'D', 'R');
517#else
518constexpr int32_t kHeader = B_PACK_CHARS('S', 'Y', 'S', 'T');
519#endif
520
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700521// Write RPC headers. (previously just the interface token)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700522status_t Parcel::writeInterfaceToken(const String16& interface)
523{
Olivier Gaillard91a04802018-11-14 17:32:41 +0000524 const IPCThreadState* threadState = IPCThreadState::self();
525 writeInt32(threadState->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER);
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000526 updateWorkSourceRequestHeaderPosition();
Olivier Gaillard91a04802018-11-14 17:32:41 +0000527 writeInt32(threadState->shouldPropagateWorkSource() ?
528 threadState->getCallingWorkSourceUid() : IPCThreadState::kUnsetWorkSource);
Steven Morelandd70160f2019-07-23 10:20:38 -0700529 writeInt32(kHeader);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700530 // currently the interface identification token is just its name as a string
531 return writeString16(interface);
532}
533
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000534bool Parcel::replaceCallingWorkSourceUid(uid_t uid)
535{
536 if (!mRequestHeaderPresent) {
537 return false;
538 }
539
540 const size_t initialPosition = dataPosition();
541 setDataPosition(mWorkSourceRequestHeaderPosition);
542 status_t err = writeInt32(uid);
543 setDataPosition(initialPosition);
544 return err == NO_ERROR;
545}
546
547uid_t Parcel::readCallingWorkSourceUid()
548{
549 if (!mRequestHeaderPresent) {
550 return IPCThreadState::kUnsetWorkSource;
551 }
552
553 const size_t initialPosition = dataPosition();
554 setDataPosition(mWorkSourceRequestHeaderPosition);
555 uid_t uid = readInt32();
556 setDataPosition(initialPosition);
557 return uid;
558}
559
Mathias Agopian83c04462009-05-22 19:00:22 -0700560bool Parcel::checkInterface(IBinder* binder) const
561{
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700562 return enforceInterface(binder->getInterfaceDescriptor());
Mathias Agopian83c04462009-05-22 19:00:22 -0700563}
564
Brad Fitzpatricka877cd82010-07-07 16:06:39 -0700565bool Parcel::enforceInterface(const String16& interface,
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700566 IPCThreadState* threadState) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700567{
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100568 // StrictModePolicy.
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700569 int32_t strictPolicy = readInt32();
Yi Kong91635562018-06-07 14:38:36 -0700570 if (threadState == nullptr) {
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700571 threadState = IPCThreadState::self();
Brad Fitzpatricka877cd82010-07-07 16:06:39 -0700572 }
Brad Fitzpatrick52736032010-08-30 16:01:16 -0700573 if ((threadState->getLastTransactionBinderFlags() &
574 IBinder::FLAG_ONEWAY) != 0) {
575 // For one-way calls, the callee is running entirely
576 // disconnected from the caller, so disable StrictMode entirely.
577 // Not only does disk/network usage not impact the caller, but
578 // there's no way to commuicate back any violations anyway.
579 threadState->setStrictModePolicy(0);
580 } else {
581 threadState->setStrictModePolicy(strictPolicy);
582 }
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100583 // WorkSource.
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000584 updateWorkSourceRequestHeaderPosition();
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100585 int32_t workSource = readInt32();
Olivier Gaillard91a04802018-11-14 17:32:41 +0000586 threadState->setCallingWorkSourceUidWithoutPropagation(workSource);
Steven Morelandd70160f2019-07-23 10:20:38 -0700587 // vendor header
588 int32_t header = readInt32();
589 if (header != kHeader) {
590 ALOGE("Expecting header 0x%x but found 0x%x. Mixing copies of libbinder?", kHeader, header);
591 return false;
592 }
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100593 // Interface descriptor.
Mathias Agopian83c04462009-05-22 19:00:22 -0700594 const String16 str(readString16());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700595 if (str == interface) {
596 return true;
597 } else {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700598 ALOGW("**** enforceInterface() expected '%s' but read '%s'",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700599 String8(interface).string(), String8(str).string());
600 return false;
601 }
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700602}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700603
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700604size_t Parcel::objectsCount() const
605{
606 return mObjectsSize;
607}
608
609status_t Parcel::errorCheck() const
610{
611 return mError;
612}
613
614void Parcel::setError(status_t err)
615{
616 mError = err;
617}
618
619status_t Parcel::finishWrite(size_t len)
620{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700621 if (len > INT32_MAX) {
622 // don't accept size_t values which may have come from an
623 // inadvertent conversion from a negative int.
624 return BAD_VALUE;
625 }
626
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700627 //printf("Finish write of %d\n", len);
628 mDataPos += len;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700629 ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700630 if (mDataPos > mDataSize) {
631 mDataSize = mDataPos;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700632 ALOGV("finishWrite Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700633 }
634 //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
635 return NO_ERROR;
636}
637
638status_t Parcel::writeUnpadded(const void* data, size_t len)
639{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700640 if (len > INT32_MAX) {
641 // don't accept size_t values which may have come from an
642 // inadvertent conversion from a negative int.
643 return BAD_VALUE;
644 }
645
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700646 size_t end = mDataPos + len;
647 if (end < mDataPos) {
648 // integer overflow
649 return BAD_VALUE;
650 }
651
652 if (end <= mDataCapacity) {
653restart_write:
654 memcpy(mData+mDataPos, data, len);
655 return finishWrite(len);
656 }
657
658 status_t err = growData(len);
659 if (err == NO_ERROR) goto restart_write;
660 return err;
661}
662
663status_t Parcel::write(const void* data, size_t len)
664{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700665 if (len > INT32_MAX) {
666 // don't accept size_t values which may have come from an
667 // inadvertent conversion from a negative int.
668 return BAD_VALUE;
669 }
670
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700671 void* const d = writeInplace(len);
672 if (d) {
673 memcpy(d, data, len);
674 return NO_ERROR;
675 }
676 return mError;
677}
678
679void* Parcel::writeInplace(size_t len)
680{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700681 if (len > INT32_MAX) {
682 // don't accept size_t values which may have come from an
683 // inadvertent conversion from a negative int.
Yi Kong91635562018-06-07 14:38:36 -0700684 return nullptr;
Nick Kralevichb6b14232015-04-02 09:36:02 -0700685 }
686
687 const size_t padded = pad_size(len);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700688
689 // sanity check for integer overflow
690 if (mDataPos+padded < mDataPos) {
Yi Kong91635562018-06-07 14:38:36 -0700691 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700692 }
693
694 if ((mDataPos+padded) <= mDataCapacity) {
695restart_write:
696 //printf("Writing %ld bytes, padded to %ld\n", len, padded);
697 uint8_t* const data = mData+mDataPos;
698
699 // Need to pad at end?
700 if (padded != len) {
701#if BYTE_ORDER == BIG_ENDIAN
702 static const uint32_t mask[4] = {
703 0x00000000, 0xffffff00, 0xffff0000, 0xff000000
704 };
705#endif
706#if BYTE_ORDER == LITTLE_ENDIAN
707 static const uint32_t mask[4] = {
708 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
709 };
710#endif
711 //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
712 // *reinterpret_cast<void**>(data+padded-4));
713 *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
714 }
715
716 finishWrite(padded);
717 return data;
718 }
719
720 status_t err = growData(padded);
721 if (err == NO_ERROR) goto restart_write;
Yi Kong91635562018-06-07 14:38:36 -0700722 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700723}
724
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800725status_t Parcel::writeUtf8AsUtf16(const std::string& str) {
726 const uint8_t* strData = (uint8_t*)str.data();
727 const size_t strLen= str.length();
728 const ssize_t utf16Len = utf8_to_utf16_length(strData, strLen);
Sergio Girof4607432016-07-21 14:46:35 +0100729 if (utf16Len < 0 || utf16Len > std::numeric_limits<int32_t>::max()) {
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800730 return BAD_VALUE;
731 }
732
733 status_t err = writeInt32(utf16Len);
734 if (err) {
735 return err;
736 }
737
738 // Allocate enough bytes to hold our converted string and its terminating NULL.
739 void* dst = writeInplace((utf16Len + 1) * sizeof(char16_t));
740 if (!dst) {
741 return NO_MEMORY;
742 }
743
Sergio Girof4607432016-07-21 14:46:35 +0100744 utf8_to_utf16(strData, strLen, (char16_t*)dst, (size_t) utf16Len + 1);
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800745
746 return NO_ERROR;
747}
748
749status_t Parcel::writeUtf8AsUtf16(const std::unique_ptr<std::string>& str) {
750 if (!str) {
751 return writeInt32(-1);
752 }
753 return writeUtf8AsUtf16(*str);
754}
755
Casey Dahlin185d3442016-02-09 11:08:35 -0800756namespace {
Casey Dahlinb9872622015-11-25 15:09:45 -0800757
Casey Dahlin185d3442016-02-09 11:08:35 -0800758template<typename T>
759status_t writeByteVectorInternal(Parcel* parcel, const std::vector<T>& val)
Casey Dahlin451ff582015-10-19 18:12:18 -0700760{
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700761 status_t status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700762 if (val.size() > std::numeric_limits<int32_t>::max()) {
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700763 status = BAD_VALUE;
764 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700765 }
766
Casey Dahlin185d3442016-02-09 11:08:35 -0800767 status = parcel->writeInt32(val.size());
Casey Dahlin451ff582015-10-19 18:12:18 -0700768 if (status != OK) {
769 return status;
770 }
771
Casey Dahlin185d3442016-02-09 11:08:35 -0800772 void* data = parcel->writeInplace(val.size());
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700773 if (!data) {
774 status = BAD_VALUE;
775 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700776 }
777
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700778 memcpy(data, val.data(), val.size());
779 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700780}
781
Casey Dahlin185d3442016-02-09 11:08:35 -0800782template<typename T>
783status_t writeByteVectorInternalPtr(Parcel* parcel,
784 const std::unique_ptr<std::vector<T>>& val)
785{
786 if (!val) {
787 return parcel->writeInt32(-1);
788 }
789
790 return writeByteVectorInternal(parcel, *val);
791}
792
793} // namespace
794
795status_t Parcel::writeByteVector(const std::vector<int8_t>& val) {
796 return writeByteVectorInternal(this, val);
797}
798
799status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val)
800{
801 return writeByteVectorInternalPtr(this, val);
802}
803
804status_t Parcel::writeByteVector(const std::vector<uint8_t>& val) {
805 return writeByteVectorInternal(this, val);
806}
807
808status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val)
809{
810 return writeByteVectorInternalPtr(this, val);
811}
812
Casey Dahlin451ff582015-10-19 18:12:18 -0700813status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val)
814{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800815 return writeTypedVector(val, &Parcel::writeInt32);
Casey Dahlin451ff582015-10-19 18:12:18 -0700816}
817
Casey Dahlinb9872622015-11-25 15:09:45 -0800818status_t Parcel::writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val)
819{
820 return writeNullableTypedVector(val, &Parcel::writeInt32);
821}
822
Casey Dahlin451ff582015-10-19 18:12:18 -0700823status_t Parcel::writeInt64Vector(const std::vector<int64_t>& val)
824{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800825 return writeTypedVector(val, &Parcel::writeInt64);
Casey Dahlin451ff582015-10-19 18:12:18 -0700826}
827
Casey Dahlinb9872622015-11-25 15:09:45 -0800828status_t Parcel::writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val)
829{
830 return writeNullableTypedVector(val, &Parcel::writeInt64);
831}
832
Kevin DuBois2f82d5b2018-12-05 12:56:10 -0800833status_t Parcel::writeUint64Vector(const std::vector<uint64_t>& val)
834{
835 return writeTypedVector(val, &Parcel::writeUint64);
836}
837
838status_t Parcel::writeUint64Vector(const std::unique_ptr<std::vector<uint64_t>>& val)
839{
840 return writeNullableTypedVector(val, &Parcel::writeUint64);
841}
842
Casey Dahlin451ff582015-10-19 18:12:18 -0700843status_t Parcel::writeFloatVector(const std::vector<float>& val)
844{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800845 return writeTypedVector(val, &Parcel::writeFloat);
Casey Dahlin451ff582015-10-19 18:12:18 -0700846}
847
Casey Dahlinb9872622015-11-25 15:09:45 -0800848status_t Parcel::writeFloatVector(const std::unique_ptr<std::vector<float>>& val)
849{
850 return writeNullableTypedVector(val, &Parcel::writeFloat);
851}
852
Casey Dahlin451ff582015-10-19 18:12:18 -0700853status_t Parcel::writeDoubleVector(const std::vector<double>& val)
854{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800855 return writeTypedVector(val, &Parcel::writeDouble);
Casey Dahlin451ff582015-10-19 18:12:18 -0700856}
857
Casey Dahlinb9872622015-11-25 15:09:45 -0800858status_t Parcel::writeDoubleVector(const std::unique_ptr<std::vector<double>>& val)
859{
860 return writeNullableTypedVector(val, &Parcel::writeDouble);
861}
862
Casey Dahlin451ff582015-10-19 18:12:18 -0700863status_t Parcel::writeBoolVector(const std::vector<bool>& val)
864{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800865 return writeTypedVector(val, &Parcel::writeBool);
Casey Dahlin451ff582015-10-19 18:12:18 -0700866}
867
Casey Dahlinb9872622015-11-25 15:09:45 -0800868status_t Parcel::writeBoolVector(const std::unique_ptr<std::vector<bool>>& val)
869{
870 return writeNullableTypedVector(val, &Parcel::writeBool);
871}
872
Casey Dahlin451ff582015-10-19 18:12:18 -0700873status_t Parcel::writeCharVector(const std::vector<char16_t>& val)
874{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800875 return writeTypedVector(val, &Parcel::writeChar);
Casey Dahlin451ff582015-10-19 18:12:18 -0700876}
877
Casey Dahlinb9872622015-11-25 15:09:45 -0800878status_t Parcel::writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val)
879{
880 return writeNullableTypedVector(val, &Parcel::writeChar);
881}
882
Casey Dahlin451ff582015-10-19 18:12:18 -0700883status_t Parcel::writeString16Vector(const std::vector<String16>& val)
884{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800885 return writeTypedVector(val, &Parcel::writeString16);
Casey Dahlin451ff582015-10-19 18:12:18 -0700886}
887
Casey Dahlinb9872622015-11-25 15:09:45 -0800888status_t Parcel::writeString16Vector(
889 const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val)
890{
891 return writeNullableTypedVector(val, &Parcel::writeString16);
892}
893
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800894status_t Parcel::writeUtf8VectorAsUtf16Vector(
895 const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val) {
896 return writeNullableTypedVector(val, &Parcel::writeUtf8AsUtf16);
897}
898
899status_t Parcel::writeUtf8VectorAsUtf16Vector(const std::vector<std::string>& val) {
900 return writeTypedVector(val, &Parcel::writeUtf8AsUtf16);
901}
902
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700903status_t Parcel::writeInt32(int32_t val)
904{
Andreas Huber84a6d042009-08-17 13:33:27 -0700905 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700906}
Dan Stoza41a0f2f2014-12-01 10:01:10 -0800907
908status_t Parcel::writeUint32(uint32_t val)
909{
910 return writeAligned(val);
911}
912
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700913status_t Parcel::writeInt32Array(size_t len, const int32_t *val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -0700914 if (len > INT32_MAX) {
915 // don't accept size_t values which may have come from an
916 // inadvertent conversion from a negative int.
917 return BAD_VALUE;
918 }
919
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700920 if (!val) {
Chad Brubakere59cb432015-06-30 14:03:55 -0700921 return writeInt32(-1);
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700922 }
Chad Brubakere59cb432015-06-30 14:03:55 -0700923 status_t ret = writeInt32(static_cast<uint32_t>(len));
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700924 if (ret == NO_ERROR) {
925 ret = write(val, len * sizeof(*val));
926 }
927 return ret;
928}
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700929status_t Parcel::writeByteArray(size_t len, const uint8_t *val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -0700930 if (len > INT32_MAX) {
931 // don't accept size_t values which may have come from an
932 // inadvertent conversion from a negative int.
933 return BAD_VALUE;
934 }
935
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700936 if (!val) {
Chad Brubakere59cb432015-06-30 14:03:55 -0700937 return writeInt32(-1);
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700938 }
Chad Brubakere59cb432015-06-30 14:03:55 -0700939 status_t ret = writeInt32(static_cast<uint32_t>(len));
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700940 if (ret == NO_ERROR) {
941 ret = write(val, len * sizeof(*val));
942 }
943 return ret;
944}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700945
Casey Dahlind6848f52015-10-15 15:44:59 -0700946status_t Parcel::writeBool(bool val)
947{
948 return writeInt32(int32_t(val));
949}
950
951status_t Parcel::writeChar(char16_t val)
952{
953 return writeInt32(int32_t(val));
954}
955
956status_t Parcel::writeByte(int8_t val)
957{
958 return writeInt32(int32_t(val));
959}
960
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700961status_t Parcel::writeInt64(int64_t val)
962{
Andreas Huber84a6d042009-08-17 13:33:27 -0700963 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700964}
965
Ronghua Wu2d13afd2015-03-16 11:11:07 -0700966status_t Parcel::writeUint64(uint64_t val)
967{
968 return writeAligned(val);
969}
970
Serban Constantinescuf683e012013-11-05 16:53:55 +0000971status_t Parcel::writePointer(uintptr_t val)
972{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800973 return writeAligned<binder_uintptr_t>(val);
Serban Constantinescuf683e012013-11-05 16:53:55 +0000974}
975
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700976status_t Parcel::writeFloat(float val)
977{
Andreas Huber84a6d042009-08-17 13:33:27 -0700978 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700979}
980
Douglas Leungcc1a4bb2013-01-11 15:00:55 -0800981#if defined(__mips__) && defined(__mips_hard_float)
982
983status_t Parcel::writeDouble(double val)
984{
985 union {
986 double d;
987 unsigned long long ll;
988 } u;
989 u.d = val;
990 return writeAligned(u.ll);
991}
992
993#else
994
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700995status_t Parcel::writeDouble(double val)
996{
Andreas Huber84a6d042009-08-17 13:33:27 -0700997 return writeAligned(val);
998}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700999
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001000#endif
1001
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001002status_t Parcel::writeCString(const char* str)
1003{
1004 return write(str, strlen(str)+1);
1005}
1006
1007status_t Parcel::writeString8(const String8& str)
1008{
1009 status_t err = writeInt32(str.bytes());
Pravat Dalbeherad1dff8d2010-12-15 08:40:00 +01001010 // only write string if its length is more than zero characters,
1011 // as readString8 will only read if the length field is non-zero.
1012 // this is slightly different from how writeString16 works.
1013 if (str.bytes() > 0 && err == NO_ERROR) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001014 err = write(str.string(), str.bytes()+1);
1015 }
1016 return err;
1017}
1018
Casey Dahlinb9872622015-11-25 15:09:45 -08001019status_t Parcel::writeString16(const std::unique_ptr<String16>& str)
1020{
1021 if (!str) {
1022 return writeInt32(-1);
1023 }
1024
1025 return writeString16(*str);
1026}
1027
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001028status_t Parcel::writeString16(const String16& str)
1029{
1030 return writeString16(str.string(), str.size());
1031}
1032
1033status_t Parcel::writeString16(const char16_t* str, size_t len)
1034{
Yi Kong91635562018-06-07 14:38:36 -07001035 if (str == nullptr) return writeInt32(-1);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001036
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001037 status_t err = writeInt32(len);
1038 if (err == NO_ERROR) {
1039 len *= sizeof(char16_t);
1040 uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
1041 if (data) {
1042 memcpy(data, str, len);
1043 *reinterpret_cast<char16_t*>(data+len) = 0;
1044 return NO_ERROR;
1045 }
1046 err = mError;
1047 }
1048 return err;
1049}
1050
1051status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
1052{
Steven Morelanda86a3562019-08-01 23:28:34 +00001053 return flattenBinder(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001054}
1055
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001056status_t Parcel::writeStrongBinderVector(const std::vector<sp<IBinder>>& val)
1057{
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001058 return writeTypedVector(val, &Parcel::writeStrongBinder);
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001059}
1060
Casey Dahlinb9872622015-11-25 15:09:45 -08001061status_t Parcel::writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val)
1062{
1063 return writeNullableTypedVector(val, &Parcel::writeStrongBinder);
1064}
1065
1066status_t Parcel::readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const {
Christopher Wiley35d77ca2016-03-08 10:49:51 -08001067 return readNullableTypedVector(val, &Parcel::readNullableStrongBinder);
Casey Dahlinb9872622015-11-25 15:09:45 -08001068}
1069
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001070status_t Parcel::readStrongBinderVector(std::vector<sp<IBinder>>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001071 return readTypedVector(val, &Parcel::readStrongBinder);
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001072}
1073
Casey Dahlinb9872622015-11-25 15:09:45 -08001074status_t Parcel::writeRawNullableParcelable(const Parcelable* parcelable) {
1075 if (!parcelable) {
1076 return writeInt32(0);
1077 }
1078
1079 return writeParcelable(*parcelable);
1080}
1081
Christopher Wiley97f048d2015-11-19 06:49:05 -08001082status_t Parcel::writeParcelable(const Parcelable& parcelable) {
1083 status_t status = writeInt32(1); // parcelable is not null.
1084 if (status != OK) {
1085 return status;
1086 }
1087 return parcelable.writeToParcel(this);
1088}
1089
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001090status_t Parcel::writeNativeHandle(const native_handle* handle)
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001091{
Mathias Agopian1d0a95b2009-07-31 16:12:13 -07001092 if (!handle || handle->version != sizeof(native_handle))
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001093 return BAD_TYPE;
1094
1095 status_t err;
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001096 err = writeInt32(handle->numFds);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001097 if (err != NO_ERROR) return err;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001098
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001099 err = writeInt32(handle->numInts);
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 for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)
1103 err = writeDupFileDescriptor(handle->data[i]);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001104
1105 if (err != NO_ERROR) {
Steve Block9d453682011-12-20 16:23:08 +00001106 ALOGD("write native handle, write dup fd failed");
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001107 return err;
1108 }
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001109 err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001110 return err;
1111}
1112
Jeff Brown93ff1f92011-11-04 19:01:44 -07001113status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001114{
1115 flat_binder_object obj;
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07001116 obj.hdr.type = BINDER_TYPE_FD;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001117 obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
Arve Hjønnevåg07fd0f12014-02-18 21:10:29 -08001118 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001119 obj.handle = fd;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001120 obj.cookie = takeOwnership ? 1 : 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001121 return writeObject(obj, true);
1122}
1123
1124status_t Parcel::writeDupFileDescriptor(int fd)
1125{
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08001126 int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
Jeff Brownd341c712011-11-04 20:19:33 -07001127 if (dupFd < 0) {
1128 return -errno;
1129 }
1130 status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/);
Casey Dahlin06673e32015-11-23 13:24:23 -08001131 if (err != OK) {
Jeff Brownd341c712011-11-04 20:19:33 -07001132 close(dupFd);
1133 }
1134 return err;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001135}
1136
Dianne Hackborn1941a402016-08-29 12:30:43 -07001137status_t Parcel::writeParcelFileDescriptor(int fd, bool takeOwnership)
1138{
1139 writeInt32(0);
1140 return writeFileDescriptor(fd, takeOwnership);
1141}
1142
Ryo Hashimotobf551892018-05-31 16:58:35 +09001143status_t Parcel::writeDupParcelFileDescriptor(int fd)
1144{
1145 int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
1146 if (dupFd < 0) {
1147 return -errno;
1148 }
1149 status_t err = writeParcelFileDescriptor(dupFd, true /*takeOwnership*/);
1150 if (err != OK) {
1151 close(dupFd);
1152 }
1153 return err;
1154}
1155
Christopher Wiley2cf19952016-04-11 11:09:37 -07001156status_t Parcel::writeUniqueFileDescriptor(const base::unique_fd& fd) {
Casey Dahlin06673e32015-11-23 13:24:23 -08001157 return writeDupFileDescriptor(fd.get());
1158}
1159
Christopher Wiley2cf19952016-04-11 11:09:37 -07001160status_t Parcel::writeUniqueFileDescriptorVector(const std::vector<base::unique_fd>& val) {
Casey Dahlin06673e32015-11-23 13:24:23 -08001161 return writeTypedVector(val, &Parcel::writeUniqueFileDescriptor);
1162}
1163
Christopher Wiley2cf19952016-04-11 11:09:37 -07001164status_t Parcel::writeUniqueFileDescriptorVector(const std::unique_ptr<std::vector<base::unique_fd>>& val) {
Casey Dahlinb9872622015-11-25 15:09:45 -08001165 return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
1166}
1167
Jeff Brown13b16042014-11-11 16:44:25 -08001168status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob)
Jeff Brown5707dbf2011-09-23 21:17:56 -07001169{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001170 if (len > INT32_MAX) {
1171 // don't accept size_t values which may have come from an
1172 // inadvertent conversion from a negative int.
1173 return BAD_VALUE;
1174 }
1175
Jeff Brown13b16042014-11-11 16:44:25 -08001176 status_t status;
1177 if (!mAllowFds || len <= BLOB_INPLACE_LIMIT) {
Steve Block6807e592011-10-20 11:56:00 +01001178 ALOGV("writeBlob: write in place");
Jeff Brown13b16042014-11-11 16:44:25 -08001179 status = writeInt32(BLOB_INPLACE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001180 if (status) return status;
1181
1182 void* ptr = writeInplace(len);
1183 if (!ptr) return NO_MEMORY;
1184
Jeff Brown13b16042014-11-11 16:44:25 -08001185 outBlob->init(-1, ptr, len, false);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001186 return NO_ERROR;
1187 }
1188
Steve Block6807e592011-10-20 11:56:00 +01001189 ALOGV("writeBlob: write to ashmem");
Jeff Brown5707dbf2011-09-23 21:17:56 -07001190 int fd = ashmem_create_region("Parcel Blob", len);
1191 if (fd < 0) return NO_MEMORY;
1192
1193 int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
1194 if (result < 0) {
Jeff Brownec4e0062011-10-10 14:50:10 -07001195 status = result;
Jeff Brown5707dbf2011-09-23 21:17:56 -07001196 } else {
Yi Kong91635562018-06-07 14:38:36 -07001197 void* ptr = ::mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001198 if (ptr == MAP_FAILED) {
1199 status = -errno;
1200 } else {
Jeff Brown13b16042014-11-11 16:44:25 -08001201 if (!mutableCopy) {
1202 result = ashmem_set_prot_region(fd, PROT_READ);
1203 }
Jeff Brown5707dbf2011-09-23 21:17:56 -07001204 if (result < 0) {
Jeff Brownec4e0062011-10-10 14:50:10 -07001205 status = result;
Jeff Brown5707dbf2011-09-23 21:17:56 -07001206 } else {
Jeff Brown13b16042014-11-11 16:44:25 -08001207 status = writeInt32(mutableCopy ? BLOB_ASHMEM_MUTABLE : BLOB_ASHMEM_IMMUTABLE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001208 if (!status) {
Jeff Brown93ff1f92011-11-04 19:01:44 -07001209 status = writeFileDescriptor(fd, true /*takeOwnership*/);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001210 if (!status) {
Jeff Brown13b16042014-11-11 16:44:25 -08001211 outBlob->init(fd, ptr, len, mutableCopy);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001212 return NO_ERROR;
1213 }
1214 }
1215 }
1216 }
1217 ::munmap(ptr, len);
1218 }
1219 ::close(fd);
1220 return status;
1221}
1222
Jeff Brown13b16042014-11-11 16:44:25 -08001223status_t Parcel::writeDupImmutableBlobFileDescriptor(int fd)
1224{
1225 // Must match up with what's done in writeBlob.
1226 if (!mAllowFds) return FDS_NOT_ALLOWED;
1227 status_t status = writeInt32(BLOB_ASHMEM_IMMUTABLE);
1228 if (status) return status;
1229 return writeDupFileDescriptor(fd);
1230}
1231
Mathias Agopiane1424282013-07-29 21:24:40 -07001232status_t Parcel::write(const FlattenableHelperInterface& val)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001233{
1234 status_t err;
1235
1236 // size if needed
Mathias Agopiane1424282013-07-29 21:24:40 -07001237 const size_t len = val.getFlattenedSize();
1238 const size_t fd_count = val.getFdCount();
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001239
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001240 if ((len > INT32_MAX) || (fd_count >= gMaxFds)) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001241 // don't accept size_t values which may have come from an
1242 // inadvertent conversion from a negative int.
1243 return BAD_VALUE;
1244 }
1245
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001246 err = this->writeInt32(len);
1247 if (err) return err;
1248
1249 err = this->writeInt32(fd_count);
1250 if (err) return err;
1251
1252 // payload
Martijn Coenenf8542382018-04-04 11:46:56 +02001253 void* const buf = this->writeInplace(len);
Yi Kong91635562018-06-07 14:38:36 -07001254 if (buf == nullptr)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001255 return BAD_VALUE;
1256
Yi Kong91635562018-06-07 14:38:36 -07001257 int* fds = nullptr;
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001258 if (fd_count) {
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001259 fds = new (std::nothrow) int[fd_count];
1260 if (fds == nullptr) {
1261 ALOGE("write: failed to allocate requested %zu fds", fd_count);
1262 return BAD_VALUE;
1263 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001264 }
1265
1266 err = val.flatten(buf, len, fds, fd_count);
1267 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
1268 err = this->writeDupFileDescriptor( fds[i] );
1269 }
1270
1271 if (fd_count) {
1272 delete [] fds;
1273 }
1274
1275 return err;
1276}
1277
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001278status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
1279{
1280 const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
1281 const bool enoughObjects = mObjectsSize < mObjectsCapacity;
1282 if (enoughData && enoughObjects) {
1283restart_write:
1284 *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001285
Christopher Tate98e67d32015-06-03 18:44:15 -07001286 // remember if it's a file descriptor
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07001287 if (val.hdr.type == BINDER_TYPE_FD) {
Christopher Tate98e67d32015-06-03 18:44:15 -07001288 if (!mAllowFds) {
1289 // fail before modifying our object index
1290 return FDS_NOT_ALLOWED;
1291 }
1292 mHasFds = mFdsKnown = true;
1293 }
1294
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001295 // Need to write meta-data?
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001296 if (nullMetaData || val.binder != 0) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001297 mObjects[mObjectsSize] = mDataPos;
Adrian Rooscbf37262015-10-22 16:12:53 -07001298 acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001299 mObjectsSize++;
1300 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001301
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001302 return finishWrite(sizeof(flat_binder_object));
1303 }
1304
1305 if (!enoughData) {
1306 const status_t err = growData(sizeof(val));
1307 if (err != NO_ERROR) return err;
1308 }
1309 if (!enoughObjects) {
1310 size_t newSize = ((mObjectsSize+2)*3)/2;
Christopher Tate44235112016-11-03 13:32:41 -07001311 if (newSize*sizeof(binder_size_t) < mObjectsSize) return NO_MEMORY; // overflow
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001312 binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
Yi Kong91635562018-06-07 14:38:36 -07001313 if (objects == nullptr) return NO_MEMORY;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001314 mObjects = objects;
1315 mObjectsCapacity = newSize;
1316 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001317
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001318 goto restart_write;
1319}
1320
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07001321status_t Parcel::writeNoException()
1322{
Christopher Wiley09eb7492015-11-09 15:06:15 -08001323 binder::Status status;
1324 return status.writeToParcel(this);
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07001325}
1326
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001327status_t Parcel::validateReadData(size_t upperBound) const
1328{
1329 // Don't allow non-object reads on object data
1330 if (mObjectsSorted || mObjectsSize <= 1) {
1331data_sorted:
1332 // Expect to check only against the next object
1333 if (mNextObjectHint < mObjectsSize && upperBound > mObjects[mNextObjectHint]) {
1334 // For some reason the current read position is greater than the next object
1335 // hint. Iterate until we find the right object
1336 size_t nextObject = mNextObjectHint;
1337 do {
1338 if (mDataPos < mObjects[nextObject] + sizeof(flat_binder_object)) {
1339 // Requested info overlaps with an object
1340 ALOGE("Attempt to read from protected data in Parcel %p", this);
1341 return PERMISSION_DENIED;
1342 }
1343 nextObject++;
1344 } while (nextObject < mObjectsSize && upperBound > mObjects[nextObject]);
1345 mNextObjectHint = nextObject;
1346 }
1347 return NO_ERROR;
1348 }
1349 // Quickly determine if mObjects is sorted.
1350 binder_size_t* currObj = mObjects + mObjectsSize - 1;
1351 binder_size_t* prevObj = currObj;
1352 while (currObj > mObjects) {
1353 prevObj--;
1354 if(*prevObj > *currObj) {
1355 goto data_unsorted;
1356 }
1357 currObj--;
1358 }
1359 mObjectsSorted = true;
1360 goto data_sorted;
1361
1362data_unsorted:
1363 // Insertion Sort mObjects
1364 // Great for mostly sorted lists. If randomly sorted or reverse ordered mObjects become common,
1365 // switch to std::sort(mObjects, mObjects + mObjectsSize);
1366 for (binder_size_t* iter0 = mObjects + 1; iter0 < mObjects + mObjectsSize; iter0++) {
1367 binder_size_t temp = *iter0;
1368 binder_size_t* iter1 = iter0 - 1;
1369 while (iter1 >= mObjects && *iter1 > temp) {
1370 *(iter1 + 1) = *iter1;
1371 iter1--;
1372 }
1373 *(iter1 + 1) = temp;
1374 }
1375 mNextObjectHint = 0;
1376 mObjectsSorted = true;
1377 goto data_sorted;
1378}
1379
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001380status_t Parcel::read(void* outData, size_t len) const
1381{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001382 if (len > INT32_MAX) {
1383 // don't accept size_t values which may have come from an
1384 // inadvertent conversion from a negative int.
1385 return BAD_VALUE;
1386 }
1387
1388 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1389 && len <= pad_size(len)) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001390 if (mObjectsSize > 0) {
1391 status_t err = validateReadData(mDataPos + pad_size(len));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001392 if(err != NO_ERROR) {
1393 // Still increment the data position by the expected length
1394 mDataPos += pad_size(len);
1395 ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
1396 return err;
1397 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001398 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001399 memcpy(outData, mData+mDataPos, len);
Nick Kralevichb6b14232015-04-02 09:36:02 -07001400 mDataPos += pad_size(len);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001401 ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001402 return NO_ERROR;
1403 }
1404 return NOT_ENOUGH_DATA;
1405}
1406
1407const void* Parcel::readInplace(size_t len) const
1408{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001409 if (len > INT32_MAX) {
1410 // don't accept size_t values which may have come from an
1411 // inadvertent conversion from a negative int.
Yi Kong91635562018-06-07 14:38:36 -07001412 return nullptr;
Nick Kralevichb6b14232015-04-02 09:36:02 -07001413 }
1414
1415 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1416 && len <= pad_size(len)) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001417 if (mObjectsSize > 0) {
1418 status_t err = validateReadData(mDataPos + pad_size(len));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001419 if(err != NO_ERROR) {
1420 // Still increment the data position by the expected length
1421 mDataPos += pad_size(len);
1422 ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
Yi Kong91635562018-06-07 14:38:36 -07001423 return nullptr;
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001424 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001425 }
1426
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001427 const void* data = mData+mDataPos;
Nick Kralevichb6b14232015-04-02 09:36:02 -07001428 mDataPos += pad_size(len);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001429 ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001430 return data;
1431 }
Yi Kong91635562018-06-07 14:38:36 -07001432 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001433}
1434
Andreas Huber84a6d042009-08-17 13:33:27 -07001435template<class T>
1436status_t Parcel::readAligned(T *pArg) const {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001437 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
Andreas Huber84a6d042009-08-17 13:33:27 -07001438
1439 if ((mDataPos+sizeof(T)) <= mDataSize) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001440 if (mObjectsSize > 0) {
1441 status_t err = validateReadData(mDataPos + sizeof(T));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001442 if(err != NO_ERROR) {
1443 // Still increment the data position by the expected length
1444 mDataPos += sizeof(T);
1445 return err;
1446 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001447 }
1448
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001449 const void* data = mData+mDataPos;
Andreas Huber84a6d042009-08-17 13:33:27 -07001450 mDataPos += sizeof(T);
1451 *pArg = *reinterpret_cast<const T*>(data);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001452 return NO_ERROR;
1453 } else {
1454 return NOT_ENOUGH_DATA;
1455 }
1456}
1457
Andreas Huber84a6d042009-08-17 13:33:27 -07001458template<class T>
1459T Parcel::readAligned() const {
1460 T result;
1461 if (readAligned(&result) != NO_ERROR) {
1462 result = 0;
1463 }
1464
1465 return result;
1466}
1467
1468template<class T>
1469status_t Parcel::writeAligned(T val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001470 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
Andreas Huber84a6d042009-08-17 13:33:27 -07001471
1472 if ((mDataPos+sizeof(val)) <= mDataCapacity) {
1473restart_write:
1474 *reinterpret_cast<T*>(mData+mDataPos) = val;
1475 return finishWrite(sizeof(val));
1476 }
1477
1478 status_t err = growData(sizeof(val));
1479 if (err == NO_ERROR) goto restart_write;
1480 return err;
1481}
1482
Casey Dahlin185d3442016-02-09 11:08:35 -08001483namespace {
1484
1485template<typename T>
1486status_t readByteVectorInternal(const Parcel* parcel,
1487 std::vector<T>* val) {
Casey Dahlin451ff582015-10-19 18:12:18 -07001488 val->clear();
1489
1490 int32_t size;
Casey Dahlin185d3442016-02-09 11:08:35 -08001491 status_t status = parcel->readInt32(&size);
Casey Dahlin451ff582015-10-19 18:12:18 -07001492
1493 if (status != OK) {
1494 return status;
1495 }
1496
Christopher Wiley4db672d2015-11-10 09:44:30 -08001497 if (size < 0) {
1498 status = UNEXPECTED_NULL;
1499 return status;
1500 }
Casey Dahlin185d3442016-02-09 11:08:35 -08001501 if (size_t(size) > parcel->dataAvail()) {
Christopher Wileyf0fc52b2015-10-31 13:22:15 -07001502 status = BAD_VALUE;
1503 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -07001504 }
Christopher Wiley4db672d2015-11-10 09:44:30 -08001505
Paul Lietar433e87b2016-09-16 10:39:32 -07001506 T* data = const_cast<T*>(reinterpret_cast<const T*>(parcel->readInplace(size)));
Christopher Wileyf0fc52b2015-10-31 13:22:15 -07001507 if (!data) {
1508 status = BAD_VALUE;
1509 return status;
1510 }
Paul Lietar433e87b2016-09-16 10:39:32 -07001511 val->reserve(size);
1512 val->insert(val->end(), data, data + size);
Casey Dahlin451ff582015-10-19 18:12:18 -07001513
Christopher Wileyf0fc52b2015-10-31 13:22:15 -07001514 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -07001515}
1516
Casey Dahlin185d3442016-02-09 11:08:35 -08001517template<typename T>
1518status_t readByteVectorInternalPtr(
1519 const Parcel* parcel,
1520 std::unique_ptr<std::vector<T>>* val) {
1521 const int32_t start = parcel->dataPosition();
Casey Dahlinb9872622015-11-25 15:09:45 -08001522 int32_t size;
Casey Dahlin185d3442016-02-09 11:08:35 -08001523 status_t status = parcel->readInt32(&size);
Casey Dahlinb9872622015-11-25 15:09:45 -08001524 val->reset();
1525
1526 if (status != OK || size < 0) {
1527 return status;
1528 }
1529
Casey Dahlin185d3442016-02-09 11:08:35 -08001530 parcel->setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001531 val->reset(new (std::nothrow) std::vector<T>());
Casey Dahlinb9872622015-11-25 15:09:45 -08001532
Casey Dahlin185d3442016-02-09 11:08:35 -08001533 status = readByteVectorInternal(parcel, val->get());
Casey Dahlinb9872622015-11-25 15:09:45 -08001534
1535 if (status != OK) {
1536 val->reset();
1537 }
1538
1539 return status;
1540}
1541
Casey Dahlin185d3442016-02-09 11:08:35 -08001542} // namespace
1543
1544status_t Parcel::readByteVector(std::vector<int8_t>* val) const {
1545 return readByteVectorInternal(this, val);
1546}
1547
1548status_t Parcel::readByteVector(std::vector<uint8_t>* val) const {
1549 return readByteVectorInternal(this, val);
1550}
1551
1552status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const {
1553 return readByteVectorInternalPtr(this, val);
1554}
1555
1556status_t Parcel::readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const {
1557 return readByteVectorInternalPtr(this, val);
1558}
1559
Casey Dahlinb9872622015-11-25 15:09:45 -08001560status_t Parcel::readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const {
1561 return readNullableTypedVector(val, &Parcel::readInt32);
1562}
1563
Casey Dahlin451ff582015-10-19 18:12:18 -07001564status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001565 return readTypedVector(val, &Parcel::readInt32);
Casey Dahlin451ff582015-10-19 18:12:18 -07001566}
1567
Casey Dahlinb9872622015-11-25 15:09:45 -08001568status_t Parcel::readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const {
1569 return readNullableTypedVector(val, &Parcel::readInt64);
1570}
1571
Casey Dahlin451ff582015-10-19 18:12:18 -07001572status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001573 return readTypedVector(val, &Parcel::readInt64);
Casey Dahlin451ff582015-10-19 18:12:18 -07001574}
1575
Kevin DuBois2f82d5b2018-12-05 12:56:10 -08001576status_t Parcel::readUint64Vector(std::unique_ptr<std::vector<uint64_t>>* val) const {
1577 return readNullableTypedVector(val, &Parcel::readUint64);
1578}
1579
1580status_t Parcel::readUint64Vector(std::vector<uint64_t>* val) const {
1581 return readTypedVector(val, &Parcel::readUint64);
1582}
1583
Casey Dahlinb9872622015-11-25 15:09:45 -08001584status_t Parcel::readFloatVector(std::unique_ptr<std::vector<float>>* val) const {
1585 return readNullableTypedVector(val, &Parcel::readFloat);
1586}
1587
Casey Dahlin451ff582015-10-19 18:12:18 -07001588status_t Parcel::readFloatVector(std::vector<float>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001589 return readTypedVector(val, &Parcel::readFloat);
Casey Dahlin451ff582015-10-19 18:12:18 -07001590}
1591
Casey Dahlinb9872622015-11-25 15:09:45 -08001592status_t Parcel::readDoubleVector(std::unique_ptr<std::vector<double>>* val) const {
1593 return readNullableTypedVector(val, &Parcel::readDouble);
1594}
1595
Casey Dahlin451ff582015-10-19 18:12:18 -07001596status_t Parcel::readDoubleVector(std::vector<double>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001597 return readTypedVector(val, &Parcel::readDouble);
Casey Dahlin451ff582015-10-19 18:12:18 -07001598}
1599
Casey Dahlinb9872622015-11-25 15:09:45 -08001600status_t Parcel::readBoolVector(std::unique_ptr<std::vector<bool>>* val) const {
1601 const int32_t start = dataPosition();
1602 int32_t size;
1603 status_t status = readInt32(&size);
1604 val->reset();
Casey Dahlin451ff582015-10-19 18:12:18 -07001605
Casey Dahlinb9872622015-11-25 15:09:45 -08001606 if (status != OK || size < 0) {
1607 return status;
1608 }
1609
1610 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001611 val->reset(new (std::nothrow) std::vector<bool>());
Casey Dahlinb9872622015-11-25 15:09:45 -08001612
1613 status = readBoolVector(val->get());
1614
1615 if (status != OK) {
1616 val->reset();
1617 }
1618
1619 return status;
1620}
1621
1622status_t Parcel::readBoolVector(std::vector<bool>* val) const {
Casey Dahlin451ff582015-10-19 18:12:18 -07001623 int32_t size;
1624 status_t status = readInt32(&size);
1625
1626 if (status != OK) {
1627 return status;
1628 }
1629
1630 if (size < 0) {
Christopher Wiley4db672d2015-11-10 09:44:30 -08001631 return UNEXPECTED_NULL;
Casey Dahlin451ff582015-10-19 18:12:18 -07001632 }
1633
1634 val->resize(size);
1635
1636 /* C++ bool handling means a vector of bools isn't necessarily addressable
1637 * (we might use individual bits)
1638 */
Christopher Wiley97887982015-10-27 16:33:47 -07001639 bool data;
1640 for (int32_t i = 0; i < size; ++i) {
Casey Dahlin451ff582015-10-19 18:12:18 -07001641 status = readBool(&data);
1642 (*val)[i] = data;
1643
1644 if (status != OK) {
1645 return status;
1646 }
1647 }
1648
1649 return OK;
1650}
1651
Casey Dahlinb9872622015-11-25 15:09:45 -08001652status_t Parcel::readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const {
1653 return readNullableTypedVector(val, &Parcel::readChar);
1654}
1655
Casey Dahlin451ff582015-10-19 18:12:18 -07001656status_t Parcel::readCharVector(std::vector<char16_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001657 return readTypedVector(val, &Parcel::readChar);
Casey Dahlin451ff582015-10-19 18:12:18 -07001658}
1659
Casey Dahlinb9872622015-11-25 15:09:45 -08001660status_t Parcel::readString16Vector(
1661 std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const {
1662 return readNullableTypedVector(val, &Parcel::readString16);
1663}
1664
Casey Dahlin451ff582015-10-19 18:12:18 -07001665status_t Parcel::readString16Vector(std::vector<String16>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001666 return readTypedVector(val, &Parcel::readString16);
Casey Dahlin451ff582015-10-19 18:12:18 -07001667}
1668
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001669status_t Parcel::readUtf8VectorFromUtf16Vector(
1670 std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const {
1671 return readNullableTypedVector(val, &Parcel::readUtf8FromUtf16);
1672}
1673
1674status_t Parcel::readUtf8VectorFromUtf16Vector(std::vector<std::string>* val) const {
1675 return readTypedVector(val, &Parcel::readUtf8FromUtf16);
1676}
Casey Dahlin451ff582015-10-19 18:12:18 -07001677
Andreas Huber84a6d042009-08-17 13:33:27 -07001678status_t Parcel::readInt32(int32_t *pArg) const
1679{
1680 return readAligned(pArg);
1681}
1682
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001683int32_t Parcel::readInt32() const
1684{
Andreas Huber84a6d042009-08-17 13:33:27 -07001685 return readAligned<int32_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001686}
1687
Dan Stoza41a0f2f2014-12-01 10:01:10 -08001688status_t Parcel::readUint32(uint32_t *pArg) const
1689{
1690 return readAligned(pArg);
1691}
1692
1693uint32_t Parcel::readUint32() const
1694{
1695 return readAligned<uint32_t>();
1696}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001697
1698status_t Parcel::readInt64(int64_t *pArg) const
1699{
Andreas Huber84a6d042009-08-17 13:33:27 -07001700 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001701}
1702
1703
1704int64_t Parcel::readInt64() const
1705{
Andreas Huber84a6d042009-08-17 13:33:27 -07001706 return readAligned<int64_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001707}
1708
Ronghua Wu2d13afd2015-03-16 11:11:07 -07001709status_t Parcel::readUint64(uint64_t *pArg) const
1710{
1711 return readAligned(pArg);
1712}
1713
1714uint64_t Parcel::readUint64() const
1715{
1716 return readAligned<uint64_t>();
1717}
1718
Serban Constantinescuf683e012013-11-05 16:53:55 +00001719status_t Parcel::readPointer(uintptr_t *pArg) const
1720{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001721 status_t ret;
1722 binder_uintptr_t ptr;
1723 ret = readAligned(&ptr);
1724 if (!ret)
1725 *pArg = ptr;
1726 return ret;
Serban Constantinescuf683e012013-11-05 16:53:55 +00001727}
1728
1729uintptr_t Parcel::readPointer() const
1730{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001731 return readAligned<binder_uintptr_t>();
Serban Constantinescuf683e012013-11-05 16:53:55 +00001732}
1733
1734
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001735status_t Parcel::readFloat(float *pArg) const
1736{
Andreas Huber84a6d042009-08-17 13:33:27 -07001737 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001738}
1739
1740
1741float Parcel::readFloat() const
1742{
Andreas Huber84a6d042009-08-17 13:33:27 -07001743 return readAligned<float>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001744}
1745
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001746#if defined(__mips__) && defined(__mips_hard_float)
1747
1748status_t Parcel::readDouble(double *pArg) const
1749{
1750 union {
1751 double d;
1752 unsigned long long ll;
1753 } u;
Narayan Kamath2c68d382014-06-04 15:04:29 +01001754 u.d = 0;
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001755 status_t status;
1756 status = readAligned(&u.ll);
1757 *pArg = u.d;
1758 return status;
1759}
1760
1761double Parcel::readDouble() const
1762{
1763 union {
1764 double d;
1765 unsigned long long ll;
1766 } u;
1767 u.ll = readAligned<unsigned long long>();
1768 return u.d;
1769}
1770
1771#else
1772
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001773status_t Parcel::readDouble(double *pArg) const
1774{
Andreas Huber84a6d042009-08-17 13:33:27 -07001775 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001776}
1777
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001778double Parcel::readDouble() const
1779{
Andreas Huber84a6d042009-08-17 13:33:27 -07001780 return readAligned<double>();
1781}
1782
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001783#endif
1784
Andreas Huber84a6d042009-08-17 13:33:27 -07001785status_t Parcel::readIntPtr(intptr_t *pArg) const
1786{
1787 return readAligned(pArg);
1788}
1789
1790
1791intptr_t Parcel::readIntPtr() const
1792{
1793 return readAligned<intptr_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001794}
1795
Casey Dahlind6848f52015-10-15 15:44:59 -07001796status_t Parcel::readBool(bool *pArg) const
1797{
Manoj Gupta6eb62052017-07-12 10:29:15 -07001798 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07001799 status_t ret = readInt32(&tmp);
1800 *pArg = (tmp != 0);
1801 return ret;
1802}
1803
1804bool Parcel::readBool() const
1805{
1806 return readInt32() != 0;
1807}
1808
1809status_t Parcel::readChar(char16_t *pArg) const
1810{
Manoj Gupta6eb62052017-07-12 10:29:15 -07001811 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07001812 status_t ret = readInt32(&tmp);
1813 *pArg = char16_t(tmp);
1814 return ret;
1815}
1816
1817char16_t Parcel::readChar() const
1818{
1819 return char16_t(readInt32());
1820}
1821
1822status_t Parcel::readByte(int8_t *pArg) const
1823{
Manoj Gupta6eb62052017-07-12 10:29:15 -07001824 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07001825 status_t ret = readInt32(&tmp);
1826 *pArg = int8_t(tmp);
1827 return ret;
1828}
1829
1830int8_t Parcel::readByte() const
1831{
1832 return int8_t(readInt32());
1833}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001834
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001835status_t Parcel::readUtf8FromUtf16(std::string* str) const {
1836 size_t utf16Size = 0;
1837 const char16_t* src = readString16Inplace(&utf16Size);
1838 if (!src) {
1839 return UNEXPECTED_NULL;
1840 }
1841
1842 // Save ourselves the trouble, we're done.
1843 if (utf16Size == 0u) {
1844 str->clear();
1845 return NO_ERROR;
1846 }
1847
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001848 // Allow for closing '\0'
1849 ssize_t utf8Size = utf16_to_utf8_length(src, utf16Size) + 1;
1850 if (utf8Size < 1) {
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001851 return BAD_VALUE;
1852 }
1853 // Note that while it is probably safe to assume string::resize keeps a
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001854 // spare byte around for the trailing null, we still pass the size including the trailing null
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001855 str->resize(utf8Size);
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001856 utf16_to_utf8(src, utf16Size, &((*str)[0]), utf8Size);
1857 str->resize(utf8Size - 1);
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001858 return NO_ERROR;
1859}
1860
1861status_t Parcel::readUtf8FromUtf16(std::unique_ptr<std::string>* str) const {
1862 const int32_t start = dataPosition();
1863 int32_t size;
1864 status_t status = readInt32(&size);
1865 str->reset();
1866
1867 if (status != OK || size < 0) {
1868 return status;
1869 }
1870
1871 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001872 str->reset(new (std::nothrow) std::string());
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001873 return readUtf8FromUtf16(str->get());
1874}
1875
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001876const char* Parcel::readCString() const
1877{
Steven Morelandd0d4b582019-05-17 13:14:06 -07001878 if (mDataPos < mDataSize) {
1879 const size_t avail = mDataSize-mDataPos;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001880 const char* str = reinterpret_cast<const char*>(mData+mDataPos);
1881 // is the string's trailing NUL within the parcel's valid bounds?
1882 const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
1883 if (eos) {
1884 const size_t len = eos - str;
Nick Kralevichb6b14232015-04-02 09:36:02 -07001885 mDataPos += pad_size(len+1);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001886 ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001887 return str;
1888 }
1889 }
Yi Kong91635562018-06-07 14:38:36 -07001890 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001891}
1892
1893String8 Parcel::readString8() const
1894{
Roshan Pius87b64d22016-07-18 12:51:02 -07001895 String8 retString;
1896 status_t status = readString8(&retString);
1897 if (status != OK) {
1898 // We don't care about errors here, so just return an empty string.
1899 return String8();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001900 }
Roshan Pius87b64d22016-07-18 12:51:02 -07001901 return retString;
1902}
1903
1904status_t Parcel::readString8(String8* pArg) const
1905{
1906 int32_t size;
1907 status_t status = readInt32(&size);
1908 if (status != OK) {
1909 return status;
1910 }
1911 // watch for potential int overflow from size+1
1912 if (size < 0 || size >= INT32_MAX) {
1913 return BAD_VALUE;
1914 }
1915 // |writeString8| writes nothing for empty string.
1916 if (size == 0) {
1917 *pArg = String8();
1918 return OK;
1919 }
1920 const char* str = (const char*)readInplace(size + 1);
Yi Kong91635562018-06-07 14:38:36 -07001921 if (str == nullptr) {
Roshan Pius87b64d22016-07-18 12:51:02 -07001922 return BAD_VALUE;
1923 }
1924 pArg->setTo(str, size);
1925 return OK;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001926}
1927
1928String16 Parcel::readString16() const
1929{
1930 size_t len;
1931 const char16_t* str = readString16Inplace(&len);
1932 if (str) return String16(str, len);
Steve Blocke6f43dd2012-01-06 19:20:56 +00001933 ALOGE("Reading a NULL string not supported here.");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001934 return String16();
1935}
1936
Casey Dahlinb9872622015-11-25 15:09:45 -08001937status_t Parcel::readString16(std::unique_ptr<String16>* pArg) const
1938{
1939 const int32_t start = dataPosition();
1940 int32_t size;
1941 status_t status = readInt32(&size);
1942 pArg->reset();
1943
1944 if (status != OK || size < 0) {
1945 return status;
1946 }
1947
1948 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001949 pArg->reset(new (std::nothrow) String16());
Casey Dahlinb9872622015-11-25 15:09:45 -08001950
1951 status = readString16(pArg->get());
1952
1953 if (status != OK) {
1954 pArg->reset();
1955 }
1956
1957 return status;
1958}
1959
Casey Dahlin451ff582015-10-19 18:12:18 -07001960status_t Parcel::readString16(String16* pArg) const
1961{
1962 size_t len;
1963 const char16_t* str = readString16Inplace(&len);
1964 if (str) {
Casey Dahlin1515ea12015-10-20 16:26:23 -07001965 pArg->setTo(str, len);
Casey Dahlin451ff582015-10-19 18:12:18 -07001966 return 0;
1967 } else {
1968 *pArg = String16();
Christopher Wiley4db672d2015-11-10 09:44:30 -08001969 return UNEXPECTED_NULL;
Casey Dahlin451ff582015-10-19 18:12:18 -07001970 }
1971}
1972
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001973const char16_t* Parcel::readString16Inplace(size_t* outLen) const
1974{
1975 int32_t size = readInt32();
1976 // watch for potential int overflow from size+1
1977 if (size >= 0 && size < INT32_MAX) {
1978 *outLen = size;
1979 const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
Yi Kong91635562018-06-07 14:38:36 -07001980 if (str != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001981 return str;
1982 }
1983 }
1984 *outLen = 0;
Yi Kong91635562018-06-07 14:38:36 -07001985 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001986}
1987
Casey Dahlinf0c13772015-10-27 18:33:56 -07001988status_t Parcel::readStrongBinder(sp<IBinder>* val) const
1989{
Christopher Wiley35d77ca2016-03-08 10:49:51 -08001990 status_t status = readNullableStrongBinder(val);
1991 if (status == OK && !val->get()) {
1992 status = UNEXPECTED_NULL;
1993 }
1994 return status;
1995}
1996
1997status_t Parcel::readNullableStrongBinder(sp<IBinder>* val) const
1998{
Steven Morelanda86a3562019-08-01 23:28:34 +00001999 return unflattenBinder(val);
Casey Dahlinf0c13772015-10-27 18:33:56 -07002000}
2001
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002002sp<IBinder> Parcel::readStrongBinder() const
2003{
2004 sp<IBinder> val;
Christopher Wiley35d77ca2016-03-08 10:49:51 -08002005 // Note that a lot of code in Android reads binders by hand with this
2006 // method, and that code has historically been ok with getting nullptr
2007 // back (while ignoring error codes).
2008 readNullableStrongBinder(&val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002009 return val;
2010}
2011
Christopher Wiley97f048d2015-11-19 06:49:05 -08002012status_t Parcel::readParcelable(Parcelable* parcelable) const {
2013 int32_t have_parcelable = 0;
2014 status_t status = readInt32(&have_parcelable);
2015 if (status != OK) {
2016 return status;
2017 }
2018 if (!have_parcelable) {
2019 return UNEXPECTED_NULL;
2020 }
2021 return parcelable->readFromParcel(this);
2022}
2023
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07002024int32_t Parcel::readExceptionCode() const
2025{
Christopher Wiley09eb7492015-11-09 15:06:15 -08002026 binder::Status status;
2027 status.readFromParcel(*this);
2028 return status.exceptionCode();
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07002029}
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002030
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002031native_handle* Parcel::readNativeHandle() const
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002032{
2033 int numFds, numInts;
2034 status_t err;
2035 err = readInt32(&numFds);
Yi Kong91635562018-06-07 14:38:36 -07002036 if (err != NO_ERROR) return nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002037 err = readInt32(&numInts);
Yi Kong91635562018-06-07 14:38:36 -07002038 if (err != NO_ERROR) return nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002039
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002040 native_handle* h = native_handle_create(numFds, numInts);
Adam Lesinskieaac99a2015-05-12 17:35:48 -07002041 if (!h) {
Yi Kong91635562018-06-07 14:38:36 -07002042 return nullptr;
Adam Lesinskieaac99a2015-05-12 17:35:48 -07002043 }
2044
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002045 for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002046 h->data[i] = fcntl(readFileDescriptor(), F_DUPFD_CLOEXEC, 0);
Marco Nelissen1de79662016-04-26 08:44:09 -07002047 if (h->data[i] < 0) {
2048 for (int j = 0; j < i; j++) {
2049 close(h->data[j]);
2050 }
2051 native_handle_delete(h);
Yi Kong91635562018-06-07 14:38:36 -07002052 return nullptr;
Marco Nelissen1de79662016-04-26 08:44:09 -07002053 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002054 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002055 err = read(h->data + numFds, sizeof(int)*numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002056 if (err != NO_ERROR) {
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002057 native_handle_close(h);
2058 native_handle_delete(h);
Yi Kong91635562018-06-07 14:38:36 -07002059 h = nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002060 }
2061 return h;
2062}
2063
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002064int Parcel::readFileDescriptor() const
2065{
2066 const flat_binder_object* flat = readObject(true);
Casey Dahlin06673e32015-11-23 13:24:23 -08002067
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002068 if (flat && flat->hdr.type == BINDER_TYPE_FD) {
Casey Dahlin06673e32015-11-23 13:24:23 -08002069 return flat->handle;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002070 }
Casey Dahlin06673e32015-11-23 13:24:23 -08002071
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002072 return BAD_TYPE;
2073}
2074
Dianne Hackborn1941a402016-08-29 12:30:43 -07002075int Parcel::readParcelFileDescriptor() const
2076{
2077 int32_t hasComm = readInt32();
2078 int fd = readFileDescriptor();
2079 if (hasComm != 0) {
Steven Morelandb73806a2018-11-12 19:35:47 -08002080 // detach (owned by the binder driver)
2081 int comm = readFileDescriptor();
2082
2083 // warning: this must be kept in sync with:
2084 // frameworks/base/core/java/android/os/ParcelFileDescriptor.java
2085 enum ParcelFileDescriptorStatus {
2086 DETACHED = 2,
2087 };
2088
2089#if BYTE_ORDER == BIG_ENDIAN
2090 const int32_t message = ParcelFileDescriptorStatus::DETACHED;
2091#endif
2092#if BYTE_ORDER == LITTLE_ENDIAN
2093 const int32_t message = __builtin_bswap32(ParcelFileDescriptorStatus::DETACHED);
2094#endif
2095
2096 ssize_t written = TEMP_FAILURE_RETRY(
2097 ::write(comm, &message, sizeof(message)));
2098
2099 if (written == -1 || written != sizeof(message)) {
2100 ALOGW("Failed to detach ParcelFileDescriptor written: %zd err: %s",
2101 written, strerror(errno));
2102 return BAD_TYPE;
2103 }
Dianne Hackborn1941a402016-08-29 12:30:43 -07002104 }
2105 return fd;
2106}
2107
Christopher Wiley2cf19952016-04-11 11:09:37 -07002108status_t Parcel::readUniqueFileDescriptor(base::unique_fd* val) const
Casey Dahlin06673e32015-11-23 13:24:23 -08002109{
2110 int got = readFileDescriptor();
2111
2112 if (got == BAD_TYPE) {
2113 return BAD_TYPE;
2114 }
2115
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002116 val->reset(fcntl(got, F_DUPFD_CLOEXEC, 0));
Casey Dahlin06673e32015-11-23 13:24:23 -08002117
2118 if (val->get() < 0) {
2119 return BAD_VALUE;
2120 }
2121
2122 return OK;
2123}
2124
Ryo Hashimotobf551892018-05-31 16:58:35 +09002125status_t Parcel::readUniqueParcelFileDescriptor(base::unique_fd* val) const
2126{
2127 int got = readParcelFileDescriptor();
2128
2129 if (got == BAD_TYPE) {
2130 return BAD_TYPE;
2131 }
2132
2133 val->reset(fcntl(got, F_DUPFD_CLOEXEC, 0));
2134
2135 if (val->get() < 0) {
2136 return BAD_VALUE;
2137 }
2138
2139 return OK;
2140}
Casey Dahlin06673e32015-11-23 13:24:23 -08002141
Christopher Wiley2cf19952016-04-11 11:09:37 -07002142status_t Parcel::readUniqueFileDescriptorVector(std::unique_ptr<std::vector<base::unique_fd>>* val) const {
Casey Dahlinb9872622015-11-25 15:09:45 -08002143 return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
2144}
2145
Christopher Wiley2cf19952016-04-11 11:09:37 -07002146status_t Parcel::readUniqueFileDescriptorVector(std::vector<base::unique_fd>* val) const {
Casey Dahlin06673e32015-11-23 13:24:23 -08002147 return readTypedVector(val, &Parcel::readUniqueFileDescriptor);
2148}
2149
Jeff Brown5707dbf2011-09-23 21:17:56 -07002150status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
2151{
Jeff Brown13b16042014-11-11 16:44:25 -08002152 int32_t blobType;
2153 status_t status = readInt32(&blobType);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002154 if (status) return status;
2155
Jeff Brown13b16042014-11-11 16:44:25 -08002156 if (blobType == BLOB_INPLACE) {
Steve Block6807e592011-10-20 11:56:00 +01002157 ALOGV("readBlob: read in place");
Jeff Brown5707dbf2011-09-23 21:17:56 -07002158 const void* ptr = readInplace(len);
2159 if (!ptr) return BAD_VALUE;
2160
Jeff Brown13b16042014-11-11 16:44:25 -08002161 outBlob->init(-1, const_cast<void*>(ptr), len, false);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002162 return NO_ERROR;
2163 }
2164
Steve Block6807e592011-10-20 11:56:00 +01002165 ALOGV("readBlob: read from ashmem");
Jeff Brown13b16042014-11-11 16:44:25 -08002166 bool isMutable = (blobType == BLOB_ASHMEM_MUTABLE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002167 int fd = readFileDescriptor();
2168 if (fd == int(BAD_TYPE)) return BAD_VALUE;
2169
Jorim Jaggi150b4ef2018-07-13 11:18:30 +00002170 if (!ashmem_valid(fd)) {
2171 ALOGE("invalid fd");
2172 return BAD_VALUE;
2173 }
Marco Nelissen7a96ec42018-06-06 07:37:46 -07002174 int size = ashmem_get_size_region(fd);
2175 if (size < 0 || size_t(size) < len) {
Jorim Jaggi150b4ef2018-07-13 11:18:30 +00002176 ALOGE("request size %zu does not match fd size %d", len, size);
Marco Nelissen7a96ec42018-06-06 07:37:46 -07002177 return BAD_VALUE;
2178 }
Yi Kong91635562018-06-07 14:38:36 -07002179 void* ptr = ::mmap(nullptr, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ,
Jeff Brown13b16042014-11-11 16:44:25 -08002180 MAP_SHARED, fd, 0);
Narayan Kamath9ea09752014-10-08 17:35:45 +01002181 if (ptr == MAP_FAILED) return NO_MEMORY;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002182
Jeff Brown13b16042014-11-11 16:44:25 -08002183 outBlob->init(fd, ptr, len, isMutable);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002184 return NO_ERROR;
2185}
2186
Mathias Agopiane1424282013-07-29 21:24:40 -07002187status_t Parcel::read(FlattenableHelperInterface& val) const
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002188{
2189 // size
2190 const size_t len = this->readInt32();
2191 const size_t fd_count = this->readInt32();
2192
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002193 if ((len > INT32_MAX) || (fd_count >= gMaxFds)) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07002194 // don't accept size_t values which may have come from an
2195 // inadvertent conversion from a negative int.
2196 return BAD_VALUE;
2197 }
2198
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002199 // payload
Nick Kralevichb6b14232015-04-02 09:36:02 -07002200 void const* const buf = this->readInplace(pad_size(len));
Yi Kong91635562018-06-07 14:38:36 -07002201 if (buf == nullptr)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002202 return BAD_VALUE;
2203
Yi Kong91635562018-06-07 14:38:36 -07002204 int* fds = nullptr;
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002205 if (fd_count) {
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002206 fds = new (std::nothrow) int[fd_count];
2207 if (fds == nullptr) {
2208 ALOGE("read: failed to allocate requested %zu fds", fd_count);
2209 return BAD_VALUE;
2210 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002211 }
2212
2213 status_t err = NO_ERROR;
2214 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
Fabien Sanglardd84ff312016-10-21 10:58:26 -07002215 int fd = this->readFileDescriptor();
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002216 if (fd < 0 || ((fds[i] = fcntl(fd, F_DUPFD_CLOEXEC, 0)) < 0)) {
Jun Jiangabf8a2c2014-04-29 14:22:10 +08002217 err = BAD_VALUE;
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002218 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 -07002219 i, fds[i], fd_count, strerror(fd < 0 ? -fd : errno));
2220 // Close all the file descriptors that were dup-ed.
2221 for (size_t j=0; j<i ;j++) {
2222 close(fds[j]);
2223 }
Jun Jiangabf8a2c2014-04-29 14:22:10 +08002224 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002225 }
2226
2227 if (err == NO_ERROR) {
2228 err = val.unflatten(buf, len, fds, fd_count);
2229 }
2230
2231 if (fd_count) {
2232 delete [] fds;
2233 }
2234
2235 return err;
2236}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002237const flat_binder_object* Parcel::readObject(bool nullMetaData) const
2238{
2239 const size_t DPOS = mDataPos;
2240 if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
2241 const flat_binder_object* obj
2242 = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
2243 mDataPos = DPOS + sizeof(flat_binder_object);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002244 if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) {
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002245 // When transferring a NULL object, we don't write it into
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002246 // the object list, so we don't want to check for it when
2247 // reading.
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002248 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002249 return obj;
2250 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002251
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002252 // Ensure that this object is valid...
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002253 binder_size_t* const OBJS = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002254 const size_t N = mObjectsSize;
2255 size_t opos = mNextObjectHint;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002256
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002257 if (N > 0) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002258 ALOGV("Parcel %p looking for obj at %zu, hint=%zu",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002259 this, DPOS, opos);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002260
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002261 // Start at the current hint position, looking for an object at
2262 // the current data position.
2263 if (opos < N) {
2264 while (opos < (N-1) && OBJS[opos] < DPOS) {
2265 opos++;
2266 }
2267 } else {
2268 opos = N-1;
2269 }
2270 if (OBJS[opos] == DPOS) {
2271 // Found it!
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002272 ALOGV("Parcel %p found obj %zu at index %zu with forward search",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002273 this, DPOS, opos);
2274 mNextObjectHint = opos+1;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002275 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002276 return obj;
2277 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002278
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002279 // Look backwards for it...
2280 while (opos > 0 && OBJS[opos] > DPOS) {
2281 opos--;
2282 }
2283 if (OBJS[opos] == DPOS) {
2284 // Found it!
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002285 ALOGV("Parcel %p found obj %zu at index %zu with backward search",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002286 this, DPOS, opos);
2287 mNextObjectHint = opos+1;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002288 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002289 return obj;
2290 }
2291 }
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002292 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 -07002293 this, DPOS);
2294 }
Yi Kong91635562018-06-07 14:38:36 -07002295 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002296}
2297
2298void Parcel::closeFileDescriptors()
2299{
2300 size_t i = mObjectsSize;
2301 if (i > 0) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002302 //ALOGI("Closing file descriptors for %zu objects...", i);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002303 }
2304 while (i > 0) {
2305 i--;
2306 const flat_binder_object* flat
2307 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002308 if (flat->hdr.type == BINDER_TYPE_FD) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002309 //ALOGI("Closing fd: %ld", flat->handle);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002310 close(flat->handle);
2311 }
2312 }
2313}
2314
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002315uintptr_t Parcel::ipcData() const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002316{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002317 return reinterpret_cast<uintptr_t>(mData);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002318}
2319
2320size_t Parcel::ipcDataSize() const
2321{
2322 return (mDataSize > mDataPos ? mDataSize : mDataPos);
2323}
2324
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002325uintptr_t Parcel::ipcObjects() const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002326{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002327 return reinterpret_cast<uintptr_t>(mObjects);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002328}
2329
2330size_t Parcel::ipcObjectsCount() const
2331{
2332 return mObjectsSize;
2333}
2334
2335void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002336 const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002337{
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002338 binder_size_t minOffset = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002339 freeDataNoInit();
2340 mError = NO_ERROR;
2341 mData = const_cast<uint8_t*>(data);
2342 mDataSize = mDataCapacity = dataSize;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002343 //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)", this, mDataSize, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002344 mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002345 ALOGV("setDataReference Setting data pos of %p to %zu", this, mDataPos);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002346 mObjects = const_cast<binder_size_t*>(objects);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002347 mObjectsSize = mObjectsCapacity = objectsCount;
2348 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002349 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002350 mOwner = relFunc;
2351 mOwnerCookie = relCookie;
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002352 for (size_t i = 0; i < mObjectsSize; i++) {
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002353 binder_size_t offset = mObjects[i];
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002354 if (offset < minOffset) {
Dan Albert3bdc5b82014-11-20 11:50:23 -08002355 ALOGE("%s: bad object offset %" PRIu64 " < %" PRIu64 "\n",
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002356 __func__, (uint64_t)offset, (uint64_t)minOffset);
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002357 mObjectsSize = 0;
2358 break;
2359 }
2360 minOffset = offset + sizeof(flat_binder_object);
2361 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002362 scanForFds();
2363}
2364
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002365void Parcel::print(TextOutput& to, uint32_t /*flags*/) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002366{
2367 to << "Parcel(";
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002368
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002369 if (errorCheck() != NO_ERROR) {
2370 const status_t err = errorCheck();
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002371 to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\"";
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002372 } else if (dataSize() > 0) {
2373 const uint8_t* DATA = data();
2374 to << indent << HexDump(DATA, dataSize()) << dedent;
Steven Moreland8bd01352019-07-15 16:36:14 -07002375 const binder_size_t* OBJS = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002376 const size_t N = objectsCount();
2377 for (size_t i=0; i<N; i++) {
2378 const flat_binder_object* flat
2379 = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
2380 to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002381 << TypeCode(flat->hdr.type & 0x7f7f7f00)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002382 << " = " << flat->binder;
2383 }
2384 } else {
2385 to << "NULL";
2386 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002387
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002388 to << ")";
2389}
2390
2391void Parcel::releaseObjects()
2392{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002393 size_t i = mObjectsSize;
Martijn Coenen69390d42018-10-22 15:18:10 +02002394 if (i == 0) {
2395 return;
2396 }
2397 sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002398 uint8_t* const data = mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002399 binder_size_t* const objects = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002400 while (i > 0) {
2401 i--;
2402 const flat_binder_object* flat
2403 = reinterpret_cast<flat_binder_object*>(data+objects[i]);
Adrian Rooscbf37262015-10-22 16:12:53 -07002404 release_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002405 }
2406}
2407
2408void Parcel::acquireObjects()
2409{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002410 size_t i = mObjectsSize;
Martijn Coenen69390d42018-10-22 15:18:10 +02002411 if (i == 0) {
2412 return;
2413 }
2414 const sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002415 uint8_t* const data = mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002416 binder_size_t* const objects = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002417 while (i > 0) {
2418 i--;
2419 const flat_binder_object* flat
2420 = reinterpret_cast<flat_binder_object*>(data+objects[i]);
Adrian Rooscbf37262015-10-22 16:12:53 -07002421 acquire_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002422 }
2423}
2424
2425void Parcel::freeData()
2426{
2427 freeDataNoInit();
2428 initState();
2429}
2430
2431void Parcel::freeDataNoInit()
2432{
2433 if (mOwner) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002434 LOG_ALLOC("Parcel %p: freeing other owner data", this);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002435 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002436 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
2437 } else {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002438 LOG_ALLOC("Parcel %p: freeing allocated data", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002439 releaseObjects();
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002440 if (mData) {
2441 LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002442 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dan Austin48fd7b42015-09-10 13:46:02 -07002443 if (mDataCapacity <= gParcelGlobalAllocSize) {
2444 gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity;
2445 } else {
2446 gParcelGlobalAllocSize = 0;
2447 }
2448 if (gParcelGlobalAllocCount > 0) {
2449 gParcelGlobalAllocCount--;
2450 }
Dianne Hackborna4cff882014-11-13 17:07:40 -08002451 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002452 free(mData);
2453 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002454 if (mObjects) free(mObjects);
2455 }
2456}
2457
2458status_t Parcel::growData(size_t len)
2459{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002460 if (len > INT32_MAX) {
2461 // don't accept size_t values which may have come from an
2462 // inadvertent conversion from a negative int.
2463 return BAD_VALUE;
2464 }
2465
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002466 size_t newSize = ((mDataSize+len)*3)/2;
2467 return (newSize <= mDataSize)
2468 ? (status_t) NO_MEMORY
2469 : continueWrite(newSize);
2470}
2471
2472status_t Parcel::restartWrite(size_t desired)
2473{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002474 if (desired > INT32_MAX) {
2475 // don't accept size_t values which may have come from an
2476 // inadvertent conversion from a negative int.
2477 return BAD_VALUE;
2478 }
2479
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002480 if (mOwner) {
2481 freeData();
2482 return continueWrite(desired);
2483 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002484
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002485 uint8_t* data = (uint8_t*)realloc(mData, desired);
2486 if (!data && desired > mDataCapacity) {
2487 mError = NO_MEMORY;
2488 return NO_MEMORY;
2489 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002490
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002491 releaseObjects();
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002492
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002493 if (data) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002494 LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002495 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002496 gParcelGlobalAllocSize += desired;
2497 gParcelGlobalAllocSize -= mDataCapacity;
Colin Cross83ec65e2015-12-08 17:15:50 -08002498 if (!mData) {
2499 gParcelGlobalAllocCount++;
2500 }
Dianne Hackborna4cff882014-11-13 17:07:40 -08002501 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002502 mData = data;
2503 mDataCapacity = desired;
2504 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002505
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002506 mDataSize = mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002507 ALOGV("restartWrite Setting data size of %p to %zu", this, mDataSize);
2508 ALOGV("restartWrite Setting data pos of %p to %zu", this, mDataPos);
2509
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002510 free(mObjects);
Yi Kong91635562018-06-07 14:38:36 -07002511 mObjects = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002512 mObjectsSize = mObjectsCapacity = 0;
2513 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002514 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002515 mHasFds = false;
2516 mFdsKnown = true;
Dianne Hackborn8938ed22011-09-28 23:19:47 -04002517 mAllowFds = true;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002518
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002519 return NO_ERROR;
2520}
2521
2522status_t Parcel::continueWrite(size_t desired)
2523{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002524 if (desired > INT32_MAX) {
2525 // don't accept size_t values which may have come from an
2526 // inadvertent conversion from a negative int.
2527 return BAD_VALUE;
2528 }
2529
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002530 // If shrinking, first adjust for any objects that appear
2531 // after the new data size.
2532 size_t objectsSize = mObjectsSize;
2533 if (desired < mDataSize) {
2534 if (desired == 0) {
2535 objectsSize = 0;
2536 } else {
2537 while (objectsSize > 0) {
Michael Wachenschwanza6541632017-05-18 22:08:32 +00002538 if (mObjects[objectsSize-1] < desired)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002539 break;
2540 objectsSize--;
2541 }
2542 }
2543 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002544
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002545 if (mOwner) {
2546 // If the size is going to zero, just release the owner's data.
2547 if (desired == 0) {
2548 freeData();
2549 return NO_ERROR;
2550 }
2551
2552 // If there is a different owner, we need to take
2553 // posession.
2554 uint8_t* data = (uint8_t*)malloc(desired);
2555 if (!data) {
2556 mError = NO_MEMORY;
2557 return NO_MEMORY;
2558 }
Yi Kong91635562018-06-07 14:38:36 -07002559 binder_size_t* objects = nullptr;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002560
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002561 if (objectsSize) {
Nick Kraleviche9881a32015-04-28 16:21:30 -07002562 objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002563 if (!objects) {
Hyejin Kim3f727c02013-03-09 11:28:54 +09002564 free(data);
2565
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002566 mError = NO_MEMORY;
2567 return NO_MEMORY;
2568 }
2569
2570 // Little hack to only acquire references on objects
2571 // we will be keeping.
2572 size_t oldObjectsSize = mObjectsSize;
2573 mObjectsSize = objectsSize;
2574 acquireObjects();
2575 mObjectsSize = oldObjectsSize;
2576 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002577
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002578 if (mData) {
2579 memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
2580 }
2581 if (objects && mObjects) {
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002582 memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002583 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002584 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002585 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
Yi Kong91635562018-06-07 14:38:36 -07002586 mOwner = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002587
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002588 LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002589 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002590 gParcelGlobalAllocSize += desired;
2591 gParcelGlobalAllocCount++;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002592 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002593
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002594 mData = data;
2595 mObjects = objects;
2596 mDataSize = (mDataSize < desired) ? mDataSize : desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002597 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002598 mDataCapacity = desired;
2599 mObjectsSize = mObjectsCapacity = objectsSize;
2600 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002601 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002602
2603 } else if (mData) {
2604 if (objectsSize < mObjectsSize) {
2605 // Need to release refs on any objects we are dropping.
2606 const sp<ProcessState> proc(ProcessState::self());
2607 for (size_t i=objectsSize; i<mObjectsSize; i++) {
2608 const flat_binder_object* flat
2609 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002610 if (flat->hdr.type == BINDER_TYPE_FD) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002611 // will need to rescan because we may have lopped off the only FDs
2612 mFdsKnown = false;
2613 }
Adrian Rooscbf37262015-10-22 16:12:53 -07002614 release_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002615 }
Michael Wachenschwanz6af27a82019-06-03 17:24:51 -07002616
2617 if (objectsSize == 0) {
2618 free(mObjects);
2619 mObjects = nullptr;
2620 } else {
2621 binder_size_t* objects =
2622 (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
2623 if (objects) {
2624 mObjects = objects;
2625 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002626 }
2627 mObjectsSize = objectsSize;
2628 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002629 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002630 }
2631
2632 // We own the data, so we can just do a realloc().
2633 if (desired > mDataCapacity) {
2634 uint8_t* data = (uint8_t*)realloc(mData, desired);
2635 if (data) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002636 LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity,
2637 desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002638 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002639 gParcelGlobalAllocSize += desired;
2640 gParcelGlobalAllocSize -= mDataCapacity;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002641 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002642 mData = data;
2643 mDataCapacity = desired;
Ganesh Mahendranade89892017-09-28 16:56:03 +08002644 } else {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002645 mError = NO_MEMORY;
2646 return NO_MEMORY;
2647 }
2648 } else {
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -07002649 if (mDataSize > desired) {
2650 mDataSize = desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002651 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -07002652 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002653 if (mDataPos > desired) {
2654 mDataPos = desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002655 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002656 }
2657 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002658
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002659 } else {
2660 // This is the first data. Easy!
2661 uint8_t* data = (uint8_t*)malloc(desired);
2662 if (!data) {
2663 mError = NO_MEMORY;
2664 return NO_MEMORY;
2665 }
Hyejin Kim3f727c02013-03-09 11:28:54 +09002666
Yi Kong91635562018-06-07 14:38:36 -07002667 if(!(mDataCapacity == 0 && mObjects == nullptr
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002668 && mObjectsCapacity == 0)) {
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002669 ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002670 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002671
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002672 LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002673 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002674 gParcelGlobalAllocSize += desired;
2675 gParcelGlobalAllocCount++;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002676 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002677
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002678 mData = data;
2679 mDataSize = mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002680 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
2681 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002682 mDataCapacity = desired;
2683 }
2684
2685 return NO_ERROR;
2686}
2687
2688void Parcel::initState()
2689{
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002690 LOG_ALLOC("Parcel %p: initState", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002691 mError = NO_ERROR;
Yi Kong91635562018-06-07 14:38:36 -07002692 mData = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002693 mDataSize = 0;
2694 mDataCapacity = 0;
2695 mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002696 ALOGV("initState Setting data size of %p to %zu", this, mDataSize);
2697 ALOGV("initState Setting data pos of %p to %zu", this, mDataPos);
Yi Kong91635562018-06-07 14:38:36 -07002698 mObjects = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002699 mObjectsSize = 0;
2700 mObjectsCapacity = 0;
2701 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002702 mObjectsSorted = false;
Steven Morelanda86a3562019-08-01 23:28:34 +00002703 mAllowFds = true;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002704 mHasFds = false;
2705 mFdsKnown = true;
Steven Morelanda86a3562019-08-01 23:28:34 +00002706 mRequiredStability = internal::Stability::UNDECLARED;
Yi Kong91635562018-06-07 14:38:36 -07002707 mOwner = nullptr;
Adrian Rooscbf37262015-10-22 16:12:53 -07002708 mOpenAshmemSize = 0;
Olivier Gaillarddc848a02019-01-30 17:10:44 +00002709 mWorkSourceRequestHeaderPosition = 0;
2710 mRequestHeaderPresent = false;
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002711
2712 // racing multiple init leads only to multiple identical write
2713 if (gMaxFds == 0) {
2714 struct rlimit result;
2715 if (!getrlimit(RLIMIT_NOFILE, &result)) {
2716 gMaxFds = (size_t)result.rlim_cur;
Christopher Tatebf14e942016-03-25 14:16:24 -07002717 //ALOGI("parcel fd limit set to %zu", gMaxFds);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002718 } else {
2719 ALOGW("Unable to getrlimit: %s", strerror(errno));
2720 gMaxFds = 1024;
2721 }
2722 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002723}
2724
2725void Parcel::scanForFds() const
2726{
2727 bool hasFds = false;
2728 for (size_t i=0; i<mObjectsSize; i++) {
2729 const flat_binder_object* flat
2730 = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002731 if (flat->hdr.type == BINDER_TYPE_FD) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002732 hasFds = true;
2733 break;
2734 }
2735 }
2736 mHasFds = hasFds;
2737 mFdsKnown = true;
2738}
2739
Dan Sandleraa5c2342015-04-10 10:08:45 -04002740size_t Parcel::getBlobAshmemSize() const
2741{
Adrian Roos6bb31142015-10-22 16:46:12 -07002742 // This used to return the size of all blobs that were written to ashmem, now we're returning
2743 // the ashmem currently referenced by this Parcel, which should be equivalent.
2744 // TODO: Remove method once ABI can be changed.
2745 return mOpenAshmemSize;
Dan Sandleraa5c2342015-04-10 10:08:45 -04002746}
2747
Adrian Rooscbf37262015-10-22 16:12:53 -07002748size_t Parcel::getOpenAshmemSize() const
2749{
2750 return mOpenAshmemSize;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002751}
2752
2753// --- Parcel::Blob ---
2754
2755Parcel::Blob::Blob() :
Yi Kong91635562018-06-07 14:38:36 -07002756 mFd(-1), mData(nullptr), mSize(0), mMutable(false) {
Jeff Brown5707dbf2011-09-23 21:17:56 -07002757}
2758
2759Parcel::Blob::~Blob() {
2760 release();
2761}
2762
2763void Parcel::Blob::release() {
Jeff Brown13b16042014-11-11 16:44:25 -08002764 if (mFd != -1 && mData) {
Jeff Brown5707dbf2011-09-23 21:17:56 -07002765 ::munmap(mData, mSize);
2766 }
2767 clear();
2768}
2769
Jeff Brown13b16042014-11-11 16:44:25 -08002770void Parcel::Blob::init(int fd, void* data, size_t size, bool isMutable) {
2771 mFd = fd;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002772 mData = data;
2773 mSize = size;
Jeff Brown13b16042014-11-11 16:44:25 -08002774 mMutable = isMutable;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002775}
2776
2777void Parcel::Blob::clear() {
Jeff Brown13b16042014-11-11 16:44:25 -08002778 mFd = -1;
Yi Kong91635562018-06-07 14:38:36 -07002779 mData = nullptr;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002780 mSize = 0;
Jeff Brown13b16042014-11-11 16:44:25 -08002781 mMutable = false;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002782}
2783
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002784}; // namespace android