blob: fe592db907bda17e8527ac0626a2d12225044f3b [file] [log] [blame]
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001/*
2 * Copyright (C) 2005 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Parcel"
18//#define LOG_NDEBUG 0
19
Mark Salyzynabed7f72016-01-27 08:02:48 -080020#include <errno.h>
Mark Salyzyn70f36652016-02-02 10:27:03 -080021#include <fcntl.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080022#include <inttypes.h>
Steven Morelandbf1915b2020-07-16 22:43:02 +000023#include <linux/sched.h>
Mark Salyzyn70f36652016-02-02 10:27:03 -080024#include <pthread.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080025#include <stdint.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <sys/mman.h>
Mark Salyzyneab2afc2016-01-27 08:02:48 -080029#include <sys/stat.h>
30#include <sys/types.h>
Christopher Tatee4e0ae82016-03-24 16:03:44 -070031#include <sys/resource.h>
Mark Salyzyneab2afc2016-01-27 08:02:48 -080032#include <unistd.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070033
Mathias Agopianc5b2c0b2009-05-19 19:08:10 -070034#include <binder/Binder.h>
35#include <binder/BpBinder.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080036#include <binder/IPCThreadState.h>
37#include <binder/Parcel.h>
Mathias Agopianc5b2c0b2009-05-19 19:08:10 -070038#include <binder/ProcessState.h>
Steven Moreland6e5a7752019-08-05 20:30:14 -070039#include <binder/Stability.h>
Christopher Wiley09eb7492015-11-09 15:06:15 -080040#include <binder/Status.h>
Mathias Agopian002e1e52013-05-06 20:20:50 -070041#include <binder/TextOutput.h>
42
Mark Salyzynabed7f72016-01-27 08:02:48 -080043#include <cutils/ashmem.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080044#include <utils/Flattenable.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070045#include <utils/Log.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080046#include <utils/misc.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070047#include <utils/String8.h>
48#include <utils/String16.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070049
Mathias Agopian208059f2009-05-18 15:08:03 -070050#include <private/binder/binder_module.h>
Steven Morelanda4853cd2019-07-12 15:44:37 -070051#include "Static.h"
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070052
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070053#define LOG_REFS(...)
Mark Salyzyne93390b2016-01-27 08:02:48 -080054//#define LOG_REFS(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
Dianne Hackborn7e790af2014-11-11 12:22:53 -080055#define LOG_ALLOC(...)
Mark Salyzyne93390b2016-01-27 08:02:48 -080056//#define LOG_ALLOC(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070057
58// ---------------------------------------------------------------------------
59
Nick Kralevichb6b14232015-04-02 09:36:02 -070060// This macro should never be used at runtime, as a too large value
61// of s could cause an integer overflow. Instead, you should always
62// use the wrapper function pad_size()
63#define PAD_SIZE_UNSAFE(s) (((s)+3)&~3)
64
65static size_t pad_size(size_t s) {
Steven Moreland28723ae2019-04-01 18:52:30 -070066 if (s > (std::numeric_limits<size_t>::max() - 3)) {
Steven Moreland6adf33c2019-09-25 13:18:09 -070067 LOG_ALWAYS_FATAL("pad size too big %zu", s);
Nick Kralevichb6b14232015-04-02 09:36:02 -070068 }
69 return PAD_SIZE_UNSAFE(s);
70}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070071
Brad Fitzpatricka877cd82010-07-07 16:06:39 -070072// Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
Jeff Sharkey05827be2018-06-26 10:52:38 -060073#define STRICT_MODE_PENALTY_GATHER (1 << 31)
Brad Fitzpatricka877cd82010-07-07 16:06:39 -070074
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070075namespace android {
76
Steven Moreland7b102262019-08-01 15:48:43 -070077// many things compile this into prebuilts on the stack
78static_assert(sizeof(Parcel) == 60 || sizeof(Parcel) == 120);
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
Steven Moreland6e5a7752019-08-05 20:30:14 -0700173 internal::Stability::tryMarkCompilationUnit(binder.get());
Steven Morelanda86a3562019-08-01 23:28:34 +0000174 return writeInt32(internal::Stability::get(binder.get()));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700175}
176
Steven Morelanda86a3562019-08-01 23:28:34 +0000177status_t Parcel::finishUnflattenBinder(
178 const sp<IBinder>& binder, sp<IBinder>* out) const
179{
180 int32_t stability;
181 status_t status = readInt32(&stability);
182 if (status != OK) return status;
183
Steven Moreland05929552019-07-31 17:51:25 -0700184 status = internal::Stability::set(binder.get(), stability, true /*log*/);
Steven Morelanda86a3562019-08-01 23:28:34 +0000185 if (status != OK) return status;
186
187 *out = binder;
188 return OK;
189}
190
Steven Morelandbf1915b2020-07-16 22:43:02 +0000191static constexpr inline int schedPolicyMask(int policy, int priority) {
192 return (priority & FLAT_BINDER_FLAG_PRIORITY_MASK) | ((policy & 3) << FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT);
193}
194
Steven Morelanda86a3562019-08-01 23:28:34 +0000195status_t Parcel::flattenBinder(const sp<IBinder>& binder)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700196{
197 flat_binder_object obj;
Steven Morelandbf1915b2020-07-16 22:43:02 +0000198 obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700199
Steven Morelandbf1915b2020-07-16 22:43:02 +0000200 int schedBits = 0;
201 if (!IPCThreadState::self()->backgroundSchedulingDisabled()) {
202 schedBits = schedPolicyMask(SCHED_NORMAL, 19);
Martijn Coenen2b631742017-05-05 11:16:59 -0700203 }
204
Yi Kong91635562018-06-07 14:38:36 -0700205 if (binder != nullptr) {
Steven Morelandf0212002018-12-26 13:59:23 -0800206 BBinder *local = binder->localBinder();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700207 if (!local) {
208 BpBinder *proxy = binder->remoteBinder();
Yi Kong91635562018-06-07 14:38:36 -0700209 if (proxy == nullptr) {
Steve Blocke6f43dd2012-01-06 19:20:56 +0000210 ALOGE("null proxy");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700211 }
212 const int32_t handle = proxy ? proxy->handle() : 0;
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700213 obj.hdr.type = BINDER_TYPE_HANDLE;
Arve Hjønnevåg07fd0f12014-02-18 21:10:29 -0800214 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700215 obj.handle = handle;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800216 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700217 } else {
Steven Morelandbf1915b2020-07-16 22:43:02 +0000218 int policy = local->getMinSchedulerPolicy();
219 int priority = local->getMinSchedulerPriority();
220
221 if (policy != 0 || priority != 0) {
222 // override value, since it is set explicitly
223 schedBits = schedPolicyMask(policy, priority);
224 }
Steven Morelandf0212002018-12-26 13:59:23 -0800225 if (local->isRequestingSid()) {
226 obj.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
227 }
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700228 obj.hdr.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800229 obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
230 obj.cookie = reinterpret_cast<uintptr_t>(local);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700231 }
232 } else {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700233 obj.hdr.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800234 obj.binder = 0;
235 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700236 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700237
Steven Morelandbf1915b2020-07-16 22:43:02 +0000238 obj.flags |= schedBits;
239
Steven Morelanda86a3562019-08-01 23:28:34 +0000240 return finishFlattenBinder(binder, obj);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700241}
242
Steven Morelanda86a3562019-08-01 23:28:34 +0000243status_t Parcel::unflattenBinder(sp<IBinder>* out) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700244{
Steven Morelanda86a3562019-08-01 23:28:34 +0000245 const flat_binder_object* flat = readObject(false);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700246
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700247 if (flat) {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700248 switch (flat->hdr.type) {
Steven Morelanda86a3562019-08-01 23:28:34 +0000249 case BINDER_TYPE_BINDER: {
250 sp<IBinder> binder = reinterpret_cast<IBinder*>(flat->cookie);
251 return finishUnflattenBinder(binder, out);
252 }
253 case BINDER_TYPE_HANDLE: {
254 sp<IBinder> binder =
255 ProcessState::self()->getStrongProxyForHandle(flat->handle);
256 return finishUnflattenBinder(binder, out);
257 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700258 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700259 }
260 return BAD_TYPE;
261}
262
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700263// ---------------------------------------------------------------------------
264
265Parcel::Parcel()
266{
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800267 LOG_ALLOC("Parcel %p: constructing", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700268 initState();
269}
270
271Parcel::~Parcel()
272{
273 freeDataNoInit();
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800274 LOG_ALLOC("Parcel %p: destroyed", this);
275}
276
277size_t Parcel::getGlobalAllocSize() {
Dianne Hackborna4cff882014-11-13 17:07:40 -0800278 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
279 size_t size = gParcelGlobalAllocSize;
280 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
281 return size;
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800282}
283
284size_t Parcel::getGlobalAllocCount() {
Dianne Hackborna4cff882014-11-13 17:07:40 -0800285 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
286 size_t count = gParcelGlobalAllocCount;
287 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
288 return count;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700289}
290
291const uint8_t* Parcel::data() const
292{
293 return mData;
294}
295
296size_t Parcel::dataSize() const
297{
298 return (mDataSize > mDataPos ? mDataSize : mDataPos);
299}
300
301size_t Parcel::dataAvail() const
302{
Nick Kralevichcfe27de2015-09-16 09:49:15 -0700303 size_t result = dataSize() - dataPosition();
304 if (result > INT32_MAX) {
Steven Moreland6adf33c2019-09-25 13:18:09 -0700305 LOG_ALWAYS_FATAL("result too big: %zu", result);
Nick Kralevichcfe27de2015-09-16 09:49:15 -0700306 }
307 return result;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700308}
309
310size_t Parcel::dataPosition() const
311{
312 return mDataPos;
313}
314
315size_t Parcel::dataCapacity() const
316{
317 return mDataCapacity;
318}
319
320status_t Parcel::setDataSize(size_t size)
321{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700322 if (size > INT32_MAX) {
323 // don't accept size_t values which may have come from an
324 // inadvertent conversion from a negative int.
325 return BAD_VALUE;
326 }
327
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700328 status_t err;
329 err = continueWrite(size);
330 if (err == NO_ERROR) {
331 mDataSize = size;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700332 ALOGV("setDataSize Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700333 }
334 return err;
335}
336
337void Parcel::setDataPosition(size_t pos) const
338{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700339 if (pos > INT32_MAX) {
340 // don't accept size_t values which may have come from an
341 // inadvertent conversion from a negative int.
Steven Moreland6adf33c2019-09-25 13:18:09 -0700342 LOG_ALWAYS_FATAL("pos too big: %zu", pos);
Nick Kralevichb6b14232015-04-02 09:36:02 -0700343 }
344
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700345 mDataPos = pos;
346 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -0800347 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700348}
349
350status_t Parcel::setDataCapacity(size_t size)
351{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700352 if (size > INT32_MAX) {
353 // don't accept size_t values which may have come from an
354 // inadvertent conversion from a negative int.
355 return BAD_VALUE;
356 }
357
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -0700358 if (size > mDataCapacity) return continueWrite(size);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700359 return NO_ERROR;
360}
361
362status_t Parcel::setData(const uint8_t* buffer, size_t len)
363{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700364 if (len > INT32_MAX) {
365 // don't accept size_t values which may have come from an
366 // inadvertent conversion from a negative int.
367 return BAD_VALUE;
368 }
369
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700370 status_t err = restartWrite(len);
371 if (err == NO_ERROR) {
372 memcpy(const_cast<uint8_t*>(data()), buffer, len);
373 mDataSize = len;
374 mFdsKnown = false;
375 }
376 return err;
377}
378
Andreas Huber51faf462011-04-13 10:21:56 -0700379status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700380{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700381 status_t err;
Andreas Huber51faf462011-04-13 10:21:56 -0700382 const uint8_t *data = parcel->mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800383 const binder_size_t *objects = parcel->mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700384 size_t size = parcel->mObjectsSize;
385 int startPos = mDataPos;
386 int firstIndex = -1, lastIndex = -2;
387
388 if (len == 0) {
389 return NO_ERROR;
390 }
391
Nick Kralevichb6b14232015-04-02 09:36:02 -0700392 if (len > INT32_MAX) {
393 // don't accept size_t values which may have come from an
394 // inadvertent conversion from a negative int.
395 return BAD_VALUE;
396 }
397
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700398 // range checks against the source parcel size
399 if ((offset > parcel->mDataSize)
400 || (len > parcel->mDataSize)
401 || (offset + len > parcel->mDataSize)) {
402 return BAD_VALUE;
403 }
404
405 // Count objects in range
406 for (int i = 0; i < (int) size; i++) {
407 size_t off = objects[i];
Christopher Tate27182be2015-05-27 17:53:02 -0700408 if ((off >= offset) && (off + sizeof(flat_binder_object) <= offset + len)) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700409 if (firstIndex == -1) {
410 firstIndex = i;
411 }
412 lastIndex = i;
413 }
414 }
415 int numObjects = lastIndex - firstIndex + 1;
416
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -0700417 if ((mDataSize+len) > mDataCapacity) {
418 // grow data
419 err = growData(len);
420 if (err != NO_ERROR) {
421 return err;
422 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700423 }
424
425 // append data
426 memcpy(mData + mDataPos, data + offset, len);
427 mDataPos += len;
428 mDataSize += len;
429
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400430 err = NO_ERROR;
431
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700432 if (numObjects > 0) {
Martijn Coenen69390d42018-10-22 15:18:10 +0200433 const sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700434 // grow objects
435 if (mObjectsCapacity < mObjectsSize + numObjects) {
Martijn Coenenda2f2fd2020-01-22 10:46:25 +0100436 if ((size_t) numObjects > SIZE_MAX - mObjectsSize) return NO_MEMORY; // overflow
437 if (mObjectsSize + numObjects > SIZE_MAX / 3) return NO_MEMORY; // overflow
Christopher Tateed7a50c2015-06-08 14:45:14 -0700438 size_t newSize = ((mObjectsSize + numObjects)*3)/2;
Martijn Coenenda2f2fd2020-01-22 10:46:25 +0100439 if (newSize > SIZE_MAX / sizeof(binder_size_t)) return NO_MEMORY; // overflow
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800440 binder_size_t *objects =
441 (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
Yi Kong91635562018-06-07 14:38:36 -0700442 if (objects == (binder_size_t*)nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700443 return NO_MEMORY;
444 }
445 mObjects = objects;
446 mObjectsCapacity = newSize;
447 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700448
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700449 // append and acquire objects
450 int idx = mObjectsSize;
451 for (int i = firstIndex; i <= lastIndex; i++) {
452 size_t off = objects[i] - offset + startPos;
453 mObjects[idx++] = off;
454 mObjectsSize++;
455
Dianne Hackborn8af0f822009-05-22 13:20:23 -0700456 flat_binder_object* flat
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700457 = reinterpret_cast<flat_binder_object*>(mData + off);
Adrian Rooscbf37262015-10-22 16:12:53 -0700458 acquire_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700459
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700460 if (flat->hdr.type == BINDER_TYPE_FD) {
Dianne Hackborn8af0f822009-05-22 13:20:23 -0700461 // If this is a file descriptor, we need to dup it so the
462 // new Parcel now owns its own fd, and can declare that we
463 // officially know we have fds.
Nick Kralevichec9ec7d2016-12-17 19:47:27 -0800464 flat->handle = fcntl(flat->handle, F_DUPFD_CLOEXEC, 0);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800465 flat->cookie = 1;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700466 mHasFds = mFdsKnown = true;
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400467 if (!mAllowFds) {
468 err = FDS_NOT_ALLOWED;
469 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700470 }
471 }
472 }
473
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400474 return err;
475}
476
Dianne Hackborn15feb9b2017-04-10 15:34:35 -0700477int Parcel::compareData(const Parcel& other) {
478 size_t size = dataSize();
479 if (size != other.dataSize()) {
480 return size < other.dataSize() ? -1 : 1;
481 }
482 return memcmp(data(), other.data(), size);
483}
484
Jeff Brown13b16042014-11-11 16:44:25 -0800485bool Parcel::allowFds() const
486{
487 return mAllowFds;
488}
489
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700490bool Parcel::pushAllowFds(bool allowFds)
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400491{
492 const bool origValue = mAllowFds;
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700493 if (!allowFds) {
494 mAllowFds = false;
495 }
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400496 return origValue;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700497}
498
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700499void Parcel::restoreAllowFds(bool lastValue)
500{
501 mAllowFds = lastValue;
502}
503
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700504bool Parcel::hasFileDescriptors() const
505{
506 if (!mFdsKnown) {
507 scanForFds();
508 }
509 return mHasFds;
510}
511
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000512void Parcel::updateWorkSourceRequestHeaderPosition() const {
513 // Only update the request headers once. We only want to point
514 // to the first headers read/written.
515 if (!mRequestHeaderPresent) {
516 mWorkSourceRequestHeaderPosition = dataPosition();
517 mRequestHeaderPresent = true;
518 }
519}
520
Steven Moreland8852cc72020-08-18 18:15:03 +0000521#ifdef __ANDROID_APEX__
522#error APEX cannot include libbinder. The wire protocol for libbinder is not\
523 frozen, and including it in an APEX would also require APEX\
524 servicemanagers which is not an options. Use libbinder_ndk instead.
525#endif
526
527#if defined(__ANDROID_VNDK__)
Steven Moreland0f452742019-07-31 15:50:51 +0000528constexpr int32_t kHeader = B_PACK_CHARS('V', 'N', 'D', 'R');
529#else
530constexpr int32_t kHeader = B_PACK_CHARS('S', 'Y', 'S', 'T');
531#endif
532
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700533// Write RPC headers. (previously just the interface token)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700534status_t Parcel::writeInterfaceToken(const String16& interface)
535{
Olivier Gaillard91a04802018-11-14 17:32:41 +0000536 const IPCThreadState* threadState = IPCThreadState::self();
537 writeInt32(threadState->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER);
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000538 updateWorkSourceRequestHeaderPosition();
Olivier Gaillard91a04802018-11-14 17:32:41 +0000539 writeInt32(threadState->shouldPropagateWorkSource() ?
540 threadState->getCallingWorkSourceUid() : IPCThreadState::kUnsetWorkSource);
Steven Moreland0f452742019-07-31 15:50:51 +0000541 writeInt32(kHeader);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700542 // currently the interface identification token is just its name as a string
543 return writeString16(interface);
544}
545
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000546bool Parcel::replaceCallingWorkSourceUid(uid_t uid)
547{
548 if (!mRequestHeaderPresent) {
549 return false;
550 }
551
552 const size_t initialPosition = dataPosition();
553 setDataPosition(mWorkSourceRequestHeaderPosition);
554 status_t err = writeInt32(uid);
555 setDataPosition(initialPosition);
556 return err == NO_ERROR;
557}
558
Steven Moreland0891c9b2019-05-06 15:05:13 -0700559uid_t Parcel::readCallingWorkSourceUid() const
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000560{
561 if (!mRequestHeaderPresent) {
562 return IPCThreadState::kUnsetWorkSource;
563 }
564
565 const size_t initialPosition = dataPosition();
566 setDataPosition(mWorkSourceRequestHeaderPosition);
567 uid_t uid = readInt32();
568 setDataPosition(initialPosition);
569 return uid;
570}
571
Mathias Agopian83c04462009-05-22 19:00:22 -0700572bool Parcel::checkInterface(IBinder* binder) const
573{
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700574 return enforceInterface(binder->getInterfaceDescriptor());
Mathias Agopian83c04462009-05-22 19:00:22 -0700575}
576
Brad Fitzpatricka877cd82010-07-07 16:06:39 -0700577bool Parcel::enforceInterface(const String16& interface,
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700578 IPCThreadState* threadState) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700579{
Daniel Colascione0bb330d2019-10-29 16:44:19 -0700580 return enforceInterface(interface.string(), interface.size(), threadState);
581}
582
583bool Parcel::enforceInterface(const char16_t* interface,
584 size_t len,
585 IPCThreadState* threadState) const
586{
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100587 // StrictModePolicy.
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700588 int32_t strictPolicy = readInt32();
Yi Kong91635562018-06-07 14:38:36 -0700589 if (threadState == nullptr) {
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700590 threadState = IPCThreadState::self();
Brad Fitzpatricka877cd82010-07-07 16:06:39 -0700591 }
Brad Fitzpatrick52736032010-08-30 16:01:16 -0700592 if ((threadState->getLastTransactionBinderFlags() &
593 IBinder::FLAG_ONEWAY) != 0) {
594 // For one-way calls, the callee is running entirely
595 // disconnected from the caller, so disable StrictMode entirely.
596 // Not only does disk/network usage not impact the caller, but
597 // there's no way to commuicate back any violations anyway.
598 threadState->setStrictModePolicy(0);
599 } else {
600 threadState->setStrictModePolicy(strictPolicy);
601 }
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100602 // WorkSource.
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000603 updateWorkSourceRequestHeaderPosition();
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100604 int32_t workSource = readInt32();
Olivier Gaillard91a04802018-11-14 17:32:41 +0000605 threadState->setCallingWorkSourceUidWithoutPropagation(workSource);
Steven Moreland0f452742019-07-31 15:50:51 +0000606 // vendor header
607 int32_t header = readInt32();
608 if (header != kHeader) {
609 ALOGE("Expecting header 0x%x but found 0x%x. Mixing copies of libbinder?", kHeader, header);
610 return false;
611 }
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100612 // Interface descriptor.
Daniel Colascione0bb330d2019-10-29 16:44:19 -0700613 size_t parcel_interface_len;
614 const char16_t* parcel_interface = readString16Inplace(&parcel_interface_len);
615 if (len == parcel_interface_len &&
616 (!len || !memcmp(parcel_interface, interface, len * sizeof (char16_t)))) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700617 return true;
618 } else {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700619 ALOGW("**** enforceInterface() expected '%s' but read '%s'",
Daniel Colascione0bb330d2019-10-29 16:44:19 -0700620 String8(interface, len).string(),
621 String8(parcel_interface, parcel_interface_len).string());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700622 return false;
623 }
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700624}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700625
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700626size_t Parcel::objectsCount() const
627{
628 return mObjectsSize;
629}
630
631status_t Parcel::errorCheck() const
632{
633 return mError;
634}
635
636void Parcel::setError(status_t err)
637{
638 mError = err;
639}
640
641status_t Parcel::finishWrite(size_t len)
642{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700643 if (len > INT32_MAX) {
644 // don't accept size_t values which may have come from an
645 // inadvertent conversion from a negative int.
646 return BAD_VALUE;
647 }
648
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700649 //printf("Finish write of %d\n", len);
650 mDataPos += len;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700651 ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700652 if (mDataPos > mDataSize) {
653 mDataSize = mDataPos;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700654 ALOGV("finishWrite Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700655 }
656 //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
657 return NO_ERROR;
658}
659
660status_t Parcel::writeUnpadded(const void* data, size_t len)
661{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700662 if (len > INT32_MAX) {
663 // don't accept size_t values which may have come from an
664 // inadvertent conversion from a negative int.
665 return BAD_VALUE;
666 }
667
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700668 size_t end = mDataPos + len;
669 if (end < mDataPos) {
670 // integer overflow
671 return BAD_VALUE;
672 }
673
674 if (end <= mDataCapacity) {
675restart_write:
676 memcpy(mData+mDataPos, data, len);
677 return finishWrite(len);
678 }
679
680 status_t err = growData(len);
681 if (err == NO_ERROR) goto restart_write;
682 return err;
683}
684
685status_t Parcel::write(const void* data, size_t len)
686{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700687 if (len > INT32_MAX) {
688 // don't accept size_t values which may have come from an
689 // inadvertent conversion from a negative int.
690 return BAD_VALUE;
691 }
692
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700693 void* const d = writeInplace(len);
694 if (d) {
695 memcpy(d, data, len);
696 return NO_ERROR;
697 }
698 return mError;
699}
700
701void* Parcel::writeInplace(size_t len)
702{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700703 if (len > INT32_MAX) {
704 // don't accept size_t values which may have come from an
705 // inadvertent conversion from a negative int.
Yi Kong91635562018-06-07 14:38:36 -0700706 return nullptr;
Nick Kralevichb6b14232015-04-02 09:36:02 -0700707 }
708
709 const size_t padded = pad_size(len);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700710
711 // sanity check for integer overflow
712 if (mDataPos+padded < mDataPos) {
Yi Kong91635562018-06-07 14:38:36 -0700713 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700714 }
715
716 if ((mDataPos+padded) <= mDataCapacity) {
717restart_write:
718 //printf("Writing %ld bytes, padded to %ld\n", len, padded);
719 uint8_t* const data = mData+mDataPos;
720
721 // Need to pad at end?
722 if (padded != len) {
723#if BYTE_ORDER == BIG_ENDIAN
724 static const uint32_t mask[4] = {
725 0x00000000, 0xffffff00, 0xffff0000, 0xff000000
726 };
727#endif
728#if BYTE_ORDER == LITTLE_ENDIAN
729 static const uint32_t mask[4] = {
730 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
731 };
732#endif
733 //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
734 // *reinterpret_cast<void**>(data+padded-4));
735 *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
736 }
737
738 finishWrite(padded);
739 return data;
740 }
741
742 status_t err = growData(padded);
743 if (err == NO_ERROR) goto restart_write;
Yi Kong91635562018-06-07 14:38:36 -0700744 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700745}
746
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800747status_t Parcel::writeUtf8AsUtf16(const std::string& str) {
748 const uint8_t* strData = (uint8_t*)str.data();
749 const size_t strLen= str.length();
750 const ssize_t utf16Len = utf8_to_utf16_length(strData, strLen);
Sergio Girof4607432016-07-21 14:46:35 +0100751 if (utf16Len < 0 || utf16Len > std::numeric_limits<int32_t>::max()) {
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800752 return BAD_VALUE;
753 }
754
755 status_t err = writeInt32(utf16Len);
756 if (err) {
757 return err;
758 }
759
760 // Allocate enough bytes to hold our converted string and its terminating NULL.
761 void* dst = writeInplace((utf16Len + 1) * sizeof(char16_t));
762 if (!dst) {
763 return NO_MEMORY;
764 }
765
Sergio Girof4607432016-07-21 14:46:35 +0100766 utf8_to_utf16(strData, strLen, (char16_t*)dst, (size_t) utf16Len + 1);
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800767
768 return NO_ERROR;
769}
770
Jooyung Han2d5878e2020-01-23 12:45:10 +0900771status_t Parcel::writeUtf8AsUtf16(const std::optional<std::string>& str) {
772 if (!str) {
773 return writeInt32(-1);
774 }
775 return writeUtf8AsUtf16(*str);
776}
777
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800778status_t Parcel::writeUtf8AsUtf16(const std::unique_ptr<std::string>& str) {
779 if (!str) {
780 return writeInt32(-1);
781 }
782 return writeUtf8AsUtf16(*str);
783}
784
Daniel Normand0337ef2019-09-20 15:46:03 -0700785status_t Parcel::writeByteVectorInternal(const int8_t* data, size_t size) {
786 if (size > std::numeric_limits<int32_t>::max()) {
787 return BAD_VALUE;
Casey Dahlin451ff582015-10-19 18:12:18 -0700788 }
789
Daniel Normand0337ef2019-09-20 15:46:03 -0700790 status_t status = writeInt32(size);
Casey Dahlin451ff582015-10-19 18:12:18 -0700791 if (status != OK) {
792 return status;
793 }
794
Daniel Normand0337ef2019-09-20 15:46:03 -0700795 return write(data, size);
Casey Dahlin451ff582015-10-19 18:12:18 -0700796}
797
Casey Dahlin185d3442016-02-09 11:08:35 -0800798status_t Parcel::writeByteVector(const std::vector<int8_t>& val) {
Daniel Normand0337ef2019-09-20 15:46:03 -0700799 return writeByteVectorInternal(val.data(), val.size());
Casey Dahlin185d3442016-02-09 11:08:35 -0800800}
801
Jooyung Han2d5878e2020-01-23 12:45:10 +0900802status_t Parcel::writeByteVector(const std::optional<std::vector<int8_t>>& val)
803{
804 if (!val) return writeInt32(-1);
805 return writeByteVectorInternal(val->data(), val->size());
806}
807
Casey Dahlin185d3442016-02-09 11:08:35 -0800808status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val)
809{
Daniel Normand0337ef2019-09-20 15:46:03 -0700810 if (!val) return writeInt32(-1);
811 return writeByteVectorInternal(val->data(), val->size());
Casey Dahlin185d3442016-02-09 11:08:35 -0800812}
813
814status_t Parcel::writeByteVector(const std::vector<uint8_t>& val) {
Daniel Normand0337ef2019-09-20 15:46:03 -0700815 return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val.data()), val.size());
Casey Dahlin185d3442016-02-09 11:08:35 -0800816}
817
Jooyung Han2d5878e2020-01-23 12:45:10 +0900818status_t Parcel::writeByteVector(const std::optional<std::vector<uint8_t>>& val)
819{
820 if (!val) return writeInt32(-1);
821 return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size());
822}
823
Casey Dahlin185d3442016-02-09 11:08:35 -0800824status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val)
825{
Daniel Normand0337ef2019-09-20 15:46:03 -0700826 if (!val) return writeInt32(-1);
827 return writeByteVectorInternal(reinterpret_cast<const int8_t*>(val->data()), val->size());
Casey Dahlin185d3442016-02-09 11:08:35 -0800828}
829
Casey Dahlin451ff582015-10-19 18:12:18 -0700830status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val)
831{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800832 return writeTypedVector(val, &Parcel::writeInt32);
Casey Dahlin451ff582015-10-19 18:12:18 -0700833}
834
Jooyung Han2d5878e2020-01-23 12:45:10 +0900835status_t Parcel::writeInt32Vector(const std::optional<std::vector<int32_t>>& val)
836{
837 return writeNullableTypedVector(val, &Parcel::writeInt32);
838}
839
Casey Dahlinb9872622015-11-25 15:09:45 -0800840status_t Parcel::writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val)
841{
842 return writeNullableTypedVector(val, &Parcel::writeInt32);
843}
844
Casey Dahlin451ff582015-10-19 18:12:18 -0700845status_t Parcel::writeInt64Vector(const std::vector<int64_t>& val)
846{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800847 return writeTypedVector(val, &Parcel::writeInt64);
Casey Dahlin451ff582015-10-19 18:12:18 -0700848}
849
Jooyung Han2d5878e2020-01-23 12:45:10 +0900850status_t Parcel::writeInt64Vector(const std::optional<std::vector<int64_t>>& val)
851{
852 return writeNullableTypedVector(val, &Parcel::writeInt64);
853}
854
Casey Dahlinb9872622015-11-25 15:09:45 -0800855status_t Parcel::writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val)
856{
857 return writeNullableTypedVector(val, &Parcel::writeInt64);
858}
859
Kevin DuBois2f82d5b2018-12-05 12:56:10 -0800860status_t Parcel::writeUint64Vector(const std::vector<uint64_t>& val)
861{
862 return writeTypedVector(val, &Parcel::writeUint64);
863}
864
Jooyung Han2d5878e2020-01-23 12:45:10 +0900865status_t Parcel::writeUint64Vector(const std::optional<std::vector<uint64_t>>& val)
866{
867 return writeNullableTypedVector(val, &Parcel::writeUint64);
868}
869
Kevin DuBois2f82d5b2018-12-05 12:56:10 -0800870status_t Parcel::writeUint64Vector(const std::unique_ptr<std::vector<uint64_t>>& val)
871{
872 return writeNullableTypedVector(val, &Parcel::writeUint64);
873}
874
Casey Dahlin451ff582015-10-19 18:12:18 -0700875status_t Parcel::writeFloatVector(const std::vector<float>& val)
876{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800877 return writeTypedVector(val, &Parcel::writeFloat);
Casey Dahlin451ff582015-10-19 18:12:18 -0700878}
879
Jooyung Han2d5878e2020-01-23 12:45:10 +0900880status_t Parcel::writeFloatVector(const std::optional<std::vector<float>>& val)
881{
882 return writeNullableTypedVector(val, &Parcel::writeFloat);
883}
884
Casey Dahlinb9872622015-11-25 15:09:45 -0800885status_t Parcel::writeFloatVector(const std::unique_ptr<std::vector<float>>& val)
886{
887 return writeNullableTypedVector(val, &Parcel::writeFloat);
888}
889
Casey Dahlin451ff582015-10-19 18:12:18 -0700890status_t Parcel::writeDoubleVector(const std::vector<double>& val)
891{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800892 return writeTypedVector(val, &Parcel::writeDouble);
Casey Dahlin451ff582015-10-19 18:12:18 -0700893}
894
Jooyung Han2d5878e2020-01-23 12:45:10 +0900895status_t Parcel::writeDoubleVector(const std::optional<std::vector<double>>& val)
896{
897 return writeNullableTypedVector(val, &Parcel::writeDouble);
898}
899
Casey Dahlinb9872622015-11-25 15:09:45 -0800900status_t Parcel::writeDoubleVector(const std::unique_ptr<std::vector<double>>& val)
901{
902 return writeNullableTypedVector(val, &Parcel::writeDouble);
903}
904
Casey Dahlin451ff582015-10-19 18:12:18 -0700905status_t Parcel::writeBoolVector(const std::vector<bool>& val)
906{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800907 return writeTypedVector(val, &Parcel::writeBool);
Casey Dahlin451ff582015-10-19 18:12:18 -0700908}
909
Jooyung Han2d5878e2020-01-23 12:45:10 +0900910status_t Parcel::writeBoolVector(const std::optional<std::vector<bool>>& val)
911{
912 return writeNullableTypedVector(val, &Parcel::writeBool);
913}
914
Casey Dahlinb9872622015-11-25 15:09:45 -0800915status_t Parcel::writeBoolVector(const std::unique_ptr<std::vector<bool>>& val)
916{
917 return writeNullableTypedVector(val, &Parcel::writeBool);
918}
919
Casey Dahlin451ff582015-10-19 18:12:18 -0700920status_t Parcel::writeCharVector(const std::vector<char16_t>& val)
921{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800922 return writeTypedVector(val, &Parcel::writeChar);
Casey Dahlin451ff582015-10-19 18:12:18 -0700923}
924
Jooyung Han2d5878e2020-01-23 12:45:10 +0900925status_t Parcel::writeCharVector(const std::optional<std::vector<char16_t>>& val)
926{
927 return writeNullableTypedVector(val, &Parcel::writeChar);
928}
929
Casey Dahlinb9872622015-11-25 15:09:45 -0800930status_t Parcel::writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val)
931{
932 return writeNullableTypedVector(val, &Parcel::writeChar);
933}
934
Casey Dahlin451ff582015-10-19 18:12:18 -0700935status_t Parcel::writeString16Vector(const std::vector<String16>& val)
936{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800937 return writeTypedVector(val, &Parcel::writeString16);
Casey Dahlin451ff582015-10-19 18:12:18 -0700938}
939
Casey Dahlinb9872622015-11-25 15:09:45 -0800940status_t Parcel::writeString16Vector(
Jooyung Han2d5878e2020-01-23 12:45:10 +0900941 const std::optional<std::vector<std::optional<String16>>>& val)
942{
943 return writeNullableTypedVector(val, &Parcel::writeString16);
944}
945
946status_t Parcel::writeString16Vector(
Casey Dahlinb9872622015-11-25 15:09:45 -0800947 const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val)
948{
949 return writeNullableTypedVector(val, &Parcel::writeString16);
950}
951
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800952status_t Parcel::writeUtf8VectorAsUtf16Vector(
Jooyung Han2d5878e2020-01-23 12:45:10 +0900953 const std::optional<std::vector<std::optional<std::string>>>& val) {
954 return writeNullableTypedVector(val, &Parcel::writeUtf8AsUtf16);
955}
956
957status_t Parcel::writeUtf8VectorAsUtf16Vector(
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800958 const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val) {
959 return writeNullableTypedVector(val, &Parcel::writeUtf8AsUtf16);
960}
961
962status_t Parcel::writeUtf8VectorAsUtf16Vector(const std::vector<std::string>& val) {
963 return writeTypedVector(val, &Parcel::writeUtf8AsUtf16);
964}
965
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700966status_t Parcel::writeInt32(int32_t val)
967{
Andreas Huber84a6d042009-08-17 13:33:27 -0700968 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700969}
Dan Stoza41a0f2f2014-12-01 10:01:10 -0800970
971status_t Parcel::writeUint32(uint32_t val)
972{
973 return writeAligned(val);
974}
975
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700976status_t Parcel::writeInt32Array(size_t len, const int32_t *val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -0700977 if (len > INT32_MAX) {
978 // don't accept size_t values which may have come from an
979 // inadvertent conversion from a negative int.
980 return BAD_VALUE;
981 }
982
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700983 if (!val) {
Chad Brubakere59cb432015-06-30 14:03:55 -0700984 return writeInt32(-1);
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700985 }
Chad Brubakere59cb432015-06-30 14:03:55 -0700986 status_t ret = writeInt32(static_cast<uint32_t>(len));
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700987 if (ret == NO_ERROR) {
988 ret = write(val, len * sizeof(*val));
989 }
990 return ret;
991}
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700992status_t Parcel::writeByteArray(size_t len, const uint8_t *val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -0700993 if (len > INT32_MAX) {
994 // don't accept size_t values which may have come from an
995 // inadvertent conversion from a negative int.
996 return BAD_VALUE;
997 }
998
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700999 if (!val) {
Chad Brubakere59cb432015-06-30 14:03:55 -07001000 return writeInt32(-1);
Marco Nelissenf0190bf2014-03-13 14:17:40 -07001001 }
Chad Brubakere59cb432015-06-30 14:03:55 -07001002 status_t ret = writeInt32(static_cast<uint32_t>(len));
Marco Nelissenf0190bf2014-03-13 14:17:40 -07001003 if (ret == NO_ERROR) {
1004 ret = write(val, len * sizeof(*val));
1005 }
1006 return ret;
1007}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001008
Casey Dahlind6848f52015-10-15 15:44:59 -07001009status_t Parcel::writeBool(bool val)
1010{
1011 return writeInt32(int32_t(val));
1012}
1013
1014status_t Parcel::writeChar(char16_t val)
1015{
1016 return writeInt32(int32_t(val));
1017}
1018
1019status_t Parcel::writeByte(int8_t val)
1020{
1021 return writeInt32(int32_t(val));
1022}
1023
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001024status_t Parcel::writeInt64(int64_t val)
1025{
Andreas Huber84a6d042009-08-17 13:33:27 -07001026 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001027}
1028
Ronghua Wu2d13afd2015-03-16 11:11:07 -07001029status_t Parcel::writeUint64(uint64_t val)
1030{
1031 return writeAligned(val);
1032}
1033
Serban Constantinescuf683e012013-11-05 16:53:55 +00001034status_t Parcel::writePointer(uintptr_t val)
1035{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001036 return writeAligned<binder_uintptr_t>(val);
Serban Constantinescuf683e012013-11-05 16:53:55 +00001037}
1038
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001039status_t Parcel::writeFloat(float val)
1040{
Andreas Huber84a6d042009-08-17 13:33:27 -07001041 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001042}
1043
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001044#if defined(__mips__) && defined(__mips_hard_float)
1045
1046status_t Parcel::writeDouble(double val)
1047{
1048 union {
1049 double d;
1050 unsigned long long ll;
1051 } u;
1052 u.d = val;
1053 return writeAligned(u.ll);
1054}
1055
1056#else
1057
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001058status_t Parcel::writeDouble(double val)
1059{
Andreas Huber84a6d042009-08-17 13:33:27 -07001060 return writeAligned(val);
1061}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001062
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001063#endif
1064
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001065status_t Parcel::writeCString(const char* str)
1066{
1067 return write(str, strlen(str)+1);
1068}
1069
1070status_t Parcel::writeString8(const String8& str)
1071{
Jeff Sharkey2f8bdb52020-04-19 21:41:26 -06001072 return writeString8(str.string(), str.size());
1073}
1074
1075status_t Parcel::writeString8(const char* str, size_t len)
1076{
1077 if (str == nullptr) return writeInt32(-1);
1078
1079 status_t err = writeInt32(len);
1080 if (err == NO_ERROR) {
1081 uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char));
1082 if (data) {
1083 memcpy(data, str, len);
1084 *reinterpret_cast<char*>(data+len) = 0;
1085 return NO_ERROR;
1086 }
1087 err = mError;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001088 }
1089 return err;
1090}
1091
Jooyung Han2d5878e2020-01-23 12:45:10 +09001092status_t Parcel::writeString16(const std::optional<String16>& str)
1093{
1094 if (!str) {
1095 return writeInt32(-1);
1096 }
1097
1098 return writeString16(*str);
1099}
1100
Casey Dahlinb9872622015-11-25 15:09:45 -08001101status_t Parcel::writeString16(const std::unique_ptr<String16>& str)
1102{
1103 if (!str) {
1104 return writeInt32(-1);
1105 }
1106
1107 return writeString16(*str);
1108}
1109
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001110status_t Parcel::writeString16(const String16& str)
1111{
1112 return writeString16(str.string(), str.size());
1113}
1114
1115status_t Parcel::writeString16(const char16_t* str, size_t len)
1116{
Yi Kong91635562018-06-07 14:38:36 -07001117 if (str == nullptr) return writeInt32(-1);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001118
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001119 status_t err = writeInt32(len);
1120 if (err == NO_ERROR) {
1121 len *= sizeof(char16_t);
1122 uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
1123 if (data) {
1124 memcpy(data, str, len);
1125 *reinterpret_cast<char16_t*>(data+len) = 0;
1126 return NO_ERROR;
1127 }
1128 err = mError;
1129 }
1130 return err;
1131}
1132
1133status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
1134{
Steven Morelanda86a3562019-08-01 23:28:34 +00001135 return flattenBinder(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001136}
1137
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001138status_t Parcel::writeStrongBinderVector(const std::vector<sp<IBinder>>& val)
1139{
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001140 return writeTypedVector(val, &Parcel::writeStrongBinder);
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001141}
1142
Jooyung Han2d5878e2020-01-23 12:45:10 +09001143status_t Parcel::writeStrongBinderVector(const std::optional<std::vector<sp<IBinder>>>& val)
1144{
1145 return writeNullableTypedVector(val, &Parcel::writeStrongBinder);
1146}
1147
Casey Dahlinb9872622015-11-25 15:09:45 -08001148status_t Parcel::writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val)
1149{
1150 return writeNullableTypedVector(val, &Parcel::writeStrongBinder);
1151}
1152
Jooyung Han2d5878e2020-01-23 12:45:10 +09001153status_t Parcel::readStrongBinderVector(std::optional<std::vector<sp<IBinder>>>* val) const {
1154 return readNullableTypedVector(val, &Parcel::readNullableStrongBinder);
1155}
1156
Casey Dahlinb9872622015-11-25 15:09:45 -08001157status_t Parcel::readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const {
Christopher Wiley35d77ca2016-03-08 10:49:51 -08001158 return readNullableTypedVector(val, &Parcel::readNullableStrongBinder);
Casey Dahlinb9872622015-11-25 15:09:45 -08001159}
1160
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001161status_t Parcel::readStrongBinderVector(std::vector<sp<IBinder>>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001162 return readTypedVector(val, &Parcel::readStrongBinder);
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001163}
1164
Casey Dahlinb9872622015-11-25 15:09:45 -08001165status_t Parcel::writeRawNullableParcelable(const Parcelable* parcelable) {
1166 if (!parcelable) {
1167 return writeInt32(0);
1168 }
1169
1170 return writeParcelable(*parcelable);
1171}
1172
Christopher Wiley97f048d2015-11-19 06:49:05 -08001173status_t Parcel::writeParcelable(const Parcelable& parcelable) {
1174 status_t status = writeInt32(1); // parcelable is not null.
1175 if (status != OK) {
1176 return status;
1177 }
1178 return parcelable.writeToParcel(this);
1179}
1180
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001181status_t Parcel::writeNativeHandle(const native_handle* handle)
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001182{
Mathias Agopian1d0a95b2009-07-31 16:12:13 -07001183 if (!handle || handle->version != sizeof(native_handle))
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001184 return BAD_TYPE;
1185
1186 status_t err;
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001187 err = writeInt32(handle->numFds);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001188 if (err != NO_ERROR) return err;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001189
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001190 err = writeInt32(handle->numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001191 if (err != NO_ERROR) return err;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001192
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001193 for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)
1194 err = writeDupFileDescriptor(handle->data[i]);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001195
1196 if (err != NO_ERROR) {
Steve Block9d453682011-12-20 16:23:08 +00001197 ALOGD("write native handle, write dup fd failed");
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001198 return err;
1199 }
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001200 err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001201 return err;
1202}
1203
Jeff Brown93ff1f92011-11-04 19:01:44 -07001204status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001205{
1206 flat_binder_object obj;
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07001207 obj.hdr.type = BINDER_TYPE_FD;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001208 obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
Arve Hjønnevåg07fd0f12014-02-18 21:10:29 -08001209 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001210 obj.handle = fd;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001211 obj.cookie = takeOwnership ? 1 : 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001212 return writeObject(obj, true);
1213}
1214
1215status_t Parcel::writeDupFileDescriptor(int fd)
1216{
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08001217 int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
Jeff Brownd341c712011-11-04 20:19:33 -07001218 if (dupFd < 0) {
1219 return -errno;
1220 }
1221 status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/);
Casey Dahlin06673e32015-11-23 13:24:23 -08001222 if (err != OK) {
Jeff Brownd341c712011-11-04 20:19:33 -07001223 close(dupFd);
1224 }
1225 return err;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001226}
1227
Dianne Hackborn1941a402016-08-29 12:30:43 -07001228status_t Parcel::writeParcelFileDescriptor(int fd, bool takeOwnership)
1229{
1230 writeInt32(0);
1231 return writeFileDescriptor(fd, takeOwnership);
1232}
1233
Ryo Hashimotobf551892018-05-31 16:58:35 +09001234status_t Parcel::writeDupParcelFileDescriptor(int fd)
1235{
1236 int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
1237 if (dupFd < 0) {
1238 return -errno;
1239 }
1240 status_t err = writeParcelFileDescriptor(dupFd, true /*takeOwnership*/);
1241 if (err != OK) {
1242 close(dupFd);
1243 }
1244 return err;
1245}
1246
Christopher Wiley2cf19952016-04-11 11:09:37 -07001247status_t Parcel::writeUniqueFileDescriptor(const base::unique_fd& fd) {
Casey Dahlin06673e32015-11-23 13:24:23 -08001248 return writeDupFileDescriptor(fd.get());
1249}
1250
Christopher Wiley2cf19952016-04-11 11:09:37 -07001251status_t Parcel::writeUniqueFileDescriptorVector(const std::vector<base::unique_fd>& val) {
Casey Dahlin06673e32015-11-23 13:24:23 -08001252 return writeTypedVector(val, &Parcel::writeUniqueFileDescriptor);
1253}
1254
Jooyung Han2d5878e2020-01-23 12:45:10 +09001255status_t Parcel::writeUniqueFileDescriptorVector(const std::optional<std::vector<base::unique_fd>>& val) {
1256 return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
1257}
1258
Christopher Wiley2cf19952016-04-11 11:09:37 -07001259status_t Parcel::writeUniqueFileDescriptorVector(const std::unique_ptr<std::vector<base::unique_fd>>& val) {
Casey Dahlinb9872622015-11-25 15:09:45 -08001260 return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
1261}
1262
Jeff Brown13b16042014-11-11 16:44:25 -08001263status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob)
Jeff Brown5707dbf2011-09-23 21:17:56 -07001264{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001265 if (len > INT32_MAX) {
1266 // don't accept size_t values which may have come from an
1267 // inadvertent conversion from a negative int.
1268 return BAD_VALUE;
1269 }
1270
Jeff Brown13b16042014-11-11 16:44:25 -08001271 status_t status;
1272 if (!mAllowFds || len <= BLOB_INPLACE_LIMIT) {
Steve Block6807e592011-10-20 11:56:00 +01001273 ALOGV("writeBlob: write in place");
Jeff Brown13b16042014-11-11 16:44:25 -08001274 status = writeInt32(BLOB_INPLACE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001275 if (status) return status;
1276
1277 void* ptr = writeInplace(len);
1278 if (!ptr) return NO_MEMORY;
1279
Jeff Brown13b16042014-11-11 16:44:25 -08001280 outBlob->init(-1, ptr, len, false);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001281 return NO_ERROR;
1282 }
1283
Steve Block6807e592011-10-20 11:56:00 +01001284 ALOGV("writeBlob: write to ashmem");
Jeff Brown5707dbf2011-09-23 21:17:56 -07001285 int fd = ashmem_create_region("Parcel Blob", len);
1286 if (fd < 0) return NO_MEMORY;
1287
1288 int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
1289 if (result < 0) {
Jeff Brownec4e0062011-10-10 14:50:10 -07001290 status = result;
Jeff Brown5707dbf2011-09-23 21:17:56 -07001291 } else {
Yi Kong91635562018-06-07 14:38:36 -07001292 void* ptr = ::mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001293 if (ptr == MAP_FAILED) {
1294 status = -errno;
1295 } else {
Jeff Brown13b16042014-11-11 16:44:25 -08001296 if (!mutableCopy) {
1297 result = ashmem_set_prot_region(fd, PROT_READ);
1298 }
Jeff Brown5707dbf2011-09-23 21:17:56 -07001299 if (result < 0) {
Jeff Brownec4e0062011-10-10 14:50:10 -07001300 status = result;
Jeff Brown5707dbf2011-09-23 21:17:56 -07001301 } else {
Jeff Brown13b16042014-11-11 16:44:25 -08001302 status = writeInt32(mutableCopy ? BLOB_ASHMEM_MUTABLE : BLOB_ASHMEM_IMMUTABLE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001303 if (!status) {
Jeff Brown93ff1f92011-11-04 19:01:44 -07001304 status = writeFileDescriptor(fd, true /*takeOwnership*/);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001305 if (!status) {
Jeff Brown13b16042014-11-11 16:44:25 -08001306 outBlob->init(fd, ptr, len, mutableCopy);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001307 return NO_ERROR;
1308 }
1309 }
1310 }
1311 }
1312 ::munmap(ptr, len);
1313 }
1314 ::close(fd);
1315 return status;
1316}
1317
Jeff Brown13b16042014-11-11 16:44:25 -08001318status_t Parcel::writeDupImmutableBlobFileDescriptor(int fd)
1319{
1320 // Must match up with what's done in writeBlob.
1321 if (!mAllowFds) return FDS_NOT_ALLOWED;
1322 status_t status = writeInt32(BLOB_ASHMEM_IMMUTABLE);
1323 if (status) return status;
1324 return writeDupFileDescriptor(fd);
1325}
1326
Mathias Agopiane1424282013-07-29 21:24:40 -07001327status_t Parcel::write(const FlattenableHelperInterface& val)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001328{
1329 status_t err;
1330
1331 // size if needed
Mathias Agopiane1424282013-07-29 21:24:40 -07001332 const size_t len = val.getFlattenedSize();
1333 const size_t fd_count = val.getFdCount();
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001334
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001335 if ((len > INT32_MAX) || (fd_count >= gMaxFds)) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001336 // don't accept size_t values which may have come from an
1337 // inadvertent conversion from a negative int.
1338 return BAD_VALUE;
1339 }
1340
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001341 err = this->writeInt32(len);
1342 if (err) return err;
1343
1344 err = this->writeInt32(fd_count);
1345 if (err) return err;
1346
1347 // payload
Martijn Coenenf8542382018-04-04 11:46:56 +02001348 void* const buf = this->writeInplace(len);
Yi Kong91635562018-06-07 14:38:36 -07001349 if (buf == nullptr)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001350 return BAD_VALUE;
1351
Yi Kong91635562018-06-07 14:38:36 -07001352 int* fds = nullptr;
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001353 if (fd_count) {
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001354 fds = new (std::nothrow) int[fd_count];
1355 if (fds == nullptr) {
1356 ALOGE("write: failed to allocate requested %zu fds", fd_count);
1357 return BAD_VALUE;
1358 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001359 }
1360
1361 err = val.flatten(buf, len, fds, fd_count);
1362 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
1363 err = this->writeDupFileDescriptor( fds[i] );
1364 }
1365
1366 if (fd_count) {
1367 delete [] fds;
1368 }
1369
1370 return err;
1371}
1372
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001373status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
1374{
1375 const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
1376 const bool enoughObjects = mObjectsSize < mObjectsCapacity;
1377 if (enoughData && enoughObjects) {
1378restart_write:
1379 *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001380
Christopher Tate98e67d32015-06-03 18:44:15 -07001381 // remember if it's a file descriptor
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07001382 if (val.hdr.type == BINDER_TYPE_FD) {
Christopher Tate98e67d32015-06-03 18:44:15 -07001383 if (!mAllowFds) {
1384 // fail before modifying our object index
1385 return FDS_NOT_ALLOWED;
1386 }
1387 mHasFds = mFdsKnown = true;
1388 }
1389
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001390 // Need to write meta-data?
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001391 if (nullMetaData || val.binder != 0) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001392 mObjects[mObjectsSize] = mDataPos;
Adrian Rooscbf37262015-10-22 16:12:53 -07001393 acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001394 mObjectsSize++;
1395 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001396
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001397 return finishWrite(sizeof(flat_binder_object));
1398 }
1399
1400 if (!enoughData) {
1401 const status_t err = growData(sizeof(val));
1402 if (err != NO_ERROR) return err;
1403 }
1404 if (!enoughObjects) {
Martijn Coenenda2f2fd2020-01-22 10:46:25 +01001405 if (mObjectsSize > SIZE_MAX - 2) return NO_MEMORY; // overflow
1406 if ((mObjectsSize + 2) > SIZE_MAX / 3) return NO_MEMORY; // overflow
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001407 size_t newSize = ((mObjectsSize+2)*3)/2;
Martijn Coenenda2f2fd2020-01-22 10:46:25 +01001408 if (newSize > SIZE_MAX / sizeof(binder_size_t)) return NO_MEMORY; // overflow
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001409 binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
Yi Kong91635562018-06-07 14:38:36 -07001410 if (objects == nullptr) return NO_MEMORY;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001411 mObjects = objects;
1412 mObjectsCapacity = newSize;
1413 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001414
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001415 goto restart_write;
1416}
1417
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07001418status_t Parcel::writeNoException()
1419{
Christopher Wiley09eb7492015-11-09 15:06:15 -08001420 binder::Status status;
1421 return status.writeToParcel(this);
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07001422}
1423
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001424status_t Parcel::validateReadData(size_t upperBound) const
1425{
1426 // Don't allow non-object reads on object data
1427 if (mObjectsSorted || mObjectsSize <= 1) {
1428data_sorted:
1429 // Expect to check only against the next object
1430 if (mNextObjectHint < mObjectsSize && upperBound > mObjects[mNextObjectHint]) {
1431 // For some reason the current read position is greater than the next object
1432 // hint. Iterate until we find the right object
1433 size_t nextObject = mNextObjectHint;
1434 do {
1435 if (mDataPos < mObjects[nextObject] + sizeof(flat_binder_object)) {
1436 // Requested info overlaps with an object
1437 ALOGE("Attempt to read from protected data in Parcel %p", this);
1438 return PERMISSION_DENIED;
1439 }
1440 nextObject++;
1441 } while (nextObject < mObjectsSize && upperBound > mObjects[nextObject]);
1442 mNextObjectHint = nextObject;
1443 }
1444 return NO_ERROR;
1445 }
1446 // Quickly determine if mObjects is sorted.
1447 binder_size_t* currObj = mObjects + mObjectsSize - 1;
1448 binder_size_t* prevObj = currObj;
1449 while (currObj > mObjects) {
1450 prevObj--;
1451 if(*prevObj > *currObj) {
1452 goto data_unsorted;
1453 }
1454 currObj--;
1455 }
1456 mObjectsSorted = true;
1457 goto data_sorted;
1458
1459data_unsorted:
1460 // Insertion Sort mObjects
1461 // Great for mostly sorted lists. If randomly sorted or reverse ordered mObjects become common,
1462 // switch to std::sort(mObjects, mObjects + mObjectsSize);
1463 for (binder_size_t* iter0 = mObjects + 1; iter0 < mObjects + mObjectsSize; iter0++) {
1464 binder_size_t temp = *iter0;
1465 binder_size_t* iter1 = iter0 - 1;
1466 while (iter1 >= mObjects && *iter1 > temp) {
1467 *(iter1 + 1) = *iter1;
1468 iter1--;
1469 }
1470 *(iter1 + 1) = temp;
1471 }
1472 mNextObjectHint = 0;
1473 mObjectsSorted = true;
1474 goto data_sorted;
1475}
1476
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001477status_t Parcel::read(void* outData, size_t len) const
1478{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001479 if (len > INT32_MAX) {
1480 // don't accept size_t values which may have come from an
1481 // inadvertent conversion from a negative int.
1482 return BAD_VALUE;
1483 }
1484
1485 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1486 && len <= pad_size(len)) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001487 if (mObjectsSize > 0) {
1488 status_t err = validateReadData(mDataPos + pad_size(len));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001489 if(err != NO_ERROR) {
1490 // Still increment the data position by the expected length
1491 mDataPos += pad_size(len);
1492 ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
1493 return err;
1494 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001495 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001496 memcpy(outData, mData+mDataPos, len);
Nick Kralevichb6b14232015-04-02 09:36:02 -07001497 mDataPos += pad_size(len);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001498 ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001499 return NO_ERROR;
1500 }
1501 return NOT_ENOUGH_DATA;
1502}
1503
1504const void* Parcel::readInplace(size_t len) const
1505{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001506 if (len > INT32_MAX) {
1507 // don't accept size_t values which may have come from an
1508 // inadvertent conversion from a negative int.
Yi Kong91635562018-06-07 14:38:36 -07001509 return nullptr;
Nick Kralevichb6b14232015-04-02 09:36:02 -07001510 }
1511
1512 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1513 && len <= pad_size(len)) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001514 if (mObjectsSize > 0) {
1515 status_t err = validateReadData(mDataPos + pad_size(len));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001516 if(err != NO_ERROR) {
1517 // Still increment the data position by the expected length
1518 mDataPos += pad_size(len);
1519 ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
Yi Kong91635562018-06-07 14:38:36 -07001520 return nullptr;
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001521 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001522 }
1523
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001524 const void* data = mData+mDataPos;
Nick Kralevichb6b14232015-04-02 09:36:02 -07001525 mDataPos += pad_size(len);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001526 ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001527 return data;
1528 }
Yi Kong91635562018-06-07 14:38:36 -07001529 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001530}
1531
Andreas Huber84a6d042009-08-17 13:33:27 -07001532template<class T>
1533status_t Parcel::readAligned(T *pArg) const {
Elliott Hughes42a9b942020-08-17 15:53:31 -07001534 static_assert(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
Andreas Huber84a6d042009-08-17 13:33:27 -07001535
1536 if ((mDataPos+sizeof(T)) <= mDataSize) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001537 if (mObjectsSize > 0) {
1538 status_t err = validateReadData(mDataPos + sizeof(T));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001539 if(err != NO_ERROR) {
1540 // Still increment the data position by the expected length
1541 mDataPos += sizeof(T);
1542 return err;
1543 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001544 }
1545
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001546 const void* data = mData+mDataPos;
Andreas Huber84a6d042009-08-17 13:33:27 -07001547 mDataPos += sizeof(T);
1548 *pArg = *reinterpret_cast<const T*>(data);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001549 return NO_ERROR;
1550 } else {
1551 return NOT_ENOUGH_DATA;
1552 }
1553}
1554
Andreas Huber84a6d042009-08-17 13:33:27 -07001555template<class T>
1556T Parcel::readAligned() const {
1557 T result;
1558 if (readAligned(&result) != NO_ERROR) {
1559 result = 0;
1560 }
1561
1562 return result;
1563}
1564
1565template<class T>
1566status_t Parcel::writeAligned(T val) {
Elliott Hughes42a9b942020-08-17 15:53:31 -07001567 static_assert(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
Andreas Huber84a6d042009-08-17 13:33:27 -07001568
1569 if ((mDataPos+sizeof(val)) <= mDataCapacity) {
1570restart_write:
1571 *reinterpret_cast<T*>(mData+mDataPos) = val;
1572 return finishWrite(sizeof(val));
1573 }
1574
1575 status_t err = growData(sizeof(val));
1576 if (err == NO_ERROR) goto restart_write;
1577 return err;
1578}
1579
Casey Dahlin185d3442016-02-09 11:08:35 -08001580status_t Parcel::readByteVector(std::vector<int8_t>* val) const {
Daniel Normanc8646c32019-10-30 10:33:22 -07001581 size_t size;
1582 if (status_t status = reserveOutVector(val, &size); status != OK) return status;
1583 return readByteVectorInternal(val, size);
Casey Dahlin185d3442016-02-09 11:08:35 -08001584}
1585
1586status_t Parcel::readByteVector(std::vector<uint8_t>* val) const {
Daniel Normanc8646c32019-10-30 10:33:22 -07001587 size_t size;
1588 if (status_t status = reserveOutVector(val, &size); status != OK) return status;
1589 return readByteVectorInternal(val, size);
Casey Dahlin185d3442016-02-09 11:08:35 -08001590}
1591
Jooyung Han2d5878e2020-01-23 12:45:10 +09001592status_t Parcel::readByteVector(std::optional<std::vector<int8_t>>* val) const {
1593 size_t size;
1594 if (status_t status = reserveOutVector(val, &size); status != OK) return status;
1595 if (!*val) {
1596 // reserveOutVector does not create the out vector if size is < 0.
1597 // This occurs when writing a null byte vector.
1598 return OK;
1599 }
1600 return readByteVectorInternal(&**val, size);
1601}
1602
Casey Dahlin185d3442016-02-09 11:08:35 -08001603status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const {
Daniel Normanc8646c32019-10-30 10:33:22 -07001604 size_t size;
1605 if (status_t status = reserveOutVector(val, &size); status != OK) return status;
Daniel Normand0337ef2019-09-20 15:46:03 -07001606 if (val->get() == nullptr) {
Daniel Normanc8646c32019-10-30 10:33:22 -07001607 // reserveOutVector does not create the out vector if size is < 0.
Daniel Normand0337ef2019-09-20 15:46:03 -07001608 // This occurs when writing a null byte vector.
1609 return OK;
1610 }
Daniel Normanc8646c32019-10-30 10:33:22 -07001611 return readByteVectorInternal(val->get(), size);
Casey Dahlin185d3442016-02-09 11:08:35 -08001612}
1613
Jooyung Han2d5878e2020-01-23 12:45:10 +09001614status_t Parcel::readByteVector(std::optional<std::vector<uint8_t>>* val) const {
1615 size_t size;
1616 if (status_t status = reserveOutVector(val, &size); status != OK) return status;
1617 if (!*val) {
1618 // reserveOutVector does not create the out vector if size is < 0.
1619 // This occurs when writing a null byte vector.
1620 return OK;
1621 }
1622 return readByteVectorInternal(&**val, size);
1623}
1624
Casey Dahlin185d3442016-02-09 11:08:35 -08001625status_t Parcel::readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const {
Daniel Normanc8646c32019-10-30 10:33:22 -07001626 size_t size;
1627 if (status_t status = reserveOutVector(val, &size); status != OK) return status;
Daniel Normand0337ef2019-09-20 15:46:03 -07001628 if (val->get() == nullptr) {
Daniel Normanc8646c32019-10-30 10:33:22 -07001629 // reserveOutVector does not create the out vector if size is < 0.
Daniel Normand0337ef2019-09-20 15:46:03 -07001630 // This occurs when writing a null byte vector.
1631 return OK;
1632 }
Daniel Normanc8646c32019-10-30 10:33:22 -07001633 return readByteVectorInternal(val->get(), size);
Casey Dahlin185d3442016-02-09 11:08:35 -08001634}
1635
Jooyung Han2d5878e2020-01-23 12:45:10 +09001636status_t Parcel::readInt32Vector(std::optional<std::vector<int32_t>>* val) const {
1637 return readNullableTypedVector(val, &Parcel::readInt32);
1638}
1639
Casey Dahlinb9872622015-11-25 15:09:45 -08001640status_t Parcel::readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const {
1641 return readNullableTypedVector(val, &Parcel::readInt32);
1642}
1643
Casey Dahlin451ff582015-10-19 18:12:18 -07001644status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001645 return readTypedVector(val, &Parcel::readInt32);
Casey Dahlin451ff582015-10-19 18:12:18 -07001646}
1647
Jooyung Han2d5878e2020-01-23 12:45:10 +09001648status_t Parcel::readInt64Vector(std::optional<std::vector<int64_t>>* val) const {
1649 return readNullableTypedVector(val, &Parcel::readInt64);
1650}
1651
Casey Dahlinb9872622015-11-25 15:09:45 -08001652status_t Parcel::readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const {
1653 return readNullableTypedVector(val, &Parcel::readInt64);
1654}
1655
Casey Dahlin451ff582015-10-19 18:12:18 -07001656status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001657 return readTypedVector(val, &Parcel::readInt64);
Casey Dahlin451ff582015-10-19 18:12:18 -07001658}
1659
Jooyung Han2d5878e2020-01-23 12:45:10 +09001660status_t Parcel::readUint64Vector(std::optional<std::vector<uint64_t>>* val) const {
1661 return readNullableTypedVector(val, &Parcel::readUint64);
1662}
1663
Kevin DuBois2f82d5b2018-12-05 12:56:10 -08001664status_t Parcel::readUint64Vector(std::unique_ptr<std::vector<uint64_t>>* val) const {
1665 return readNullableTypedVector(val, &Parcel::readUint64);
1666}
1667
1668status_t Parcel::readUint64Vector(std::vector<uint64_t>* val) const {
1669 return readTypedVector(val, &Parcel::readUint64);
1670}
1671
Jooyung Han2d5878e2020-01-23 12:45:10 +09001672status_t Parcel::readFloatVector(std::optional<std::vector<float>>* val) const {
1673 return readNullableTypedVector(val, &Parcel::readFloat);
1674}
1675
Casey Dahlinb9872622015-11-25 15:09:45 -08001676status_t Parcel::readFloatVector(std::unique_ptr<std::vector<float>>* val) const {
1677 return readNullableTypedVector(val, &Parcel::readFloat);
1678}
1679
Casey Dahlin451ff582015-10-19 18:12:18 -07001680status_t Parcel::readFloatVector(std::vector<float>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001681 return readTypedVector(val, &Parcel::readFloat);
Casey Dahlin451ff582015-10-19 18:12:18 -07001682}
1683
Jooyung Han2d5878e2020-01-23 12:45:10 +09001684status_t Parcel::readDoubleVector(std::optional<std::vector<double>>* val) const {
1685 return readNullableTypedVector(val, &Parcel::readDouble);
1686}
1687
Casey Dahlinb9872622015-11-25 15:09:45 -08001688status_t Parcel::readDoubleVector(std::unique_ptr<std::vector<double>>* val) const {
1689 return readNullableTypedVector(val, &Parcel::readDouble);
1690}
1691
Casey Dahlin451ff582015-10-19 18:12:18 -07001692status_t Parcel::readDoubleVector(std::vector<double>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001693 return readTypedVector(val, &Parcel::readDouble);
Casey Dahlin451ff582015-10-19 18:12:18 -07001694}
1695
Jooyung Han2d5878e2020-01-23 12:45:10 +09001696status_t Parcel::readBoolVector(std::optional<std::vector<bool>>* val) const {
1697 const int32_t start = dataPosition();
1698 int32_t size;
1699 status_t status = readInt32(&size);
1700 val->reset();
1701
1702 if (status != OK || size < 0) {
1703 return status;
1704 }
1705
1706 setDataPosition(start);
1707 val->emplace();
1708
1709 status = readBoolVector(&**val);
1710
1711 if (status != OK) {
1712 val->reset();
1713 }
1714
1715 return status;
1716}
1717
Casey Dahlinb9872622015-11-25 15:09:45 -08001718status_t Parcel::readBoolVector(std::unique_ptr<std::vector<bool>>* val) const {
1719 const int32_t start = dataPosition();
1720 int32_t size;
1721 status_t status = readInt32(&size);
1722 val->reset();
Casey Dahlin451ff582015-10-19 18:12:18 -07001723
Casey Dahlinb9872622015-11-25 15:09:45 -08001724 if (status != OK || size < 0) {
1725 return status;
1726 }
1727
1728 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001729 val->reset(new (std::nothrow) std::vector<bool>());
Casey Dahlinb9872622015-11-25 15:09:45 -08001730
1731 status = readBoolVector(val->get());
1732
1733 if (status != OK) {
1734 val->reset();
1735 }
1736
1737 return status;
1738}
1739
1740status_t Parcel::readBoolVector(std::vector<bool>* val) const {
Casey Dahlin451ff582015-10-19 18:12:18 -07001741 int32_t size;
1742 status_t status = readInt32(&size);
1743
1744 if (status != OK) {
1745 return status;
1746 }
1747
1748 if (size < 0) {
Christopher Wiley4db672d2015-11-10 09:44:30 -08001749 return UNEXPECTED_NULL;
Casey Dahlin451ff582015-10-19 18:12:18 -07001750 }
1751
1752 val->resize(size);
1753
1754 /* C++ bool handling means a vector of bools isn't necessarily addressable
1755 * (we might use individual bits)
1756 */
Christopher Wiley97887982015-10-27 16:33:47 -07001757 bool data;
1758 for (int32_t i = 0; i < size; ++i) {
Casey Dahlin451ff582015-10-19 18:12:18 -07001759 status = readBool(&data);
1760 (*val)[i] = data;
1761
1762 if (status != OK) {
1763 return status;
1764 }
1765 }
1766
1767 return OK;
1768}
1769
Jooyung Han2d5878e2020-01-23 12:45:10 +09001770status_t Parcel::readCharVector(std::optional<std::vector<char16_t>>* val) const {
1771 return readNullableTypedVector(val, &Parcel::readChar);
1772}
1773
Casey Dahlinb9872622015-11-25 15:09:45 -08001774status_t Parcel::readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const {
1775 return readNullableTypedVector(val, &Parcel::readChar);
1776}
1777
Casey Dahlin451ff582015-10-19 18:12:18 -07001778status_t Parcel::readCharVector(std::vector<char16_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001779 return readTypedVector(val, &Parcel::readChar);
Casey Dahlin451ff582015-10-19 18:12:18 -07001780}
1781
Casey Dahlinb9872622015-11-25 15:09:45 -08001782status_t Parcel::readString16Vector(
Jooyung Han2d5878e2020-01-23 12:45:10 +09001783 std::optional<std::vector<std::optional<String16>>>* val) const {
1784 return readNullableTypedVector(val, &Parcel::readString16);
1785}
1786
1787status_t Parcel::readString16Vector(
Casey Dahlinb9872622015-11-25 15:09:45 -08001788 std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const {
1789 return readNullableTypedVector(val, &Parcel::readString16);
1790}
1791
Casey Dahlin451ff582015-10-19 18:12:18 -07001792status_t Parcel::readString16Vector(std::vector<String16>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001793 return readTypedVector(val, &Parcel::readString16);
Casey Dahlin451ff582015-10-19 18:12:18 -07001794}
1795
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001796status_t Parcel::readUtf8VectorFromUtf16Vector(
Jooyung Han2d5878e2020-01-23 12:45:10 +09001797 std::optional<std::vector<std::optional<std::string>>>* val) const {
1798 return readNullableTypedVector(val, &Parcel::readUtf8FromUtf16);
1799}
1800
1801status_t Parcel::readUtf8VectorFromUtf16Vector(
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001802 std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const {
1803 return readNullableTypedVector(val, &Parcel::readUtf8FromUtf16);
1804}
1805
1806status_t Parcel::readUtf8VectorFromUtf16Vector(std::vector<std::string>* val) const {
1807 return readTypedVector(val, &Parcel::readUtf8FromUtf16);
1808}
Casey Dahlin451ff582015-10-19 18:12:18 -07001809
Andreas Huber84a6d042009-08-17 13:33:27 -07001810status_t Parcel::readInt32(int32_t *pArg) const
1811{
1812 return readAligned(pArg);
1813}
1814
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001815int32_t Parcel::readInt32() const
1816{
Andreas Huber84a6d042009-08-17 13:33:27 -07001817 return readAligned<int32_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001818}
1819
Dan Stoza41a0f2f2014-12-01 10:01:10 -08001820status_t Parcel::readUint32(uint32_t *pArg) const
1821{
1822 return readAligned(pArg);
1823}
1824
1825uint32_t Parcel::readUint32() const
1826{
1827 return readAligned<uint32_t>();
1828}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001829
1830status_t Parcel::readInt64(int64_t *pArg) const
1831{
Andreas Huber84a6d042009-08-17 13:33:27 -07001832 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001833}
1834
1835
1836int64_t Parcel::readInt64() const
1837{
Andreas Huber84a6d042009-08-17 13:33:27 -07001838 return readAligned<int64_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001839}
1840
Ronghua Wu2d13afd2015-03-16 11:11:07 -07001841status_t Parcel::readUint64(uint64_t *pArg) const
1842{
1843 return readAligned(pArg);
1844}
1845
1846uint64_t Parcel::readUint64() const
1847{
1848 return readAligned<uint64_t>();
1849}
1850
Serban Constantinescuf683e012013-11-05 16:53:55 +00001851status_t Parcel::readPointer(uintptr_t *pArg) const
1852{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001853 status_t ret;
1854 binder_uintptr_t ptr;
1855 ret = readAligned(&ptr);
1856 if (!ret)
1857 *pArg = ptr;
1858 return ret;
Serban Constantinescuf683e012013-11-05 16:53:55 +00001859}
1860
1861uintptr_t Parcel::readPointer() const
1862{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001863 return readAligned<binder_uintptr_t>();
Serban Constantinescuf683e012013-11-05 16:53:55 +00001864}
1865
1866
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001867status_t Parcel::readFloat(float *pArg) const
1868{
Andreas Huber84a6d042009-08-17 13:33:27 -07001869 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001870}
1871
1872
1873float Parcel::readFloat() const
1874{
Andreas Huber84a6d042009-08-17 13:33:27 -07001875 return readAligned<float>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001876}
1877
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001878#if defined(__mips__) && defined(__mips_hard_float)
1879
1880status_t Parcel::readDouble(double *pArg) const
1881{
1882 union {
1883 double d;
1884 unsigned long long ll;
1885 } u;
Narayan Kamath2c68d382014-06-04 15:04:29 +01001886 u.d = 0;
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001887 status_t status;
1888 status = readAligned(&u.ll);
1889 *pArg = u.d;
1890 return status;
1891}
1892
1893double Parcel::readDouble() const
1894{
1895 union {
1896 double d;
1897 unsigned long long ll;
1898 } u;
1899 u.ll = readAligned<unsigned long long>();
1900 return u.d;
1901}
1902
1903#else
1904
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001905status_t Parcel::readDouble(double *pArg) const
1906{
Andreas Huber84a6d042009-08-17 13:33:27 -07001907 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001908}
1909
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001910double Parcel::readDouble() const
1911{
Andreas Huber84a6d042009-08-17 13:33:27 -07001912 return readAligned<double>();
1913}
1914
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001915#endif
1916
Andreas Huber84a6d042009-08-17 13:33:27 -07001917status_t Parcel::readIntPtr(intptr_t *pArg) const
1918{
1919 return readAligned(pArg);
1920}
1921
1922
1923intptr_t Parcel::readIntPtr() const
1924{
1925 return readAligned<intptr_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001926}
1927
Casey Dahlind6848f52015-10-15 15:44:59 -07001928status_t Parcel::readBool(bool *pArg) const
1929{
Manoj Gupta6eb62052017-07-12 10:29:15 -07001930 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07001931 status_t ret = readInt32(&tmp);
1932 *pArg = (tmp != 0);
1933 return ret;
1934}
1935
1936bool Parcel::readBool() const
1937{
1938 return readInt32() != 0;
1939}
1940
1941status_t Parcel::readChar(char16_t *pArg) const
1942{
Manoj Gupta6eb62052017-07-12 10:29:15 -07001943 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07001944 status_t ret = readInt32(&tmp);
1945 *pArg = char16_t(tmp);
1946 return ret;
1947}
1948
1949char16_t Parcel::readChar() const
1950{
1951 return char16_t(readInt32());
1952}
1953
1954status_t Parcel::readByte(int8_t *pArg) const
1955{
Manoj Gupta6eb62052017-07-12 10:29:15 -07001956 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07001957 status_t ret = readInt32(&tmp);
1958 *pArg = int8_t(tmp);
1959 return ret;
1960}
1961
1962int8_t Parcel::readByte() const
1963{
1964 return int8_t(readInt32());
1965}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001966
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001967status_t Parcel::readUtf8FromUtf16(std::string* str) const {
1968 size_t utf16Size = 0;
1969 const char16_t* src = readString16Inplace(&utf16Size);
1970 if (!src) {
1971 return UNEXPECTED_NULL;
1972 }
1973
1974 // Save ourselves the trouble, we're done.
1975 if (utf16Size == 0u) {
1976 str->clear();
1977 return NO_ERROR;
1978 }
1979
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001980 // Allow for closing '\0'
1981 ssize_t utf8Size = utf16_to_utf8_length(src, utf16Size) + 1;
1982 if (utf8Size < 1) {
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001983 return BAD_VALUE;
1984 }
1985 // Note that while it is probably safe to assume string::resize keeps a
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001986 // spare byte around for the trailing null, we still pass the size including the trailing null
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001987 str->resize(utf8Size);
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001988 utf16_to_utf8(src, utf16Size, &((*str)[0]), utf8Size);
1989 str->resize(utf8Size - 1);
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001990 return NO_ERROR;
1991}
1992
Jooyung Han2d5878e2020-01-23 12:45:10 +09001993status_t Parcel::readUtf8FromUtf16(std::optional<std::string>* str) const {
1994 const int32_t start = dataPosition();
1995 int32_t size;
1996 status_t status = readInt32(&size);
1997 str->reset();
1998
1999 if (status != OK || size < 0) {
2000 return status;
2001 }
2002
2003 setDataPosition(start);
2004 str->emplace();
2005 return readUtf8FromUtf16(&**str);
2006}
2007
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08002008status_t Parcel::readUtf8FromUtf16(std::unique_ptr<std::string>* str) const {
2009 const int32_t start = dataPosition();
2010 int32_t size;
2011 status_t status = readInt32(&size);
2012 str->reset();
2013
2014 if (status != OK || size < 0) {
2015 return status;
2016 }
2017
2018 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002019 str->reset(new (std::nothrow) std::string());
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08002020 return readUtf8FromUtf16(str->get());
2021}
2022
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002023const char* Parcel::readCString() const
2024{
Steven Morelandf5e6c7e2019-05-17 13:14:06 -07002025 if (mDataPos < mDataSize) {
2026 const size_t avail = mDataSize-mDataPos;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002027 const char* str = reinterpret_cast<const char*>(mData+mDataPos);
2028 // is the string's trailing NUL within the parcel's valid bounds?
2029 const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
2030 if (eos) {
2031 const size_t len = eos - str;
Nick Kralevichb6b14232015-04-02 09:36:02 -07002032 mDataPos += pad_size(len+1);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002033 ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002034 return str;
2035 }
2036 }
Yi Kong91635562018-06-07 14:38:36 -07002037 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002038}
2039
2040String8 Parcel::readString8() const
2041{
Jeff Sharkey2f8bdb52020-04-19 21:41:26 -06002042 size_t len;
2043 const char* str = readString8Inplace(&len);
2044 if (str) return String8(str, len);
2045 ALOGE("Reading a NULL string not supported here.");
2046 return String8();
Roshan Pius87b64d22016-07-18 12:51:02 -07002047}
2048
2049status_t Parcel::readString8(String8* pArg) const
2050{
Jeff Sharkey2f8bdb52020-04-19 21:41:26 -06002051 size_t len;
2052 const char* str = readString8Inplace(&len);
2053 if (str) {
2054 pArg->setTo(str, len);
2055 return 0;
2056 } else {
Roshan Pius87b64d22016-07-18 12:51:02 -07002057 *pArg = String8();
Jeff Sharkey2f8bdb52020-04-19 21:41:26 -06002058 return UNEXPECTED_NULL;
Roshan Pius87b64d22016-07-18 12:51:02 -07002059 }
Jeff Sharkey2f8bdb52020-04-19 21:41:26 -06002060}
2061
2062const char* Parcel::readString8Inplace(size_t* outLen) const
2063{
2064 int32_t size = readInt32();
2065 // watch for potential int overflow from size+1
2066 if (size >= 0 && size < INT32_MAX) {
2067 *outLen = size;
2068 const char* str = (const char*)readInplace(size+1);
2069 if (str != nullptr) {
2070 return str;
2071 }
Roshan Pius87b64d22016-07-18 12:51:02 -07002072 }
Jeff Sharkey2f8bdb52020-04-19 21:41:26 -06002073 *outLen = 0;
2074 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002075}
2076
2077String16 Parcel::readString16() const
2078{
2079 size_t len;
2080 const char16_t* str = readString16Inplace(&len);
2081 if (str) return String16(str, len);
Steve Blocke6f43dd2012-01-06 19:20:56 +00002082 ALOGE("Reading a NULL string not supported here.");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002083 return String16();
2084}
2085
Jooyung Han2d5878e2020-01-23 12:45:10 +09002086status_t Parcel::readString16(std::optional<String16>* pArg) const
2087{
2088 const int32_t start = dataPosition();
2089 int32_t size;
2090 status_t status = readInt32(&size);
2091 pArg->reset();
2092
2093 if (status != OK || size < 0) {
2094 return status;
2095 }
2096
2097 setDataPosition(start);
2098 pArg->emplace();
2099
2100 status = readString16(&**pArg);
2101
2102 if (status != OK) {
2103 pArg->reset();
2104 }
2105
2106 return status;
2107}
2108
Casey Dahlinb9872622015-11-25 15:09:45 -08002109status_t Parcel::readString16(std::unique_ptr<String16>* pArg) const
2110{
2111 const int32_t start = dataPosition();
2112 int32_t size;
2113 status_t status = readInt32(&size);
2114 pArg->reset();
2115
2116 if (status != OK || size < 0) {
2117 return status;
2118 }
2119
2120 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002121 pArg->reset(new (std::nothrow) String16());
Casey Dahlinb9872622015-11-25 15:09:45 -08002122
2123 status = readString16(pArg->get());
2124
2125 if (status != OK) {
2126 pArg->reset();
2127 }
2128
2129 return status;
2130}
2131
Casey Dahlin451ff582015-10-19 18:12:18 -07002132status_t Parcel::readString16(String16* pArg) const
2133{
2134 size_t len;
2135 const char16_t* str = readString16Inplace(&len);
2136 if (str) {
Casey Dahlin1515ea12015-10-20 16:26:23 -07002137 pArg->setTo(str, len);
Casey Dahlin451ff582015-10-19 18:12:18 -07002138 return 0;
2139 } else {
2140 *pArg = String16();
Christopher Wiley4db672d2015-11-10 09:44:30 -08002141 return UNEXPECTED_NULL;
Casey Dahlin451ff582015-10-19 18:12:18 -07002142 }
2143}
2144
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002145const char16_t* Parcel::readString16Inplace(size_t* outLen) const
2146{
2147 int32_t size = readInt32();
2148 // watch for potential int overflow from size+1
2149 if (size >= 0 && size < INT32_MAX) {
2150 *outLen = size;
2151 const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
Yi Kong91635562018-06-07 14:38:36 -07002152 if (str != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002153 return str;
2154 }
2155 }
2156 *outLen = 0;
Yi Kong91635562018-06-07 14:38:36 -07002157 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002158}
2159
Casey Dahlinf0c13772015-10-27 18:33:56 -07002160status_t Parcel::readStrongBinder(sp<IBinder>* val) const
2161{
Christopher Wiley35d77ca2016-03-08 10:49:51 -08002162 status_t status = readNullableStrongBinder(val);
2163 if (status == OK && !val->get()) {
2164 status = UNEXPECTED_NULL;
2165 }
2166 return status;
2167}
2168
2169status_t Parcel::readNullableStrongBinder(sp<IBinder>* val) const
2170{
Steven Morelanda86a3562019-08-01 23:28:34 +00002171 return unflattenBinder(val);
Casey Dahlinf0c13772015-10-27 18:33:56 -07002172}
2173
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002174sp<IBinder> Parcel::readStrongBinder() const
2175{
2176 sp<IBinder> val;
Christopher Wiley35d77ca2016-03-08 10:49:51 -08002177 // Note that a lot of code in Android reads binders by hand with this
2178 // method, and that code has historically been ok with getting nullptr
2179 // back (while ignoring error codes).
2180 readNullableStrongBinder(&val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002181 return val;
2182}
2183
Christopher Wiley97f048d2015-11-19 06:49:05 -08002184status_t Parcel::readParcelable(Parcelable* parcelable) const {
2185 int32_t have_parcelable = 0;
2186 status_t status = readInt32(&have_parcelable);
2187 if (status != OK) {
2188 return status;
2189 }
2190 if (!have_parcelable) {
2191 return UNEXPECTED_NULL;
2192 }
2193 return parcelable->readFromParcel(this);
2194}
2195
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07002196int32_t Parcel::readExceptionCode() const
2197{
Christopher Wiley09eb7492015-11-09 15:06:15 -08002198 binder::Status status;
2199 status.readFromParcel(*this);
2200 return status.exceptionCode();
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07002201}
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002202
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002203native_handle* Parcel::readNativeHandle() const
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002204{
2205 int numFds, numInts;
2206 status_t err;
2207 err = readInt32(&numFds);
Yi Kong91635562018-06-07 14:38:36 -07002208 if (err != NO_ERROR) return nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002209 err = readInt32(&numInts);
Yi Kong91635562018-06-07 14:38:36 -07002210 if (err != NO_ERROR) return nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002211
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002212 native_handle* h = native_handle_create(numFds, numInts);
Adam Lesinskieaac99a2015-05-12 17:35:48 -07002213 if (!h) {
Yi Kong91635562018-06-07 14:38:36 -07002214 return nullptr;
Adam Lesinskieaac99a2015-05-12 17:35:48 -07002215 }
2216
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002217 for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002218 h->data[i] = fcntl(readFileDescriptor(), F_DUPFD_CLOEXEC, 0);
Marco Nelissen1de79662016-04-26 08:44:09 -07002219 if (h->data[i] < 0) {
2220 for (int j = 0; j < i; j++) {
2221 close(h->data[j]);
2222 }
2223 native_handle_delete(h);
Yi Kong91635562018-06-07 14:38:36 -07002224 return nullptr;
Marco Nelissen1de79662016-04-26 08:44:09 -07002225 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002226 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002227 err = read(h->data + numFds, sizeof(int)*numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002228 if (err != NO_ERROR) {
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002229 native_handle_close(h);
2230 native_handle_delete(h);
Yi Kong91635562018-06-07 14:38:36 -07002231 h = nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002232 }
2233 return h;
2234}
2235
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002236int Parcel::readFileDescriptor() const
2237{
2238 const flat_binder_object* flat = readObject(true);
Casey Dahlin06673e32015-11-23 13:24:23 -08002239
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002240 if (flat && flat->hdr.type == BINDER_TYPE_FD) {
Casey Dahlin06673e32015-11-23 13:24:23 -08002241 return flat->handle;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002242 }
Casey Dahlin06673e32015-11-23 13:24:23 -08002243
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002244 return BAD_TYPE;
2245}
2246
Dianne Hackborn1941a402016-08-29 12:30:43 -07002247int Parcel::readParcelFileDescriptor() const
2248{
2249 int32_t hasComm = readInt32();
2250 int fd = readFileDescriptor();
2251 if (hasComm != 0) {
Steven Morelandb73806a2018-11-12 19:35:47 -08002252 // detach (owned by the binder driver)
2253 int comm = readFileDescriptor();
2254
2255 // warning: this must be kept in sync with:
2256 // frameworks/base/core/java/android/os/ParcelFileDescriptor.java
2257 enum ParcelFileDescriptorStatus {
2258 DETACHED = 2,
2259 };
2260
2261#if BYTE_ORDER == BIG_ENDIAN
2262 const int32_t message = ParcelFileDescriptorStatus::DETACHED;
2263#endif
2264#if BYTE_ORDER == LITTLE_ENDIAN
2265 const int32_t message = __builtin_bswap32(ParcelFileDescriptorStatus::DETACHED);
2266#endif
2267
2268 ssize_t written = TEMP_FAILURE_RETRY(
2269 ::write(comm, &message, sizeof(message)));
2270
2271 if (written == -1 || written != sizeof(message)) {
2272 ALOGW("Failed to detach ParcelFileDescriptor written: %zd err: %s",
2273 written, strerror(errno));
2274 return BAD_TYPE;
2275 }
Dianne Hackborn1941a402016-08-29 12:30:43 -07002276 }
2277 return fd;
2278}
2279
Christopher Wiley2cf19952016-04-11 11:09:37 -07002280status_t Parcel::readUniqueFileDescriptor(base::unique_fd* val) const
Casey Dahlin06673e32015-11-23 13:24:23 -08002281{
2282 int got = readFileDescriptor();
2283
2284 if (got == BAD_TYPE) {
2285 return BAD_TYPE;
2286 }
2287
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002288 val->reset(fcntl(got, F_DUPFD_CLOEXEC, 0));
Casey Dahlin06673e32015-11-23 13:24:23 -08002289
2290 if (val->get() < 0) {
2291 return BAD_VALUE;
2292 }
2293
2294 return OK;
2295}
2296
Ryo Hashimotobf551892018-05-31 16:58:35 +09002297status_t Parcel::readUniqueParcelFileDescriptor(base::unique_fd* val) const
2298{
2299 int got = readParcelFileDescriptor();
2300
2301 if (got == BAD_TYPE) {
2302 return BAD_TYPE;
2303 }
2304
2305 val->reset(fcntl(got, F_DUPFD_CLOEXEC, 0));
2306
2307 if (val->get() < 0) {
2308 return BAD_VALUE;
2309 }
2310
2311 return OK;
2312}
Casey Dahlin06673e32015-11-23 13:24:23 -08002313
Jooyung Han2d5878e2020-01-23 12:45:10 +09002314status_t Parcel::readUniqueFileDescriptorVector(std::optional<std::vector<base::unique_fd>>* val) const {
2315 return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
2316}
2317
Christopher Wiley2cf19952016-04-11 11:09:37 -07002318status_t Parcel::readUniqueFileDescriptorVector(std::unique_ptr<std::vector<base::unique_fd>>* val) const {
Casey Dahlinb9872622015-11-25 15:09:45 -08002319 return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
2320}
2321
Christopher Wiley2cf19952016-04-11 11:09:37 -07002322status_t Parcel::readUniqueFileDescriptorVector(std::vector<base::unique_fd>* val) const {
Casey Dahlin06673e32015-11-23 13:24:23 -08002323 return readTypedVector(val, &Parcel::readUniqueFileDescriptor);
2324}
2325
Jeff Brown5707dbf2011-09-23 21:17:56 -07002326status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
2327{
Jeff Brown13b16042014-11-11 16:44:25 -08002328 int32_t blobType;
2329 status_t status = readInt32(&blobType);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002330 if (status) return status;
2331
Jeff Brown13b16042014-11-11 16:44:25 -08002332 if (blobType == BLOB_INPLACE) {
Steve Block6807e592011-10-20 11:56:00 +01002333 ALOGV("readBlob: read in place");
Jeff Brown5707dbf2011-09-23 21:17:56 -07002334 const void* ptr = readInplace(len);
2335 if (!ptr) return BAD_VALUE;
2336
Jeff Brown13b16042014-11-11 16:44:25 -08002337 outBlob->init(-1, const_cast<void*>(ptr), len, false);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002338 return NO_ERROR;
2339 }
2340
Steve Block6807e592011-10-20 11:56:00 +01002341 ALOGV("readBlob: read from ashmem");
Jeff Brown13b16042014-11-11 16:44:25 -08002342 bool isMutable = (blobType == BLOB_ASHMEM_MUTABLE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002343 int fd = readFileDescriptor();
2344 if (fd == int(BAD_TYPE)) return BAD_VALUE;
2345
Jorim Jaggi150b4ef2018-07-13 11:18:30 +00002346 if (!ashmem_valid(fd)) {
2347 ALOGE("invalid fd");
2348 return BAD_VALUE;
2349 }
Marco Nelissen7a96ec42018-06-06 07:37:46 -07002350 int size = ashmem_get_size_region(fd);
2351 if (size < 0 || size_t(size) < len) {
Jorim Jaggi150b4ef2018-07-13 11:18:30 +00002352 ALOGE("request size %zu does not match fd size %d", len, size);
Marco Nelissen7a96ec42018-06-06 07:37:46 -07002353 return BAD_VALUE;
2354 }
Yi Kong91635562018-06-07 14:38:36 -07002355 void* ptr = ::mmap(nullptr, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ,
Jeff Brown13b16042014-11-11 16:44:25 -08002356 MAP_SHARED, fd, 0);
Narayan Kamath9ea09752014-10-08 17:35:45 +01002357 if (ptr == MAP_FAILED) return NO_MEMORY;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002358
Jeff Brown13b16042014-11-11 16:44:25 -08002359 outBlob->init(fd, ptr, len, isMutable);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002360 return NO_ERROR;
2361}
2362
Mathias Agopiane1424282013-07-29 21:24:40 -07002363status_t Parcel::read(FlattenableHelperInterface& val) const
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002364{
2365 // size
2366 const size_t len = this->readInt32();
2367 const size_t fd_count = this->readInt32();
2368
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002369 if ((len > INT32_MAX) || (fd_count >= gMaxFds)) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07002370 // don't accept size_t values which may have come from an
2371 // inadvertent conversion from a negative int.
2372 return BAD_VALUE;
2373 }
2374
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002375 // payload
Nick Kralevichb6b14232015-04-02 09:36:02 -07002376 void const* const buf = this->readInplace(pad_size(len));
Yi Kong91635562018-06-07 14:38:36 -07002377 if (buf == nullptr)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002378 return BAD_VALUE;
2379
Yi Kong91635562018-06-07 14:38:36 -07002380 int* fds = nullptr;
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002381 if (fd_count) {
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002382 fds = new (std::nothrow) int[fd_count];
2383 if (fds == nullptr) {
2384 ALOGE("read: failed to allocate requested %zu fds", fd_count);
2385 return BAD_VALUE;
2386 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002387 }
2388
2389 status_t err = NO_ERROR;
2390 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
Fabien Sanglardd84ff312016-10-21 10:58:26 -07002391 int fd = this->readFileDescriptor();
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002392 if (fd < 0 || ((fds[i] = fcntl(fd, F_DUPFD_CLOEXEC, 0)) < 0)) {
Jun Jiangabf8a2c2014-04-29 14:22:10 +08002393 err = BAD_VALUE;
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002394 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 -07002395 i, fds[i], fd_count, strerror(fd < 0 ? -fd : errno));
2396 // Close all the file descriptors that were dup-ed.
2397 for (size_t j=0; j<i ;j++) {
2398 close(fds[j]);
2399 }
Jun Jiangabf8a2c2014-04-29 14:22:10 +08002400 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002401 }
2402
2403 if (err == NO_ERROR) {
2404 err = val.unflatten(buf, len, fds, fd_count);
2405 }
2406
2407 if (fd_count) {
2408 delete [] fds;
2409 }
2410
2411 return err;
2412}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002413const flat_binder_object* Parcel::readObject(bool nullMetaData) const
2414{
2415 const size_t DPOS = mDataPos;
2416 if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
2417 const flat_binder_object* obj
2418 = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
2419 mDataPos = DPOS + sizeof(flat_binder_object);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002420 if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) {
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002421 // When transferring a NULL object, we don't write it into
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002422 // the object list, so we don't want to check for it when
2423 // reading.
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002424 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002425 return obj;
2426 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002427
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002428 // Ensure that this object is valid...
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002429 binder_size_t* const OBJS = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002430 const size_t N = mObjectsSize;
2431 size_t opos = mNextObjectHint;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002432
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002433 if (N > 0) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002434 ALOGV("Parcel %p looking for obj at %zu, hint=%zu",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002435 this, DPOS, opos);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002436
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002437 // Start at the current hint position, looking for an object at
2438 // the current data position.
2439 if (opos < N) {
2440 while (opos < (N-1) && OBJS[opos] < DPOS) {
2441 opos++;
2442 }
2443 } else {
2444 opos = N-1;
2445 }
2446 if (OBJS[opos] == DPOS) {
2447 // Found it!
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002448 ALOGV("Parcel %p found obj %zu at index %zu with forward search",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002449 this, DPOS, opos);
2450 mNextObjectHint = opos+1;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002451 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002452 return obj;
2453 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002454
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002455 // Look backwards for it...
2456 while (opos > 0 && OBJS[opos] > DPOS) {
2457 opos--;
2458 }
2459 if (OBJS[opos] == DPOS) {
2460 // Found it!
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002461 ALOGV("Parcel %p found obj %zu at index %zu with backward search",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002462 this, DPOS, opos);
2463 mNextObjectHint = opos+1;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002464 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002465 return obj;
2466 }
2467 }
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002468 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 -07002469 this, DPOS);
2470 }
Yi Kong91635562018-06-07 14:38:36 -07002471 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002472}
2473
2474void Parcel::closeFileDescriptors()
2475{
2476 size_t i = mObjectsSize;
2477 if (i > 0) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002478 //ALOGI("Closing file descriptors for %zu objects...", i);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002479 }
2480 while (i > 0) {
2481 i--;
2482 const flat_binder_object* flat
2483 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002484 if (flat->hdr.type == BINDER_TYPE_FD) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002485 //ALOGI("Closing fd: %ld", flat->handle);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002486 close(flat->handle);
2487 }
2488 }
2489}
2490
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002491uintptr_t Parcel::ipcData() const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002492{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002493 return reinterpret_cast<uintptr_t>(mData);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002494}
2495
2496size_t Parcel::ipcDataSize() const
2497{
2498 return (mDataSize > mDataPos ? mDataSize : mDataPos);
2499}
2500
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002501uintptr_t Parcel::ipcObjects() const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002502{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002503 return reinterpret_cast<uintptr_t>(mObjects);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002504}
2505
2506size_t Parcel::ipcObjectsCount() const
2507{
2508 return mObjectsSize;
2509}
2510
2511void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002512 const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002513{
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002514 binder_size_t minOffset = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002515 freeDataNoInit();
2516 mError = NO_ERROR;
2517 mData = const_cast<uint8_t*>(data);
2518 mDataSize = mDataCapacity = dataSize;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002519 //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)", this, mDataSize, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002520 mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002521 ALOGV("setDataReference Setting data pos of %p to %zu", this, mDataPos);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002522 mObjects = const_cast<binder_size_t*>(objects);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002523 mObjectsSize = mObjectsCapacity = objectsCount;
2524 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002525 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002526 mOwner = relFunc;
2527 mOwnerCookie = relCookie;
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002528 for (size_t i = 0; i < mObjectsSize; i++) {
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002529 binder_size_t offset = mObjects[i];
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002530 if (offset < minOffset) {
Dan Albert3bdc5b82014-11-20 11:50:23 -08002531 ALOGE("%s: bad object offset %" PRIu64 " < %" PRIu64 "\n",
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002532 __func__, (uint64_t)offset, (uint64_t)minOffset);
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002533 mObjectsSize = 0;
2534 break;
2535 }
Martijn Coenen82c75312019-07-24 15:18:30 +02002536 const flat_binder_object* flat
2537 = reinterpret_cast<const flat_binder_object*>(mData + offset);
2538 uint32_t type = flat->hdr.type;
2539 if (!(type == BINDER_TYPE_BINDER || type == BINDER_TYPE_HANDLE ||
2540 type == BINDER_TYPE_FD)) {
2541 // We should never receive other types (eg BINDER_TYPE_FDA) as long as we don't support
2542 // them in libbinder. If we do receive them, it probably means a kernel bug; try to
2543 // recover gracefully by clearing out the objects, and releasing the objects we do
2544 // know about.
2545 android_errorWriteLog(0x534e4554, "135930648");
2546 ALOGE("%s: unsupported type object (%" PRIu32 ") at offset %" PRIu64 "\n",
2547 __func__, type, (uint64_t)offset);
2548 releaseObjects();
2549 mObjectsSize = 0;
2550 break;
2551 }
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002552 minOffset = offset + sizeof(flat_binder_object);
2553 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002554 scanForFds();
2555}
2556
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002557void Parcel::print(TextOutput& to, uint32_t /*flags*/) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002558{
2559 to << "Parcel(";
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002560
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002561 if (errorCheck() != NO_ERROR) {
2562 const status_t err = errorCheck();
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002563 to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\"";
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002564 } else if (dataSize() > 0) {
2565 const uint8_t* DATA = data();
2566 to << indent << HexDump(DATA, dataSize()) << dedent;
Steven Moreland8bd01352019-07-15 16:36:14 -07002567 const binder_size_t* OBJS = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002568 const size_t N = objectsCount();
2569 for (size_t i=0; i<N; i++) {
2570 const flat_binder_object* flat
2571 = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
2572 to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002573 << TypeCode(flat->hdr.type & 0x7f7f7f00)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002574 << " = " << flat->binder;
2575 }
2576 } else {
2577 to << "NULL";
2578 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002579
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002580 to << ")";
2581}
2582
2583void Parcel::releaseObjects()
2584{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002585 size_t i = mObjectsSize;
Martijn Coenen69390d42018-10-22 15:18:10 +02002586 if (i == 0) {
2587 return;
2588 }
2589 sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002590 uint8_t* const data = mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002591 binder_size_t* const objects = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002592 while (i > 0) {
2593 i--;
2594 const flat_binder_object* flat
2595 = reinterpret_cast<flat_binder_object*>(data+objects[i]);
Adrian Rooscbf37262015-10-22 16:12:53 -07002596 release_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002597 }
2598}
2599
2600void Parcel::acquireObjects()
2601{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002602 size_t i = mObjectsSize;
Martijn Coenen69390d42018-10-22 15:18:10 +02002603 if (i == 0) {
2604 return;
2605 }
2606 const sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002607 uint8_t* const data = mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002608 binder_size_t* const objects = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002609 while (i > 0) {
2610 i--;
2611 const flat_binder_object* flat
2612 = reinterpret_cast<flat_binder_object*>(data+objects[i]);
Adrian Rooscbf37262015-10-22 16:12:53 -07002613 acquire_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002614 }
2615}
2616
2617void Parcel::freeData()
2618{
2619 freeDataNoInit();
2620 initState();
2621}
2622
2623void Parcel::freeDataNoInit()
2624{
2625 if (mOwner) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002626 LOG_ALLOC("Parcel %p: freeing other owner data", this);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002627 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002628 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
2629 } else {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002630 LOG_ALLOC("Parcel %p: freeing allocated data", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002631 releaseObjects();
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002632 if (mData) {
2633 LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002634 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dan Austin48fd7b42015-09-10 13:46:02 -07002635 if (mDataCapacity <= gParcelGlobalAllocSize) {
2636 gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity;
2637 } else {
2638 gParcelGlobalAllocSize = 0;
2639 }
2640 if (gParcelGlobalAllocCount > 0) {
2641 gParcelGlobalAllocCount--;
2642 }
Dianne Hackborna4cff882014-11-13 17:07:40 -08002643 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002644 free(mData);
2645 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002646 if (mObjects) free(mObjects);
2647 }
2648}
2649
2650status_t Parcel::growData(size_t len)
2651{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002652 if (len > INT32_MAX) {
2653 // don't accept size_t values which may have come from an
2654 // inadvertent conversion from a negative int.
2655 return BAD_VALUE;
2656 }
2657
Martijn Coenenda2f2fd2020-01-22 10:46:25 +01002658 if (len > SIZE_MAX - mDataSize) return NO_MEMORY; // overflow
2659 if (mDataSize + len > SIZE_MAX / 3) return NO_MEMORY; // overflow
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002660 size_t newSize = ((mDataSize+len)*3)/2;
2661 return (newSize <= mDataSize)
2662 ? (status_t) NO_MEMORY
Steven Moreland042ae822020-05-27 17:45:17 +00002663 : continueWrite(std::max(newSize, (size_t) 128));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002664}
2665
2666status_t Parcel::restartWrite(size_t desired)
2667{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002668 if (desired > INT32_MAX) {
2669 // don't accept size_t values which may have come from an
2670 // inadvertent conversion from a negative int.
2671 return BAD_VALUE;
2672 }
2673
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002674 if (mOwner) {
2675 freeData();
2676 return continueWrite(desired);
2677 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002678
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002679 uint8_t* data = (uint8_t*)realloc(mData, desired);
2680 if (!data && desired > mDataCapacity) {
2681 mError = NO_MEMORY;
2682 return NO_MEMORY;
2683 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002684
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002685 releaseObjects();
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002686
Devin Moore4a0a55e2020-06-04 13:23:10 -07002687 if (data || desired == 0) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002688 LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002689 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002690 gParcelGlobalAllocSize += desired;
2691 gParcelGlobalAllocSize -= mDataCapacity;
Colin Cross83ec65e2015-12-08 17:15:50 -08002692 if (!mData) {
2693 gParcelGlobalAllocCount++;
2694 }
Dianne Hackborna4cff882014-11-13 17:07:40 -08002695 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002696 mData = data;
2697 mDataCapacity = desired;
2698 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002699
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002700 mDataSize = mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002701 ALOGV("restartWrite Setting data size of %p to %zu", this, mDataSize);
2702 ALOGV("restartWrite Setting data pos of %p to %zu", this, mDataPos);
2703
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002704 free(mObjects);
Yi Kong91635562018-06-07 14:38:36 -07002705 mObjects = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002706 mObjectsSize = mObjectsCapacity = 0;
2707 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002708 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002709 mHasFds = false;
2710 mFdsKnown = true;
Dianne Hackborn8938ed22011-09-28 23:19:47 -04002711 mAllowFds = true;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002712
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002713 return NO_ERROR;
2714}
2715
2716status_t Parcel::continueWrite(size_t desired)
2717{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002718 if (desired > INT32_MAX) {
2719 // don't accept size_t values which may have come from an
2720 // inadvertent conversion from a negative int.
2721 return BAD_VALUE;
2722 }
2723
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002724 // If shrinking, first adjust for any objects that appear
2725 // after the new data size.
2726 size_t objectsSize = mObjectsSize;
2727 if (desired < mDataSize) {
2728 if (desired == 0) {
2729 objectsSize = 0;
2730 } else {
2731 while (objectsSize > 0) {
Michael Wachenschwanza6541632017-05-18 22:08:32 +00002732 if (mObjects[objectsSize-1] < desired)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002733 break;
2734 objectsSize--;
2735 }
2736 }
2737 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002738
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002739 if (mOwner) {
2740 // If the size is going to zero, just release the owner's data.
2741 if (desired == 0) {
2742 freeData();
2743 return NO_ERROR;
2744 }
2745
2746 // If there is a different owner, we need to take
2747 // posession.
2748 uint8_t* data = (uint8_t*)malloc(desired);
2749 if (!data) {
2750 mError = NO_MEMORY;
2751 return NO_MEMORY;
2752 }
Yi Kong91635562018-06-07 14:38:36 -07002753 binder_size_t* objects = nullptr;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002754
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002755 if (objectsSize) {
Nick Kraleviche9881a32015-04-28 16:21:30 -07002756 objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002757 if (!objects) {
Hyejin Kim3f727c02013-03-09 11:28:54 +09002758 free(data);
2759
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002760 mError = NO_MEMORY;
2761 return NO_MEMORY;
2762 }
2763
2764 // Little hack to only acquire references on objects
2765 // we will be keeping.
2766 size_t oldObjectsSize = mObjectsSize;
2767 mObjectsSize = objectsSize;
2768 acquireObjects();
2769 mObjectsSize = oldObjectsSize;
2770 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002771
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002772 if (mData) {
2773 memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
2774 }
2775 if (objects && mObjects) {
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002776 memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002777 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002778 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002779 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
Yi Kong91635562018-06-07 14:38:36 -07002780 mOwner = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002781
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002782 LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002783 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002784 gParcelGlobalAllocSize += desired;
2785 gParcelGlobalAllocCount++;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002786 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002787
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002788 mData = data;
2789 mObjects = objects;
2790 mDataSize = (mDataSize < desired) ? mDataSize : desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002791 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002792 mDataCapacity = desired;
2793 mObjectsSize = mObjectsCapacity = objectsSize;
2794 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002795 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002796
2797 } else if (mData) {
2798 if (objectsSize < mObjectsSize) {
2799 // Need to release refs on any objects we are dropping.
2800 const sp<ProcessState> proc(ProcessState::self());
2801 for (size_t i=objectsSize; i<mObjectsSize; i++) {
2802 const flat_binder_object* flat
2803 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002804 if (flat->hdr.type == BINDER_TYPE_FD) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002805 // will need to rescan because we may have lopped off the only FDs
2806 mFdsKnown = false;
2807 }
Adrian Rooscbf37262015-10-22 16:12:53 -07002808 release_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002809 }
Michael Wachenschwanz6af27a82019-06-03 17:24:51 -07002810
2811 if (objectsSize == 0) {
2812 free(mObjects);
2813 mObjects = nullptr;
Michael Wachenschwanzc67d9f32019-10-15 11:49:22 -07002814 mObjectsCapacity = 0;
Michael Wachenschwanz6af27a82019-06-03 17:24:51 -07002815 } else {
2816 binder_size_t* objects =
2817 (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
2818 if (objects) {
2819 mObjects = objects;
Michael Wachenschwanzc67d9f32019-10-15 11:49:22 -07002820 mObjectsCapacity = objectsSize;
Michael Wachenschwanz6af27a82019-06-03 17:24:51 -07002821 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002822 }
2823 mObjectsSize = objectsSize;
2824 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002825 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002826 }
2827
2828 // We own the data, so we can just do a realloc().
2829 if (desired > mDataCapacity) {
2830 uint8_t* data = (uint8_t*)realloc(mData, desired);
2831 if (data) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002832 LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity,
2833 desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002834 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002835 gParcelGlobalAllocSize += desired;
2836 gParcelGlobalAllocSize -= mDataCapacity;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002837 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002838 mData = data;
2839 mDataCapacity = desired;
Ganesh Mahendranade89892017-09-28 16:56:03 +08002840 } else {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002841 mError = NO_MEMORY;
2842 return NO_MEMORY;
2843 }
2844 } else {
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -07002845 if (mDataSize > desired) {
2846 mDataSize = desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002847 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -07002848 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002849 if (mDataPos > desired) {
2850 mDataPos = desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002851 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002852 }
2853 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002854
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002855 } else {
2856 // This is the first data. Easy!
2857 uint8_t* data = (uint8_t*)malloc(desired);
2858 if (!data) {
2859 mError = NO_MEMORY;
2860 return NO_MEMORY;
2861 }
Hyejin Kim3f727c02013-03-09 11:28:54 +09002862
Yi Kong91635562018-06-07 14:38:36 -07002863 if(!(mDataCapacity == 0 && mObjects == nullptr
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002864 && mObjectsCapacity == 0)) {
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002865 ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002866 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002867
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002868 LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002869 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002870 gParcelGlobalAllocSize += desired;
2871 gParcelGlobalAllocCount++;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002872 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002873
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002874 mData = data;
2875 mDataSize = mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002876 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
2877 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002878 mDataCapacity = desired;
2879 }
2880
2881 return NO_ERROR;
2882}
2883
2884void Parcel::initState()
2885{
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002886 LOG_ALLOC("Parcel %p: initState", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002887 mError = NO_ERROR;
Yi Kong91635562018-06-07 14:38:36 -07002888 mData = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002889 mDataSize = 0;
2890 mDataCapacity = 0;
2891 mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002892 ALOGV("initState Setting data size of %p to %zu", this, mDataSize);
2893 ALOGV("initState Setting data pos of %p to %zu", this, mDataPos);
Yi Kong91635562018-06-07 14:38:36 -07002894 mObjects = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002895 mObjectsSize = 0;
2896 mObjectsCapacity = 0;
2897 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002898 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002899 mHasFds = false;
2900 mFdsKnown = true;
Steven Moreland6e5a7752019-08-05 20:30:14 -07002901 mAllowFds = true;
Yi Kong91635562018-06-07 14:38:36 -07002902 mOwner = nullptr;
Adrian Rooscbf37262015-10-22 16:12:53 -07002903 mOpenAshmemSize = 0;
Olivier Gaillarddc848a02019-01-30 17:10:44 +00002904 mWorkSourceRequestHeaderPosition = 0;
2905 mRequestHeaderPresent = false;
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002906
2907 // racing multiple init leads only to multiple identical write
2908 if (gMaxFds == 0) {
2909 struct rlimit result;
2910 if (!getrlimit(RLIMIT_NOFILE, &result)) {
2911 gMaxFds = (size_t)result.rlim_cur;
Christopher Tatebf14e942016-03-25 14:16:24 -07002912 //ALOGI("parcel fd limit set to %zu", gMaxFds);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002913 } else {
2914 ALOGW("Unable to getrlimit: %s", strerror(errno));
2915 gMaxFds = 1024;
2916 }
2917 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002918}
2919
2920void Parcel::scanForFds() const
2921{
2922 bool hasFds = false;
2923 for (size_t i=0; i<mObjectsSize; i++) {
2924 const flat_binder_object* flat
2925 = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002926 if (flat->hdr.type == BINDER_TYPE_FD) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002927 hasFds = true;
2928 break;
2929 }
2930 }
2931 mHasFds = hasFds;
2932 mFdsKnown = true;
2933}
2934
Dan Sandleraa5c2342015-04-10 10:08:45 -04002935size_t Parcel::getBlobAshmemSize() const
2936{
Adrian Roos6bb31142015-10-22 16:46:12 -07002937 // This used to return the size of all blobs that were written to ashmem, now we're returning
2938 // the ashmem currently referenced by this Parcel, which should be equivalent.
2939 // TODO: Remove method once ABI can be changed.
2940 return mOpenAshmemSize;
Dan Sandleraa5c2342015-04-10 10:08:45 -04002941}
2942
Adrian Rooscbf37262015-10-22 16:12:53 -07002943size_t Parcel::getOpenAshmemSize() const
2944{
2945 return mOpenAshmemSize;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002946}
2947
2948// --- Parcel::Blob ---
2949
2950Parcel::Blob::Blob() :
Yi Kong91635562018-06-07 14:38:36 -07002951 mFd(-1), mData(nullptr), mSize(0), mMutable(false) {
Jeff Brown5707dbf2011-09-23 21:17:56 -07002952}
2953
2954Parcel::Blob::~Blob() {
2955 release();
2956}
2957
2958void Parcel::Blob::release() {
Jeff Brown13b16042014-11-11 16:44:25 -08002959 if (mFd != -1 && mData) {
Jeff Brown5707dbf2011-09-23 21:17:56 -07002960 ::munmap(mData, mSize);
2961 }
2962 clear();
2963}
2964
Jeff Brown13b16042014-11-11 16:44:25 -08002965void Parcel::Blob::init(int fd, void* data, size_t size, bool isMutable) {
2966 mFd = fd;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002967 mData = data;
2968 mSize = size;
Jeff Brown13b16042014-11-11 16:44:25 -08002969 mMutable = isMutable;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002970}
2971
2972void Parcel::Blob::clear() {
Jeff Brown13b16042014-11-11 16:44:25 -08002973 mFd = -1;
Yi Kong91635562018-06-07 14:38:36 -07002974 mData = nullptr;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002975 mSize = 0;
Jeff Brown13b16042014-11-11 16:44:25 -08002976 mMutable = false;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002977}
2978
Steven Moreland6511af52019-09-26 16:05:45 -07002979} // namespace android