blob: 9e6a441a1a6f4216b14c224275b9000c78a93ec2 [file] [log] [blame]
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001/*
2 * Copyright (C) 2005 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Parcel"
18//#define LOG_NDEBUG 0
19
Mark Salyzynabed7f72016-01-27 08:02:48 -080020#include <errno.h>
Mark Salyzyn70f36652016-02-02 10:27:03 -080021#include <fcntl.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080022#include <inttypes.h>
Mark Salyzyn70f36652016-02-02 10:27:03 -080023#include <pthread.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080024#include <stdint.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <sys/mman.h>
Mark Salyzyneab2afc2016-01-27 08:02:48 -080028#include <sys/stat.h>
29#include <sys/types.h>
Christopher Tatee4e0ae82016-03-24 16:03:44 -070030#include <sys/resource.h>
Mark Salyzyneab2afc2016-01-27 08:02:48 -080031#include <unistd.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070032
Mathias Agopianc5b2c0b2009-05-19 19:08:10 -070033#include <binder/Binder.h>
34#include <binder/BpBinder.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080035#include <binder/IPCThreadState.h>
36#include <binder/Parcel.h>
Mathias Agopianc5b2c0b2009-05-19 19:08:10 -070037#include <binder/ProcessState.h>
Christopher Wiley09eb7492015-11-09 15:06:15 -080038#include <binder/Status.h>
Mathias Agopian002e1e52013-05-06 20:20:50 -070039#include <binder/TextOutput.h>
40
Mark Salyzynabed7f72016-01-27 08:02:48 -080041#include <cutils/ashmem.h>
Mathias Agopian002e1e52013-05-06 20:20:50 -070042#include <utils/Debug.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080043#include <utils/Flattenable.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070044#include <utils/Log.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080045#include <utils/misc.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070046#include <utils/String8.h>
47#include <utils/String16.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070048
Mathias Agopian208059f2009-05-18 15:08:03 -070049#include <private/binder/binder_module.h>
Steven Morelanda4853cd2019-07-12 15:44:37 -070050#include "Static.h"
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070051
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070052#ifndef INT32_MAX
53#define INT32_MAX ((int32_t)(2147483647))
54#endif
55
56#define LOG_REFS(...)
Mark Salyzyne93390b2016-01-27 08:02:48 -080057//#define LOG_REFS(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
Dianne Hackborn7e790af2014-11-11 12:22:53 -080058#define LOG_ALLOC(...)
Mark Salyzyne93390b2016-01-27 08:02:48 -080059//#define LOG_ALLOC(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070060
61// ---------------------------------------------------------------------------
62
Nick Kralevichb6b14232015-04-02 09:36:02 -070063// This macro should never be used at runtime, as a too large value
64// of s could cause an integer overflow. Instead, you should always
65// use the wrapper function pad_size()
66#define PAD_SIZE_UNSAFE(s) (((s)+3)&~3)
67
68static size_t pad_size(size_t s) {
69 if (s > (SIZE_T_MAX - 3)) {
70 abort();
71 }
72 return PAD_SIZE_UNSAFE(s);
73}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070074
Brad Fitzpatricka877cd82010-07-07 16:06:39 -070075// Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
Jeff 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 -070078namespace android {
79
Dianne Hackborna4cff882014-11-13 17:07:40 -080080static pthread_mutex_t gParcelGlobalAllocSizeLock = PTHREAD_MUTEX_INITIALIZER;
81static size_t gParcelGlobalAllocSize = 0;
82static size_t gParcelGlobalAllocCount = 0;
83
Christopher Tatee4e0ae82016-03-24 16:03:44 -070084static size_t gMaxFds = 0;
85
Jeff Brown13b16042014-11-11 16:44:25 -080086// Maximum size of a blob to transfer in-place.
87static const size_t BLOB_INPLACE_LIMIT = 16 * 1024;
88
89enum {
90 BLOB_INPLACE = 0,
91 BLOB_ASHMEM_IMMUTABLE = 1,
92 BLOB_ASHMEM_MUTABLE = 2,
93};
94
Steven Morelandb1c81202019-04-05 18:49:55 -070095static void acquire_object(const sp<ProcessState>& proc,
Adrian Rooscbf37262015-10-22 16:12:53 -070096 const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070097{
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -070098 switch (obj.hdr.type) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070099 case BINDER_TYPE_BINDER:
100 if (obj.binder) {
101 LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800102 reinterpret_cast<IBinder*>(obj.cookie)->incStrong(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700103 }
104 return;
105 case BINDER_TYPE_WEAK_BINDER:
106 if (obj.binder)
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800107 reinterpret_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700108 return;
109 case BINDER_TYPE_HANDLE: {
110 const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
Yi Kongfdd8da92018-06-07 17:52:27 -0700111 if (b != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700112 LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
113 b->incStrong(who);
114 }
115 return;
116 }
117 case BINDER_TYPE_WEAK_HANDLE: {
118 const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
Yi Kongfdd8da92018-06-07 17:52:27 -0700119 if (b != nullptr) b.get_refs()->incWeak(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700120 return;
121 }
122 case BINDER_TYPE_FD: {
Yi Kongfdd8da92018-06-07 17:52:27 -0700123 if ((obj.cookie != 0) && (outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
Mark Salyzyn80589362016-08-23 16:15:04 -0700124 // If we own an ashmem fd, keep track of how much memory it refers to.
125 int size = ashmem_get_size_region(obj.handle);
126 if (size > 0) {
127 *outAshmemSize += size;
Adrian Rooscbf37262015-10-22 16:12:53 -0700128 }
129 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700130 return;
131 }
132 }
133
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700134 ALOGD("Invalid object type 0x%08x", obj.hdr.type);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700135}
136
Adrian Roos6bb31142015-10-22 16:46:12 -0700137static void release_object(const sp<ProcessState>& proc,
Adrian Rooscbf37262015-10-22 16:12:53 -0700138 const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700139{
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700140 switch (obj.hdr.type) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700141 case BINDER_TYPE_BINDER:
142 if (obj.binder) {
143 LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800144 reinterpret_cast<IBinder*>(obj.cookie)->decStrong(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700145 }
146 return;
147 case BINDER_TYPE_WEAK_BINDER:
148 if (obj.binder)
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800149 reinterpret_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700150 return;
151 case BINDER_TYPE_HANDLE: {
152 const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
Yi Kongfdd8da92018-06-07 17:52:27 -0700153 if (b != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700154 LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
155 b->decStrong(who);
156 }
157 return;
158 }
159 case BINDER_TYPE_WEAK_HANDLE: {
160 const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
Yi Kongfdd8da92018-06-07 17:52:27 -0700161 if (b != nullptr) b.get_refs()->decWeak(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700162 return;
163 }
164 case BINDER_TYPE_FD: {
Mark Salyzynb454d8f2016-01-27 08:02:48 -0800165 if (obj.cookie != 0) { // owned
Yi Kongfdd8da92018-06-07 17:52:27 -0700166 if ((outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
Mark Salyzyn80589362016-08-23 16:15:04 -0700167 int size = ashmem_get_size_region(obj.handle);
168 if (size > 0) {
Tri Voaa6e1112019-01-29 13:23:46 -0800169 // ashmem size might have changed since last time it was accounted for, e.g.
170 // in acquire_object(). Value of *outAshmemSize is not critical since we are
171 // releasing the object anyway. Check for integer overflow condition.
172 *outAshmemSize -= std::min(*outAshmemSize, static_cast<size_t>(size));
Adrian Roos6bb31142015-10-22 16:46:12 -0700173 }
Adrian Roos6bb31142015-10-22 16:46:12 -0700174 }
Mark Salyzynb454d8f2016-01-27 08:02:48 -0800175
176 close(obj.handle);
Adrian Rooscbf37262015-10-22 16:12:53 -0700177 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700178 return;
179 }
180 }
181
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700182 ALOGE("Invalid object type 0x%08x", obj.hdr.type);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700183}
184
185inline static status_t finish_flatten_binder(
Colin Cross6f4f3ab2014-02-05 17:42:44 -0800186 const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700187{
188 return out->writeObject(flat, false);
189}
190
Steven Morelandb1c81202019-04-05 18:49:55 -0700191static status_t flatten_binder(const sp<ProcessState>& /*proc*/,
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700192 const sp<IBinder>& binder, Parcel* out)
193{
194 flat_binder_object obj;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700195
Martijn Coenen2b631742017-05-05 11:16:59 -0700196 if (IPCThreadState::self()->backgroundSchedulingDisabled()) {
197 /* minimum priority for all nodes is nice 0 */
198 obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;
199 } else {
200 /* minimum priority for all nodes is MAX_NICE(19) */
201 obj.flags = 0x13 | FLAT_BINDER_FLAG_ACCEPTS_FDS;
202 }
203
Yi Kongfdd8da92018-06-07 17:52:27 -0700204 if (binder != nullptr) {
Steven Moreland3085a472018-12-26 13:59:23 -0800205 BBinder *local = binder->localBinder();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700206 if (!local) {
207 BpBinder *proxy = binder->remoteBinder();
Yi Kongfdd8da92018-06-07 17:52:27 -0700208 if (proxy == nullptr) {
Steve Blocke6f43dd2012-01-06 19:20:56 +0000209 ALOGE("null proxy");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700210 }
211 const int32_t handle = proxy ? proxy->handle() : 0;
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700212 obj.hdr.type = BINDER_TYPE_HANDLE;
Arve Hjønnevåg07fd0f12014-02-18 21:10:29 -0800213 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700214 obj.handle = handle;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800215 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700216 } else {
Steven Moreland3085a472018-12-26 13:59:23 -0800217 if (local->isRequestingSid()) {
218 obj.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
219 }
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700220 obj.hdr.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800221 obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
222 obj.cookie = reinterpret_cast<uintptr_t>(local);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700223 }
224 } else {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700225 obj.hdr.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800226 obj.binder = 0;
227 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700228 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700229
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700230 return finish_flatten_binder(binder, obj, out);
231}
232
Steven Morelandb1c81202019-04-05 18:49:55 -0700233static status_t flatten_binder(const sp<ProcessState>& /*proc*/,
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700234 const wp<IBinder>& binder, Parcel* out)
235{
236 flat_binder_object obj;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700237
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700238 obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
Yi Kongfdd8da92018-06-07 17:52:27 -0700239 if (binder != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700240 sp<IBinder> real = binder.promote();
Yi Kongfdd8da92018-06-07 17:52:27 -0700241 if (real != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700242 IBinder *local = real->localBinder();
243 if (!local) {
244 BpBinder *proxy = real->remoteBinder();
Yi Kongfdd8da92018-06-07 17:52:27 -0700245 if (proxy == nullptr) {
Steve Blocke6f43dd2012-01-06 19:20:56 +0000246 ALOGE("null proxy");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700247 }
248 const int32_t handle = proxy ? proxy->handle() : 0;
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700249 obj.hdr.type = BINDER_TYPE_WEAK_HANDLE;
Arve Hjønnevåg07fd0f12014-02-18 21:10:29 -0800250 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700251 obj.handle = handle;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800252 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700253 } else {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700254 obj.hdr.type = BINDER_TYPE_WEAK_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800255 obj.binder = reinterpret_cast<uintptr_t>(binder.get_refs());
256 obj.cookie = reinterpret_cast<uintptr_t>(binder.unsafe_get());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700257 }
258 return finish_flatten_binder(real, obj, out);
259 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700260
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700261 // XXX How to deal? In order to flatten the given binder,
262 // we need to probe it for information, which requires a primary
263 // reference... but we don't have one.
264 //
265 // The OpenBinder implementation uses a dynamic_cast<> here,
266 // but we can't do that with the different reference counting
267 // implementation we are using.
Steve Blocke6f43dd2012-01-06 19:20:56 +0000268 ALOGE("Unable to unflatten Binder weak reference!");
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700269 obj.hdr.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800270 obj.binder = 0;
271 obj.cookie = 0;
Yi Kongfdd8da92018-06-07 17:52:27 -0700272 return finish_flatten_binder(nullptr, obj, out);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700273
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700274 } else {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700275 obj.hdr.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800276 obj.binder = 0;
277 obj.cookie = 0;
Yi Kongfdd8da92018-06-07 17:52:27 -0700278 return finish_flatten_binder(nullptr, obj, out);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700279 }
280}
281
282inline static status_t finish_unflatten_binder(
Colin Cross6f4f3ab2014-02-05 17:42:44 -0800283 BpBinder* /*proxy*/, const flat_binder_object& /*flat*/,
284 const Parcel& /*in*/)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700285{
286 return NO_ERROR;
287}
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700288
Steven Morelandb1c81202019-04-05 18:49:55 -0700289static status_t unflatten_binder(const sp<ProcessState>& proc,
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700290 const Parcel& in, sp<IBinder>* out)
291{
292 const flat_binder_object* flat = in.readObject(false);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700293
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700294 if (flat) {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700295 switch (flat->hdr.type) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700296 case BINDER_TYPE_BINDER:
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800297 *out = reinterpret_cast<IBinder*>(flat->cookie);
Yi Kongfdd8da92018-06-07 17:52:27 -0700298 return finish_unflatten_binder(nullptr, *flat, in);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700299 case BINDER_TYPE_HANDLE:
300 *out = proc->getStrongProxyForHandle(flat->handle);
301 return finish_unflatten_binder(
302 static_cast<BpBinder*>(out->get()), *flat, in);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700303 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700304 }
305 return BAD_TYPE;
306}
307
Steven Morelandb1c81202019-04-05 18:49:55 -0700308static status_t unflatten_binder(const sp<ProcessState>& proc,
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700309 const Parcel& in, wp<IBinder>* out)
310{
311 const flat_binder_object* flat = in.readObject(false);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700312
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700313 if (flat) {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700314 switch (flat->hdr.type) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700315 case BINDER_TYPE_BINDER:
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800316 *out = reinterpret_cast<IBinder*>(flat->cookie);
Yi Kongfdd8da92018-06-07 17:52:27 -0700317 return finish_unflatten_binder(nullptr, *flat, in);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700318 case BINDER_TYPE_WEAK_BINDER:
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800319 if (flat->binder != 0) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700320 out->set_object_and_refs(
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800321 reinterpret_cast<IBinder*>(flat->cookie),
322 reinterpret_cast<RefBase::weakref_type*>(flat->binder));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700323 } else {
Yi Kongfdd8da92018-06-07 17:52:27 -0700324 *out = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700325 }
Yi Kongfdd8da92018-06-07 17:52:27 -0700326 return finish_unflatten_binder(nullptr, *flat, in);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700327 case BINDER_TYPE_HANDLE:
328 case BINDER_TYPE_WEAK_HANDLE:
329 *out = proc->getWeakProxyForHandle(flat->handle);
330 return finish_unflatten_binder(
331 static_cast<BpBinder*>(out->unsafe_get()), *flat, in);
332 }
333 }
334 return BAD_TYPE;
335}
336
337// ---------------------------------------------------------------------------
338
339Parcel::Parcel()
340{
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800341 LOG_ALLOC("Parcel %p: constructing", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700342 initState();
343}
344
345Parcel::~Parcel()
346{
347 freeDataNoInit();
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800348 LOG_ALLOC("Parcel %p: destroyed", this);
349}
350
351size_t Parcel::getGlobalAllocSize() {
Dianne Hackborna4cff882014-11-13 17:07:40 -0800352 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
353 size_t size = gParcelGlobalAllocSize;
354 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
355 return size;
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800356}
357
358size_t Parcel::getGlobalAllocCount() {
Dianne Hackborna4cff882014-11-13 17:07:40 -0800359 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
360 size_t count = gParcelGlobalAllocCount;
361 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
362 return count;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700363}
364
365const uint8_t* Parcel::data() const
366{
367 return mData;
368}
369
370size_t Parcel::dataSize() const
371{
372 return (mDataSize > mDataPos ? mDataSize : mDataPos);
373}
374
375size_t Parcel::dataAvail() const
376{
Nick Kralevichcfe27de2015-09-16 09:49:15 -0700377 size_t result = dataSize() - dataPosition();
378 if (result > INT32_MAX) {
379 abort();
380 }
381 return result;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700382}
383
384size_t Parcel::dataPosition() const
385{
386 return mDataPos;
387}
388
389size_t Parcel::dataCapacity() const
390{
391 return mDataCapacity;
392}
393
394status_t Parcel::setDataSize(size_t size)
395{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700396 if (size > INT32_MAX) {
397 // don't accept size_t values which may have come from an
398 // inadvertent conversion from a negative int.
399 return BAD_VALUE;
400 }
401
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700402 status_t err;
403 err = continueWrite(size);
404 if (err == NO_ERROR) {
405 mDataSize = size;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700406 ALOGV("setDataSize Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700407 }
408 return err;
409}
410
411void Parcel::setDataPosition(size_t pos) const
412{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700413 if (pos > INT32_MAX) {
414 // don't accept size_t values which may have come from an
415 // inadvertent conversion from a negative int.
416 abort();
417 }
418
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700419 mDataPos = pos;
420 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -0800421 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700422}
423
424status_t Parcel::setDataCapacity(size_t size)
425{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700426 if (size > INT32_MAX) {
427 // don't accept size_t values which may have come from an
428 // inadvertent conversion from a negative int.
429 return BAD_VALUE;
430 }
431
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -0700432 if (size > mDataCapacity) return continueWrite(size);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700433 return NO_ERROR;
434}
435
436status_t Parcel::setData(const uint8_t* buffer, size_t len)
437{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700438 if (len > INT32_MAX) {
439 // don't accept size_t values which may have come from an
440 // inadvertent conversion from a negative int.
441 return BAD_VALUE;
442 }
443
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700444 status_t err = restartWrite(len);
445 if (err == NO_ERROR) {
446 memcpy(const_cast<uint8_t*>(data()), buffer, len);
447 mDataSize = len;
448 mFdsKnown = false;
449 }
450 return err;
451}
452
Andreas Huber51faf462011-04-13 10:21:56 -0700453status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700454{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700455 status_t err;
Andreas Huber51faf462011-04-13 10:21:56 -0700456 const uint8_t *data = parcel->mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800457 const binder_size_t *objects = parcel->mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700458 size_t size = parcel->mObjectsSize;
459 int startPos = mDataPos;
460 int firstIndex = -1, lastIndex = -2;
461
462 if (len == 0) {
463 return NO_ERROR;
464 }
465
Nick Kralevichb6b14232015-04-02 09:36:02 -0700466 if (len > INT32_MAX) {
467 // don't accept size_t values which may have come from an
468 // inadvertent conversion from a negative int.
469 return BAD_VALUE;
470 }
471
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700472 // range checks against the source parcel size
473 if ((offset > parcel->mDataSize)
474 || (len > parcel->mDataSize)
475 || (offset + len > parcel->mDataSize)) {
476 return BAD_VALUE;
477 }
478
479 // Count objects in range
480 for (int i = 0; i < (int) size; i++) {
481 size_t off = objects[i];
Christopher Tate27182be2015-05-27 17:53:02 -0700482 if ((off >= offset) && (off + sizeof(flat_binder_object) <= offset + len)) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700483 if (firstIndex == -1) {
484 firstIndex = i;
485 }
486 lastIndex = i;
487 }
488 }
489 int numObjects = lastIndex - firstIndex + 1;
490
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -0700491 if ((mDataSize+len) > mDataCapacity) {
492 // grow data
493 err = growData(len);
494 if (err != NO_ERROR) {
495 return err;
496 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700497 }
498
499 // append data
500 memcpy(mData + mDataPos, data + offset, len);
501 mDataPos += len;
502 mDataSize += len;
503
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400504 err = NO_ERROR;
505
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700506 if (numObjects > 0) {
Martijn Coenen69390d42018-10-22 15:18:10 +0200507 const sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700508 // grow objects
509 if (mObjectsCapacity < mObjectsSize + numObjects) {
Christopher Tateed7a50c2015-06-08 14:45:14 -0700510 size_t newSize = ((mObjectsSize + numObjects)*3)/2;
Christopher Tate44235112016-11-03 13:32:41 -0700511 if (newSize*sizeof(binder_size_t) < mObjectsSize) return NO_MEMORY; // overflow
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800512 binder_size_t *objects =
513 (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
Yi Kongfdd8da92018-06-07 17:52:27 -0700514 if (objects == (binder_size_t*)nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700515 return NO_MEMORY;
516 }
517 mObjects = objects;
518 mObjectsCapacity = newSize;
519 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700520
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700521 // append and acquire objects
522 int idx = mObjectsSize;
523 for (int i = firstIndex; i <= lastIndex; i++) {
524 size_t off = objects[i] - offset + startPos;
525 mObjects[idx++] = off;
526 mObjectsSize++;
527
Dianne Hackborn8af0f822009-05-22 13:20:23 -0700528 flat_binder_object* flat
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700529 = reinterpret_cast<flat_binder_object*>(mData + off);
Adrian Rooscbf37262015-10-22 16:12:53 -0700530 acquire_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700531
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700532 if (flat->hdr.type == BINDER_TYPE_FD) {
Dianne Hackborn8af0f822009-05-22 13:20:23 -0700533 // If this is a file descriptor, we need to dup it so the
534 // new Parcel now owns its own fd, and can declare that we
535 // officially know we have fds.
Nick Kralevichec9ec7d2016-12-17 19:47:27 -0800536 flat->handle = fcntl(flat->handle, F_DUPFD_CLOEXEC, 0);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800537 flat->cookie = 1;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700538 mHasFds = mFdsKnown = true;
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400539 if (!mAllowFds) {
540 err = FDS_NOT_ALLOWED;
541 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700542 }
543 }
544 }
545
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400546 return err;
547}
548
Dianne Hackborn15feb9b2017-04-10 15:34:35 -0700549int Parcel::compareData(const Parcel& other) {
550 size_t size = dataSize();
551 if (size != other.dataSize()) {
552 return size < other.dataSize() ? -1 : 1;
553 }
554 return memcmp(data(), other.data(), size);
555}
556
Jeff Brown13b16042014-11-11 16:44:25 -0800557bool Parcel::allowFds() const
558{
559 return mAllowFds;
560}
561
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700562bool Parcel::pushAllowFds(bool allowFds)
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400563{
564 const bool origValue = mAllowFds;
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700565 if (!allowFds) {
566 mAllowFds = false;
567 }
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400568 return origValue;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700569}
570
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700571void Parcel::restoreAllowFds(bool lastValue)
572{
573 mAllowFds = lastValue;
574}
575
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700576bool Parcel::hasFileDescriptors() const
577{
578 if (!mFdsKnown) {
579 scanForFds();
580 }
581 return mHasFds;
582}
583
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700584// Write RPC headers. (previously just the interface token)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700585status_t Parcel::writeInterfaceToken(const String16& interface)
586{
Brad Fitzpatricka877cd82010-07-07 16:06:39 -0700587 writeInt32(IPCThreadState::self()->getStrictModePolicy() |
588 STRICT_MODE_PENALTY_GATHER);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700589 // currently the interface identification token is just its name as a string
590 return writeString16(interface);
591}
592
Mathias Agopian83c04462009-05-22 19:00:22 -0700593bool Parcel::checkInterface(IBinder* binder) const
594{
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700595 return enforceInterface(binder->getInterfaceDescriptor());
Mathias Agopian83c04462009-05-22 19:00:22 -0700596}
597
Brad Fitzpatricka877cd82010-07-07 16:06:39 -0700598bool Parcel::enforceInterface(const String16& interface,
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700599 IPCThreadState* threadState) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700600{
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700601 int32_t strictPolicy = readInt32();
Yi Kongfdd8da92018-06-07 17:52:27 -0700602 if (threadState == nullptr) {
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700603 threadState = IPCThreadState::self();
Brad Fitzpatricka877cd82010-07-07 16:06:39 -0700604 }
Brad Fitzpatrick52736032010-08-30 16:01:16 -0700605 if ((threadState->getLastTransactionBinderFlags() &
606 IBinder::FLAG_ONEWAY) != 0) {
607 // For one-way calls, the callee is running entirely
608 // disconnected from the caller, so disable StrictMode entirely.
609 // Not only does disk/network usage not impact the caller, but
610 // there's no way to commuicate back any violations anyway.
611 threadState->setStrictModePolicy(0);
612 } else {
613 threadState->setStrictModePolicy(strictPolicy);
614 }
Mathias Agopian83c04462009-05-22 19:00:22 -0700615 const String16 str(readString16());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700616 if (str == interface) {
617 return true;
618 } else {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700619 ALOGW("**** enforceInterface() expected '%s' but read '%s'",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700620 String8(interface).string(), String8(str).string());
621 return false;
622 }
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700623}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700624
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700625size_t Parcel::objectsCount() const
626{
627 return mObjectsSize;
628}
629
630status_t Parcel::errorCheck() const
631{
632 return mError;
633}
634
635void Parcel::setError(status_t err)
636{
637 mError = err;
638}
639
640status_t Parcel::finishWrite(size_t len)
641{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700642 if (len > INT32_MAX) {
643 // don't accept size_t values which may have come from an
644 // inadvertent conversion from a negative int.
645 return BAD_VALUE;
646 }
647
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700648 //printf("Finish write of %d\n", len);
649 mDataPos += len;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700650 ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700651 if (mDataPos > mDataSize) {
652 mDataSize = mDataPos;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700653 ALOGV("finishWrite Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700654 }
655 //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
656 return NO_ERROR;
657}
658
659status_t Parcel::writeUnpadded(const void* data, size_t len)
660{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700661 if (len > INT32_MAX) {
662 // don't accept size_t values which may have come from an
663 // inadvertent conversion from a negative int.
664 return BAD_VALUE;
665 }
666
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700667 size_t end = mDataPos + len;
668 if (end < mDataPos) {
669 // integer overflow
670 return BAD_VALUE;
671 }
672
673 if (end <= mDataCapacity) {
674restart_write:
675 memcpy(mData+mDataPos, data, len);
676 return finishWrite(len);
677 }
678
679 status_t err = growData(len);
680 if (err == NO_ERROR) goto restart_write;
681 return err;
682}
683
684status_t Parcel::write(const void* data, size_t len)
685{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700686 if (len > INT32_MAX) {
687 // don't accept size_t values which may have come from an
688 // inadvertent conversion from a negative int.
689 return BAD_VALUE;
690 }
691
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700692 void* const d = writeInplace(len);
693 if (d) {
694 memcpy(d, data, len);
695 return NO_ERROR;
696 }
697 return mError;
698}
699
700void* Parcel::writeInplace(size_t len)
701{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700702 if (len > INT32_MAX) {
703 // don't accept size_t values which may have come from an
704 // inadvertent conversion from a negative int.
Yi Kongfdd8da92018-06-07 17:52:27 -0700705 return nullptr;
Nick Kralevichb6b14232015-04-02 09:36:02 -0700706 }
707
708 const size_t padded = pad_size(len);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700709
710 // sanity check for integer overflow
711 if (mDataPos+padded < mDataPos) {
Yi Kongfdd8da92018-06-07 17:52:27 -0700712 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700713 }
714
715 if ((mDataPos+padded) <= mDataCapacity) {
716restart_write:
717 //printf("Writing %ld bytes, padded to %ld\n", len, padded);
718 uint8_t* const data = mData+mDataPos;
719
720 // Need to pad at end?
721 if (padded != len) {
722#if BYTE_ORDER == BIG_ENDIAN
723 static const uint32_t mask[4] = {
724 0x00000000, 0xffffff00, 0xffff0000, 0xff000000
725 };
726#endif
727#if BYTE_ORDER == LITTLE_ENDIAN
728 static const uint32_t mask[4] = {
729 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
730 };
731#endif
732 //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
733 // *reinterpret_cast<void**>(data+padded-4));
734 *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
735 }
736
737 finishWrite(padded);
738 return data;
739 }
740
741 status_t err = growData(padded);
742 if (err == NO_ERROR) goto restart_write;
Yi Kongfdd8da92018-06-07 17:52:27 -0700743 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700744}
745
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800746status_t Parcel::writeUtf8AsUtf16(const std::string& str) {
747 const uint8_t* strData = (uint8_t*)str.data();
748 const size_t strLen= str.length();
749 const ssize_t utf16Len = utf8_to_utf16_length(strData, strLen);
Sergio Girof4607432016-07-21 14:46:35 +0100750 if (utf16Len < 0 || utf16Len > std::numeric_limits<int32_t>::max()) {
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800751 return BAD_VALUE;
752 }
753
754 status_t err = writeInt32(utf16Len);
755 if (err) {
756 return err;
757 }
758
759 // Allocate enough bytes to hold our converted string and its terminating NULL.
760 void* dst = writeInplace((utf16Len + 1) * sizeof(char16_t));
761 if (!dst) {
762 return NO_MEMORY;
763 }
764
Sergio Girof4607432016-07-21 14:46:35 +0100765 utf8_to_utf16(strData, strLen, (char16_t*)dst, (size_t) utf16Len + 1);
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800766
767 return NO_ERROR;
768}
769
770status_t Parcel::writeUtf8AsUtf16(const std::unique_ptr<std::string>& str) {
771 if (!str) {
772 return writeInt32(-1);
773 }
774 return writeUtf8AsUtf16(*str);
775}
776
Casey Dahlin185d3442016-02-09 11:08:35 -0800777namespace {
Casey Dahlinb9872622015-11-25 15:09:45 -0800778
Casey Dahlin185d3442016-02-09 11:08:35 -0800779template<typename T>
780status_t writeByteVectorInternal(Parcel* parcel, const std::vector<T>& val)
Casey Dahlin451ff582015-10-19 18:12:18 -0700781{
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700782 status_t status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700783 if (val.size() > std::numeric_limits<int32_t>::max()) {
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700784 status = BAD_VALUE;
785 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700786 }
787
Casey Dahlin185d3442016-02-09 11:08:35 -0800788 status = parcel->writeInt32(val.size());
Casey Dahlin451ff582015-10-19 18:12:18 -0700789 if (status != OK) {
790 return status;
791 }
792
Casey Dahlin185d3442016-02-09 11:08:35 -0800793 void* data = parcel->writeInplace(val.size());
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700794 if (!data) {
795 status = BAD_VALUE;
796 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700797 }
798
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700799 memcpy(data, val.data(), val.size());
800 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700801}
802
Casey Dahlin185d3442016-02-09 11:08:35 -0800803template<typename T>
804status_t writeByteVectorInternalPtr(Parcel* parcel,
805 const std::unique_ptr<std::vector<T>>& val)
806{
807 if (!val) {
808 return parcel->writeInt32(-1);
809 }
810
811 return writeByteVectorInternal(parcel, *val);
812}
813
814} // namespace
815
816status_t Parcel::writeByteVector(const std::vector<int8_t>& val) {
817 return writeByteVectorInternal(this, val);
818}
819
820status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val)
821{
822 return writeByteVectorInternalPtr(this, val);
823}
824
825status_t Parcel::writeByteVector(const std::vector<uint8_t>& val) {
826 return writeByteVectorInternal(this, val);
827}
828
829status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val)
830{
831 return writeByteVectorInternalPtr(this, val);
832}
833
Casey Dahlin451ff582015-10-19 18:12:18 -0700834status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val)
835{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800836 return writeTypedVector(val, &Parcel::writeInt32);
Casey Dahlin451ff582015-10-19 18:12:18 -0700837}
838
Casey Dahlinb9872622015-11-25 15:09:45 -0800839status_t Parcel::writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val)
840{
841 return writeNullableTypedVector(val, &Parcel::writeInt32);
842}
843
Casey Dahlin451ff582015-10-19 18:12:18 -0700844status_t Parcel::writeInt64Vector(const std::vector<int64_t>& val)
845{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800846 return writeTypedVector(val, &Parcel::writeInt64);
Casey Dahlin451ff582015-10-19 18:12:18 -0700847}
848
Casey Dahlinb9872622015-11-25 15:09:45 -0800849status_t Parcel::writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val)
850{
851 return writeNullableTypedVector(val, &Parcel::writeInt64);
852}
853
Casey Dahlin451ff582015-10-19 18:12:18 -0700854status_t Parcel::writeFloatVector(const std::vector<float>& val)
855{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800856 return writeTypedVector(val, &Parcel::writeFloat);
Casey Dahlin451ff582015-10-19 18:12:18 -0700857}
858
Casey Dahlinb9872622015-11-25 15:09:45 -0800859status_t Parcel::writeFloatVector(const std::unique_ptr<std::vector<float>>& val)
860{
861 return writeNullableTypedVector(val, &Parcel::writeFloat);
862}
863
Casey Dahlin451ff582015-10-19 18:12:18 -0700864status_t Parcel::writeDoubleVector(const std::vector<double>& val)
865{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800866 return writeTypedVector(val, &Parcel::writeDouble);
Casey Dahlin451ff582015-10-19 18:12:18 -0700867}
868
Casey Dahlinb9872622015-11-25 15:09:45 -0800869status_t Parcel::writeDoubleVector(const std::unique_ptr<std::vector<double>>& val)
870{
871 return writeNullableTypedVector(val, &Parcel::writeDouble);
872}
873
Casey Dahlin451ff582015-10-19 18:12:18 -0700874status_t Parcel::writeBoolVector(const std::vector<bool>& val)
875{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800876 return writeTypedVector(val, &Parcel::writeBool);
Casey Dahlin451ff582015-10-19 18:12:18 -0700877}
878
Casey Dahlinb9872622015-11-25 15:09:45 -0800879status_t Parcel::writeBoolVector(const std::unique_ptr<std::vector<bool>>& val)
880{
881 return writeNullableTypedVector(val, &Parcel::writeBool);
882}
883
Casey Dahlin451ff582015-10-19 18:12:18 -0700884status_t Parcel::writeCharVector(const std::vector<char16_t>& val)
885{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800886 return writeTypedVector(val, &Parcel::writeChar);
Casey Dahlin451ff582015-10-19 18:12:18 -0700887}
888
Casey Dahlinb9872622015-11-25 15:09:45 -0800889status_t Parcel::writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val)
890{
891 return writeNullableTypedVector(val, &Parcel::writeChar);
892}
893
Casey Dahlin451ff582015-10-19 18:12:18 -0700894status_t Parcel::writeString16Vector(const std::vector<String16>& val)
895{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800896 return writeTypedVector(val, &Parcel::writeString16);
Casey Dahlin451ff582015-10-19 18:12:18 -0700897}
898
Casey Dahlinb9872622015-11-25 15:09:45 -0800899status_t Parcel::writeString16Vector(
900 const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val)
901{
902 return writeNullableTypedVector(val, &Parcel::writeString16);
903}
904
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800905status_t Parcel::writeUtf8VectorAsUtf16Vector(
906 const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val) {
907 return writeNullableTypedVector(val, &Parcel::writeUtf8AsUtf16);
908}
909
910status_t Parcel::writeUtf8VectorAsUtf16Vector(const std::vector<std::string>& val) {
911 return writeTypedVector(val, &Parcel::writeUtf8AsUtf16);
912}
913
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700914status_t Parcel::writeInt32(int32_t val)
915{
Andreas Huber84a6d042009-08-17 13:33:27 -0700916 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700917}
Dan Stoza41a0f2f2014-12-01 10:01:10 -0800918
919status_t Parcel::writeUint32(uint32_t val)
920{
921 return writeAligned(val);
922}
923
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700924status_t Parcel::writeInt32Array(size_t len, const int32_t *val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -0700925 if (len > INT32_MAX) {
926 // don't accept size_t values which may have come from an
927 // inadvertent conversion from a negative int.
928 return BAD_VALUE;
929 }
930
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700931 if (!val) {
Chad Brubakere59cb432015-06-30 14:03:55 -0700932 return writeInt32(-1);
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700933 }
Chad Brubakere59cb432015-06-30 14:03:55 -0700934 status_t ret = writeInt32(static_cast<uint32_t>(len));
Marco Nelissen5c0106e2013-10-16 10:57:51 -0700935 if (ret == NO_ERROR) {
936 ret = write(val, len * sizeof(*val));
937 }
938 return ret;
939}
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700940status_t Parcel::writeByteArray(size_t len, const uint8_t *val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -0700941 if (len > INT32_MAX) {
942 // don't accept size_t values which may have come from an
943 // inadvertent conversion from a negative int.
944 return BAD_VALUE;
945 }
946
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700947 if (!val) {
Chad Brubakere59cb432015-06-30 14:03:55 -0700948 return writeInt32(-1);
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700949 }
Chad Brubakere59cb432015-06-30 14:03:55 -0700950 status_t ret = writeInt32(static_cast<uint32_t>(len));
Marco Nelissenf0190bf2014-03-13 14:17:40 -0700951 if (ret == NO_ERROR) {
952 ret = write(val, len * sizeof(*val));
953 }
954 return ret;
955}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700956
Casey Dahlind6848f52015-10-15 15:44:59 -0700957status_t Parcel::writeBool(bool val)
958{
959 return writeInt32(int32_t(val));
960}
961
962status_t Parcel::writeChar(char16_t val)
963{
964 return writeInt32(int32_t(val));
965}
966
967status_t Parcel::writeByte(int8_t val)
968{
969 return writeInt32(int32_t(val));
970}
971
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700972status_t Parcel::writeInt64(int64_t val)
973{
Andreas Huber84a6d042009-08-17 13:33:27 -0700974 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700975}
976
Ronghua Wu2d13afd2015-03-16 11:11:07 -0700977status_t Parcel::writeUint64(uint64_t val)
978{
979 return writeAligned(val);
980}
981
Serban Constantinescuf683e012013-11-05 16:53:55 +0000982status_t Parcel::writePointer(uintptr_t val)
983{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800984 return writeAligned<binder_uintptr_t>(val);
Serban Constantinescuf683e012013-11-05 16:53:55 +0000985}
986
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700987status_t Parcel::writeFloat(float val)
988{
Andreas Huber84a6d042009-08-17 13:33:27 -0700989 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700990}
991
Douglas Leungcc1a4bb2013-01-11 15:00:55 -0800992#if defined(__mips__) && defined(__mips_hard_float)
993
994status_t Parcel::writeDouble(double val)
995{
996 union {
997 double d;
998 unsigned long long ll;
999 } u;
1000 u.d = val;
1001 return writeAligned(u.ll);
1002}
1003
1004#else
1005
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001006status_t Parcel::writeDouble(double val)
1007{
Andreas Huber84a6d042009-08-17 13:33:27 -07001008 return writeAligned(val);
1009}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001010
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001011#endif
1012
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001013status_t Parcel::writeCString(const char* str)
1014{
1015 return write(str, strlen(str)+1);
1016}
1017
1018status_t Parcel::writeString8(const String8& str)
1019{
1020 status_t err = writeInt32(str.bytes());
Pravat Dalbeherad1dff8d2010-12-15 08:40:00 +01001021 // only write string if its length is more than zero characters,
1022 // as readString8 will only read if the length field is non-zero.
1023 // this is slightly different from how writeString16 works.
1024 if (str.bytes() > 0 && err == NO_ERROR) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001025 err = write(str.string(), str.bytes()+1);
1026 }
1027 return err;
1028}
1029
Casey Dahlinb9872622015-11-25 15:09:45 -08001030status_t Parcel::writeString16(const std::unique_ptr<String16>& str)
1031{
1032 if (!str) {
1033 return writeInt32(-1);
1034 }
1035
1036 return writeString16(*str);
1037}
1038
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001039status_t Parcel::writeString16(const String16& str)
1040{
1041 return writeString16(str.string(), str.size());
1042}
1043
1044status_t Parcel::writeString16(const char16_t* str, size_t len)
1045{
Yi Kongfdd8da92018-06-07 17:52:27 -07001046 if (str == nullptr) return writeInt32(-1);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001047
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001048 status_t err = writeInt32(len);
1049 if (err == NO_ERROR) {
1050 len *= sizeof(char16_t);
1051 uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
1052 if (data) {
1053 memcpy(data, str, len);
1054 *reinterpret_cast<char16_t*>(data+len) = 0;
1055 return NO_ERROR;
1056 }
1057 err = mError;
1058 }
1059 return err;
1060}
1061
1062status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
1063{
1064 return flatten_binder(ProcessState::self(), val, this);
1065}
1066
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001067status_t Parcel::writeStrongBinderVector(const std::vector<sp<IBinder>>& val)
1068{
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001069 return writeTypedVector(val, &Parcel::writeStrongBinder);
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001070}
1071
Casey Dahlinb9872622015-11-25 15:09:45 -08001072status_t Parcel::writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val)
1073{
1074 return writeNullableTypedVector(val, &Parcel::writeStrongBinder);
1075}
1076
1077status_t Parcel::readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const {
Christopher Wiley35d77ca2016-03-08 10:49:51 -08001078 return readNullableTypedVector(val, &Parcel::readNullableStrongBinder);
Casey Dahlinb9872622015-11-25 15:09:45 -08001079}
1080
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001081status_t Parcel::readStrongBinderVector(std::vector<sp<IBinder>>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001082 return readTypedVector(val, &Parcel::readStrongBinder);
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001083}
1084
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001085status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
1086{
1087 return flatten_binder(ProcessState::self(), val, this);
1088}
1089
Casey Dahlinb9872622015-11-25 15:09:45 -08001090status_t Parcel::writeRawNullableParcelable(const Parcelable* parcelable) {
1091 if (!parcelable) {
1092 return writeInt32(0);
1093 }
1094
1095 return writeParcelable(*parcelable);
1096}
1097
Christopher Wiley97f048d2015-11-19 06:49:05 -08001098status_t Parcel::writeParcelable(const Parcelable& parcelable) {
1099 status_t status = writeInt32(1); // parcelable is not null.
1100 if (status != OK) {
1101 return status;
1102 }
1103 return parcelable.writeToParcel(this);
1104}
1105
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001106status_t Parcel::writeNativeHandle(const native_handle* handle)
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001107{
Mathias Agopian1d0a95b2009-07-31 16:12:13 -07001108 if (!handle || handle->version != sizeof(native_handle))
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001109 return BAD_TYPE;
1110
1111 status_t err;
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001112 err = writeInt32(handle->numFds);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001113 if (err != NO_ERROR) return err;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001114
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001115 err = writeInt32(handle->numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001116 if (err != NO_ERROR) return err;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001117
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001118 for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)
1119 err = writeDupFileDescriptor(handle->data[i]);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001120
1121 if (err != NO_ERROR) {
Steve Block9d453682011-12-20 16:23:08 +00001122 ALOGD("write native handle, write dup fd failed");
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001123 return err;
1124 }
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001125 err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001126 return err;
1127}
1128
Jeff Brown93ff1f92011-11-04 19:01:44 -07001129status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001130{
1131 flat_binder_object obj;
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07001132 obj.hdr.type = BINDER_TYPE_FD;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001133 obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
Arve Hjønnevåg07fd0f12014-02-18 21:10:29 -08001134 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001135 obj.handle = fd;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001136 obj.cookie = takeOwnership ? 1 : 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001137 return writeObject(obj, true);
1138}
1139
1140status_t Parcel::writeDupFileDescriptor(int fd)
1141{
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08001142 int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
Jeff Brownd341c712011-11-04 20:19:33 -07001143 if (dupFd < 0) {
1144 return -errno;
1145 }
1146 status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/);
Casey Dahlin06673e32015-11-23 13:24:23 -08001147 if (err != OK) {
Jeff Brownd341c712011-11-04 20:19:33 -07001148 close(dupFd);
1149 }
1150 return err;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001151}
1152
Dianne Hackborn1941a402016-08-29 12:30:43 -07001153status_t Parcel::writeParcelFileDescriptor(int fd, bool takeOwnership)
1154{
1155 writeInt32(0);
1156 return writeFileDescriptor(fd, takeOwnership);
1157}
1158
Ryo Hashimotobf551892018-05-31 16:58:35 +09001159status_t Parcel::writeDupParcelFileDescriptor(int fd)
1160{
1161 int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
1162 if (dupFd < 0) {
1163 return -errno;
1164 }
1165 status_t err = writeParcelFileDescriptor(dupFd, true /*takeOwnership*/);
1166 if (err != OK) {
1167 close(dupFd);
1168 }
1169 return err;
1170}
1171
Christopher Wiley2cf19952016-04-11 11:09:37 -07001172status_t Parcel::writeUniqueFileDescriptor(const base::unique_fd& fd) {
Casey Dahlin06673e32015-11-23 13:24:23 -08001173 return writeDupFileDescriptor(fd.get());
1174}
1175
Christopher Wiley2cf19952016-04-11 11:09:37 -07001176status_t Parcel::writeUniqueFileDescriptorVector(const std::vector<base::unique_fd>& val) {
Casey Dahlin06673e32015-11-23 13:24:23 -08001177 return writeTypedVector(val, &Parcel::writeUniqueFileDescriptor);
1178}
1179
Christopher Wiley2cf19952016-04-11 11:09:37 -07001180status_t Parcel::writeUniqueFileDescriptorVector(const std::unique_ptr<std::vector<base::unique_fd>>& val) {
Casey Dahlinb9872622015-11-25 15:09:45 -08001181 return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
1182}
1183
Jeff Brown13b16042014-11-11 16:44:25 -08001184status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob)
Jeff Brown5707dbf2011-09-23 21:17:56 -07001185{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001186 if (len > INT32_MAX) {
1187 // don't accept size_t values which may have come from an
1188 // inadvertent conversion from a negative int.
1189 return BAD_VALUE;
1190 }
1191
Jeff Brown13b16042014-11-11 16:44:25 -08001192 status_t status;
1193 if (!mAllowFds || len <= BLOB_INPLACE_LIMIT) {
Steve Block6807e592011-10-20 11:56:00 +01001194 ALOGV("writeBlob: write in place");
Jeff Brown13b16042014-11-11 16:44:25 -08001195 status = writeInt32(BLOB_INPLACE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001196 if (status) return status;
1197
1198 void* ptr = writeInplace(len);
1199 if (!ptr) return NO_MEMORY;
1200
Jeff Brown13b16042014-11-11 16:44:25 -08001201 outBlob->init(-1, ptr, len, false);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001202 return NO_ERROR;
1203 }
1204
Steve Block6807e592011-10-20 11:56:00 +01001205 ALOGV("writeBlob: write to ashmem");
Jeff Brown5707dbf2011-09-23 21:17:56 -07001206 int fd = ashmem_create_region("Parcel Blob", len);
1207 if (fd < 0) return NO_MEMORY;
1208
1209 int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
1210 if (result < 0) {
Jeff Brownec4e0062011-10-10 14:50:10 -07001211 status = result;
Jeff Brown5707dbf2011-09-23 21:17:56 -07001212 } else {
Yi Kongfdd8da92018-06-07 17:52:27 -07001213 void* ptr = ::mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001214 if (ptr == MAP_FAILED) {
1215 status = -errno;
1216 } else {
Jeff Brown13b16042014-11-11 16:44:25 -08001217 if (!mutableCopy) {
1218 result = ashmem_set_prot_region(fd, PROT_READ);
1219 }
Jeff Brown5707dbf2011-09-23 21:17:56 -07001220 if (result < 0) {
Jeff Brownec4e0062011-10-10 14:50:10 -07001221 status = result;
Jeff Brown5707dbf2011-09-23 21:17:56 -07001222 } else {
Jeff Brown13b16042014-11-11 16:44:25 -08001223 status = writeInt32(mutableCopy ? BLOB_ASHMEM_MUTABLE : BLOB_ASHMEM_IMMUTABLE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001224 if (!status) {
Jeff Brown93ff1f92011-11-04 19:01:44 -07001225 status = writeFileDescriptor(fd, true /*takeOwnership*/);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001226 if (!status) {
Jeff Brown13b16042014-11-11 16:44:25 -08001227 outBlob->init(fd, ptr, len, mutableCopy);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001228 return NO_ERROR;
1229 }
1230 }
1231 }
1232 }
1233 ::munmap(ptr, len);
1234 }
1235 ::close(fd);
1236 return status;
1237}
1238
Jeff Brown13b16042014-11-11 16:44:25 -08001239status_t Parcel::writeDupImmutableBlobFileDescriptor(int fd)
1240{
1241 // Must match up with what's done in writeBlob.
1242 if (!mAllowFds) return FDS_NOT_ALLOWED;
1243 status_t status = writeInt32(BLOB_ASHMEM_IMMUTABLE);
1244 if (status) return status;
1245 return writeDupFileDescriptor(fd);
1246}
1247
Mathias Agopiane1424282013-07-29 21:24:40 -07001248status_t Parcel::write(const FlattenableHelperInterface& val)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001249{
1250 status_t err;
1251
1252 // size if needed
Mathias Agopiane1424282013-07-29 21:24:40 -07001253 const size_t len = val.getFlattenedSize();
1254 const size_t fd_count = val.getFdCount();
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001255
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001256 if ((len > INT32_MAX) || (fd_count >= gMaxFds)) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001257 // don't accept size_t values which may have come from an
1258 // inadvertent conversion from a negative int.
1259 return BAD_VALUE;
1260 }
1261
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001262 err = this->writeInt32(len);
1263 if (err) return err;
1264
1265 err = this->writeInt32(fd_count);
1266 if (err) return err;
1267
1268 // payload
Martijn Coenenf8542382018-04-04 11:46:56 +02001269 void* const buf = this->writeInplace(len);
Yi Kongfdd8da92018-06-07 17:52:27 -07001270 if (buf == nullptr)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001271 return BAD_VALUE;
1272
Yi Kongfdd8da92018-06-07 17:52:27 -07001273 int* fds = nullptr;
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001274 if (fd_count) {
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001275 fds = new (std::nothrow) int[fd_count];
1276 if (fds == nullptr) {
1277 ALOGE("write: failed to allocate requested %zu fds", fd_count);
1278 return BAD_VALUE;
1279 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001280 }
1281
1282 err = val.flatten(buf, len, fds, fd_count);
1283 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
1284 err = this->writeDupFileDescriptor( fds[i] );
1285 }
1286
1287 if (fd_count) {
1288 delete [] fds;
1289 }
1290
1291 return err;
1292}
1293
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001294status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
1295{
1296 const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
1297 const bool enoughObjects = mObjectsSize < mObjectsCapacity;
1298 if (enoughData && enoughObjects) {
1299restart_write:
1300 *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001301
Christopher Tate98e67d32015-06-03 18:44:15 -07001302 // remember if it's a file descriptor
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07001303 if (val.hdr.type == BINDER_TYPE_FD) {
Christopher Tate98e67d32015-06-03 18:44:15 -07001304 if (!mAllowFds) {
1305 // fail before modifying our object index
1306 return FDS_NOT_ALLOWED;
1307 }
1308 mHasFds = mFdsKnown = true;
1309 }
1310
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001311 // Need to write meta-data?
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001312 if (nullMetaData || val.binder != 0) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001313 mObjects[mObjectsSize] = mDataPos;
Adrian Rooscbf37262015-10-22 16:12:53 -07001314 acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001315 mObjectsSize++;
1316 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001317
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001318 return finishWrite(sizeof(flat_binder_object));
1319 }
1320
1321 if (!enoughData) {
1322 const status_t err = growData(sizeof(val));
1323 if (err != NO_ERROR) return err;
1324 }
1325 if (!enoughObjects) {
1326 size_t newSize = ((mObjectsSize+2)*3)/2;
Christopher Tate44235112016-11-03 13:32:41 -07001327 if (newSize*sizeof(binder_size_t) < mObjectsSize) return NO_MEMORY; // overflow
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001328 binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
Yi Kongfdd8da92018-06-07 17:52:27 -07001329 if (objects == nullptr) return NO_MEMORY;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001330 mObjects = objects;
1331 mObjectsCapacity = newSize;
1332 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001333
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001334 goto restart_write;
1335}
1336
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07001337status_t Parcel::writeNoException()
1338{
Christopher Wiley09eb7492015-11-09 15:06:15 -08001339 binder::Status status;
1340 return status.writeToParcel(this);
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07001341}
1342
Colin Cross6f4f3ab2014-02-05 17:42:44 -08001343void Parcel::remove(size_t /*start*/, size_t /*amt*/)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001344{
1345 LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
1346}
1347
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001348status_t Parcel::validateReadData(size_t upperBound) const
1349{
1350 // Don't allow non-object reads on object data
1351 if (mObjectsSorted || mObjectsSize <= 1) {
1352data_sorted:
1353 // Expect to check only against the next object
1354 if (mNextObjectHint < mObjectsSize && upperBound > mObjects[mNextObjectHint]) {
1355 // For some reason the current read position is greater than the next object
1356 // hint. Iterate until we find the right object
1357 size_t nextObject = mNextObjectHint;
1358 do {
1359 if (mDataPos < mObjects[nextObject] + sizeof(flat_binder_object)) {
1360 // Requested info overlaps with an object
1361 ALOGE("Attempt to read from protected data in Parcel %p", this);
1362 return PERMISSION_DENIED;
1363 }
1364 nextObject++;
1365 } while (nextObject < mObjectsSize && upperBound > mObjects[nextObject]);
1366 mNextObjectHint = nextObject;
1367 }
1368 return NO_ERROR;
1369 }
1370 // Quickly determine if mObjects is sorted.
1371 binder_size_t* currObj = mObjects + mObjectsSize - 1;
1372 binder_size_t* prevObj = currObj;
1373 while (currObj > mObjects) {
1374 prevObj--;
1375 if(*prevObj > *currObj) {
1376 goto data_unsorted;
1377 }
1378 currObj--;
1379 }
1380 mObjectsSorted = true;
1381 goto data_sorted;
1382
1383data_unsorted:
1384 // Insertion Sort mObjects
1385 // Great for mostly sorted lists. If randomly sorted or reverse ordered mObjects become common,
1386 // switch to std::sort(mObjects, mObjects + mObjectsSize);
1387 for (binder_size_t* iter0 = mObjects + 1; iter0 < mObjects + mObjectsSize; iter0++) {
1388 binder_size_t temp = *iter0;
1389 binder_size_t* iter1 = iter0 - 1;
1390 while (iter1 >= mObjects && *iter1 > temp) {
1391 *(iter1 + 1) = *iter1;
1392 iter1--;
1393 }
1394 *(iter1 + 1) = temp;
1395 }
1396 mNextObjectHint = 0;
1397 mObjectsSorted = true;
1398 goto data_sorted;
1399}
1400
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001401status_t Parcel::read(void* outData, size_t len) const
1402{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001403 if (len > INT32_MAX) {
1404 // don't accept size_t values which may have come from an
1405 // inadvertent conversion from a negative int.
1406 return BAD_VALUE;
1407 }
1408
1409 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1410 && len <= pad_size(len)) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001411 if (mObjectsSize > 0) {
1412 status_t err = validateReadData(mDataPos + pad_size(len));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001413 if(err != NO_ERROR) {
1414 // Still increment the data position by the expected length
1415 mDataPos += pad_size(len);
1416 ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
1417 return err;
1418 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001419 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001420 memcpy(outData, mData+mDataPos, len);
Nick Kralevichb6b14232015-04-02 09:36:02 -07001421 mDataPos += pad_size(len);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001422 ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001423 return NO_ERROR;
1424 }
1425 return NOT_ENOUGH_DATA;
1426}
1427
1428const void* Parcel::readInplace(size_t len) const
1429{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001430 if (len > INT32_MAX) {
1431 // don't accept size_t values which may have come from an
1432 // inadvertent conversion from a negative int.
Yi Kongfdd8da92018-06-07 17:52:27 -07001433 return nullptr;
Nick Kralevichb6b14232015-04-02 09:36:02 -07001434 }
1435
1436 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1437 && len <= pad_size(len)) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001438 if (mObjectsSize > 0) {
1439 status_t err = validateReadData(mDataPos + pad_size(len));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001440 if(err != NO_ERROR) {
1441 // Still increment the data position by the expected length
1442 mDataPos += pad_size(len);
1443 ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
Xin Lif11e2bd2018-06-08 15:11:57 -07001444 return nullptr;
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001445 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001446 }
1447
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001448 const void* data = mData+mDataPos;
Nick Kralevichb6b14232015-04-02 09:36:02 -07001449 mDataPos += pad_size(len);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001450 ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001451 return data;
1452 }
Yi Kongfdd8da92018-06-07 17:52:27 -07001453 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001454}
1455
Andreas Huber84a6d042009-08-17 13:33:27 -07001456template<class T>
1457status_t Parcel::readAligned(T *pArg) const {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001458 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
Andreas Huber84a6d042009-08-17 13:33:27 -07001459
1460 if ((mDataPos+sizeof(T)) <= mDataSize) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001461 if (mObjectsSize > 0) {
1462 status_t err = validateReadData(mDataPos + sizeof(T));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001463 if(err != NO_ERROR) {
1464 // Still increment the data position by the expected length
1465 mDataPos += sizeof(T);
1466 return err;
1467 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001468 }
1469
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001470 const void* data = mData+mDataPos;
Andreas Huber84a6d042009-08-17 13:33:27 -07001471 mDataPos += sizeof(T);
1472 *pArg = *reinterpret_cast<const T*>(data);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001473 return NO_ERROR;
1474 } else {
1475 return NOT_ENOUGH_DATA;
1476 }
1477}
1478
Andreas Huber84a6d042009-08-17 13:33:27 -07001479template<class T>
1480T Parcel::readAligned() const {
1481 T result;
1482 if (readAligned(&result) != NO_ERROR) {
1483 result = 0;
1484 }
1485
1486 return result;
1487}
1488
1489template<class T>
1490status_t Parcel::writeAligned(T val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001491 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
Andreas Huber84a6d042009-08-17 13:33:27 -07001492
1493 if ((mDataPos+sizeof(val)) <= mDataCapacity) {
1494restart_write:
1495 *reinterpret_cast<T*>(mData+mDataPos) = val;
1496 return finishWrite(sizeof(val));
1497 }
1498
1499 status_t err = growData(sizeof(val));
1500 if (err == NO_ERROR) goto restart_write;
1501 return err;
1502}
1503
Casey Dahlin185d3442016-02-09 11:08:35 -08001504namespace {
1505
1506template<typename T>
1507status_t readByteVectorInternal(const Parcel* parcel,
1508 std::vector<T>* val) {
Casey Dahlin451ff582015-10-19 18:12:18 -07001509 val->clear();
1510
1511 int32_t size;
Casey Dahlin185d3442016-02-09 11:08:35 -08001512 status_t status = parcel->readInt32(&size);
Casey Dahlin451ff582015-10-19 18:12:18 -07001513
1514 if (status != OK) {
1515 return status;
1516 }
1517
Christopher Wiley4db672d2015-11-10 09:44:30 -08001518 if (size < 0) {
1519 status = UNEXPECTED_NULL;
1520 return status;
1521 }
Casey Dahlin185d3442016-02-09 11:08:35 -08001522 if (size_t(size) > parcel->dataAvail()) {
Christopher Wileyf0fc52b2015-10-31 13:22:15 -07001523 status = BAD_VALUE;
1524 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -07001525 }
Christopher Wiley4db672d2015-11-10 09:44:30 -08001526
Paul Lietar433e87b2016-09-16 10:39:32 -07001527 T* data = const_cast<T*>(reinterpret_cast<const T*>(parcel->readInplace(size)));
Christopher Wileyf0fc52b2015-10-31 13:22:15 -07001528 if (!data) {
1529 status = BAD_VALUE;
1530 return status;
1531 }
Paul Lietar433e87b2016-09-16 10:39:32 -07001532 val->reserve(size);
1533 val->insert(val->end(), data, data + size);
Casey Dahlin451ff582015-10-19 18:12:18 -07001534
Christopher Wileyf0fc52b2015-10-31 13:22:15 -07001535 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -07001536}
1537
Casey Dahlin185d3442016-02-09 11:08:35 -08001538template<typename T>
1539status_t readByteVectorInternalPtr(
1540 const Parcel* parcel,
1541 std::unique_ptr<std::vector<T>>* val) {
1542 const int32_t start = parcel->dataPosition();
Casey Dahlinb9872622015-11-25 15:09:45 -08001543 int32_t size;
Casey Dahlin185d3442016-02-09 11:08:35 -08001544 status_t status = parcel->readInt32(&size);
Casey Dahlinb9872622015-11-25 15:09:45 -08001545 val->reset();
1546
1547 if (status != OK || size < 0) {
1548 return status;
1549 }
1550
Casey Dahlin185d3442016-02-09 11:08:35 -08001551 parcel->setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001552 val->reset(new (std::nothrow) std::vector<T>());
Casey Dahlinb9872622015-11-25 15:09:45 -08001553
Casey Dahlin185d3442016-02-09 11:08:35 -08001554 status = readByteVectorInternal(parcel, val->get());
Casey Dahlinb9872622015-11-25 15:09:45 -08001555
1556 if (status != OK) {
1557 val->reset();
1558 }
1559
1560 return status;
1561}
1562
Casey Dahlin185d3442016-02-09 11:08:35 -08001563} // namespace
1564
1565status_t Parcel::readByteVector(std::vector<int8_t>* val) const {
1566 return readByteVectorInternal(this, val);
1567}
1568
1569status_t Parcel::readByteVector(std::vector<uint8_t>* val) const {
1570 return readByteVectorInternal(this, val);
1571}
1572
1573status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const {
1574 return readByteVectorInternalPtr(this, val);
1575}
1576
1577status_t Parcel::readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const {
1578 return readByteVectorInternalPtr(this, val);
1579}
1580
Casey Dahlinb9872622015-11-25 15:09:45 -08001581status_t Parcel::readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const {
1582 return readNullableTypedVector(val, &Parcel::readInt32);
1583}
1584
Casey Dahlin451ff582015-10-19 18:12:18 -07001585status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001586 return readTypedVector(val, &Parcel::readInt32);
Casey Dahlin451ff582015-10-19 18:12:18 -07001587}
1588
Casey Dahlinb9872622015-11-25 15:09:45 -08001589status_t Parcel::readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const {
1590 return readNullableTypedVector(val, &Parcel::readInt64);
1591}
1592
Casey Dahlin451ff582015-10-19 18:12:18 -07001593status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001594 return readTypedVector(val, &Parcel::readInt64);
Casey Dahlin451ff582015-10-19 18:12:18 -07001595}
1596
Casey Dahlinb9872622015-11-25 15:09:45 -08001597status_t Parcel::readFloatVector(std::unique_ptr<std::vector<float>>* val) const {
1598 return readNullableTypedVector(val, &Parcel::readFloat);
1599}
1600
Casey Dahlin451ff582015-10-19 18:12:18 -07001601status_t Parcel::readFloatVector(std::vector<float>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001602 return readTypedVector(val, &Parcel::readFloat);
Casey Dahlin451ff582015-10-19 18:12:18 -07001603}
1604
Casey Dahlinb9872622015-11-25 15:09:45 -08001605status_t Parcel::readDoubleVector(std::unique_ptr<std::vector<double>>* val) const {
1606 return readNullableTypedVector(val, &Parcel::readDouble);
1607}
1608
Casey Dahlin451ff582015-10-19 18:12:18 -07001609status_t Parcel::readDoubleVector(std::vector<double>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001610 return readTypedVector(val, &Parcel::readDouble);
Casey Dahlin451ff582015-10-19 18:12:18 -07001611}
1612
Casey Dahlinb9872622015-11-25 15:09:45 -08001613status_t Parcel::readBoolVector(std::unique_ptr<std::vector<bool>>* val) const {
1614 const int32_t start = dataPosition();
1615 int32_t size;
1616 status_t status = readInt32(&size);
1617 val->reset();
Casey Dahlin451ff582015-10-19 18:12:18 -07001618
Casey Dahlinb9872622015-11-25 15:09:45 -08001619 if (status != OK || size < 0) {
1620 return status;
1621 }
1622
1623 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001624 val->reset(new (std::nothrow) std::vector<bool>());
Casey Dahlinb9872622015-11-25 15:09:45 -08001625
1626 status = readBoolVector(val->get());
1627
1628 if (status != OK) {
1629 val->reset();
1630 }
1631
1632 return status;
1633}
1634
1635status_t Parcel::readBoolVector(std::vector<bool>* val) const {
Casey Dahlin451ff582015-10-19 18:12:18 -07001636 int32_t size;
1637 status_t status = readInt32(&size);
1638
1639 if (status != OK) {
1640 return status;
1641 }
1642
1643 if (size < 0) {
Christopher Wiley4db672d2015-11-10 09:44:30 -08001644 return UNEXPECTED_NULL;
Casey Dahlin451ff582015-10-19 18:12:18 -07001645 }
1646
1647 val->resize(size);
1648
1649 /* C++ bool handling means a vector of bools isn't necessarily addressable
1650 * (we might use individual bits)
1651 */
Christopher Wiley97887982015-10-27 16:33:47 -07001652 bool data;
1653 for (int32_t i = 0; i < size; ++i) {
Casey Dahlin451ff582015-10-19 18:12:18 -07001654 status = readBool(&data);
1655 (*val)[i] = data;
1656
1657 if (status != OK) {
1658 return status;
1659 }
1660 }
1661
1662 return OK;
1663}
1664
Casey Dahlinb9872622015-11-25 15:09:45 -08001665status_t Parcel::readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const {
1666 return readNullableTypedVector(val, &Parcel::readChar);
1667}
1668
Casey Dahlin451ff582015-10-19 18:12:18 -07001669status_t Parcel::readCharVector(std::vector<char16_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001670 return readTypedVector(val, &Parcel::readChar);
Casey Dahlin451ff582015-10-19 18:12:18 -07001671}
1672
Casey Dahlinb9872622015-11-25 15:09:45 -08001673status_t Parcel::readString16Vector(
1674 std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const {
1675 return readNullableTypedVector(val, &Parcel::readString16);
1676}
1677
Casey Dahlin451ff582015-10-19 18:12:18 -07001678status_t Parcel::readString16Vector(std::vector<String16>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001679 return readTypedVector(val, &Parcel::readString16);
Casey Dahlin451ff582015-10-19 18:12:18 -07001680}
1681
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001682status_t Parcel::readUtf8VectorFromUtf16Vector(
1683 std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const {
1684 return readNullableTypedVector(val, &Parcel::readUtf8FromUtf16);
1685}
1686
1687status_t Parcel::readUtf8VectorFromUtf16Vector(std::vector<std::string>* val) const {
1688 return readTypedVector(val, &Parcel::readUtf8FromUtf16);
1689}
Casey Dahlin451ff582015-10-19 18:12:18 -07001690
Andreas Huber84a6d042009-08-17 13:33:27 -07001691status_t Parcel::readInt32(int32_t *pArg) const
1692{
1693 return readAligned(pArg);
1694}
1695
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001696int32_t Parcel::readInt32() const
1697{
Andreas Huber84a6d042009-08-17 13:33:27 -07001698 return readAligned<int32_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001699}
1700
Dan Stoza41a0f2f2014-12-01 10:01:10 -08001701status_t Parcel::readUint32(uint32_t *pArg) const
1702{
1703 return readAligned(pArg);
1704}
1705
1706uint32_t Parcel::readUint32() const
1707{
1708 return readAligned<uint32_t>();
1709}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001710
1711status_t Parcel::readInt64(int64_t *pArg) const
1712{
Andreas Huber84a6d042009-08-17 13:33:27 -07001713 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001714}
1715
1716
1717int64_t Parcel::readInt64() const
1718{
Andreas Huber84a6d042009-08-17 13:33:27 -07001719 return readAligned<int64_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001720}
1721
Ronghua Wu2d13afd2015-03-16 11:11:07 -07001722status_t Parcel::readUint64(uint64_t *pArg) const
1723{
1724 return readAligned(pArg);
1725}
1726
1727uint64_t Parcel::readUint64() const
1728{
1729 return readAligned<uint64_t>();
1730}
1731
Serban Constantinescuf683e012013-11-05 16:53:55 +00001732status_t Parcel::readPointer(uintptr_t *pArg) const
1733{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001734 status_t ret;
1735 binder_uintptr_t ptr;
1736 ret = readAligned(&ptr);
1737 if (!ret)
1738 *pArg = ptr;
1739 return ret;
Serban Constantinescuf683e012013-11-05 16:53:55 +00001740}
1741
1742uintptr_t Parcel::readPointer() const
1743{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001744 return readAligned<binder_uintptr_t>();
Serban Constantinescuf683e012013-11-05 16:53:55 +00001745}
1746
1747
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001748status_t Parcel::readFloat(float *pArg) const
1749{
Andreas Huber84a6d042009-08-17 13:33:27 -07001750 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001751}
1752
1753
1754float Parcel::readFloat() const
1755{
Andreas Huber84a6d042009-08-17 13:33:27 -07001756 return readAligned<float>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001757}
1758
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001759#if defined(__mips__) && defined(__mips_hard_float)
1760
1761status_t Parcel::readDouble(double *pArg) const
1762{
1763 union {
1764 double d;
1765 unsigned long long ll;
1766 } u;
Narayan Kamath2c68d382014-06-04 15:04:29 +01001767 u.d = 0;
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001768 status_t status;
1769 status = readAligned(&u.ll);
1770 *pArg = u.d;
1771 return status;
1772}
1773
1774double Parcel::readDouble() const
1775{
1776 union {
1777 double d;
1778 unsigned long long ll;
1779 } u;
1780 u.ll = readAligned<unsigned long long>();
1781 return u.d;
1782}
1783
1784#else
1785
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001786status_t Parcel::readDouble(double *pArg) const
1787{
Andreas Huber84a6d042009-08-17 13:33:27 -07001788 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001789}
1790
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001791double Parcel::readDouble() const
1792{
Andreas Huber84a6d042009-08-17 13:33:27 -07001793 return readAligned<double>();
1794}
1795
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001796#endif
1797
Andreas Huber84a6d042009-08-17 13:33:27 -07001798status_t Parcel::readIntPtr(intptr_t *pArg) const
1799{
1800 return readAligned(pArg);
1801}
1802
1803
1804intptr_t Parcel::readIntPtr() const
1805{
1806 return readAligned<intptr_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001807}
1808
Casey Dahlind6848f52015-10-15 15:44:59 -07001809status_t Parcel::readBool(bool *pArg) const
1810{
Manoj Gupta6eb62052017-07-12 10:29:15 -07001811 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07001812 status_t ret = readInt32(&tmp);
1813 *pArg = (tmp != 0);
1814 return ret;
1815}
1816
1817bool Parcel::readBool() const
1818{
1819 return readInt32() != 0;
1820}
1821
1822status_t Parcel::readChar(char16_t *pArg) const
1823{
Manoj Gupta6eb62052017-07-12 10:29:15 -07001824 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07001825 status_t ret = readInt32(&tmp);
1826 *pArg = char16_t(tmp);
1827 return ret;
1828}
1829
1830char16_t Parcel::readChar() const
1831{
1832 return char16_t(readInt32());
1833}
1834
1835status_t Parcel::readByte(int8_t *pArg) const
1836{
Manoj Gupta6eb62052017-07-12 10:29:15 -07001837 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07001838 status_t ret = readInt32(&tmp);
1839 *pArg = int8_t(tmp);
1840 return ret;
1841}
1842
1843int8_t Parcel::readByte() const
1844{
1845 return int8_t(readInt32());
1846}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001847
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001848status_t Parcel::readUtf8FromUtf16(std::string* str) const {
1849 size_t utf16Size = 0;
1850 const char16_t* src = readString16Inplace(&utf16Size);
1851 if (!src) {
1852 return UNEXPECTED_NULL;
1853 }
1854
1855 // Save ourselves the trouble, we're done.
1856 if (utf16Size == 0u) {
1857 str->clear();
1858 return NO_ERROR;
1859 }
1860
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001861 // Allow for closing '\0'
1862 ssize_t utf8Size = utf16_to_utf8_length(src, utf16Size) + 1;
1863 if (utf8Size < 1) {
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001864 return BAD_VALUE;
1865 }
1866 // Note that while it is probably safe to assume string::resize keeps a
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001867 // spare byte around for the trailing null, we still pass the size including the trailing null
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001868 str->resize(utf8Size);
Sergio Giro9b39ebe2016-06-28 18:19:33 +01001869 utf16_to_utf8(src, utf16Size, &((*str)[0]), utf8Size);
1870 str->resize(utf8Size - 1);
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001871 return NO_ERROR;
1872}
1873
1874status_t Parcel::readUtf8FromUtf16(std::unique_ptr<std::string>* str) const {
1875 const int32_t start = dataPosition();
1876 int32_t size;
1877 status_t status = readInt32(&size);
1878 str->reset();
1879
1880 if (status != OK || size < 0) {
1881 return status;
1882 }
1883
1884 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001885 str->reset(new (std::nothrow) std::string());
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001886 return readUtf8FromUtf16(str->get());
1887}
1888
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001889const char* Parcel::readCString() const
1890{
1891 const size_t avail = mDataSize-mDataPos;
1892 if (avail > 0) {
1893 const char* str = reinterpret_cast<const char*>(mData+mDataPos);
1894 // is the string's trailing NUL within the parcel's valid bounds?
1895 const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
1896 if (eos) {
1897 const size_t len = eos - str;
Nick Kralevichb6b14232015-04-02 09:36:02 -07001898 mDataPos += pad_size(len+1);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001899 ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001900 return str;
1901 }
1902 }
Yi Kongfdd8da92018-06-07 17:52:27 -07001903 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001904}
1905
1906String8 Parcel::readString8() const
1907{
Roshan Pius87b64d22016-07-18 12:51:02 -07001908 String8 retString;
1909 status_t status = readString8(&retString);
1910 if (status != OK) {
1911 // We don't care about errors here, so just return an empty string.
1912 return String8();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001913 }
Roshan Pius87b64d22016-07-18 12:51:02 -07001914 return retString;
1915}
1916
1917status_t Parcel::readString8(String8* pArg) const
1918{
1919 int32_t size;
1920 status_t status = readInt32(&size);
1921 if (status != OK) {
1922 return status;
1923 }
1924 // watch for potential int overflow from size+1
1925 if (size < 0 || size >= INT32_MAX) {
1926 return BAD_VALUE;
1927 }
1928 // |writeString8| writes nothing for empty string.
1929 if (size == 0) {
1930 *pArg = String8();
1931 return OK;
1932 }
1933 const char* str = (const char*)readInplace(size + 1);
Yi Kongfdd8da92018-06-07 17:52:27 -07001934 if (str == nullptr) {
Roshan Pius87b64d22016-07-18 12:51:02 -07001935 return BAD_VALUE;
1936 }
1937 pArg->setTo(str, size);
1938 return OK;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001939}
1940
1941String16 Parcel::readString16() const
1942{
1943 size_t len;
1944 const char16_t* str = readString16Inplace(&len);
1945 if (str) return String16(str, len);
Steve Blocke6f43dd2012-01-06 19:20:56 +00001946 ALOGE("Reading a NULL string not supported here.");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001947 return String16();
1948}
1949
Casey Dahlinb9872622015-11-25 15:09:45 -08001950status_t Parcel::readString16(std::unique_ptr<String16>* pArg) const
1951{
1952 const int32_t start = dataPosition();
1953 int32_t size;
1954 status_t status = readInt32(&size);
1955 pArg->reset();
1956
1957 if (status != OK || size < 0) {
1958 return status;
1959 }
1960
1961 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001962 pArg->reset(new (std::nothrow) String16());
Casey Dahlinb9872622015-11-25 15:09:45 -08001963
1964 status = readString16(pArg->get());
1965
1966 if (status != OK) {
1967 pArg->reset();
1968 }
1969
1970 return status;
1971}
1972
Casey Dahlin451ff582015-10-19 18:12:18 -07001973status_t Parcel::readString16(String16* pArg) const
1974{
1975 size_t len;
1976 const char16_t* str = readString16Inplace(&len);
1977 if (str) {
Casey Dahlin1515ea12015-10-20 16:26:23 -07001978 pArg->setTo(str, len);
Casey Dahlin451ff582015-10-19 18:12:18 -07001979 return 0;
1980 } else {
1981 *pArg = String16();
Christopher Wiley4db672d2015-11-10 09:44:30 -08001982 return UNEXPECTED_NULL;
Casey Dahlin451ff582015-10-19 18:12:18 -07001983 }
1984}
1985
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001986const char16_t* Parcel::readString16Inplace(size_t* outLen) const
1987{
1988 int32_t size = readInt32();
1989 // watch for potential int overflow from size+1
1990 if (size >= 0 && size < INT32_MAX) {
1991 *outLen = size;
1992 const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
Yi Kongfdd8da92018-06-07 17:52:27 -07001993 if (str != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001994 return str;
1995 }
1996 }
1997 *outLen = 0;
Yi Kongfdd8da92018-06-07 17:52:27 -07001998 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001999}
2000
Casey Dahlinf0c13772015-10-27 18:33:56 -07002001status_t Parcel::readStrongBinder(sp<IBinder>* val) const
2002{
Christopher Wiley35d77ca2016-03-08 10:49:51 -08002003 status_t status = readNullableStrongBinder(val);
2004 if (status == OK && !val->get()) {
2005 status = UNEXPECTED_NULL;
2006 }
2007 return status;
2008}
2009
2010status_t Parcel::readNullableStrongBinder(sp<IBinder>* val) const
2011{
Casey Dahlinf0c13772015-10-27 18:33:56 -07002012 return unflatten_binder(ProcessState::self(), *this, val);
2013}
2014
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002015sp<IBinder> Parcel::readStrongBinder() const
2016{
2017 sp<IBinder> val;
Christopher Wiley35d77ca2016-03-08 10:49:51 -08002018 // Note that a lot of code in Android reads binders by hand with this
2019 // method, and that code has historically been ok with getting nullptr
2020 // back (while ignoring error codes).
2021 readNullableStrongBinder(&val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002022 return val;
2023}
2024
2025wp<IBinder> Parcel::readWeakBinder() const
2026{
2027 wp<IBinder> val;
2028 unflatten_binder(ProcessState::self(), *this, &val);
2029 return val;
2030}
2031
Christopher Wiley97f048d2015-11-19 06:49:05 -08002032status_t Parcel::readParcelable(Parcelable* parcelable) const {
2033 int32_t have_parcelable = 0;
2034 status_t status = readInt32(&have_parcelable);
2035 if (status != OK) {
2036 return status;
2037 }
2038 if (!have_parcelable) {
2039 return UNEXPECTED_NULL;
2040 }
2041 return parcelable->readFromParcel(this);
2042}
2043
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07002044int32_t Parcel::readExceptionCode() const
2045{
Christopher Wiley09eb7492015-11-09 15:06:15 -08002046 binder::Status status;
2047 status.readFromParcel(*this);
2048 return status.exceptionCode();
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07002049}
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002050
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002051native_handle* Parcel::readNativeHandle() const
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002052{
2053 int numFds, numInts;
2054 status_t err;
2055 err = readInt32(&numFds);
Yi Kongfdd8da92018-06-07 17:52:27 -07002056 if (err != NO_ERROR) return nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002057 err = readInt32(&numInts);
Yi Kongfdd8da92018-06-07 17:52:27 -07002058 if (err != NO_ERROR) return nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002059
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002060 native_handle* h = native_handle_create(numFds, numInts);
Adam Lesinskieaac99a2015-05-12 17:35:48 -07002061 if (!h) {
Yi Kongfdd8da92018-06-07 17:52:27 -07002062 return nullptr;
Adam Lesinskieaac99a2015-05-12 17:35:48 -07002063 }
2064
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002065 for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002066 h->data[i] = fcntl(readFileDescriptor(), F_DUPFD_CLOEXEC, 0);
Marco Nelissen1de79662016-04-26 08:44:09 -07002067 if (h->data[i] < 0) {
2068 for (int j = 0; j < i; j++) {
2069 close(h->data[j]);
2070 }
2071 native_handle_delete(h);
Yi Kongfdd8da92018-06-07 17:52:27 -07002072 return nullptr;
Marco Nelissen1de79662016-04-26 08:44:09 -07002073 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002074 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002075 err = read(h->data + numFds, sizeof(int)*numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002076 if (err != NO_ERROR) {
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002077 native_handle_close(h);
2078 native_handle_delete(h);
Yi Kongfdd8da92018-06-07 17:52:27 -07002079 h = nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002080 }
2081 return h;
2082}
2083
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002084int Parcel::readFileDescriptor() const
2085{
2086 const flat_binder_object* flat = readObject(true);
Casey Dahlin06673e32015-11-23 13:24:23 -08002087
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002088 if (flat && flat->hdr.type == BINDER_TYPE_FD) {
Casey Dahlin06673e32015-11-23 13:24:23 -08002089 return flat->handle;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002090 }
Casey Dahlin06673e32015-11-23 13:24:23 -08002091
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002092 return BAD_TYPE;
2093}
2094
Dianne Hackborn1941a402016-08-29 12:30:43 -07002095int Parcel::readParcelFileDescriptor() const
2096{
2097 int32_t hasComm = readInt32();
2098 int fd = readFileDescriptor();
2099 if (hasComm != 0) {
Steven Morelandb73806a2018-11-12 19:35:47 -08002100 // detach (owned by the binder driver)
2101 int comm = readFileDescriptor();
2102
2103 // warning: this must be kept in sync with:
2104 // frameworks/base/core/java/android/os/ParcelFileDescriptor.java
2105 enum ParcelFileDescriptorStatus {
2106 DETACHED = 2,
2107 };
2108
2109#if BYTE_ORDER == BIG_ENDIAN
2110 const int32_t message = ParcelFileDescriptorStatus::DETACHED;
2111#endif
2112#if BYTE_ORDER == LITTLE_ENDIAN
2113 const int32_t message = __builtin_bswap32(ParcelFileDescriptorStatus::DETACHED);
2114#endif
2115
2116 ssize_t written = TEMP_FAILURE_RETRY(
2117 ::write(comm, &message, sizeof(message)));
2118
2119 if (written == -1 || written != sizeof(message)) {
2120 ALOGW("Failed to detach ParcelFileDescriptor written: %zd err: %s",
2121 written, strerror(errno));
2122 return BAD_TYPE;
2123 }
Dianne Hackborn1941a402016-08-29 12:30:43 -07002124 }
2125 return fd;
2126}
2127
Christopher Wiley2cf19952016-04-11 11:09:37 -07002128status_t Parcel::readUniqueFileDescriptor(base::unique_fd* val) const
Casey Dahlin06673e32015-11-23 13:24:23 -08002129{
2130 int got = readFileDescriptor();
2131
2132 if (got == BAD_TYPE) {
2133 return BAD_TYPE;
2134 }
2135
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002136 val->reset(fcntl(got, F_DUPFD_CLOEXEC, 0));
Casey Dahlin06673e32015-11-23 13:24:23 -08002137
2138 if (val->get() < 0) {
2139 return BAD_VALUE;
2140 }
2141
2142 return OK;
2143}
2144
Ryo Hashimotobf551892018-05-31 16:58:35 +09002145status_t Parcel::readUniqueParcelFileDescriptor(base::unique_fd* val) const
2146{
2147 int got = readParcelFileDescriptor();
2148
2149 if (got == BAD_TYPE) {
2150 return BAD_TYPE;
2151 }
2152
2153 val->reset(fcntl(got, F_DUPFD_CLOEXEC, 0));
2154
2155 if (val->get() < 0) {
2156 return BAD_VALUE;
2157 }
2158
2159 return OK;
2160}
Casey Dahlin06673e32015-11-23 13:24:23 -08002161
Christopher Wiley2cf19952016-04-11 11:09:37 -07002162status_t Parcel::readUniqueFileDescriptorVector(std::unique_ptr<std::vector<base::unique_fd>>* val) const {
Casey Dahlinb9872622015-11-25 15:09:45 -08002163 return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
2164}
2165
Christopher Wiley2cf19952016-04-11 11:09:37 -07002166status_t Parcel::readUniqueFileDescriptorVector(std::vector<base::unique_fd>* val) const {
Casey Dahlin06673e32015-11-23 13:24:23 -08002167 return readTypedVector(val, &Parcel::readUniqueFileDescriptor);
2168}
2169
Jeff Brown5707dbf2011-09-23 21:17:56 -07002170status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
2171{
Jeff Brown13b16042014-11-11 16:44:25 -08002172 int32_t blobType;
2173 status_t status = readInt32(&blobType);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002174 if (status) return status;
2175
Jeff Brown13b16042014-11-11 16:44:25 -08002176 if (blobType == BLOB_INPLACE) {
Steve Block6807e592011-10-20 11:56:00 +01002177 ALOGV("readBlob: read in place");
Jeff Brown5707dbf2011-09-23 21:17:56 -07002178 const void* ptr = readInplace(len);
2179 if (!ptr) return BAD_VALUE;
2180
Jeff Brown13b16042014-11-11 16:44:25 -08002181 outBlob->init(-1, const_cast<void*>(ptr), len, false);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002182 return NO_ERROR;
2183 }
2184
Steve Block6807e592011-10-20 11:56:00 +01002185 ALOGV("readBlob: read from ashmem");
Jeff Brown13b16042014-11-11 16:44:25 -08002186 bool isMutable = (blobType == BLOB_ASHMEM_MUTABLE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002187 int fd = readFileDescriptor();
2188 if (fd == int(BAD_TYPE)) return BAD_VALUE;
2189
Yi Kongfdd8da92018-06-07 17:52:27 -07002190 void* ptr = ::mmap(nullptr, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ,
Jeff Brown13b16042014-11-11 16:44:25 -08002191 MAP_SHARED, fd, 0);
Narayan Kamath9ea09752014-10-08 17:35:45 +01002192 if (ptr == MAP_FAILED) return NO_MEMORY;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002193
Jeff Brown13b16042014-11-11 16:44:25 -08002194 outBlob->init(fd, ptr, len, isMutable);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002195 return NO_ERROR;
2196}
2197
Mathias Agopiane1424282013-07-29 21:24:40 -07002198status_t Parcel::read(FlattenableHelperInterface& val) const
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002199{
2200 // size
2201 const size_t len = this->readInt32();
2202 const size_t fd_count = this->readInt32();
2203
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002204 if ((len > INT32_MAX) || (fd_count >= gMaxFds)) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07002205 // don't accept size_t values which may have come from an
2206 // inadvertent conversion from a negative int.
2207 return BAD_VALUE;
2208 }
2209
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002210 // payload
Nick Kralevichb6b14232015-04-02 09:36:02 -07002211 void const* const buf = this->readInplace(pad_size(len));
Yi Kongfdd8da92018-06-07 17:52:27 -07002212 if (buf == nullptr)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002213 return BAD_VALUE;
2214
Yi Kongfdd8da92018-06-07 17:52:27 -07002215 int* fds = nullptr;
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002216 if (fd_count) {
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002217 fds = new (std::nothrow) int[fd_count];
2218 if (fds == nullptr) {
2219 ALOGE("read: failed to allocate requested %zu fds", fd_count);
2220 return BAD_VALUE;
2221 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002222 }
2223
2224 status_t err = NO_ERROR;
2225 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
Fabien Sanglardd84ff312016-10-21 10:58:26 -07002226 int fd = this->readFileDescriptor();
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002227 if (fd < 0 || ((fds[i] = fcntl(fd, F_DUPFD_CLOEXEC, 0)) < 0)) {
Jun Jiangabf8a2c2014-04-29 14:22:10 +08002228 err = BAD_VALUE;
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002229 ALOGE("fcntl(F_DUPFD_CLOEXEC) failed in Parcel::read, i is %zu, fds[i] is %d, fd_count is %zu, error: %s",
Fabien Sanglardd84ff312016-10-21 10:58:26 -07002230 i, fds[i], fd_count, strerror(fd < 0 ? -fd : errno));
2231 // Close all the file descriptors that were dup-ed.
2232 for (size_t j=0; j<i ;j++) {
2233 close(fds[j]);
2234 }
Jun Jiangabf8a2c2014-04-29 14:22:10 +08002235 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002236 }
2237
2238 if (err == NO_ERROR) {
2239 err = val.unflatten(buf, len, fds, fd_count);
2240 }
2241
2242 if (fd_count) {
2243 delete [] fds;
2244 }
2245
2246 return err;
2247}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002248const flat_binder_object* Parcel::readObject(bool nullMetaData) const
2249{
2250 const size_t DPOS = mDataPos;
2251 if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
2252 const flat_binder_object* obj
2253 = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
2254 mDataPos = DPOS + sizeof(flat_binder_object);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002255 if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) {
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002256 // When transferring a NULL object, we don't write it into
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002257 // the object list, so we don't want to check for it when
2258 // reading.
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002259 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002260 return obj;
2261 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002262
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002263 // Ensure that this object is valid...
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002264 binder_size_t* const OBJS = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002265 const size_t N = mObjectsSize;
2266 size_t opos = mNextObjectHint;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002267
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002268 if (N > 0) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002269 ALOGV("Parcel %p looking for obj at %zu, hint=%zu",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002270 this, DPOS, opos);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002271
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002272 // Start at the current hint position, looking for an object at
2273 // the current data position.
2274 if (opos < N) {
2275 while (opos < (N-1) && OBJS[opos] < DPOS) {
2276 opos++;
2277 }
2278 } else {
2279 opos = N-1;
2280 }
2281 if (OBJS[opos] == DPOS) {
2282 // Found it!
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002283 ALOGV("Parcel %p found obj %zu at index %zu with forward search",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002284 this, DPOS, opos);
2285 mNextObjectHint = opos+1;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002286 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002287 return obj;
2288 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002289
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002290 // Look backwards for it...
2291 while (opos > 0 && OBJS[opos] > DPOS) {
2292 opos--;
2293 }
2294 if (OBJS[opos] == DPOS) {
2295 // Found it!
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002296 ALOGV("Parcel %p found obj %zu at index %zu with backward search",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002297 this, DPOS, opos);
2298 mNextObjectHint = opos+1;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002299 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002300 return obj;
2301 }
2302 }
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002303 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 -07002304 this, DPOS);
2305 }
Yi Kongfdd8da92018-06-07 17:52:27 -07002306 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002307}
2308
2309void Parcel::closeFileDescriptors()
2310{
2311 size_t i = mObjectsSize;
2312 if (i > 0) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002313 //ALOGI("Closing file descriptors for %zu objects...", i);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002314 }
2315 while (i > 0) {
2316 i--;
2317 const flat_binder_object* flat
2318 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002319 if (flat->hdr.type == BINDER_TYPE_FD) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002320 //ALOGI("Closing fd: %ld", flat->handle);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002321 close(flat->handle);
2322 }
2323 }
2324}
2325
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002326uintptr_t Parcel::ipcData() const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002327{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002328 return reinterpret_cast<uintptr_t>(mData);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002329}
2330
2331size_t Parcel::ipcDataSize() const
2332{
2333 return (mDataSize > mDataPos ? mDataSize : mDataPos);
2334}
2335
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002336uintptr_t Parcel::ipcObjects() const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002337{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002338 return reinterpret_cast<uintptr_t>(mObjects);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002339}
2340
2341size_t Parcel::ipcObjectsCount() const
2342{
2343 return mObjectsSize;
2344}
2345
2346void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002347 const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002348{
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002349 binder_size_t minOffset = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002350 freeDataNoInit();
2351 mError = NO_ERROR;
2352 mData = const_cast<uint8_t*>(data);
2353 mDataSize = mDataCapacity = dataSize;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002354 //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)", this, mDataSize, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002355 mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002356 ALOGV("setDataReference Setting data pos of %p to %zu", this, mDataPos);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002357 mObjects = const_cast<binder_size_t*>(objects);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002358 mObjectsSize = mObjectsCapacity = objectsCount;
2359 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002360 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002361 mOwner = relFunc;
2362 mOwnerCookie = relCookie;
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002363 for (size_t i = 0; i < mObjectsSize; i++) {
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002364 binder_size_t offset = mObjects[i];
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002365 if (offset < minOffset) {
Dan Albert3bdc5b82014-11-20 11:50:23 -08002366 ALOGE("%s: bad object offset %" PRIu64 " < %" PRIu64 "\n",
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002367 __func__, (uint64_t)offset, (uint64_t)minOffset);
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002368 mObjectsSize = 0;
2369 break;
2370 }
2371 minOffset = offset + sizeof(flat_binder_object);
2372 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002373 scanForFds();
2374}
2375
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002376void Parcel::print(TextOutput& to, uint32_t /*flags*/) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002377{
2378 to << "Parcel(";
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002379
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002380 if (errorCheck() != NO_ERROR) {
2381 const status_t err = errorCheck();
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002382 to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\"";
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002383 } else if (dataSize() > 0) {
2384 const uint8_t* DATA = data();
2385 to << indent << HexDump(DATA, dataSize()) << dedent;
Steven Moreland8bd01352019-07-15 16:36:14 -07002386 const binder_size_t* OBJS = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002387 const size_t N = objectsCount();
2388 for (size_t i=0; i<N; i++) {
2389 const flat_binder_object* flat
2390 = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
2391 to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002392 << TypeCode(flat->hdr.type & 0x7f7f7f00)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002393 << " = " << flat->binder;
2394 }
2395 } else {
2396 to << "NULL";
2397 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002398
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002399 to << ")";
2400}
2401
2402void Parcel::releaseObjects()
2403{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002404 size_t i = mObjectsSize;
Martijn Coenen69390d42018-10-22 15:18:10 +02002405 if (i == 0) {
2406 return;
2407 }
2408 sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002409 uint8_t* const data = mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002410 binder_size_t* const objects = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002411 while (i > 0) {
2412 i--;
2413 const flat_binder_object* flat
2414 = reinterpret_cast<flat_binder_object*>(data+objects[i]);
Adrian Rooscbf37262015-10-22 16:12:53 -07002415 release_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002416 }
2417}
2418
2419void Parcel::acquireObjects()
2420{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002421 size_t i = mObjectsSize;
Martijn Coenen69390d42018-10-22 15:18:10 +02002422 if (i == 0) {
2423 return;
2424 }
2425 const sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002426 uint8_t* const data = mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002427 binder_size_t* const objects = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002428 while (i > 0) {
2429 i--;
2430 const flat_binder_object* flat
2431 = reinterpret_cast<flat_binder_object*>(data+objects[i]);
Adrian Rooscbf37262015-10-22 16:12:53 -07002432 acquire_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002433 }
2434}
2435
2436void Parcel::freeData()
2437{
2438 freeDataNoInit();
2439 initState();
2440}
2441
2442void Parcel::freeDataNoInit()
2443{
2444 if (mOwner) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002445 LOG_ALLOC("Parcel %p: freeing other owner data", this);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002446 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002447 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
2448 } else {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002449 LOG_ALLOC("Parcel %p: freeing allocated data", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002450 releaseObjects();
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002451 if (mData) {
2452 LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002453 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dan Austin48fd7b42015-09-10 13:46:02 -07002454 if (mDataCapacity <= gParcelGlobalAllocSize) {
2455 gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity;
2456 } else {
2457 gParcelGlobalAllocSize = 0;
2458 }
2459 if (gParcelGlobalAllocCount > 0) {
2460 gParcelGlobalAllocCount--;
2461 }
Dianne Hackborna4cff882014-11-13 17:07:40 -08002462 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002463 free(mData);
2464 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002465 if (mObjects) free(mObjects);
2466 }
2467}
2468
2469status_t Parcel::growData(size_t len)
2470{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002471 if (len > INT32_MAX) {
2472 // don't accept size_t values which may have come from an
2473 // inadvertent conversion from a negative int.
2474 return BAD_VALUE;
2475 }
2476
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002477 size_t newSize = ((mDataSize+len)*3)/2;
2478 return (newSize <= mDataSize)
2479 ? (status_t) NO_MEMORY
2480 : continueWrite(newSize);
2481}
2482
2483status_t Parcel::restartWrite(size_t desired)
2484{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002485 if (desired > INT32_MAX) {
2486 // don't accept size_t values which may have come from an
2487 // inadvertent conversion from a negative int.
2488 return BAD_VALUE;
2489 }
2490
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002491 if (mOwner) {
2492 freeData();
2493 return continueWrite(desired);
2494 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002495
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002496 uint8_t* data = (uint8_t*)realloc(mData, desired);
2497 if (!data && desired > mDataCapacity) {
2498 mError = NO_MEMORY;
2499 return NO_MEMORY;
2500 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002501
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002502 releaseObjects();
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002503
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002504 if (data) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002505 LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002506 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002507 gParcelGlobalAllocSize += desired;
2508 gParcelGlobalAllocSize -= mDataCapacity;
Colin Cross83ec65e2015-12-08 17:15:50 -08002509 if (!mData) {
2510 gParcelGlobalAllocCount++;
2511 }
Dianne Hackborna4cff882014-11-13 17:07:40 -08002512 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002513 mData = data;
2514 mDataCapacity = desired;
2515 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002516
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002517 mDataSize = mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002518 ALOGV("restartWrite Setting data size of %p to %zu", this, mDataSize);
2519 ALOGV("restartWrite Setting data pos of %p to %zu", this, mDataPos);
2520
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002521 free(mObjects);
Yi Kongfdd8da92018-06-07 17:52:27 -07002522 mObjects = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002523 mObjectsSize = mObjectsCapacity = 0;
2524 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002525 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002526 mHasFds = false;
2527 mFdsKnown = true;
Dianne Hackborn8938ed22011-09-28 23:19:47 -04002528 mAllowFds = true;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002529
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002530 return NO_ERROR;
2531}
2532
2533status_t Parcel::continueWrite(size_t desired)
2534{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002535 if (desired > INT32_MAX) {
2536 // don't accept size_t values which may have come from an
2537 // inadvertent conversion from a negative int.
2538 return BAD_VALUE;
2539 }
2540
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002541 // If shrinking, first adjust for any objects that appear
2542 // after the new data size.
2543 size_t objectsSize = mObjectsSize;
2544 if (desired < mDataSize) {
2545 if (desired == 0) {
2546 objectsSize = 0;
2547 } else {
2548 while (objectsSize > 0) {
Michael Wachenschwanza6541632017-05-18 22:08:32 +00002549 if (mObjects[objectsSize-1] < desired)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002550 break;
2551 objectsSize--;
2552 }
2553 }
2554 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002555
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002556 if (mOwner) {
2557 // If the size is going to zero, just release the owner's data.
2558 if (desired == 0) {
2559 freeData();
2560 return NO_ERROR;
2561 }
2562
2563 // If there is a different owner, we need to take
2564 // posession.
2565 uint8_t* data = (uint8_t*)malloc(desired);
2566 if (!data) {
2567 mError = NO_MEMORY;
2568 return NO_MEMORY;
2569 }
Yi Kongfdd8da92018-06-07 17:52:27 -07002570 binder_size_t* objects = nullptr;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002571
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002572 if (objectsSize) {
Nick Kraleviche9881a32015-04-28 16:21:30 -07002573 objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002574 if (!objects) {
Hyejin Kim3f727c02013-03-09 11:28:54 +09002575 free(data);
2576
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002577 mError = NO_MEMORY;
2578 return NO_MEMORY;
2579 }
2580
2581 // Little hack to only acquire references on objects
2582 // we will be keeping.
2583 size_t oldObjectsSize = mObjectsSize;
2584 mObjectsSize = objectsSize;
2585 acquireObjects();
2586 mObjectsSize = oldObjectsSize;
2587 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002588
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002589 if (mData) {
2590 memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
2591 }
2592 if (objects && mObjects) {
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002593 memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002594 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002595 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002596 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
Yi Kongfdd8da92018-06-07 17:52:27 -07002597 mOwner = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002598
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002599 LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002600 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002601 gParcelGlobalAllocSize += desired;
2602 gParcelGlobalAllocCount++;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002603 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002604
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002605 mData = data;
2606 mObjects = objects;
2607 mDataSize = (mDataSize < desired) ? mDataSize : desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002608 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002609 mDataCapacity = desired;
2610 mObjectsSize = mObjectsCapacity = objectsSize;
2611 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002612 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002613
2614 } else if (mData) {
2615 if (objectsSize < mObjectsSize) {
2616 // Need to release refs on any objects we are dropping.
2617 const sp<ProcessState> proc(ProcessState::self());
2618 for (size_t i=objectsSize; i<mObjectsSize; i++) {
2619 const flat_binder_object* flat
2620 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002621 if (flat->hdr.type == BINDER_TYPE_FD) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002622 // will need to rescan because we may have lopped off the only FDs
2623 mFdsKnown = false;
2624 }
Adrian Rooscbf37262015-10-22 16:12:53 -07002625 release_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002626 }
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002627 binder_size_t* objects =
2628 (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002629 if (objects) {
2630 mObjects = objects;
2631 }
2632 mObjectsSize = objectsSize;
2633 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002634 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002635 }
2636
2637 // We own the data, so we can just do a realloc().
2638 if (desired > mDataCapacity) {
2639 uint8_t* data = (uint8_t*)realloc(mData, desired);
2640 if (data) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002641 LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity,
2642 desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002643 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002644 gParcelGlobalAllocSize += desired;
2645 gParcelGlobalAllocSize -= mDataCapacity;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002646 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002647 mData = data;
2648 mDataCapacity = desired;
Ganesh Mahendranade89892017-09-28 16:56:03 +08002649 } else {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002650 mError = NO_MEMORY;
2651 return NO_MEMORY;
2652 }
2653 } else {
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -07002654 if (mDataSize > desired) {
2655 mDataSize = desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002656 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -07002657 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002658 if (mDataPos > desired) {
2659 mDataPos = desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002660 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002661 }
2662 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002663
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002664 } else {
2665 // This is the first data. Easy!
2666 uint8_t* data = (uint8_t*)malloc(desired);
2667 if (!data) {
2668 mError = NO_MEMORY;
2669 return NO_MEMORY;
2670 }
Hyejin Kim3f727c02013-03-09 11:28:54 +09002671
Yi Kongfdd8da92018-06-07 17:52:27 -07002672 if(!(mDataCapacity == 0 && mObjects == nullptr
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002673 && mObjectsCapacity == 0)) {
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002674 ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002675 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002676
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002677 LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002678 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002679 gParcelGlobalAllocSize += desired;
2680 gParcelGlobalAllocCount++;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002681 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002682
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002683 mData = data;
2684 mDataSize = mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002685 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
2686 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002687 mDataCapacity = desired;
2688 }
2689
2690 return NO_ERROR;
2691}
2692
2693void Parcel::initState()
2694{
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002695 LOG_ALLOC("Parcel %p: initState", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002696 mError = NO_ERROR;
Yi Kongfdd8da92018-06-07 17:52:27 -07002697 mData = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002698 mDataSize = 0;
2699 mDataCapacity = 0;
2700 mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002701 ALOGV("initState Setting data size of %p to %zu", this, mDataSize);
2702 ALOGV("initState Setting data pos of %p to %zu", this, mDataPos);
Yi Kongfdd8da92018-06-07 17:52:27 -07002703 mObjects = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002704 mObjectsSize = 0;
2705 mObjectsCapacity = 0;
2706 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002707 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002708 mHasFds = false;
2709 mFdsKnown = true;
Dianne Hackborn8938ed22011-09-28 23:19:47 -04002710 mAllowFds = true;
Yi Kongfdd8da92018-06-07 17:52:27 -07002711 mOwner = nullptr;
Adrian Rooscbf37262015-10-22 16:12:53 -07002712 mOpenAshmemSize = 0;
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002713
2714 // racing multiple init leads only to multiple identical write
2715 if (gMaxFds == 0) {
2716 struct rlimit result;
2717 if (!getrlimit(RLIMIT_NOFILE, &result)) {
2718 gMaxFds = (size_t)result.rlim_cur;
Christopher Tatebf14e942016-03-25 14:16:24 -07002719 //ALOGI("parcel fd limit set to %zu", gMaxFds);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002720 } else {
2721 ALOGW("Unable to getrlimit: %s", strerror(errno));
2722 gMaxFds = 1024;
2723 }
2724 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002725}
2726
2727void Parcel::scanForFds() const
2728{
2729 bool hasFds = false;
2730 for (size_t i=0; i<mObjectsSize; i++) {
2731 const flat_binder_object* flat
2732 = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002733 if (flat->hdr.type == BINDER_TYPE_FD) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002734 hasFds = true;
2735 break;
2736 }
2737 }
2738 mHasFds = hasFds;
2739 mFdsKnown = true;
2740}
2741
Dan Sandleraa5c2342015-04-10 10:08:45 -04002742size_t Parcel::getBlobAshmemSize() const
2743{
Adrian Roos6bb31142015-10-22 16:46:12 -07002744 // This used to return the size of all blobs that were written to ashmem, now we're returning
2745 // the ashmem currently referenced by this Parcel, which should be equivalent.
2746 // TODO: Remove method once ABI can be changed.
2747 return mOpenAshmemSize;
Dan Sandleraa5c2342015-04-10 10:08:45 -04002748}
2749
Adrian Rooscbf37262015-10-22 16:12:53 -07002750size_t Parcel::getOpenAshmemSize() const
2751{
2752 return mOpenAshmemSize;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002753}
2754
2755// --- Parcel::Blob ---
2756
2757Parcel::Blob::Blob() :
Yi Kongfdd8da92018-06-07 17:52:27 -07002758 mFd(-1), mData(nullptr), mSize(0), mMutable(false) {
Jeff Brown5707dbf2011-09-23 21:17:56 -07002759}
2760
2761Parcel::Blob::~Blob() {
2762 release();
2763}
2764
2765void Parcel::Blob::release() {
Jeff Brown13b16042014-11-11 16:44:25 -08002766 if (mFd != -1 && mData) {
Jeff Brown5707dbf2011-09-23 21:17:56 -07002767 ::munmap(mData, mSize);
2768 }
2769 clear();
2770}
2771
Jeff Brown13b16042014-11-11 16:44:25 -08002772void Parcel::Blob::init(int fd, void* data, size_t size, bool isMutable) {
2773 mFd = fd;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002774 mData = data;
2775 mSize = size;
Jeff Brown13b16042014-11-11 16:44:25 -08002776 mMutable = isMutable;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002777}
2778
2779void Parcel::Blob::clear() {
Jeff Brown13b16042014-11-11 16:44:25 -08002780 mFd = -1;
Yi Kongfdd8da92018-06-07 17:52:27 -07002781 mData = nullptr;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002782 mSize = 0;
Jeff Brown13b16042014-11-11 16:44:25 -08002783 mMutable = false;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002784}
2785
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002786}; // namespace android