blob: e9c26ea9adb2b483c8b702aaf77a01dd1b27f27c [file] [log] [blame]
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001/*
2 * Copyright (C) 2005 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Parcel"
18//#define LOG_NDEBUG 0
19
Mark Salyzynabed7f72016-01-27 08:02:48 -080020#include <errno.h>
Mark Salyzyn70f36652016-02-02 10:27:03 -080021#include <fcntl.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080022#include <inttypes.h>
Mark Salyzyn70f36652016-02-02 10:27:03 -080023#include <pthread.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080024#include <stdint.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <sys/mman.h>
Mark Salyzyneab2afc2016-01-27 08:02:48 -080028#include <sys/stat.h>
29#include <sys/types.h>
Christopher Tatee4e0ae82016-03-24 16:03:44 -070030#include <sys/resource.h>
Mark Salyzyneab2afc2016-01-27 08:02:48 -080031#include <unistd.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070032
Mathias Agopianc5b2c0b2009-05-19 19:08:10 -070033#include <binder/Binder.h>
34#include <binder/BpBinder.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080035#include <binder/IPCThreadState.h>
36#include <binder/Parcel.h>
Mathias Agopianc5b2c0b2009-05-19 19:08:10 -070037#include <binder/ProcessState.h>
Christopher Wiley09eb7492015-11-09 15:06:15 -080038#include <binder/Status.h>
Mathias Agopian002e1e52013-05-06 20:20:50 -070039#include <binder/TextOutput.h>
40
Mark Salyzynabed7f72016-01-27 08:02:48 -080041#include <cutils/ashmem.h>
Mathias Agopian002e1e52013-05-06 20:20:50 -070042#include <utils/Debug.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080043#include <utils/Flattenable.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070044#include <utils/Log.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080045#include <utils/misc.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070046#include <utils/String8.h>
47#include <utils/String16.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070048
Mathias Agopian208059f2009-05-18 15:08:03 -070049#include <private/binder/binder_module.h>
Dianne Hackborn7e790af2014-11-11 12:22:53 -080050#include <private/binder/Static.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070051
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070052#ifndef INT32_MAX
53#define INT32_MAX ((int32_t)(2147483647))
54#endif
55
56#define LOG_REFS(...)
Mark Salyzyne93390b2016-01-27 08:02:48 -080057//#define LOG_REFS(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
Dianne Hackborn7e790af2014-11-11 12:22:53 -080058#define LOG_ALLOC(...)
Mark Salyzyne93390b2016-01-27 08:02:48 -080059//#define LOG_ALLOC(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070060
61// ---------------------------------------------------------------------------
62
Nick Kralevichb6b14232015-04-02 09:36:02 -070063// This macro should never be used at runtime, as a too large value
64// of s could cause an integer overflow. Instead, you should always
65// use the wrapper function pad_size()
66#define PAD_SIZE_UNSAFE(s) (((s)+3)&~3)
67
68static size_t pad_size(size_t s) {
69 if (s > (SIZE_T_MAX - 3)) {
70 abort();
71 }
72 return PAD_SIZE_UNSAFE(s);
73}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070074
Brad Fitzpatricka877cd82010-07-07 16:06:39 -070075// Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
Jeff Sharkey0c1f5cb2014-12-18 10:26:57 -080076#define STRICT_MODE_PENALTY_GATHER (0x40 << 16)
Brad Fitzpatricka877cd82010-07-07 16:06:39 -070077
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070078// XXX This can be made public if we want to provide
79// support for typed data.
80struct small_flat_data
81{
82 uint32_t type;
83 uint32_t data;
84};
85
86namespace android {
87
Dianne Hackborna4cff882014-11-13 17:07:40 -080088static pthread_mutex_t gParcelGlobalAllocSizeLock = PTHREAD_MUTEX_INITIALIZER;
89static size_t gParcelGlobalAllocSize = 0;
90static size_t gParcelGlobalAllocCount = 0;
91
Christopher Tatee4e0ae82016-03-24 16:03:44 -070092static size_t gMaxFds = 0;
93
Jeff Brown13b16042014-11-11 16:44:25 -080094// Maximum size of a blob to transfer in-place.
95static const size_t BLOB_INPLACE_LIMIT = 16 * 1024;
96
97enum {
98 BLOB_INPLACE = 0,
99 BLOB_ASHMEM_IMMUTABLE = 1,
100 BLOB_ASHMEM_MUTABLE = 2,
101};
102
Mark Salyzyn70f36652016-02-02 10:27:03 -0800103static dev_t ashmem_rdev()
104{
105 static dev_t __ashmem_rdev;
106 static pthread_mutex_t __ashmem_rdev_lock = PTHREAD_MUTEX_INITIALIZER;
107
108 pthread_mutex_lock(&__ashmem_rdev_lock);
109
110 dev_t rdev = __ashmem_rdev;
111 if (!rdev) {
112 int fd = TEMP_FAILURE_RETRY(open("/dev/ashmem", O_RDONLY));
113 if (fd >= 0) {
114 struct stat st;
115
116 int ret = TEMP_FAILURE_RETRY(fstat(fd, &st));
117 close(fd);
118 if ((ret >= 0) && S_ISCHR(st.st_mode)) {
119 rdev = __ashmem_rdev = st.st_rdev;
120 }
121 }
122 }
123
124 pthread_mutex_unlock(&__ashmem_rdev_lock);
125
126 return rdev;
127}
128
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700129void acquire_object(const sp<ProcessState>& proc,
Adrian Rooscbf37262015-10-22 16:12:53 -0700130 const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700131{
132 switch (obj.type) {
133 case BINDER_TYPE_BINDER:
134 if (obj.binder) {
135 LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800136 reinterpret_cast<IBinder*>(obj.cookie)->incStrong(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700137 }
138 return;
139 case BINDER_TYPE_WEAK_BINDER:
140 if (obj.binder)
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800141 reinterpret_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700142 return;
143 case BINDER_TYPE_HANDLE: {
144 const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
145 if (b != NULL) {
146 LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
147 b->incStrong(who);
148 }
149 return;
150 }
151 case BINDER_TYPE_WEAK_HANDLE: {
152 const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
153 if (b != NULL) b.get_refs()->incWeak(who);
154 return;
155 }
156 case BINDER_TYPE_FD: {
Mark Salyzyneab2afc2016-01-27 08:02:48 -0800157 if ((obj.cookie != 0) && (outAshmemSize != NULL)) {
158 struct stat st;
159 int ret = fstat(obj.handle, &st);
Mark Salyzyn70f36652016-02-02 10:27:03 -0800160 if (!ret && S_ISCHR(st.st_mode) && (st.st_rdev == ashmem_rdev())) {
Adrian Roos6bb31142015-10-22 16:46:12 -0700161 // If we own an ashmem fd, keep track of how much memory it refers to.
162 int size = ashmem_get_size_region(obj.handle);
163 if (size > 0) {
164 *outAshmemSize += size;
165 }
Adrian Rooscbf37262015-10-22 16:12:53 -0700166 }
167 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700168 return;
169 }
170 }
171
Colin Cross6f4f3ab2014-02-05 17:42:44 -0800172 ALOGD("Invalid object type 0x%08x", obj.type);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700173}
174
Adrian Roos6bb31142015-10-22 16:46:12 -0700175void acquire_object(const sp<ProcessState>& proc,
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700176 const flat_binder_object& obj, const void* who)
177{
Adrian Roos6bb31142015-10-22 16:46:12 -0700178 acquire_object(proc, obj, who, NULL);
179}
180
181static void release_object(const sp<ProcessState>& proc,
Adrian Rooscbf37262015-10-22 16:12:53 -0700182 const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700183{
184 switch (obj.type) {
185 case BINDER_TYPE_BINDER:
186 if (obj.binder) {
187 LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800188 reinterpret_cast<IBinder*>(obj.cookie)->decStrong(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700189 }
190 return;
191 case BINDER_TYPE_WEAK_BINDER:
192 if (obj.binder)
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800193 reinterpret_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700194 return;
195 case BINDER_TYPE_HANDLE: {
196 const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
197 if (b != NULL) {
198 LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
199 b->decStrong(who);
200 }
201 return;
202 }
203 case BINDER_TYPE_WEAK_HANDLE: {
204 const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
205 if (b != NULL) b.get_refs()->decWeak(who);
206 return;
207 }
208 case BINDER_TYPE_FD: {
Mark Salyzynb454d8f2016-01-27 08:02:48 -0800209 if (obj.cookie != 0) { // owned
210 if (outAshmemSize != NULL) {
Mark Salyzyneab2afc2016-01-27 08:02:48 -0800211 struct stat st;
212 int ret = fstat(obj.handle, &st);
Mark Salyzyn70f36652016-02-02 10:27:03 -0800213 if (!ret && S_ISCHR(st.st_mode) && (st.st_rdev == ashmem_rdev())) {
Mark Salyzyneab2afc2016-01-27 08:02:48 -0800214 int size = ashmem_get_size_region(obj.handle);
215 if (size > 0) {
216 *outAshmemSize -= size;
217 }
Adrian Roos6bb31142015-10-22 16:46:12 -0700218 }
Adrian Roos6bb31142015-10-22 16:46:12 -0700219 }
Mark Salyzynb454d8f2016-01-27 08:02:48 -0800220
221 close(obj.handle);
Adrian Rooscbf37262015-10-22 16:12:53 -0700222 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700223 return;
224 }
225 }
226
Colin Cross6f4f3ab2014-02-05 17:42:44 -0800227 ALOGE("Invalid object type 0x%08x", obj.type);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700228}
229
Adrian Roos6bb31142015-10-22 16:46:12 -0700230void release_object(const sp<ProcessState>& proc,
231 const flat_binder_object& obj, const void* who)
232{
233 release_object(proc, obj, who, NULL);
234}
235
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700236inline static status_t finish_flatten_binder(
Colin Cross6f4f3ab2014-02-05 17:42:44 -0800237 const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700238{
239 return out->writeObject(flat, false);
240}
241
Colin Cross6f4f3ab2014-02-05 17:42:44 -0800242status_t flatten_binder(const sp<ProcessState>& /*proc*/,
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700243 const sp<IBinder>& binder, Parcel* out)
244{
245 flat_binder_object obj;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700246
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700247 obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
248 if (binder != NULL) {
249 IBinder *local = binder->localBinder();
250 if (!local) {
251 BpBinder *proxy = binder->remoteBinder();
252 if (proxy == NULL) {
Steve Blocke6f43dd2012-01-06 19:20:56 +0000253 ALOGE("null proxy");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700254 }
255 const int32_t handle = proxy ? proxy->handle() : 0;
256 obj.type = BINDER_TYPE_HANDLE;
Arve Hjønnevåg07fd0f12014-02-18 21:10:29 -0800257 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700258 obj.handle = handle;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800259 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700260 } else {
261 obj.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800262 obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
263 obj.cookie = reinterpret_cast<uintptr_t>(local);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700264 }
265 } else {
266 obj.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800267 obj.binder = 0;
268 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700269 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700270
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700271 return finish_flatten_binder(binder, obj, out);
272}
273
Colin Cross6f4f3ab2014-02-05 17:42:44 -0800274status_t flatten_binder(const sp<ProcessState>& /*proc*/,
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700275 const wp<IBinder>& binder, Parcel* out)
276{
277 flat_binder_object obj;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700278
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700279 obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
280 if (binder != NULL) {
281 sp<IBinder> real = binder.promote();
282 if (real != NULL) {
283 IBinder *local = real->localBinder();
284 if (!local) {
285 BpBinder *proxy = real->remoteBinder();
286 if (proxy == NULL) {
Steve Blocke6f43dd2012-01-06 19:20:56 +0000287 ALOGE("null proxy");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700288 }
289 const int32_t handle = proxy ? proxy->handle() : 0;
290 obj.type = BINDER_TYPE_WEAK_HANDLE;
Arve Hjønnevåg07fd0f12014-02-18 21:10:29 -0800291 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700292 obj.handle = handle;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800293 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700294 } else {
295 obj.type = BINDER_TYPE_WEAK_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800296 obj.binder = reinterpret_cast<uintptr_t>(binder.get_refs());
297 obj.cookie = reinterpret_cast<uintptr_t>(binder.unsafe_get());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700298 }
299 return finish_flatten_binder(real, obj, out);
300 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700301
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700302 // XXX How to deal? In order to flatten the given binder,
303 // we need to probe it for information, which requires a primary
304 // reference... but we don't have one.
305 //
306 // The OpenBinder implementation uses a dynamic_cast<> here,
307 // but we can't do that with the different reference counting
308 // implementation we are using.
Steve Blocke6f43dd2012-01-06 19:20:56 +0000309 ALOGE("Unable to unflatten Binder weak reference!");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700310 obj.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800311 obj.binder = 0;
312 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700313 return finish_flatten_binder(NULL, obj, out);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700314
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700315 } else {
316 obj.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800317 obj.binder = 0;
318 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700319 return finish_flatten_binder(NULL, obj, out);
320 }
321}
322
323inline static status_t finish_unflatten_binder(
Colin Cross6f4f3ab2014-02-05 17:42:44 -0800324 BpBinder* /*proxy*/, const flat_binder_object& /*flat*/,
325 const Parcel& /*in*/)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700326{
327 return NO_ERROR;
328}
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700329
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700330status_t unflatten_binder(const sp<ProcessState>& proc,
331 const Parcel& in, sp<IBinder>* out)
332{
333 const flat_binder_object* flat = in.readObject(false);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700334
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700335 if (flat) {
336 switch (flat->type) {
337 case BINDER_TYPE_BINDER:
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800338 *out = reinterpret_cast<IBinder*>(flat->cookie);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700339 return finish_unflatten_binder(NULL, *flat, in);
340 case BINDER_TYPE_HANDLE:
341 *out = proc->getStrongProxyForHandle(flat->handle);
342 return finish_unflatten_binder(
343 static_cast<BpBinder*>(out->get()), *flat, in);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700344 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700345 }
346 return BAD_TYPE;
347}
348
349status_t unflatten_binder(const sp<ProcessState>& proc,
350 const Parcel& in, wp<IBinder>* out)
351{
352 const flat_binder_object* flat = in.readObject(false);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700353
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700354 if (flat) {
355 switch (flat->type) {
356 case BINDER_TYPE_BINDER:
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800357 *out = reinterpret_cast<IBinder*>(flat->cookie);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700358 return finish_unflatten_binder(NULL, *flat, in);
359 case BINDER_TYPE_WEAK_BINDER:
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800360 if (flat->binder != 0) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700361 out->set_object_and_refs(
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800362 reinterpret_cast<IBinder*>(flat->cookie),
363 reinterpret_cast<RefBase::weakref_type*>(flat->binder));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700364 } else {
365 *out = NULL;
366 }
367 return finish_unflatten_binder(NULL, *flat, in);
368 case BINDER_TYPE_HANDLE:
369 case BINDER_TYPE_WEAK_HANDLE:
370 *out = proc->getWeakProxyForHandle(flat->handle);
371 return finish_unflatten_binder(
372 static_cast<BpBinder*>(out->unsafe_get()), *flat, in);
373 }
374 }
375 return BAD_TYPE;
376}
377
378// ---------------------------------------------------------------------------
379
380Parcel::Parcel()
381{
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800382 LOG_ALLOC("Parcel %p: constructing", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700383 initState();
384}
385
386Parcel::~Parcel()
387{
388 freeDataNoInit();
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800389 LOG_ALLOC("Parcel %p: destroyed", this);
390}
391
392size_t Parcel::getGlobalAllocSize() {
Dianne Hackborna4cff882014-11-13 17:07:40 -0800393 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
394 size_t size = gParcelGlobalAllocSize;
395 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
396 return size;
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800397}
398
399size_t Parcel::getGlobalAllocCount() {
Dianne Hackborna4cff882014-11-13 17:07:40 -0800400 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
401 size_t count = gParcelGlobalAllocCount;
402 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
403 return count;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700404}
405
406const uint8_t* Parcel::data() const
407{
408 return mData;
409}
410
411size_t Parcel::dataSize() const
412{
413 return (mDataSize > mDataPos ? mDataSize : mDataPos);
414}
415
416size_t Parcel::dataAvail() const
417{
Nick Kralevichcfe27de2015-09-16 09:49:15 -0700418 size_t result = dataSize() - dataPosition();
419 if (result > INT32_MAX) {
420 abort();
421 }
422 return result;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700423}
424
425size_t Parcel::dataPosition() const
426{
427 return mDataPos;
428}
429
430size_t Parcel::dataCapacity() const
431{
432 return mDataCapacity;
433}
434
435status_t Parcel::setDataSize(size_t size)
436{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700437 if (size > INT32_MAX) {
438 // don't accept size_t values which may have come from an
439 // inadvertent conversion from a negative int.
440 return BAD_VALUE;
441 }
442
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700443 status_t err;
444 err = continueWrite(size);
445 if (err == NO_ERROR) {
446 mDataSize = size;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700447 ALOGV("setDataSize Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700448 }
449 return err;
450}
451
452void Parcel::setDataPosition(size_t pos) const
453{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700454 if (pos > INT32_MAX) {
455 // don't accept size_t values which may have come from an
456 // inadvertent conversion from a negative int.
457 abort();
458 }
459
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700460 mDataPos = pos;
461 mNextObjectHint = 0;
akirilovf7841832018-04-03 12:56:06 -0700462 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700463}
464
465status_t Parcel::setDataCapacity(size_t size)
466{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700467 if (size > INT32_MAX) {
468 // don't accept size_t values which may have come from an
469 // inadvertent conversion from a negative int.
470 return BAD_VALUE;
471 }
472
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -0700473 if (size > mDataCapacity) return continueWrite(size);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700474 return NO_ERROR;
475}
476
477status_t Parcel::setData(const uint8_t* buffer, size_t len)
478{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700479 if (len > INT32_MAX) {
480 // don't accept size_t values which may have come from an
481 // inadvertent conversion from a negative int.
482 return BAD_VALUE;
483 }
484
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700485 status_t err = restartWrite(len);
486 if (err == NO_ERROR) {
487 memcpy(const_cast<uint8_t*>(data()), buffer, len);
488 mDataSize = len;
489 mFdsKnown = false;
490 }
491 return err;
492}
493
Andreas Huber51faf462011-04-13 10:21:56 -0700494status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700495{
496 const sp<ProcessState> proc(ProcessState::self());
497 status_t err;
Andreas Huber51faf462011-04-13 10:21:56 -0700498 const uint8_t *data = parcel->mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800499 const binder_size_t *objects = parcel->mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700500 size_t size = parcel->mObjectsSize;
501 int startPos = mDataPos;
502 int firstIndex = -1, lastIndex = -2;
503
504 if (len == 0) {
505 return NO_ERROR;
506 }
507
Nick Kralevichb6b14232015-04-02 09:36:02 -0700508 if (len > INT32_MAX) {
509 // don't accept size_t values which may have come from an
510 // inadvertent conversion from a negative int.
511 return BAD_VALUE;
512 }
513
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700514 // range checks against the source parcel size
515 if ((offset > parcel->mDataSize)
516 || (len > parcel->mDataSize)
517 || (offset + len > parcel->mDataSize)) {
518 return BAD_VALUE;
519 }
520
521 // Count objects in range
522 for (int i = 0; i < (int) size; i++) {
523 size_t off = objects[i];
Christopher Tate27182be2015-05-27 17:53:02 -0700524 if ((off >= offset) && (off + sizeof(flat_binder_object) <= offset + len)) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700525 if (firstIndex == -1) {
526 firstIndex = i;
527 }
528 lastIndex = i;
529 }
530 }
531 int numObjects = lastIndex - firstIndex + 1;
532
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -0700533 if ((mDataSize+len) > mDataCapacity) {
534 // grow data
535 err = growData(len);
536 if (err != NO_ERROR) {
537 return err;
538 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700539 }
540
541 // append data
542 memcpy(mData + mDataPos, data + offset, len);
543 mDataPos += len;
544 mDataSize += len;
545
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400546 err = NO_ERROR;
547
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700548 if (numObjects > 0) {
549 // grow objects
550 if (mObjectsCapacity < mObjectsSize + numObjects) {
Christopher Tateed7a50c2015-06-08 14:45:14 -0700551 size_t newSize = ((mObjectsSize + numObjects)*3)/2;
Christopher Tate8b643072016-11-03 13:32:41 -0700552 if (newSize*sizeof(binder_size_t) < mObjectsSize) return NO_MEMORY; // overflow
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800553 binder_size_t *objects =
554 (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
555 if (objects == (binder_size_t*)0) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700556 return NO_MEMORY;
557 }
558 mObjects = objects;
559 mObjectsCapacity = newSize;
560 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700561
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700562 // append and acquire objects
563 int idx = mObjectsSize;
564 for (int i = firstIndex; i <= lastIndex; i++) {
565 size_t off = objects[i] - offset + startPos;
566 mObjects[idx++] = off;
567 mObjectsSize++;
568
Dianne Hackborn8af0f822009-05-22 13:20:23 -0700569 flat_binder_object* flat
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700570 = reinterpret_cast<flat_binder_object*>(mData + off);
Adrian Rooscbf37262015-10-22 16:12:53 -0700571 acquire_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700572
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700573 if (flat->type == BINDER_TYPE_FD) {
Dianne Hackborn8af0f822009-05-22 13:20:23 -0700574 // If this is a file descriptor, we need to dup it so the
575 // new Parcel now owns its own fd, and can declare that we
576 // officially know we have fds.
577 flat->handle = dup(flat->handle);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800578 flat->cookie = 1;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700579 mHasFds = mFdsKnown = true;
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400580 if (!mAllowFds) {
581 err = FDS_NOT_ALLOWED;
582 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700583 }
584 }
585 }
586
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400587 return err;
588}
589
Jeff Brown13b16042014-11-11 16:44:25 -0800590bool Parcel::allowFds() const
591{
592 return mAllowFds;
593}
594
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700595bool Parcel::pushAllowFds(bool allowFds)
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400596{
597 const bool origValue = mAllowFds;
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700598 if (!allowFds) {
599 mAllowFds = false;
600 }
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400601 return origValue;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700602}
603
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700604void Parcel::restoreAllowFds(bool lastValue)
605{
606 mAllowFds = lastValue;
607}
608
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700609bool Parcel::hasFileDescriptors() const
610{
611 if (!mFdsKnown) {
612 scanForFds();
613 }
614 return mHasFds;
615}
616
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700617// Write RPC headers. (previously just the interface token)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700618status_t Parcel::writeInterfaceToken(const String16& interface)
619{
Brad Fitzpatricka877cd82010-07-07 16:06:39 -0700620 writeInt32(IPCThreadState::self()->getStrictModePolicy() |
621 STRICT_MODE_PENALTY_GATHER);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700622 // currently the interface identification token is just its name as a string
623 return writeString16(interface);
624}
625
Mathias Agopian83c04462009-05-22 19:00:22 -0700626bool Parcel::checkInterface(IBinder* binder) const
627{
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700628 return enforceInterface(binder->getInterfaceDescriptor());
Mathias Agopian83c04462009-05-22 19:00:22 -0700629}
630
Brad Fitzpatricka877cd82010-07-07 16:06:39 -0700631bool Parcel::enforceInterface(const String16& interface,
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700632 IPCThreadState* threadState) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700633{
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700634 int32_t strictPolicy = readInt32();
635 if (threadState == NULL) {
636 threadState = IPCThreadState::self();
Brad Fitzpatricka877cd82010-07-07 16:06:39 -0700637 }
Brad Fitzpatrick52736032010-08-30 16:01:16 -0700638 if ((threadState->getLastTransactionBinderFlags() &
639 IBinder::FLAG_ONEWAY) != 0) {
640 // For one-way calls, the callee is running entirely
641 // disconnected from the caller, so disable StrictMode entirely.
642 // Not only does disk/network usage not impact the caller, but
643 // there's no way to commuicate back any violations anyway.
644 threadState->setStrictModePolicy(0);
645 } else {
646 threadState->setStrictModePolicy(strictPolicy);
647 }
Mathias Agopian83c04462009-05-22 19:00:22 -0700648 const String16 str(readString16());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700649 if (str == interface) {
650 return true;
651 } else {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700652 ALOGW("**** enforceInterface() expected '%s' but read '%s'",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700653 String8(interface).string(), String8(str).string());
654 return false;
655 }
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700656}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700657
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800658const binder_size_t* Parcel::objects() const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700659{
660 return mObjects;
661}
662
663size_t Parcel::objectsCount() const
664{
665 return mObjectsSize;
666}
667
668status_t Parcel::errorCheck() const
669{
670 return mError;
671}
672
673void Parcel::setError(status_t err)
674{
675 mError = err;
676}
677
678status_t Parcel::finishWrite(size_t len)
679{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700680 if (len > INT32_MAX) {
681 // don't accept size_t values which may have come from an
682 // inadvertent conversion from a negative int.
683 return BAD_VALUE;
684 }
685
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700686 //printf("Finish write of %d\n", len);
687 mDataPos += len;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700688 ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700689 if (mDataPos > mDataSize) {
690 mDataSize = mDataPos;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700691 ALOGV("finishWrite Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700692 }
693 //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
694 return NO_ERROR;
695}
696
697status_t Parcel::writeUnpadded(const void* data, size_t len)
698{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700699 if (len > INT32_MAX) {
700 // don't accept size_t values which may have come from an
701 // inadvertent conversion from a negative int.
702 return BAD_VALUE;
703 }
704
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700705 size_t end = mDataPos + len;
706 if (end < mDataPos) {
707 // integer overflow
708 return BAD_VALUE;
709 }
710
711 if (end <= mDataCapacity) {
712restart_write:
713 memcpy(mData+mDataPos, data, len);
714 return finishWrite(len);
715 }
716
717 status_t err = growData(len);
718 if (err == NO_ERROR) goto restart_write;
719 return err;
720}
721
722status_t Parcel::write(const void* data, size_t len)
723{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700724 if (len > INT32_MAX) {
725 // don't accept size_t values which may have come from an
726 // inadvertent conversion from a negative int.
727 return BAD_VALUE;
728 }
729
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700730 void* const d = writeInplace(len);
731 if (d) {
732 memcpy(d, data, len);
733 return NO_ERROR;
734 }
735 return mError;
736}
737
738void* Parcel::writeInplace(size_t len)
739{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700740 if (len > INT32_MAX) {
741 // don't accept size_t values which may have come from an
742 // inadvertent conversion from a negative int.
743 return NULL;
744 }
745
746 const size_t padded = pad_size(len);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700747
748 // sanity check for integer overflow
749 if (mDataPos+padded < mDataPos) {
750 return NULL;
751 }
752
753 if ((mDataPos+padded) <= mDataCapacity) {
754restart_write:
755 //printf("Writing %ld bytes, padded to %ld\n", len, padded);
756 uint8_t* const data = mData+mDataPos;
757
758 // Need to pad at end?
759 if (padded != len) {
760#if BYTE_ORDER == BIG_ENDIAN
761 static const uint32_t mask[4] = {
762 0x00000000, 0xffffff00, 0xffff0000, 0xff000000
763 };
764#endif
765#if BYTE_ORDER == LITTLE_ENDIAN
766 static const uint32_t mask[4] = {
767 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
768 };
769#endif
770 //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
771 // *reinterpret_cast<void**>(data+padded-4));
772 *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
773 }
774
775 finishWrite(padded);
776 return data;
777 }
778
779 status_t err = growData(padded);
780 if (err == NO_ERROR) goto restart_write;
781 return NULL;
782}
783
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800784status_t Parcel::writeUtf8AsUtf16(const std::string& str) {
785 const uint8_t* strData = (uint8_t*)str.data();
786 const size_t strLen= str.length();
787 const ssize_t utf16Len = utf8_to_utf16_length(strData, strLen);
788 if (utf16Len < 0 || utf16Len> std::numeric_limits<int32_t>::max()) {
789 return BAD_VALUE;
790 }
791
792 status_t err = writeInt32(utf16Len);
793 if (err) {
794 return err;
795 }
796
797 // Allocate enough bytes to hold our converted string and its terminating NULL.
798 void* dst = writeInplace((utf16Len + 1) * sizeof(char16_t));
799 if (!dst) {
800 return NO_MEMORY;
801 }
802
803 utf8_to_utf16(strData, strLen, (char16_t*)dst);
804
805 return NO_ERROR;
806}
807
808status_t Parcel::writeUtf8AsUtf16(const std::unique_ptr<std::string>& str) {
809 if (!str) {
810 return writeInt32(-1);
811 }
812 return writeUtf8AsUtf16(*str);
813}
814
Casey Dahlin0b1cf332016-02-09 11:08:35 -0800815namespace {
Casey Dahlinb9872622015-11-25 15:09:45 -0800816
Casey Dahlin0b1cf332016-02-09 11:08:35 -0800817template<typename T>
818status_t writeByteVectorInternal(Parcel* parcel, const std::vector<T>& val)
Casey Dahlin451ff582015-10-19 18:12:18 -0700819{
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700820 status_t status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700821 if (val.size() > std::numeric_limits<int32_t>::max()) {
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700822 status = BAD_VALUE;
823 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700824 }
825
Casey Dahlin0b1cf332016-02-09 11:08:35 -0800826 status = parcel->writeInt32(val.size());
Casey Dahlin451ff582015-10-19 18:12:18 -0700827 if (status != OK) {
828 return status;
829 }
830
Casey Dahlin0b1cf332016-02-09 11:08:35 -0800831 void* data = parcel->writeInplace(val.size());
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700832 if (!data) {
833 status = BAD_VALUE;
834 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700835 }
836
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700837 memcpy(data, val.data(), val.size());
838 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700839}
840
Casey Dahlin0b1cf332016-02-09 11:08:35 -0800841template<typename T>
842status_t writeByteVectorInternalPtr(Parcel* parcel,
843 const std::unique_ptr<std::vector<T>>& val)
844{
845 if (!val) {
846 return parcel->writeInt32(-1);
847 }
848
849 return writeByteVectorInternal(parcel, *val);
850}
851
852} // namespace
853
854status_t Parcel::writeByteVector(const std::vector<int8_t>& val) {
855 return writeByteVectorInternal(this, val);
856}
857
858status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val)
859{
860 return writeByteVectorInternalPtr(this, val);
861}
862
863status_t Parcel::writeByteVector(const std::vector<uint8_t>& val) {
864 return writeByteVectorInternal(this, val);
865}
866
867status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val)
868{
869 return writeByteVectorInternalPtr(this, val);
870}
871
Casey Dahlin451ff582015-10-19 18:12:18 -0700872status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val)
873{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800874 return writeTypedVector(val, &Parcel::writeInt32);
Casey Dahlin451ff582015-10-19 18:12:18 -0700875}
876
Casey Dahlinb9872622015-11-25 15:09:45 -0800877status_t Parcel::writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val)
878{
879 return writeNullableTypedVector(val, &Parcel::writeInt32);
880}
881
Casey Dahlin451ff582015-10-19 18:12:18 -0700882status_t Parcel::writeInt64Vector(const std::vector<int64_t>& val)
883{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800884 return writeTypedVector(val, &Parcel::writeInt64);
Casey Dahlin451ff582015-10-19 18:12:18 -0700885}
886
Casey Dahlinb9872622015-11-25 15:09:45 -0800887status_t Parcel::writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val)
888{
889 return writeNullableTypedVector(val, &Parcel::writeInt64);
890}
891
Casey Dahlin451ff582015-10-19 18:12:18 -0700892status_t Parcel::writeFloatVector(const std::vector<float>& val)
893{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800894 return writeTypedVector(val, &Parcel::writeFloat);
Casey Dahlin451ff582015-10-19 18:12:18 -0700895}
896
Casey Dahlinb9872622015-11-25 15:09:45 -0800897status_t Parcel::writeFloatVector(const std::unique_ptr<std::vector<float>>& val)
898{
899 return writeNullableTypedVector(val, &Parcel::writeFloat);
900}
901
Casey Dahlin451ff582015-10-19 18:12:18 -0700902status_t Parcel::writeDoubleVector(const std::vector<double>& val)
903{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800904 return writeTypedVector(val, &Parcel::writeDouble);
Casey Dahlin451ff582015-10-19 18:12:18 -0700905}
906
Casey Dahlinb9872622015-11-25 15:09:45 -0800907status_t Parcel::writeDoubleVector(const std::unique_ptr<std::vector<double>>& val)
908{
909 return writeNullableTypedVector(val, &Parcel::writeDouble);
910}
911
Casey Dahlin451ff582015-10-19 18:12:18 -0700912status_t Parcel::writeBoolVector(const std::vector<bool>& val)
913{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800914 return writeTypedVector(val, &Parcel::writeBool);
Casey Dahlin451ff582015-10-19 18:12:18 -0700915}
916
Casey Dahlinb9872622015-11-25 15:09:45 -0800917status_t Parcel::writeBoolVector(const std::unique_ptr<std::vector<bool>>& val)
918{
919 return writeNullableTypedVector(val, &Parcel::writeBool);
920}
921
Casey Dahlin451ff582015-10-19 18:12:18 -0700922status_t Parcel::writeCharVector(const std::vector<char16_t>& val)
923{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800924 return writeTypedVector(val, &Parcel::writeChar);
Casey Dahlin451ff582015-10-19 18:12:18 -0700925}
926
Casey Dahlinb9872622015-11-25 15:09:45 -0800927status_t Parcel::writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val)
928{
929 return writeNullableTypedVector(val, &Parcel::writeChar);
930}
931
Casey Dahlin451ff582015-10-19 18:12:18 -0700932status_t Parcel::writeString16Vector(const std::vector<String16>& val)
933{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800934 return writeTypedVector(val, &Parcel::writeString16);
Casey Dahlin451ff582015-10-19 18:12:18 -0700935}
936
Casey Dahlinb9872622015-11-25 15:09:45 -0800937status_t Parcel::writeString16Vector(
938 const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val)
939{
940 return writeNullableTypedVector(val, &Parcel::writeString16);
941}
942
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800943status_t Parcel::writeUtf8VectorAsUtf16Vector(
944 const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val) {
945 return writeNullableTypedVector(val, &Parcel::writeUtf8AsUtf16);
946}
947
948status_t Parcel::writeUtf8VectorAsUtf16Vector(const std::vector<std::string>& val) {
949 return writeTypedVector(val, &Parcel::writeUtf8AsUtf16);
950}
951
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700952status_t Parcel::writeInt32(int32_t val)
953{
Andreas Huber84a6d042009-08-17 13:33:27 -0700954 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700955}
Dan Stoza41a0f2f2014-12-01 10:01:10 -0800956
957status_t Parcel::writeUint32(uint32_t val)
958{
959 return writeAligned(val);
960}
961
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700962status_t Parcel::writeInt32Array(size_t len, const int32_t *val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -0700963 if (len > INT32_MAX) {
964 // don't accept size_t values which may have come from an
965 // inadvertent conversion from a negative int.
966 return BAD_VALUE;
967 }
968
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700969 if (!val) {
Chad Brubakere59cb432015-06-30 14:03:55 -0700970 return writeInt32(-1);
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700971 }
Chad Brubakere59cb432015-06-30 14:03:55 -0700972 status_t ret = writeInt32(static_cast<uint32_t>(len));
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700973 if (ret == NO_ERROR) {
974 ret = write(val, len * sizeof(*val));
975 }
976 return ret;
977}
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700978status_t Parcel::writeByteArray(size_t len, const uint8_t *val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -0700979 if (len > INT32_MAX) {
980 // don't accept size_t values which may have come from an
981 // inadvertent conversion from a negative int.
982 return BAD_VALUE;
983 }
984
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700985 if (!val) {
Chad Brubakere59cb432015-06-30 14:03:55 -0700986 return writeInt32(-1);
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700987 }
Chad Brubakere59cb432015-06-30 14:03:55 -0700988 status_t ret = writeInt32(static_cast<uint32_t>(len));
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700989 if (ret == NO_ERROR) {
990 ret = write(val, len * sizeof(*val));
991 }
992 return ret;
993}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700994
Casey Dahlind6848f52015-10-15 15:44:59 -0700995status_t Parcel::writeBool(bool val)
996{
997 return writeInt32(int32_t(val));
998}
999
1000status_t Parcel::writeChar(char16_t val)
1001{
1002 return writeInt32(int32_t(val));
1003}
1004
1005status_t Parcel::writeByte(int8_t val)
1006{
1007 return writeInt32(int32_t(val));
1008}
1009
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001010status_t Parcel::writeInt64(int64_t val)
1011{
Andreas Huber84a6d042009-08-17 13:33:27 -07001012 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001013}
1014
Ronghua Wu2d13afd2015-03-16 11:11:07 -07001015status_t Parcel::writeUint64(uint64_t val)
1016{
1017 return writeAligned(val);
1018}
1019
Serban Constantinescuf683e012013-11-05 16:53:55 +00001020status_t Parcel::writePointer(uintptr_t val)
1021{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001022 return writeAligned<binder_uintptr_t>(val);
Serban Constantinescuf683e012013-11-05 16:53:55 +00001023}
1024
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001025status_t Parcel::writeFloat(float val)
1026{
Andreas Huber84a6d042009-08-17 13:33:27 -07001027 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001028}
1029
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001030#if defined(__mips__) && defined(__mips_hard_float)
1031
1032status_t Parcel::writeDouble(double val)
1033{
1034 union {
1035 double d;
1036 unsigned long long ll;
1037 } u;
1038 u.d = val;
1039 return writeAligned(u.ll);
1040}
1041
1042#else
1043
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001044status_t Parcel::writeDouble(double val)
1045{
Andreas Huber84a6d042009-08-17 13:33:27 -07001046 return writeAligned(val);
1047}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001048
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001049#endif
1050
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001051status_t Parcel::writeCString(const char* str)
1052{
1053 return write(str, strlen(str)+1);
1054}
1055
1056status_t Parcel::writeString8(const String8& str)
1057{
1058 status_t err = writeInt32(str.bytes());
Pravat Dalbeherad1dff8d2010-12-15 08:40:00 +01001059 // only write string if its length is more than zero characters,
1060 // as readString8 will only read if the length field is non-zero.
1061 // this is slightly different from how writeString16 works.
1062 if (str.bytes() > 0 && err == NO_ERROR) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001063 err = write(str.string(), str.bytes()+1);
1064 }
1065 return err;
1066}
1067
Casey Dahlinb9872622015-11-25 15:09:45 -08001068status_t Parcel::writeString16(const std::unique_ptr<String16>& str)
1069{
1070 if (!str) {
1071 return writeInt32(-1);
1072 }
1073
1074 return writeString16(*str);
1075}
1076
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001077status_t Parcel::writeString16(const String16& str)
1078{
1079 return writeString16(str.string(), str.size());
1080}
1081
1082status_t Parcel::writeString16(const char16_t* str, size_t len)
1083{
1084 if (str == NULL) return writeInt32(-1);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001085
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001086 status_t err = writeInt32(len);
1087 if (err == NO_ERROR) {
1088 len *= sizeof(char16_t);
1089 uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
1090 if (data) {
1091 memcpy(data, str, len);
1092 *reinterpret_cast<char16_t*>(data+len) = 0;
1093 return NO_ERROR;
1094 }
1095 err = mError;
1096 }
1097 return err;
1098}
1099
1100status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
1101{
1102 return flatten_binder(ProcessState::self(), val, this);
1103}
1104
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001105status_t Parcel::writeStrongBinderVector(const std::vector<sp<IBinder>>& val)
1106{
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001107 return writeTypedVector(val, &Parcel::writeStrongBinder);
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001108}
1109
Casey Dahlinb9872622015-11-25 15:09:45 -08001110status_t Parcel::writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val)
1111{
1112 return writeNullableTypedVector(val, &Parcel::writeStrongBinder);
1113}
1114
1115status_t Parcel::readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const {
1116 return readNullableTypedVector(val, &Parcel::readStrongBinder);
1117}
1118
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001119status_t Parcel::readStrongBinderVector(std::vector<sp<IBinder>>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001120 return readTypedVector(val, &Parcel::readStrongBinder);
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001121}
1122
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001123status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
1124{
1125 return flatten_binder(ProcessState::self(), val, this);
1126}
1127
Casey Dahlinb9872622015-11-25 15:09:45 -08001128status_t Parcel::writeRawNullableParcelable(const Parcelable* parcelable) {
1129 if (!parcelable) {
1130 return writeInt32(0);
1131 }
1132
1133 return writeParcelable(*parcelable);
1134}
1135
Christopher Wiley97f048d2015-11-19 06:49:05 -08001136status_t Parcel::writeParcelable(const Parcelable& parcelable) {
1137 status_t status = writeInt32(1); // parcelable is not null.
1138 if (status != OK) {
1139 return status;
1140 }
1141 return parcelable.writeToParcel(this);
1142}
1143
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001144status_t Parcel::writeNativeHandle(const native_handle* handle)
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001145{
Mathias Agopian1d0a95b2009-07-31 16:12:13 -07001146 if (!handle || handle->version != sizeof(native_handle))
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001147 return BAD_TYPE;
1148
1149 status_t err;
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001150 err = writeInt32(handle->numFds);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001151 if (err != NO_ERROR) return err;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001152
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001153 err = writeInt32(handle->numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001154 if (err != NO_ERROR) return err;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001155
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001156 for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)
1157 err = writeDupFileDescriptor(handle->data[i]);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001158
1159 if (err != NO_ERROR) {
Steve Block9d453682011-12-20 16:23:08 +00001160 ALOGD("write native handle, write dup fd failed");
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001161 return err;
1162 }
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001163 err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001164 return err;
1165}
1166
Jeff Brown93ff1f92011-11-04 19:01:44 -07001167status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001168{
1169 flat_binder_object obj;
1170 obj.type = BINDER_TYPE_FD;
1171 obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
Arve Hjønnevåg07fd0f12014-02-18 21:10:29 -08001172 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001173 obj.handle = fd;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001174 obj.cookie = takeOwnership ? 1 : 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001175 return writeObject(obj, true);
1176}
1177
1178status_t Parcel::writeDupFileDescriptor(int fd)
1179{
Jeff Brownd341c712011-11-04 20:19:33 -07001180 int dupFd = dup(fd);
1181 if (dupFd < 0) {
1182 return -errno;
1183 }
1184 status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/);
Casey Dahlin06673e32015-11-23 13:24:23 -08001185 if (err != OK) {
Jeff Brownd341c712011-11-04 20:19:33 -07001186 close(dupFd);
1187 }
1188 return err;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001189}
1190
Casey Dahlin06673e32015-11-23 13:24:23 -08001191status_t Parcel::writeUniqueFileDescriptor(const ScopedFd& fd) {
1192 return writeDupFileDescriptor(fd.get());
1193}
1194
1195status_t Parcel::writeUniqueFileDescriptorVector(const std::vector<ScopedFd>& val) {
1196 return writeTypedVector(val, &Parcel::writeUniqueFileDescriptor);
1197}
1198
Casey Dahlinb9872622015-11-25 15:09:45 -08001199status_t Parcel::writeUniqueFileDescriptorVector(const std::unique_ptr<std::vector<ScopedFd>>& val) {
1200 return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
1201}
1202
Jeff Brown13b16042014-11-11 16:44:25 -08001203status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob)
Jeff Brown5707dbf2011-09-23 21:17:56 -07001204{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001205 if (len > INT32_MAX) {
1206 // don't accept size_t values which may have come from an
1207 // inadvertent conversion from a negative int.
1208 return BAD_VALUE;
1209 }
1210
Jeff Brown13b16042014-11-11 16:44:25 -08001211 status_t status;
1212 if (!mAllowFds || len <= BLOB_INPLACE_LIMIT) {
Steve Block6807e592011-10-20 11:56:00 +01001213 ALOGV("writeBlob: write in place");
Jeff Brown13b16042014-11-11 16:44:25 -08001214 status = writeInt32(BLOB_INPLACE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001215 if (status) return status;
1216
1217 void* ptr = writeInplace(len);
1218 if (!ptr) return NO_MEMORY;
1219
Jeff Brown13b16042014-11-11 16:44:25 -08001220 outBlob->init(-1, ptr, len, false);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001221 return NO_ERROR;
1222 }
1223
Steve Block6807e592011-10-20 11:56:00 +01001224 ALOGV("writeBlob: write to ashmem");
Jeff Brown5707dbf2011-09-23 21:17:56 -07001225 int fd = ashmem_create_region("Parcel Blob", len);
1226 if (fd < 0) return NO_MEMORY;
1227
1228 int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
1229 if (result < 0) {
Jeff Brownec4e0062011-10-10 14:50:10 -07001230 status = result;
Jeff Brown5707dbf2011-09-23 21:17:56 -07001231 } else {
1232 void* ptr = ::mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
1233 if (ptr == MAP_FAILED) {
1234 status = -errno;
1235 } else {
Jeff Brown13b16042014-11-11 16:44:25 -08001236 if (!mutableCopy) {
1237 result = ashmem_set_prot_region(fd, PROT_READ);
1238 }
Jeff Brown5707dbf2011-09-23 21:17:56 -07001239 if (result < 0) {
Jeff Brownec4e0062011-10-10 14:50:10 -07001240 status = result;
Jeff Brown5707dbf2011-09-23 21:17:56 -07001241 } else {
Jeff Brown13b16042014-11-11 16:44:25 -08001242 status = writeInt32(mutableCopy ? BLOB_ASHMEM_MUTABLE : BLOB_ASHMEM_IMMUTABLE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001243 if (!status) {
Jeff Brown93ff1f92011-11-04 19:01:44 -07001244 status = writeFileDescriptor(fd, true /*takeOwnership*/);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001245 if (!status) {
Jeff Brown13b16042014-11-11 16:44:25 -08001246 outBlob->init(fd, ptr, len, mutableCopy);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001247 return NO_ERROR;
1248 }
1249 }
1250 }
1251 }
1252 ::munmap(ptr, len);
1253 }
1254 ::close(fd);
1255 return status;
1256}
1257
Jeff Brown13b16042014-11-11 16:44:25 -08001258status_t Parcel::writeDupImmutableBlobFileDescriptor(int fd)
1259{
1260 // Must match up with what's done in writeBlob.
1261 if (!mAllowFds) return FDS_NOT_ALLOWED;
1262 status_t status = writeInt32(BLOB_ASHMEM_IMMUTABLE);
1263 if (status) return status;
1264 return writeDupFileDescriptor(fd);
1265}
1266
Mathias Agopiane1424282013-07-29 21:24:40 -07001267status_t Parcel::write(const FlattenableHelperInterface& val)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001268{
1269 status_t err;
1270
1271 // size if needed
Mathias Agopiane1424282013-07-29 21:24:40 -07001272 const size_t len = val.getFlattenedSize();
1273 const size_t fd_count = val.getFdCount();
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001274
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001275 if ((len > INT32_MAX) || (fd_count >= gMaxFds)) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001276 // don't accept size_t values which may have come from an
1277 // inadvertent conversion from a negative int.
1278 return BAD_VALUE;
1279 }
1280
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001281 err = this->writeInt32(len);
1282 if (err) return err;
1283
1284 err = this->writeInt32(fd_count);
1285 if (err) return err;
1286
1287 // payload
Martijn Coenen732132b2018-04-04 11:46:56 +02001288 void* const buf = this->writeInplace(len);
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001289 if (buf == NULL)
1290 return BAD_VALUE;
1291
1292 int* fds = NULL;
1293 if (fd_count) {
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001294 fds = new (std::nothrow) int[fd_count];
1295 if (fds == nullptr) {
1296 ALOGE("write: failed to allocate requested %zu fds", fd_count);
1297 return BAD_VALUE;
1298 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001299 }
1300
1301 err = val.flatten(buf, len, fds, fd_count);
1302 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
1303 err = this->writeDupFileDescriptor( fds[i] );
1304 }
1305
1306 if (fd_count) {
1307 delete [] fds;
1308 }
1309
1310 return err;
1311}
1312
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001313status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
1314{
1315 const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
1316 const bool enoughObjects = mObjectsSize < mObjectsCapacity;
1317 if (enoughData && enoughObjects) {
1318restart_write:
1319 *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001320
Christopher Tate98e67d32015-06-03 18:44:15 -07001321 // remember if it's a file descriptor
1322 if (val.type == BINDER_TYPE_FD) {
1323 if (!mAllowFds) {
1324 // fail before modifying our object index
1325 return FDS_NOT_ALLOWED;
1326 }
1327 mHasFds = mFdsKnown = true;
1328 }
1329
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001330 // Need to write meta-data?
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001331 if (nullMetaData || val.binder != 0) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001332 mObjects[mObjectsSize] = mDataPos;
Adrian Rooscbf37262015-10-22 16:12:53 -07001333 acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001334 mObjectsSize++;
1335 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001336
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001337 return finishWrite(sizeof(flat_binder_object));
1338 }
1339
1340 if (!enoughData) {
1341 const status_t err = growData(sizeof(val));
1342 if (err != NO_ERROR) return err;
1343 }
1344 if (!enoughObjects) {
1345 size_t newSize = ((mObjectsSize+2)*3)/2;
Christopher Tate8b643072016-11-03 13:32:41 -07001346 if (newSize*sizeof(binder_size_t) < mObjectsSize) return NO_MEMORY; // overflow
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001347 binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001348 if (objects == NULL) return NO_MEMORY;
1349 mObjects = objects;
1350 mObjectsCapacity = newSize;
1351 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001352
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001353 goto restart_write;
1354}
1355
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07001356status_t Parcel::writeNoException()
1357{
Christopher Wiley09eb7492015-11-09 15:06:15 -08001358 binder::Status status;
1359 return status.writeToParcel(this);
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07001360}
1361
Colin Cross6f4f3ab2014-02-05 17:42:44 -08001362void Parcel::remove(size_t /*start*/, size_t /*amt*/)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001363{
1364 LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
1365}
1366
akirilovf7841832018-04-03 12:56:06 -07001367status_t Parcel::validateReadData(size_t upperBound) const
1368{
1369 // Don't allow non-object reads on object data
1370 if (mObjectsSorted || mObjectsSize <= 1) {
1371data_sorted:
1372 // Expect to check only against the next object
1373 if (mNextObjectHint < mObjectsSize && upperBound > mObjects[mNextObjectHint]) {
1374 // For some reason the current read position is greater than the next object
1375 // hint. Iterate until we find the right object
1376 size_t nextObject = mNextObjectHint;
1377 do {
1378 if (mDataPos < mObjects[nextObject] + sizeof(flat_binder_object)) {
1379 // Requested info overlaps with an object
1380 ALOGE("Attempt to read from protected data in Parcel %p", this);
1381 return PERMISSION_DENIED;
1382 }
1383 nextObject++;
1384 } while (nextObject < mObjectsSize && upperBound > mObjects[nextObject]);
1385 mNextObjectHint = nextObject;
1386 }
1387 return NO_ERROR;
1388 }
1389 // Quickly determine if mObjects is sorted.
1390 binder_size_t* currObj = mObjects + mObjectsSize - 1;
1391 binder_size_t* prevObj = currObj;
1392 while (currObj > mObjects) {
1393 prevObj--;
1394 if(*prevObj > *currObj) {
1395 goto data_unsorted;
1396 }
1397 currObj--;
1398 }
1399 mObjectsSorted = true;
1400 goto data_sorted;
1401
1402data_unsorted:
1403 // Insertion Sort mObjects
1404 // Great for mostly sorted lists. If randomly sorted or reverse ordered mObjects become common,
1405 // switch to std::sort(mObjects, mObjects + mObjectsSize);
1406 for (binder_size_t* iter0 = mObjects + 1; iter0 < mObjects + mObjectsSize; iter0++) {
1407 binder_size_t temp = *iter0;
1408 binder_size_t* iter1 = iter0 - 1;
1409 while (iter1 >= mObjects && *iter1 > temp) {
1410 *(iter1 + 1) = *iter1;
1411 iter1--;
1412 }
1413 *(iter1 + 1) = temp;
1414 }
1415 mNextObjectHint = 0;
1416 mObjectsSorted = true;
1417 goto data_sorted;
1418}
1419
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001420status_t Parcel::read(void* outData, size_t len) const
1421{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001422 if (len > INT32_MAX) {
1423 // don't accept size_t values which may have come from an
1424 // inadvertent conversion from a negative int.
1425 return BAD_VALUE;
1426 }
1427
1428 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1429 && len <= pad_size(len)) {
akirilovf7841832018-04-03 12:56:06 -07001430 if (mObjectsSize > 0) {
1431 status_t err = validateReadData(mDataPos + pad_size(len));
Michael Wachenschwanz6a825e82018-04-17 16:52:40 -07001432 if(err != NO_ERROR) {
1433 // Still increment the data position by the expected length
1434 mDataPos += pad_size(len);
1435 ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
1436 return err;
1437 }
akirilovf7841832018-04-03 12:56:06 -07001438 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001439 memcpy(outData, mData+mDataPos, len);
Nick Kralevichb6b14232015-04-02 09:36:02 -07001440 mDataPos += pad_size(len);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001441 ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001442 return NO_ERROR;
1443 }
1444 return NOT_ENOUGH_DATA;
1445}
1446
1447const void* Parcel::readInplace(size_t len) const
1448{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001449 if (len > INT32_MAX) {
1450 // don't accept size_t values which may have come from an
1451 // inadvertent conversion from a negative int.
1452 return NULL;
1453 }
1454
1455 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1456 && len <= pad_size(len)) {
akirilovf7841832018-04-03 12:56:06 -07001457 if (mObjectsSize > 0) {
1458 status_t err = validateReadData(mDataPos + pad_size(len));
Michael Wachenschwanz6a825e82018-04-17 16:52:40 -07001459 if(err != NO_ERROR) {
1460 // Still increment the data position by the expected length
1461 mDataPos += pad_size(len);
1462 ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
1463 return NULL;
1464 }
akirilovf7841832018-04-03 12:56:06 -07001465 }
1466
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001467 const void* data = mData+mDataPos;
Nick Kralevichb6b14232015-04-02 09:36:02 -07001468 mDataPos += pad_size(len);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001469 ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001470 return data;
1471 }
1472 return NULL;
1473}
1474
Andreas Huber84a6d042009-08-17 13:33:27 -07001475template<class T>
1476status_t Parcel::readAligned(T *pArg) const {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001477 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
Andreas Huber84a6d042009-08-17 13:33:27 -07001478
1479 if ((mDataPos+sizeof(T)) <= mDataSize) {
akirilovf7841832018-04-03 12:56:06 -07001480 if (mObjectsSize > 0) {
1481 status_t err = validateReadData(mDataPos + sizeof(T));
Michael Wachenschwanz6a825e82018-04-17 16:52:40 -07001482 if(err != NO_ERROR) {
1483 // Still increment the data position by the expected length
1484 mDataPos += sizeof(T);
1485 return err;
1486 }
akirilovf7841832018-04-03 12:56:06 -07001487 }
1488
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001489 const void* data = mData+mDataPos;
Andreas Huber84a6d042009-08-17 13:33:27 -07001490 mDataPos += sizeof(T);
1491 *pArg = *reinterpret_cast<const T*>(data);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001492 return NO_ERROR;
1493 } else {
1494 return NOT_ENOUGH_DATA;
1495 }
1496}
1497
Andreas Huber84a6d042009-08-17 13:33:27 -07001498template<class T>
1499T Parcel::readAligned() const {
1500 T result;
1501 if (readAligned(&result) != NO_ERROR) {
1502 result = 0;
1503 }
1504
1505 return result;
1506}
1507
1508template<class T>
1509status_t Parcel::writeAligned(T val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001510 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
Andreas Huber84a6d042009-08-17 13:33:27 -07001511
1512 if ((mDataPos+sizeof(val)) <= mDataCapacity) {
1513restart_write:
1514 *reinterpret_cast<T*>(mData+mDataPos) = val;
1515 return finishWrite(sizeof(val));
1516 }
1517
1518 status_t err = growData(sizeof(val));
1519 if (err == NO_ERROR) goto restart_write;
1520 return err;
1521}
1522
Casey Dahlin0b1cf332016-02-09 11:08:35 -08001523namespace {
1524
1525template<typename T>
1526status_t readByteVectorInternal(const Parcel* parcel,
1527 std::vector<T>* val) {
Casey Dahlin451ff582015-10-19 18:12:18 -07001528 val->clear();
1529
1530 int32_t size;
Casey Dahlin0b1cf332016-02-09 11:08:35 -08001531 status_t status = parcel->readInt32(&size);
Casey Dahlin451ff582015-10-19 18:12:18 -07001532
1533 if (status != OK) {
1534 return status;
1535 }
1536
Christopher Wiley4db672d2015-11-10 09:44:30 -08001537 if (size < 0) {
1538 status = UNEXPECTED_NULL;
1539 return status;
1540 }
Casey Dahlin0b1cf332016-02-09 11:08:35 -08001541 if (size_t(size) > parcel->dataAvail()) {
Christopher Wileyf0fc52b2015-10-31 13:22:15 -07001542 status = BAD_VALUE;
1543 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -07001544 }
Christopher Wiley4db672d2015-11-10 09:44:30 -08001545
Casey Dahlin0b1cf332016-02-09 11:08:35 -08001546 const void* data = parcel->readInplace(size);
Christopher Wileyf0fc52b2015-10-31 13:22:15 -07001547 if (!data) {
1548 status = BAD_VALUE;
1549 return status;
1550 }
Casey Dahlin451ff582015-10-19 18:12:18 -07001551 val->resize(size);
Christopher Wileyf0fc52b2015-10-31 13:22:15 -07001552 memcpy(val->data(), data, size);
Casey Dahlin451ff582015-10-19 18:12:18 -07001553
Christopher Wileyf0fc52b2015-10-31 13:22:15 -07001554 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -07001555}
1556
Casey Dahlin0b1cf332016-02-09 11:08:35 -08001557template<typename T>
1558status_t readByteVectorInternalPtr(
1559 const Parcel* parcel,
1560 std::unique_ptr<std::vector<T>>* val) {
1561 const int32_t start = parcel->dataPosition();
Casey Dahlinb9872622015-11-25 15:09:45 -08001562 int32_t size;
Casey Dahlin0b1cf332016-02-09 11:08:35 -08001563 status_t status = parcel->readInt32(&size);
Casey Dahlinb9872622015-11-25 15:09:45 -08001564 val->reset();
1565
1566 if (status != OK || size < 0) {
1567 return status;
1568 }
1569
Casey Dahlin0b1cf332016-02-09 11:08:35 -08001570 parcel->setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001571 val->reset(new (std::nothrow) std::vector<T>());
Casey Dahlinb9872622015-11-25 15:09:45 -08001572
Casey Dahlin0b1cf332016-02-09 11:08:35 -08001573 status = readByteVectorInternal(parcel, val->get());
Casey Dahlinb9872622015-11-25 15:09:45 -08001574
1575 if (status != OK) {
1576 val->reset();
1577 }
1578
1579 return status;
1580}
1581
Casey Dahlin0b1cf332016-02-09 11:08:35 -08001582} // namespace
1583
1584status_t Parcel::readByteVector(std::vector<int8_t>* val) const {
1585 return readByteVectorInternal(this, val);
1586}
1587
1588status_t Parcel::readByteVector(std::vector<uint8_t>* val) const {
1589 return readByteVectorInternal(this, val);
1590}
1591
1592status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const {
1593 return readByteVectorInternalPtr(this, val);
1594}
1595
1596status_t Parcel::readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const {
1597 return readByteVectorInternalPtr(this, val);
1598}
1599
Casey Dahlinb9872622015-11-25 15:09:45 -08001600status_t Parcel::readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const {
1601 return readNullableTypedVector(val, &Parcel::readInt32);
1602}
1603
Casey Dahlin451ff582015-10-19 18:12:18 -07001604status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001605 return readTypedVector(val, &Parcel::readInt32);
Casey Dahlin451ff582015-10-19 18:12:18 -07001606}
1607
Casey Dahlinb9872622015-11-25 15:09:45 -08001608status_t Parcel::readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const {
1609 return readNullableTypedVector(val, &Parcel::readInt64);
1610}
1611
Casey Dahlin451ff582015-10-19 18:12:18 -07001612status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001613 return readTypedVector(val, &Parcel::readInt64);
Casey Dahlin451ff582015-10-19 18:12:18 -07001614}
1615
Casey Dahlinb9872622015-11-25 15:09:45 -08001616status_t Parcel::readFloatVector(std::unique_ptr<std::vector<float>>* val) const {
1617 return readNullableTypedVector(val, &Parcel::readFloat);
1618}
1619
Casey Dahlin451ff582015-10-19 18:12:18 -07001620status_t Parcel::readFloatVector(std::vector<float>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001621 return readTypedVector(val, &Parcel::readFloat);
Casey Dahlin451ff582015-10-19 18:12:18 -07001622}
1623
Casey Dahlinb9872622015-11-25 15:09:45 -08001624status_t Parcel::readDoubleVector(std::unique_ptr<std::vector<double>>* val) const {
1625 return readNullableTypedVector(val, &Parcel::readDouble);
1626}
1627
Casey Dahlin451ff582015-10-19 18:12:18 -07001628status_t Parcel::readDoubleVector(std::vector<double>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001629 return readTypedVector(val, &Parcel::readDouble);
Casey Dahlin451ff582015-10-19 18:12:18 -07001630}
1631
Casey Dahlinb9872622015-11-25 15:09:45 -08001632status_t Parcel::readBoolVector(std::unique_ptr<std::vector<bool>>* val) const {
1633 const int32_t start = dataPosition();
1634 int32_t size;
1635 status_t status = readInt32(&size);
1636 val->reset();
Casey Dahlin451ff582015-10-19 18:12:18 -07001637
Casey Dahlinb9872622015-11-25 15:09:45 -08001638 if (status != OK || size < 0) {
1639 return status;
1640 }
1641
1642 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001643 val->reset(new (std::nothrow) std::vector<bool>());
Casey Dahlinb9872622015-11-25 15:09:45 -08001644
1645 status = readBoolVector(val->get());
1646
1647 if (status != OK) {
1648 val->reset();
1649 }
1650
1651 return status;
1652}
1653
1654status_t Parcel::readBoolVector(std::vector<bool>* val) const {
Casey Dahlin451ff582015-10-19 18:12:18 -07001655 int32_t size;
1656 status_t status = readInt32(&size);
1657
1658 if (status != OK) {
1659 return status;
1660 }
1661
1662 if (size < 0) {
Christopher Wiley4db672d2015-11-10 09:44:30 -08001663 return UNEXPECTED_NULL;
Casey Dahlin451ff582015-10-19 18:12:18 -07001664 }
1665
1666 val->resize(size);
1667
1668 /* C++ bool handling means a vector of bools isn't necessarily addressable
1669 * (we might use individual bits)
1670 */
Christopher Wiley97887982015-10-27 16:33:47 -07001671 bool data;
1672 for (int32_t i = 0; i < size; ++i) {
Casey Dahlin451ff582015-10-19 18:12:18 -07001673 status = readBool(&data);
1674 (*val)[i] = data;
1675
1676 if (status != OK) {
1677 return status;
1678 }
1679 }
1680
1681 return OK;
1682}
1683
Casey Dahlinb9872622015-11-25 15:09:45 -08001684status_t Parcel::readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const {
1685 return readNullableTypedVector(val, &Parcel::readChar);
1686}
1687
Casey Dahlin451ff582015-10-19 18:12:18 -07001688status_t Parcel::readCharVector(std::vector<char16_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001689 return readTypedVector(val, &Parcel::readChar);
Casey Dahlin451ff582015-10-19 18:12:18 -07001690}
1691
Casey Dahlinb9872622015-11-25 15:09:45 -08001692status_t Parcel::readString16Vector(
1693 std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const {
1694 return readNullableTypedVector(val, &Parcel::readString16);
1695}
1696
Casey Dahlin451ff582015-10-19 18:12:18 -07001697status_t Parcel::readString16Vector(std::vector<String16>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001698 return readTypedVector(val, &Parcel::readString16);
Casey Dahlin451ff582015-10-19 18:12:18 -07001699}
1700
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001701status_t Parcel::readUtf8VectorFromUtf16Vector(
1702 std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const {
1703 return readNullableTypedVector(val, &Parcel::readUtf8FromUtf16);
1704}
1705
1706status_t Parcel::readUtf8VectorFromUtf16Vector(std::vector<std::string>* val) const {
1707 return readTypedVector(val, &Parcel::readUtf8FromUtf16);
1708}
Casey Dahlin451ff582015-10-19 18:12:18 -07001709
Andreas Huber84a6d042009-08-17 13:33:27 -07001710status_t Parcel::readInt32(int32_t *pArg) const
1711{
1712 return readAligned(pArg);
1713}
1714
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001715int32_t Parcel::readInt32() const
1716{
Andreas Huber84a6d042009-08-17 13:33:27 -07001717 return readAligned<int32_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001718}
1719
Dan Stoza41a0f2f2014-12-01 10:01:10 -08001720status_t Parcel::readUint32(uint32_t *pArg) const
1721{
1722 return readAligned(pArg);
1723}
1724
1725uint32_t Parcel::readUint32() const
1726{
1727 return readAligned<uint32_t>();
1728}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001729
1730status_t Parcel::readInt64(int64_t *pArg) const
1731{
Andreas Huber84a6d042009-08-17 13:33:27 -07001732 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001733}
1734
1735
1736int64_t Parcel::readInt64() const
1737{
Andreas Huber84a6d042009-08-17 13:33:27 -07001738 return readAligned<int64_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001739}
1740
Ronghua Wu2d13afd2015-03-16 11:11:07 -07001741status_t Parcel::readUint64(uint64_t *pArg) const
1742{
1743 return readAligned(pArg);
1744}
1745
1746uint64_t Parcel::readUint64() const
1747{
1748 return readAligned<uint64_t>();
1749}
1750
Serban Constantinescuf683e012013-11-05 16:53:55 +00001751status_t Parcel::readPointer(uintptr_t *pArg) const
1752{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001753 status_t ret;
1754 binder_uintptr_t ptr;
1755 ret = readAligned(&ptr);
1756 if (!ret)
1757 *pArg = ptr;
1758 return ret;
Serban Constantinescuf683e012013-11-05 16:53:55 +00001759}
1760
1761uintptr_t Parcel::readPointer() const
1762{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001763 return readAligned<binder_uintptr_t>();
Serban Constantinescuf683e012013-11-05 16:53:55 +00001764}
1765
1766
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001767status_t Parcel::readFloat(float *pArg) const
1768{
Andreas Huber84a6d042009-08-17 13:33:27 -07001769 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001770}
1771
1772
1773float Parcel::readFloat() const
1774{
Andreas Huber84a6d042009-08-17 13:33:27 -07001775 return readAligned<float>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001776}
1777
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001778#if defined(__mips__) && defined(__mips_hard_float)
1779
1780status_t Parcel::readDouble(double *pArg) const
1781{
1782 union {
1783 double d;
1784 unsigned long long ll;
1785 } u;
Narayan Kamath2c68d382014-06-04 15:04:29 +01001786 u.d = 0;
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001787 status_t status;
1788 status = readAligned(&u.ll);
1789 *pArg = u.d;
1790 return status;
1791}
1792
1793double Parcel::readDouble() const
1794{
1795 union {
1796 double d;
1797 unsigned long long ll;
1798 } u;
1799 u.ll = readAligned<unsigned long long>();
1800 return u.d;
1801}
1802
1803#else
1804
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001805status_t Parcel::readDouble(double *pArg) const
1806{
Andreas Huber84a6d042009-08-17 13:33:27 -07001807 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001808}
1809
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001810double Parcel::readDouble() const
1811{
Andreas Huber84a6d042009-08-17 13:33:27 -07001812 return readAligned<double>();
1813}
1814
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001815#endif
1816
Andreas Huber84a6d042009-08-17 13:33:27 -07001817status_t Parcel::readIntPtr(intptr_t *pArg) const
1818{
1819 return readAligned(pArg);
1820}
1821
1822
1823intptr_t Parcel::readIntPtr() const
1824{
1825 return readAligned<intptr_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001826}
1827
Casey Dahlind6848f52015-10-15 15:44:59 -07001828status_t Parcel::readBool(bool *pArg) const
1829{
1830 int32_t tmp;
1831 status_t ret = readInt32(&tmp);
1832 *pArg = (tmp != 0);
1833 return ret;
1834}
1835
1836bool Parcel::readBool() const
1837{
1838 return readInt32() != 0;
1839}
1840
1841status_t Parcel::readChar(char16_t *pArg) const
1842{
1843 int32_t tmp;
1844 status_t ret = readInt32(&tmp);
1845 *pArg = char16_t(tmp);
1846 return ret;
1847}
1848
1849char16_t Parcel::readChar() const
1850{
1851 return char16_t(readInt32());
1852}
1853
1854status_t Parcel::readByte(int8_t *pArg) const
1855{
1856 int32_t tmp;
1857 status_t ret = readInt32(&tmp);
1858 *pArg = int8_t(tmp);
1859 return ret;
1860}
1861
1862int8_t Parcel::readByte() const
1863{
1864 return int8_t(readInt32());
1865}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001866
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001867status_t Parcel::readUtf8FromUtf16(std::string* str) const {
1868 size_t utf16Size = 0;
1869 const char16_t* src = readString16Inplace(&utf16Size);
1870 if (!src) {
1871 return UNEXPECTED_NULL;
1872 }
1873
1874 // Save ourselves the trouble, we're done.
1875 if (utf16Size == 0u) {
1876 str->clear();
1877 return NO_ERROR;
1878 }
1879
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001880 // Allow for closing '\0'
1881 ssize_t utf8Size = utf16_to_utf8_length(src, utf16Size) + 1;
1882 if (utf8Size < 1) {
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001883 return BAD_VALUE;
1884 }
1885 // Note that while it is probably safe to assume string::resize keeps a
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001886 // spare byte around for the trailing null, we still pass the size including the trailing null
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001887 str->resize(utf8Size);
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001888 utf16_to_utf8(src, utf16Size, &((*str)[0]), utf8Size);
1889 str->resize(utf8Size - 1);
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001890 return NO_ERROR;
1891}
1892
1893status_t Parcel::readUtf8FromUtf16(std::unique_ptr<std::string>* str) const {
1894 const int32_t start = dataPosition();
1895 int32_t size;
1896 status_t status = readInt32(&size);
1897 str->reset();
1898
1899 if (status != OK || size < 0) {
1900 return status;
1901 }
1902
1903 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001904 str->reset(new (std::nothrow) std::string());
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001905 return readUtf8FromUtf16(str->get());
1906}
1907
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001908const char* Parcel::readCString() const
1909{
Steven Morelandd0d4b582019-05-17 13:14:06 -07001910 if (mDataPos < mDataSize) {
1911 const size_t avail = mDataSize-mDataPos;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001912 const char* str = reinterpret_cast<const char*>(mData+mDataPos);
1913 // is the string's trailing NUL within the parcel's valid bounds?
1914 const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
1915 if (eos) {
1916 const size_t len = eos - str;
Nick Kralevichb6b14232015-04-02 09:36:02 -07001917 mDataPos += pad_size(len+1);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001918 ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001919 return str;
1920 }
1921 }
1922 return NULL;
1923}
1924
1925String8 Parcel::readString8() const
1926{
1927 int32_t size = readInt32();
1928 // watch for potential int overflow adding 1 for trailing NUL
1929 if (size > 0 && size < INT32_MAX) {
1930 const char* str = (const char*)readInplace(size+1);
1931 if (str) return String8(str, size);
1932 }
1933 return String8();
1934}
1935
1936String16 Parcel::readString16() const
1937{
1938 size_t len;
1939 const char16_t* str = readString16Inplace(&len);
1940 if (str) return String16(str, len);
Steve Blocke6f43dd2012-01-06 19:20:56 +00001941 ALOGE("Reading a NULL string not supported here.");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001942 return String16();
1943}
1944
Casey Dahlinb9872622015-11-25 15:09:45 -08001945status_t Parcel::readString16(std::unique_ptr<String16>* pArg) const
1946{
1947 const int32_t start = dataPosition();
1948 int32_t size;
1949 status_t status = readInt32(&size);
1950 pArg->reset();
1951
1952 if (status != OK || size < 0) {
1953 return status;
1954 }
1955
1956 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001957 pArg->reset(new (std::nothrow) String16());
Casey Dahlinb9872622015-11-25 15:09:45 -08001958
1959 status = readString16(pArg->get());
1960
1961 if (status != OK) {
1962 pArg->reset();
1963 }
1964
1965 return status;
1966}
1967
Casey Dahlin451ff582015-10-19 18:12:18 -07001968status_t Parcel::readString16(String16* pArg) const
1969{
1970 size_t len;
1971 const char16_t* str = readString16Inplace(&len);
1972 if (str) {
Casey Dahlin1515ea12015-10-20 16:26:23 -07001973 pArg->setTo(str, len);
Casey Dahlin451ff582015-10-19 18:12:18 -07001974 return 0;
1975 } else {
1976 *pArg = String16();
Christopher Wiley4db672d2015-11-10 09:44:30 -08001977 return UNEXPECTED_NULL;
Casey Dahlin451ff582015-10-19 18:12:18 -07001978 }
1979}
1980
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001981const char16_t* Parcel::readString16Inplace(size_t* outLen) const
1982{
1983 int32_t size = readInt32();
1984 // watch for potential int overflow from size+1
1985 if (size >= 0 && size < INT32_MAX) {
1986 *outLen = size;
1987 const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
1988 if (str != NULL) {
1989 return str;
1990 }
1991 }
1992 *outLen = 0;
1993 return NULL;
1994}
1995
Casey Dahlinf0c13772015-10-27 18:33:56 -07001996status_t Parcel::readStrongBinder(sp<IBinder>* val) const
1997{
1998 return unflatten_binder(ProcessState::self(), *this, val);
1999}
2000
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002001sp<IBinder> Parcel::readStrongBinder() const
2002{
2003 sp<IBinder> val;
Casey Dahlinf0c13772015-10-27 18:33:56 -07002004 readStrongBinder(&val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002005 return val;
2006}
2007
2008wp<IBinder> Parcel::readWeakBinder() const
2009{
2010 wp<IBinder> val;
2011 unflatten_binder(ProcessState::self(), *this, &val);
2012 return val;
2013}
2014
Christopher Wiley97f048d2015-11-19 06:49:05 -08002015status_t Parcel::readParcelable(Parcelable* parcelable) const {
2016 int32_t have_parcelable = 0;
2017 status_t status = readInt32(&have_parcelable);
2018 if (status != OK) {
2019 return status;
2020 }
2021 if (!have_parcelable) {
2022 return UNEXPECTED_NULL;
2023 }
2024 return parcelable->readFromParcel(this);
2025}
2026
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07002027int32_t Parcel::readExceptionCode() const
2028{
Christopher Wiley09eb7492015-11-09 15:06:15 -08002029 binder::Status status;
2030 status.readFromParcel(*this);
2031 return status.exceptionCode();
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07002032}
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002033
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002034native_handle* Parcel::readNativeHandle() const
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002035{
2036 int numFds, numInts;
2037 status_t err;
2038 err = readInt32(&numFds);
2039 if (err != NO_ERROR) return 0;
2040 err = readInt32(&numInts);
2041 if (err != NO_ERROR) return 0;
2042
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002043 native_handle* h = native_handle_create(numFds, numInts);
Adam Lesinskieaac99a2015-05-12 17:35:48 -07002044 if (!h) {
2045 return 0;
2046 }
2047
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002048 for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
Rebecca Schultz Zavin360211f2009-02-13 16:34:38 -08002049 h->data[i] = dup(readFileDescriptor());
Marco Nelissen1de79662016-04-26 08:44:09 -07002050 if (h->data[i] < 0) {
2051 for (int j = 0; j < i; j++) {
2052 close(h->data[j]);
2053 }
2054 native_handle_delete(h);
2055 return 0;
2056 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002057 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002058 err = read(h->data + numFds, sizeof(int)*numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002059 if (err != NO_ERROR) {
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002060 native_handle_close(h);
2061 native_handle_delete(h);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002062 h = 0;
2063 }
2064 return h;
2065}
2066
2067
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002068int Parcel::readFileDescriptor() const
2069{
2070 const flat_binder_object* flat = readObject(true);
Casey Dahlin06673e32015-11-23 13:24:23 -08002071
2072 if (flat && flat->type == BINDER_TYPE_FD) {
2073 return flat->handle;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002074 }
Casey Dahlin06673e32015-11-23 13:24:23 -08002075
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002076 return BAD_TYPE;
2077}
2078
Casey Dahlin06673e32015-11-23 13:24:23 -08002079status_t Parcel::readUniqueFileDescriptor(ScopedFd* val) const
2080{
2081 int got = readFileDescriptor();
2082
2083 if (got == BAD_TYPE) {
2084 return BAD_TYPE;
2085 }
2086
2087 val->reset(dup(got));
2088
2089 if (val->get() < 0) {
2090 return BAD_VALUE;
2091 }
2092
2093 return OK;
2094}
2095
2096
Casey Dahlinb9872622015-11-25 15:09:45 -08002097status_t Parcel::readUniqueFileDescriptorVector(std::unique_ptr<std::vector<ScopedFd>>* val) const {
2098 return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
2099}
2100
Casey Dahlin06673e32015-11-23 13:24:23 -08002101status_t Parcel::readUniqueFileDescriptorVector(std::vector<ScopedFd>* val) const {
2102 return readTypedVector(val, &Parcel::readUniqueFileDescriptor);
2103}
2104
Jeff Brown5707dbf2011-09-23 21:17:56 -07002105status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
2106{
Jeff Brown13b16042014-11-11 16:44:25 -08002107 int32_t blobType;
2108 status_t status = readInt32(&blobType);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002109 if (status) return status;
2110
Jeff Brown13b16042014-11-11 16:44:25 -08002111 if (blobType == BLOB_INPLACE) {
Steve Block6807e592011-10-20 11:56:00 +01002112 ALOGV("readBlob: read in place");
Jeff Brown5707dbf2011-09-23 21:17:56 -07002113 const void* ptr = readInplace(len);
2114 if (!ptr) return BAD_VALUE;
2115
Jeff Brown13b16042014-11-11 16:44:25 -08002116 outBlob->init(-1, const_cast<void*>(ptr), len, false);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002117 return NO_ERROR;
2118 }
2119
Steve Block6807e592011-10-20 11:56:00 +01002120 ALOGV("readBlob: read from ashmem");
Jeff Brown13b16042014-11-11 16:44:25 -08002121 bool isMutable = (blobType == BLOB_ASHMEM_MUTABLE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002122 int fd = readFileDescriptor();
2123 if (fd == int(BAD_TYPE)) return BAD_VALUE;
2124
Jeff Brown13b16042014-11-11 16:44:25 -08002125 void* ptr = ::mmap(NULL, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ,
2126 MAP_SHARED, fd, 0);
Narayan Kamath9ea09752014-10-08 17:35:45 +01002127 if (ptr == MAP_FAILED) return NO_MEMORY;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002128
Jeff Brown13b16042014-11-11 16:44:25 -08002129 outBlob->init(fd, ptr, len, isMutable);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002130 return NO_ERROR;
2131}
2132
Mathias Agopiane1424282013-07-29 21:24:40 -07002133status_t Parcel::read(FlattenableHelperInterface& val) const
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002134{
2135 // size
2136 const size_t len = this->readInt32();
2137 const size_t fd_count = this->readInt32();
2138
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002139 if ((len > INT32_MAX) || (fd_count >= gMaxFds)) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07002140 // don't accept size_t values which may have come from an
2141 // inadvertent conversion from a negative int.
2142 return BAD_VALUE;
2143 }
2144
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002145 // payload
Nick Kralevichb6b14232015-04-02 09:36:02 -07002146 void const* const buf = this->readInplace(pad_size(len));
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002147 if (buf == NULL)
2148 return BAD_VALUE;
2149
2150 int* fds = NULL;
2151 if (fd_count) {
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002152 fds = new (std::nothrow) int[fd_count];
2153 if (fds == nullptr) {
2154 ALOGE("read: failed to allocate requested %zu fds", fd_count);
2155 return BAD_VALUE;
2156 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002157 }
2158
2159 status_t err = NO_ERROR;
2160 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
Jesse Hallfee99042014-11-04 08:36:31 -08002161 fds[i] = dup(this->readFileDescriptor());
Jun Jiangabf8a2c2014-04-29 14:22:10 +08002162 if (fds[i] < 0) {
2163 err = BAD_VALUE;
Jesse Hallfee99042014-11-04 08:36:31 -08002164 ALOGE("dup() failed in Parcel::read, i is %zu, fds[i] is %d, fd_count is %zu, error: %s",
2165 i, fds[i], fd_count, strerror(errno));
Jun Jiangabf8a2c2014-04-29 14:22:10 +08002166 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002167 }
2168
2169 if (err == NO_ERROR) {
2170 err = val.unflatten(buf, len, fds, fd_count);
2171 }
2172
2173 if (fd_count) {
2174 delete [] fds;
2175 }
2176
2177 return err;
2178}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002179const flat_binder_object* Parcel::readObject(bool nullMetaData) const
2180{
2181 const size_t DPOS = mDataPos;
2182 if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
2183 const flat_binder_object* obj
2184 = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
2185 mDataPos = DPOS + sizeof(flat_binder_object);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002186 if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) {
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002187 // When transferring a NULL object, we don't write it into
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002188 // the object list, so we don't want to check for it when
2189 // reading.
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002190 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002191 return obj;
2192 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002193
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002194 // Ensure that this object is valid...
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002195 binder_size_t* const OBJS = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002196 const size_t N = mObjectsSize;
2197 size_t opos = mNextObjectHint;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002198
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002199 if (N > 0) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002200 ALOGV("Parcel %p looking for obj at %zu, hint=%zu",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002201 this, DPOS, opos);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002202
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002203 // Start at the current hint position, looking for an object at
2204 // the current data position.
2205 if (opos < N) {
2206 while (opos < (N-1) && OBJS[opos] < DPOS) {
2207 opos++;
2208 }
2209 } else {
2210 opos = N-1;
2211 }
2212 if (OBJS[opos] == DPOS) {
2213 // Found it!
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002214 ALOGV("Parcel %p found obj %zu at index %zu with forward search",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002215 this, DPOS, opos);
2216 mNextObjectHint = opos+1;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002217 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002218 return obj;
2219 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002220
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002221 // Look backwards for it...
2222 while (opos > 0 && OBJS[opos] > DPOS) {
2223 opos--;
2224 }
2225 if (OBJS[opos] == DPOS) {
2226 // Found it!
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002227 ALOGV("Parcel %p found obj %zu at index %zu with backward search",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002228 this, DPOS, opos);
2229 mNextObjectHint = opos+1;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002230 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002231 return obj;
2232 }
2233 }
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002234 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 -07002235 this, DPOS);
2236 }
2237 return NULL;
2238}
2239
2240void Parcel::closeFileDescriptors()
2241{
2242 size_t i = mObjectsSize;
2243 if (i > 0) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002244 //ALOGI("Closing file descriptors for %zu objects...", i);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002245 }
2246 while (i > 0) {
2247 i--;
2248 const flat_binder_object* flat
2249 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
2250 if (flat->type == BINDER_TYPE_FD) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002251 //ALOGI("Closing fd: %ld", flat->handle);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002252 close(flat->handle);
2253 }
2254 }
2255}
2256
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002257uintptr_t Parcel::ipcData() const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002258{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002259 return reinterpret_cast<uintptr_t>(mData);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002260}
2261
2262size_t Parcel::ipcDataSize() const
2263{
2264 return (mDataSize > mDataPos ? mDataSize : mDataPos);
2265}
2266
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002267uintptr_t Parcel::ipcObjects() const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002268{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002269 return reinterpret_cast<uintptr_t>(mObjects);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002270}
2271
2272size_t Parcel::ipcObjectsCount() const
2273{
2274 return mObjectsSize;
2275}
2276
2277void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002278 const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002279{
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002280 binder_size_t minOffset = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002281 freeDataNoInit();
2282 mError = NO_ERROR;
2283 mData = const_cast<uint8_t*>(data);
2284 mDataSize = mDataCapacity = dataSize;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002285 //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)", this, mDataSize, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002286 mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002287 ALOGV("setDataReference Setting data pos of %p to %zu", this, mDataPos);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002288 mObjects = const_cast<binder_size_t*>(objects);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002289 mObjectsSize = mObjectsCapacity = objectsCount;
2290 mNextObjectHint = 0;
akirilovf7841832018-04-03 12:56:06 -07002291 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002292 mOwner = relFunc;
2293 mOwnerCookie = relCookie;
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002294 for (size_t i = 0; i < mObjectsSize; i++) {
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002295 binder_size_t offset = mObjects[i];
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002296 if (offset < minOffset) {
Dan Albert3bdc5b82014-11-20 11:50:23 -08002297 ALOGE("%s: bad object offset %" PRIu64 " < %" PRIu64 "\n",
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002298 __func__, (uint64_t)offset, (uint64_t)minOffset);
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002299 mObjectsSize = 0;
2300 break;
2301 }
2302 minOffset = offset + sizeof(flat_binder_object);
2303 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002304 scanForFds();
2305}
2306
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002307void Parcel::print(TextOutput& to, uint32_t /*flags*/) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002308{
2309 to << "Parcel(";
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002310
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002311 if (errorCheck() != NO_ERROR) {
2312 const status_t err = errorCheck();
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002313 to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\"";
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002314 } else if (dataSize() > 0) {
2315 const uint8_t* DATA = data();
2316 to << indent << HexDump(DATA, dataSize()) << dedent;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002317 const binder_size_t* OBJS = objects();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002318 const size_t N = objectsCount();
2319 for (size_t i=0; i<N; i++) {
2320 const flat_binder_object* flat
2321 = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
2322 to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
2323 << TypeCode(flat->type & 0x7f7f7f00)
2324 << " = " << flat->binder;
2325 }
2326 } else {
2327 to << "NULL";
2328 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002329
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002330 to << ")";
2331}
2332
2333void Parcel::releaseObjects()
2334{
2335 const sp<ProcessState> proc(ProcessState::self());
2336 size_t i = mObjectsSize;
2337 uint8_t* const data = mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002338 binder_size_t* const objects = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002339 while (i > 0) {
2340 i--;
2341 const flat_binder_object* flat
2342 = reinterpret_cast<flat_binder_object*>(data+objects[i]);
Adrian Rooscbf37262015-10-22 16:12:53 -07002343 release_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002344 }
2345}
2346
2347void Parcel::acquireObjects()
2348{
2349 const sp<ProcessState> proc(ProcessState::self());
2350 size_t i = mObjectsSize;
2351 uint8_t* const data = mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002352 binder_size_t* const objects = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002353 while (i > 0) {
2354 i--;
2355 const flat_binder_object* flat
2356 = reinterpret_cast<flat_binder_object*>(data+objects[i]);
Adrian Rooscbf37262015-10-22 16:12:53 -07002357 acquire_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002358 }
2359}
2360
2361void Parcel::freeData()
2362{
2363 freeDataNoInit();
2364 initState();
2365}
2366
2367void Parcel::freeDataNoInit()
2368{
2369 if (mOwner) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002370 LOG_ALLOC("Parcel %p: freeing other owner data", this);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002371 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002372 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
2373 } else {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002374 LOG_ALLOC("Parcel %p: freeing allocated data", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002375 releaseObjects();
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002376 if (mData) {
2377 LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002378 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dan Austin48fd7b42015-09-10 13:46:02 -07002379 if (mDataCapacity <= gParcelGlobalAllocSize) {
2380 gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity;
2381 } else {
2382 gParcelGlobalAllocSize = 0;
2383 }
2384 if (gParcelGlobalAllocCount > 0) {
2385 gParcelGlobalAllocCount--;
2386 }
Dianne Hackborna4cff882014-11-13 17:07:40 -08002387 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002388 free(mData);
2389 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002390 if (mObjects) free(mObjects);
2391 }
2392}
2393
2394status_t Parcel::growData(size_t len)
2395{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002396 if (len > INT32_MAX) {
2397 // don't accept size_t values which may have come from an
2398 // inadvertent conversion from a negative int.
2399 return BAD_VALUE;
2400 }
2401
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002402 size_t newSize = ((mDataSize+len)*3)/2;
2403 return (newSize <= mDataSize)
2404 ? (status_t) NO_MEMORY
2405 : continueWrite(newSize);
2406}
2407
2408status_t Parcel::restartWrite(size_t desired)
2409{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002410 if (desired > INT32_MAX) {
2411 // don't accept size_t values which may have come from an
2412 // inadvertent conversion from a negative int.
2413 return BAD_VALUE;
2414 }
2415
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002416 if (mOwner) {
2417 freeData();
2418 return continueWrite(desired);
2419 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002420
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002421 uint8_t* data = (uint8_t*)realloc(mData, desired);
2422 if (!data && desired > mDataCapacity) {
2423 mError = NO_MEMORY;
2424 return NO_MEMORY;
2425 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002426
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002427 releaseObjects();
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002428
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002429 if (data) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002430 LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002431 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002432 gParcelGlobalAllocSize += desired;
2433 gParcelGlobalAllocSize -= mDataCapacity;
Colin Cross83ec65e2015-12-08 17:15:50 -08002434 if (!mData) {
2435 gParcelGlobalAllocCount++;
2436 }
Dianne Hackborna4cff882014-11-13 17:07:40 -08002437 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002438 mData = data;
2439 mDataCapacity = desired;
2440 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002441
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002442 mDataSize = mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002443 ALOGV("restartWrite Setting data size of %p to %zu", this, mDataSize);
2444 ALOGV("restartWrite Setting data pos of %p to %zu", this, mDataPos);
2445
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002446 free(mObjects);
2447 mObjects = NULL;
2448 mObjectsSize = mObjectsCapacity = 0;
2449 mNextObjectHint = 0;
akirilovf7841832018-04-03 12:56:06 -07002450 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002451 mHasFds = false;
2452 mFdsKnown = true;
Dianne Hackborn8938ed22011-09-28 23:19:47 -04002453 mAllowFds = true;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002454
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002455 return NO_ERROR;
2456}
2457
2458status_t Parcel::continueWrite(size_t desired)
2459{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002460 if (desired > INT32_MAX) {
2461 // don't accept size_t values which may have come from an
2462 // inadvertent conversion from a negative int.
2463 return BAD_VALUE;
2464 }
2465
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002466 // If shrinking, first adjust for any objects that appear
2467 // after the new data size.
2468 size_t objectsSize = mObjectsSize;
2469 if (desired < mDataSize) {
2470 if (desired == 0) {
2471 objectsSize = 0;
2472 } else {
2473 while (objectsSize > 0) {
2474 if (mObjects[objectsSize-1] < desired)
2475 break;
2476 objectsSize--;
2477 }
2478 }
2479 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002480
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002481 if (mOwner) {
2482 // If the size is going to zero, just release the owner's data.
2483 if (desired == 0) {
2484 freeData();
2485 return NO_ERROR;
2486 }
2487
2488 // If there is a different owner, we need to take
2489 // posession.
2490 uint8_t* data = (uint8_t*)malloc(desired);
2491 if (!data) {
2492 mError = NO_MEMORY;
2493 return NO_MEMORY;
2494 }
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002495 binder_size_t* objects = NULL;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002496
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002497 if (objectsSize) {
Nick Kraleviche9881a32015-04-28 16:21:30 -07002498 objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002499 if (!objects) {
Hyejin Kim3f727c02013-03-09 11:28:54 +09002500 free(data);
2501
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002502 mError = NO_MEMORY;
2503 return NO_MEMORY;
2504 }
2505
2506 // Little hack to only acquire references on objects
2507 // we will be keeping.
2508 size_t oldObjectsSize = mObjectsSize;
2509 mObjectsSize = objectsSize;
2510 acquireObjects();
2511 mObjectsSize = oldObjectsSize;
2512 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002513
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002514 if (mData) {
2515 memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
2516 }
2517 if (objects && mObjects) {
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002518 memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002519 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002520 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002521 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
2522 mOwner = NULL;
2523
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002524 LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002525 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002526 gParcelGlobalAllocSize += desired;
2527 gParcelGlobalAllocCount++;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002528 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002529
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002530 mData = data;
2531 mObjects = objects;
2532 mDataSize = (mDataSize < desired) ? mDataSize : desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002533 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002534 mDataCapacity = desired;
2535 mObjectsSize = mObjectsCapacity = objectsSize;
2536 mNextObjectHint = 0;
akirilovf7841832018-04-03 12:56:06 -07002537 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002538
2539 } else if (mData) {
2540 if (objectsSize < mObjectsSize) {
2541 // Need to release refs on any objects we are dropping.
2542 const sp<ProcessState> proc(ProcessState::self());
2543 for (size_t i=objectsSize; i<mObjectsSize; i++) {
2544 const flat_binder_object* flat
2545 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
2546 if (flat->type == BINDER_TYPE_FD) {
2547 // will need to rescan because we may have lopped off the only FDs
2548 mFdsKnown = false;
2549 }
Adrian Rooscbf37262015-10-22 16:12:53 -07002550 release_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002551 }
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002552 binder_size_t* objects =
2553 (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002554 if (objects) {
2555 mObjects = objects;
2556 }
2557 mObjectsSize = objectsSize;
2558 mNextObjectHint = 0;
akirilovf7841832018-04-03 12:56:06 -07002559 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002560 }
2561
2562 // We own the data, so we can just do a realloc().
2563 if (desired > mDataCapacity) {
2564 uint8_t* data = (uint8_t*)realloc(mData, desired);
2565 if (data) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002566 LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity,
2567 desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002568 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002569 gParcelGlobalAllocSize += desired;
2570 gParcelGlobalAllocSize -= mDataCapacity;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002571 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002572 mData = data;
2573 mDataCapacity = desired;
2574 } else if (desired > mDataCapacity) {
2575 mError = NO_MEMORY;
2576 return NO_MEMORY;
2577 }
2578 } else {
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -07002579 if (mDataSize > desired) {
2580 mDataSize = desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002581 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -07002582 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002583 if (mDataPos > desired) {
2584 mDataPos = desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002585 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002586 }
2587 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002588
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002589 } else {
2590 // This is the first data. Easy!
2591 uint8_t* data = (uint8_t*)malloc(desired);
2592 if (!data) {
2593 mError = NO_MEMORY;
2594 return NO_MEMORY;
2595 }
Hyejin Kim3f727c02013-03-09 11:28:54 +09002596
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002597 if(!(mDataCapacity == 0 && mObjects == NULL
2598 && mObjectsCapacity == 0)) {
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002599 ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002600 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002601
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002602 LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002603 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002604 gParcelGlobalAllocSize += desired;
2605 gParcelGlobalAllocCount++;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002606 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002607
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002608 mData = data;
2609 mDataSize = mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002610 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
2611 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002612 mDataCapacity = desired;
2613 }
2614
2615 return NO_ERROR;
2616}
2617
2618void Parcel::initState()
2619{
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002620 LOG_ALLOC("Parcel %p: initState", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002621 mError = NO_ERROR;
2622 mData = 0;
2623 mDataSize = 0;
2624 mDataCapacity = 0;
2625 mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002626 ALOGV("initState Setting data size of %p to %zu", this, mDataSize);
2627 ALOGV("initState Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002628 mObjects = NULL;
2629 mObjectsSize = 0;
2630 mObjectsCapacity = 0;
2631 mNextObjectHint = 0;
akirilovf7841832018-04-03 12:56:06 -07002632 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002633 mHasFds = false;
2634 mFdsKnown = true;
Dianne Hackborn8938ed22011-09-28 23:19:47 -04002635 mAllowFds = true;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002636 mOwner = NULL;
Adrian Rooscbf37262015-10-22 16:12:53 -07002637 mOpenAshmemSize = 0;
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002638
2639 // racing multiple init leads only to multiple identical write
2640 if (gMaxFds == 0) {
2641 struct rlimit result;
2642 if (!getrlimit(RLIMIT_NOFILE, &result)) {
2643 gMaxFds = (size_t)result.rlim_cur;
Christopher Tatebf14e942016-03-25 14:16:24 -07002644 //ALOGI("parcel fd limit set to %zu", gMaxFds);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002645 } else {
2646 ALOGW("Unable to getrlimit: %s", strerror(errno));
2647 gMaxFds = 1024;
2648 }
2649 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002650}
2651
2652void Parcel::scanForFds() const
2653{
2654 bool hasFds = false;
2655 for (size_t i=0; i<mObjectsSize; i++) {
2656 const flat_binder_object* flat
2657 = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
2658 if (flat->type == BINDER_TYPE_FD) {
2659 hasFds = true;
2660 break;
2661 }
2662 }
2663 mHasFds = hasFds;
2664 mFdsKnown = true;
2665}
2666
Dan Sandleraa5c2342015-04-10 10:08:45 -04002667size_t Parcel::getBlobAshmemSize() const
2668{
Adrian Roos6bb31142015-10-22 16:46:12 -07002669 // This used to return the size of all blobs that were written to ashmem, now we're returning
2670 // the ashmem currently referenced by this Parcel, which should be equivalent.
2671 // TODO: Remove method once ABI can be changed.
2672 return mOpenAshmemSize;
Dan Sandleraa5c2342015-04-10 10:08:45 -04002673}
2674
Adrian Rooscbf37262015-10-22 16:12:53 -07002675size_t Parcel::getOpenAshmemSize() const
2676{
2677 return mOpenAshmemSize;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002678}
2679
2680// --- Parcel::Blob ---
2681
2682Parcel::Blob::Blob() :
Jeff Brown13b16042014-11-11 16:44:25 -08002683 mFd(-1), mData(NULL), mSize(0), mMutable(false) {
Jeff Brown5707dbf2011-09-23 21:17:56 -07002684}
2685
2686Parcel::Blob::~Blob() {
2687 release();
2688}
2689
2690void Parcel::Blob::release() {
Jeff Brown13b16042014-11-11 16:44:25 -08002691 if (mFd != -1 && mData) {
Jeff Brown5707dbf2011-09-23 21:17:56 -07002692 ::munmap(mData, mSize);
2693 }
2694 clear();
2695}
2696
Jeff Brown13b16042014-11-11 16:44:25 -08002697void Parcel::Blob::init(int fd, void* data, size_t size, bool isMutable) {
2698 mFd = fd;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002699 mData = data;
2700 mSize = size;
Jeff Brown13b16042014-11-11 16:44:25 -08002701 mMutable = isMutable;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002702}
2703
2704void Parcel::Blob::clear() {
Jeff Brown13b16042014-11-11 16:44:25 -08002705 mFd = -1;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002706 mData = NULL;
2707 mSize = 0;
Jeff Brown13b16042014-11-11 16:44:25 -08002708 mMutable = false;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002709}
2710
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002711}; // namespace android