blob: 7e921535b4716f5e951320fe54d227ffa1e88eac [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>
Robert Quattlebaum6316f5b2017-01-04 13:25:14 -080040#include <binder/Value.h>
Mathias Agopian002e1e52013-05-06 20:20:50 -070041
Mark Salyzynabed7f72016-01-27 08:02:48 -080042#include <cutils/ashmem.h>
Mathias Agopian002e1e52013-05-06 20:20:50 -070043#include <utils/Debug.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080044#include <utils/Flattenable.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070045#include <utils/Log.h>
Mark Salyzynabed7f72016-01-27 08:02:48 -080046#include <utils/misc.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070047#include <utils/String8.h>
48#include <utils/String16.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070049
Mathias Agopian208059f2009-05-18 15:08:03 -070050#include <private/binder/binder_module.h>
Dianne Hackborn7e790af2014-11-11 12:22:53 -080051#include <private/binder/Static.h>
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070052
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070053#ifndef INT32_MAX
54#define INT32_MAX ((int32_t)(2147483647))
55#endif
56
57#define LOG_REFS(...)
Mark Salyzyne93390b2016-01-27 08:02:48 -080058//#define LOG_REFS(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
Dianne Hackborn7e790af2014-11-11 12:22:53 -080059#define LOG_ALLOC(...)
Mark Salyzyne93390b2016-01-27 08:02:48 -080060//#define LOG_ALLOC(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070061
62// ---------------------------------------------------------------------------
63
Nick Kralevichb6b14232015-04-02 09:36:02 -070064// This macro should never be used at runtime, as a too large value
65// of s could cause an integer overflow. Instead, you should always
66// use the wrapper function pad_size()
67#define PAD_SIZE_UNSAFE(s) (((s)+3)&~3)
68
69static size_t pad_size(size_t s) {
70 if (s > (SIZE_T_MAX - 3)) {
71 abort();
72 }
73 return PAD_SIZE_UNSAFE(s);
74}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070075
Brad Fitzpatricka877cd82010-07-07 16:06:39 -070076// Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
Jeff Sharkey05827be2018-06-26 10:52:38 -060077#define STRICT_MODE_PENALTY_GATHER (1 << 31)
Brad Fitzpatricka877cd82010-07-07 16:06:39 -070078
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070079namespace android {
80
Dianne Hackborna4cff882014-11-13 17:07:40 -080081static pthread_mutex_t gParcelGlobalAllocSizeLock = PTHREAD_MUTEX_INITIALIZER;
82static size_t gParcelGlobalAllocSize = 0;
83static size_t gParcelGlobalAllocCount = 0;
84
Christopher Tatee4e0ae82016-03-24 16:03:44 -070085static size_t gMaxFds = 0;
86
Jeff Brown13b16042014-11-11 16:44:25 -080087// Maximum size of a blob to transfer in-place.
88static const size_t BLOB_INPLACE_LIMIT = 16 * 1024;
89
90enum {
91 BLOB_INPLACE = 0,
92 BLOB_ASHMEM_IMMUTABLE = 1,
93 BLOB_ASHMEM_MUTABLE = 2,
94};
95
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070096void acquire_object(const sp<ProcessState>& proc,
Adrian Rooscbf37262015-10-22 16:12:53 -070097 const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -070098{
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -070099 switch (obj.hdr.type) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700100 case BINDER_TYPE_BINDER:
101 if (obj.binder) {
102 LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800103 reinterpret_cast<IBinder*>(obj.cookie)->incStrong(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700104 }
105 return;
106 case BINDER_TYPE_WEAK_BINDER:
107 if (obj.binder)
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800108 reinterpret_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700109 return;
110 case BINDER_TYPE_HANDLE: {
111 const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
Yi Kong91635562018-06-07 14:38:36 -0700112 if (b != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700113 LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
114 b->incStrong(who);
115 }
116 return;
117 }
118 case BINDER_TYPE_WEAK_HANDLE: {
119 const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
Yi Kong91635562018-06-07 14:38:36 -0700120 if (b != nullptr) b.get_refs()->incWeak(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700121 return;
122 }
123 case BINDER_TYPE_FD: {
Jorim Jaggi150b4ef2018-07-13 11:18:30 +0000124 if ((obj.cookie != 0) && (outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
Mark Salyzyn80589362016-08-23 16:15:04 -0700125 // If we own an ashmem fd, keep track of how much memory it refers to.
126 int size = ashmem_get_size_region(obj.handle);
127 if (size > 0) {
128 *outAshmemSize += size;
Adrian Rooscbf37262015-10-22 16:12:53 -0700129 }
130 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700131 return;
132 }
133 }
134
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700135 ALOGD("Invalid object type 0x%08x", obj.hdr.type);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700136}
137
Adrian Roos6bb31142015-10-22 16:46:12 -0700138void acquire_object(const sp<ProcessState>& proc,
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700139 const flat_binder_object& obj, const void* who)
140{
Yi Kong91635562018-06-07 14:38:36 -0700141 acquire_object(proc, obj, who, nullptr);
Adrian Roos6bb31142015-10-22 16:46:12 -0700142}
143
144static void release_object(const sp<ProcessState>& proc,
Adrian Rooscbf37262015-10-22 16:12:53 -0700145 const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700146{
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700147 switch (obj.hdr.type) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700148 case BINDER_TYPE_BINDER:
149 if (obj.binder) {
150 LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800151 reinterpret_cast<IBinder*>(obj.cookie)->decStrong(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700152 }
153 return;
154 case BINDER_TYPE_WEAK_BINDER:
155 if (obj.binder)
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800156 reinterpret_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700157 return;
158 case BINDER_TYPE_HANDLE: {
159 const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
Yi Kong91635562018-06-07 14:38:36 -0700160 if (b != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700161 LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
162 b->decStrong(who);
163 }
164 return;
165 }
166 case BINDER_TYPE_WEAK_HANDLE: {
167 const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
Yi Kong91635562018-06-07 14:38:36 -0700168 if (b != nullptr) b.get_refs()->decWeak(who);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700169 return;
170 }
171 case BINDER_TYPE_FD: {
Mark Salyzynb454d8f2016-01-27 08:02:48 -0800172 if (obj.cookie != 0) { // owned
Jorim Jaggi150b4ef2018-07-13 11:18:30 +0000173 if ((outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
Mark Salyzyn80589362016-08-23 16:15:04 -0700174 int size = ashmem_get_size_region(obj.handle);
175 if (size > 0) {
Tri Voaa6e1112019-01-29 13:23:46 -0800176 // ashmem size might have changed since last time it was accounted for, e.g.
177 // in acquire_object(). Value of *outAshmemSize is not critical since we are
178 // releasing the object anyway. Check for integer overflow condition.
179 *outAshmemSize -= std::min(*outAshmemSize, static_cast<size_t>(size));
Adrian Roos6bb31142015-10-22 16:46:12 -0700180 }
Adrian Roos6bb31142015-10-22 16:46:12 -0700181 }
Mark Salyzynb454d8f2016-01-27 08:02:48 -0800182
183 close(obj.handle);
Adrian Rooscbf37262015-10-22 16:12:53 -0700184 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700185 return;
186 }
187 }
188
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700189 ALOGE("Invalid object type 0x%08x", obj.hdr.type);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700190}
191
Adrian Roos6bb31142015-10-22 16:46:12 -0700192void release_object(const sp<ProcessState>& proc,
193 const flat_binder_object& obj, const void* who)
194{
Yi Kong91635562018-06-07 14:38:36 -0700195 release_object(proc, obj, who, nullptr);
Adrian Roos6bb31142015-10-22 16:46:12 -0700196}
197
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700198inline static status_t finish_flatten_binder(
Colin Cross6f4f3ab2014-02-05 17:42:44 -0800199 const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700200{
201 return out->writeObject(flat, false);
202}
203
Colin Cross6f4f3ab2014-02-05 17:42:44 -0800204status_t flatten_binder(const sp<ProcessState>& /*proc*/,
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700205 const sp<IBinder>& binder, Parcel* out)
206{
207 flat_binder_object obj;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700208
Martijn Coenen2b631742017-05-05 11:16:59 -0700209 if (IPCThreadState::self()->backgroundSchedulingDisabled()) {
210 /* minimum priority for all nodes is nice 0 */
211 obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;
212 } else {
213 /* minimum priority for all nodes is MAX_NICE(19) */
214 obj.flags = 0x13 | FLAT_BINDER_FLAG_ACCEPTS_FDS;
215 }
216
Yi Kong91635562018-06-07 14:38:36 -0700217 if (binder != nullptr) {
Steven Morelandf0212002018-12-26 13:59:23 -0800218 BBinder *local = binder->localBinder();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700219 if (!local) {
220 BpBinder *proxy = binder->remoteBinder();
Yi Kong91635562018-06-07 14:38:36 -0700221 if (proxy == nullptr) {
Steve Blocke6f43dd2012-01-06 19:20:56 +0000222 ALOGE("null proxy");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700223 }
224 const int32_t handle = proxy ? proxy->handle() : 0;
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700225 obj.hdr.type = BINDER_TYPE_HANDLE;
Arve Hjønnevåg07fd0f12014-02-18 21:10:29 -0800226 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700227 obj.handle = handle;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800228 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700229 } else {
Steven Morelandf0212002018-12-26 13:59:23 -0800230 if (local->isRequestingSid()) {
231 obj.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
232 }
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700233 obj.hdr.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800234 obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
235 obj.cookie = reinterpret_cast<uintptr_t>(local);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700236 }
237 } else {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700238 obj.hdr.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800239 obj.binder = 0;
240 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700241 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700242
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700243 return finish_flatten_binder(binder, obj, out);
244}
245
Colin Cross6f4f3ab2014-02-05 17:42:44 -0800246status_t flatten_binder(const sp<ProcessState>& /*proc*/,
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700247 const wp<IBinder>& binder, Parcel* out)
248{
249 flat_binder_object obj;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700250
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700251 obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
Yi Kong91635562018-06-07 14:38:36 -0700252 if (binder != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700253 sp<IBinder> real = binder.promote();
Yi Kong91635562018-06-07 14:38:36 -0700254 if (real != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700255 IBinder *local = real->localBinder();
256 if (!local) {
257 BpBinder *proxy = real->remoteBinder();
Yi Kong91635562018-06-07 14:38:36 -0700258 if (proxy == nullptr) {
Steve Blocke6f43dd2012-01-06 19:20:56 +0000259 ALOGE("null proxy");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700260 }
261 const int32_t handle = proxy ? proxy->handle() : 0;
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700262 obj.hdr.type = BINDER_TYPE_WEAK_HANDLE;
Arve Hjønnevåg07fd0f12014-02-18 21:10:29 -0800263 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700264 obj.handle = handle;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800265 obj.cookie = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700266 } else {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700267 obj.hdr.type = BINDER_TYPE_WEAK_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800268 obj.binder = reinterpret_cast<uintptr_t>(binder.get_refs());
269 obj.cookie = reinterpret_cast<uintptr_t>(binder.unsafe_get());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700270 }
271 return finish_flatten_binder(real, obj, out);
272 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700273
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700274 // XXX How to deal? In order to flatten the given binder,
275 // we need to probe it for information, which requires a primary
276 // reference... but we don't have one.
277 //
278 // The OpenBinder implementation uses a dynamic_cast<> here,
279 // but we can't do that with the different reference counting
280 // implementation we are using.
Steve Blocke6f43dd2012-01-06 19:20:56 +0000281 ALOGE("Unable to unflatten Binder weak reference!");
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700282 obj.hdr.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800283 obj.binder = 0;
284 obj.cookie = 0;
Yi Kong91635562018-06-07 14:38:36 -0700285 return finish_flatten_binder(nullptr, obj, out);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700286
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700287 } else {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700288 obj.hdr.type = BINDER_TYPE_BINDER;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800289 obj.binder = 0;
290 obj.cookie = 0;
Yi Kong91635562018-06-07 14:38:36 -0700291 return finish_flatten_binder(nullptr, obj, out);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700292 }
293}
294
295inline static status_t finish_unflatten_binder(
Colin Cross6f4f3ab2014-02-05 17:42:44 -0800296 BpBinder* /*proxy*/, const flat_binder_object& /*flat*/,
297 const Parcel& /*in*/)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700298{
299 return NO_ERROR;
300}
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700301
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700302status_t unflatten_binder(const sp<ProcessState>& proc,
303 const Parcel& in, sp<IBinder>* out)
304{
305 const flat_binder_object* flat = in.readObject(false);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700306
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700307 if (flat) {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700308 switch (flat->hdr.type) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700309 case BINDER_TYPE_BINDER:
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800310 *out = reinterpret_cast<IBinder*>(flat->cookie);
Yi Kong91635562018-06-07 14:38:36 -0700311 return finish_unflatten_binder(nullptr, *flat, in);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700312 case BINDER_TYPE_HANDLE:
313 *out = proc->getStrongProxyForHandle(flat->handle);
314 return finish_unflatten_binder(
315 static_cast<BpBinder*>(out->get()), *flat, in);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700316 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700317 }
318 return BAD_TYPE;
319}
320
321status_t unflatten_binder(const sp<ProcessState>& proc,
322 const Parcel& in, wp<IBinder>* out)
323{
324 const flat_binder_object* flat = in.readObject(false);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700325
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700326 if (flat) {
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700327 switch (flat->hdr.type) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700328 case BINDER_TYPE_BINDER:
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800329 *out = reinterpret_cast<IBinder*>(flat->cookie);
Yi Kong91635562018-06-07 14:38:36 -0700330 return finish_unflatten_binder(nullptr, *flat, in);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700331 case BINDER_TYPE_WEAK_BINDER:
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800332 if (flat->binder != 0) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700333 out->set_object_and_refs(
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800334 reinterpret_cast<IBinder*>(flat->cookie),
335 reinterpret_cast<RefBase::weakref_type*>(flat->binder));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700336 } else {
Yi Kong91635562018-06-07 14:38:36 -0700337 *out = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700338 }
Yi Kong91635562018-06-07 14:38:36 -0700339 return finish_unflatten_binder(nullptr, *flat, in);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700340 case BINDER_TYPE_HANDLE:
341 case BINDER_TYPE_WEAK_HANDLE:
342 *out = proc->getWeakProxyForHandle(flat->handle);
343 return finish_unflatten_binder(
344 static_cast<BpBinder*>(out->unsafe_get()), *flat, in);
345 }
346 }
347 return BAD_TYPE;
348}
349
350// ---------------------------------------------------------------------------
351
352Parcel::Parcel()
353{
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800354 LOG_ALLOC("Parcel %p: constructing", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700355 initState();
356}
357
358Parcel::~Parcel()
359{
360 freeDataNoInit();
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800361 LOG_ALLOC("Parcel %p: destroyed", this);
362}
363
364size_t Parcel::getGlobalAllocSize() {
Dianne Hackborna4cff882014-11-13 17:07:40 -0800365 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
366 size_t size = gParcelGlobalAllocSize;
367 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
368 return size;
Dianne Hackborn7e790af2014-11-11 12:22:53 -0800369}
370
371size_t Parcel::getGlobalAllocCount() {
Dianne Hackborna4cff882014-11-13 17:07:40 -0800372 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
373 size_t count = gParcelGlobalAllocCount;
374 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
375 return count;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700376}
377
378const uint8_t* Parcel::data() const
379{
380 return mData;
381}
382
383size_t Parcel::dataSize() const
384{
385 return (mDataSize > mDataPos ? mDataSize : mDataPos);
386}
387
388size_t Parcel::dataAvail() const
389{
Nick Kralevichcfe27de2015-09-16 09:49:15 -0700390 size_t result = dataSize() - dataPosition();
391 if (result > INT32_MAX) {
392 abort();
393 }
394 return result;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700395}
396
397size_t Parcel::dataPosition() const
398{
399 return mDataPos;
400}
401
402size_t Parcel::dataCapacity() const
403{
404 return mDataCapacity;
405}
406
407status_t Parcel::setDataSize(size_t size)
408{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700409 if (size > INT32_MAX) {
410 // don't accept size_t values which may have come from an
411 // inadvertent conversion from a negative int.
412 return BAD_VALUE;
413 }
414
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700415 status_t err;
416 err = continueWrite(size);
417 if (err == NO_ERROR) {
418 mDataSize = size;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700419 ALOGV("setDataSize Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700420 }
421 return err;
422}
423
424void Parcel::setDataPosition(size_t pos) const
425{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700426 if (pos > INT32_MAX) {
427 // don't accept size_t values which may have come from an
428 // inadvertent conversion from a negative int.
429 abort();
430 }
431
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700432 mDataPos = pos;
433 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -0800434 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700435}
436
437status_t Parcel::setDataCapacity(size_t size)
438{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700439 if (size > INT32_MAX) {
440 // don't accept size_t values which may have come from an
441 // inadvertent conversion from a negative int.
442 return BAD_VALUE;
443 }
444
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -0700445 if (size > mDataCapacity) return continueWrite(size);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700446 return NO_ERROR;
447}
448
449status_t Parcel::setData(const uint8_t* buffer, size_t len)
450{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700451 if (len > INT32_MAX) {
452 // don't accept size_t values which may have come from an
453 // inadvertent conversion from a negative int.
454 return BAD_VALUE;
455 }
456
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700457 status_t err = restartWrite(len);
458 if (err == NO_ERROR) {
459 memcpy(const_cast<uint8_t*>(data()), buffer, len);
460 mDataSize = len;
461 mFdsKnown = false;
462 }
463 return err;
464}
465
Andreas Huber51faf462011-04-13 10:21:56 -0700466status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700467{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700468 status_t err;
Andreas Huber51faf462011-04-13 10:21:56 -0700469 const uint8_t *data = parcel->mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800470 const binder_size_t *objects = parcel->mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700471 size_t size = parcel->mObjectsSize;
472 int startPos = mDataPos;
473 int firstIndex = -1, lastIndex = -2;
474
475 if (len == 0) {
476 return NO_ERROR;
477 }
478
Nick Kralevichb6b14232015-04-02 09:36:02 -0700479 if (len > INT32_MAX) {
480 // don't accept size_t values which may have come from an
481 // inadvertent conversion from a negative int.
482 return BAD_VALUE;
483 }
484
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700485 // range checks against the source parcel size
486 if ((offset > parcel->mDataSize)
487 || (len > parcel->mDataSize)
488 || (offset + len > parcel->mDataSize)) {
489 return BAD_VALUE;
490 }
491
492 // Count objects in range
493 for (int i = 0; i < (int) size; i++) {
494 size_t off = objects[i];
Christopher Tate27182be2015-05-27 17:53:02 -0700495 if ((off >= offset) && (off + sizeof(flat_binder_object) <= offset + len)) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700496 if (firstIndex == -1) {
497 firstIndex = i;
498 }
499 lastIndex = i;
500 }
501 }
502 int numObjects = lastIndex - firstIndex + 1;
503
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -0700504 if ((mDataSize+len) > mDataCapacity) {
505 // grow data
506 err = growData(len);
507 if (err != NO_ERROR) {
508 return err;
509 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700510 }
511
512 // append data
513 memcpy(mData + mDataPos, data + offset, len);
514 mDataPos += len;
515 mDataSize += len;
516
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400517 err = NO_ERROR;
518
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700519 if (numObjects > 0) {
Martijn Coenen69390d42018-10-22 15:18:10 +0200520 const sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700521 // grow objects
522 if (mObjectsCapacity < mObjectsSize + numObjects) {
Martijn Coenen93fe5182020-01-22 10:46:25 +0100523 if ((size_t) numObjects > SIZE_MAX - mObjectsSize) return NO_MEMORY; // overflow
524 if (mObjectsSize + numObjects > SIZE_MAX / 3) return NO_MEMORY; // overflow
Christopher Tateed7a50c2015-06-08 14:45:14 -0700525 size_t newSize = ((mObjectsSize + numObjects)*3)/2;
Martijn Coenen93fe5182020-01-22 10:46:25 +0100526 if (newSize > SIZE_MAX / sizeof(binder_size_t)) return NO_MEMORY; // overflow
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800527 binder_size_t *objects =
528 (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
Yi Kong91635562018-06-07 14:38:36 -0700529 if (objects == (binder_size_t*)nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700530 return NO_MEMORY;
531 }
532 mObjects = objects;
533 mObjectsCapacity = newSize;
534 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700535
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700536 // append and acquire objects
537 int idx = mObjectsSize;
538 for (int i = firstIndex; i <= lastIndex; i++) {
539 size_t off = objects[i] - offset + startPos;
540 mObjects[idx++] = off;
541 mObjectsSize++;
542
Dianne Hackborn8af0f822009-05-22 13:20:23 -0700543 flat_binder_object* flat
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700544 = reinterpret_cast<flat_binder_object*>(mData + off);
Adrian Rooscbf37262015-10-22 16:12:53 -0700545 acquire_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700546
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -0700547 if (flat->hdr.type == BINDER_TYPE_FD) {
Dianne Hackborn8af0f822009-05-22 13:20:23 -0700548 // If this is a file descriptor, we need to dup it so the
549 // new Parcel now owns its own fd, and can declare that we
550 // officially know we have fds.
Nick Kralevichec9ec7d2016-12-17 19:47:27 -0800551 flat->handle = fcntl(flat->handle, F_DUPFD_CLOEXEC, 0);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800552 flat->cookie = 1;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700553 mHasFds = mFdsKnown = true;
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400554 if (!mAllowFds) {
555 err = FDS_NOT_ALLOWED;
556 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700557 }
558 }
559 }
560
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400561 return err;
562}
563
Dianne Hackborn15feb9b2017-04-10 15:34:35 -0700564int Parcel::compareData(const Parcel& other) {
565 size_t size = dataSize();
566 if (size != other.dataSize()) {
567 return size < other.dataSize() ? -1 : 1;
568 }
569 return memcmp(data(), other.data(), size);
570}
571
Jeff Brown13b16042014-11-11 16:44:25 -0800572bool Parcel::allowFds() const
573{
574 return mAllowFds;
575}
576
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700577bool Parcel::pushAllowFds(bool allowFds)
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400578{
579 const bool origValue = mAllowFds;
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700580 if (!allowFds) {
581 mAllowFds = false;
582 }
Dianne Hackborn8938ed22011-09-28 23:19:47 -0400583 return origValue;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700584}
585
Dianne Hackborn7746cc32011-10-03 21:09:35 -0700586void Parcel::restoreAllowFds(bool lastValue)
587{
588 mAllowFds = lastValue;
589}
590
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700591bool Parcel::hasFileDescriptors() const
592{
593 if (!mFdsKnown) {
594 scanForFds();
595 }
596 return mHasFds;
597}
598
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000599void Parcel::updateWorkSourceRequestHeaderPosition() const {
600 // Only update the request headers once. We only want to point
601 // to the first headers read/written.
602 if (!mRequestHeaderPresent) {
603 mWorkSourceRequestHeaderPosition = dataPosition();
604 mRequestHeaderPresent = true;
605 }
606}
607
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700608// Write RPC headers. (previously just the interface token)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700609status_t Parcel::writeInterfaceToken(const String16& interface)
610{
Olivier Gaillard91a04802018-11-14 17:32:41 +0000611 const IPCThreadState* threadState = IPCThreadState::self();
612 writeInt32(threadState->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER);
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000613 updateWorkSourceRequestHeaderPosition();
Olivier Gaillard91a04802018-11-14 17:32:41 +0000614 writeInt32(threadState->shouldPropagateWorkSource() ?
615 threadState->getCallingWorkSourceUid() : IPCThreadState::kUnsetWorkSource);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700616 // currently the interface identification token is just its name as a string
617 return writeString16(interface);
618}
619
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000620bool Parcel::replaceCallingWorkSourceUid(uid_t uid)
621{
622 if (!mRequestHeaderPresent) {
623 return false;
624 }
625
626 const size_t initialPosition = dataPosition();
627 setDataPosition(mWorkSourceRequestHeaderPosition);
628 status_t err = writeInt32(uid);
629 setDataPosition(initialPosition);
630 return err == NO_ERROR;
631}
632
633uid_t Parcel::readCallingWorkSourceUid()
634{
635 if (!mRequestHeaderPresent) {
636 return IPCThreadState::kUnsetWorkSource;
637 }
638
639 const size_t initialPosition = dataPosition();
640 setDataPosition(mWorkSourceRequestHeaderPosition);
641 uid_t uid = readInt32();
642 setDataPosition(initialPosition);
643 return uid;
644}
645
Mathias Agopian83c04462009-05-22 19:00:22 -0700646bool Parcel::checkInterface(IBinder* binder) const
647{
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700648 return enforceInterface(binder->getInterfaceDescriptor());
Mathias Agopian83c04462009-05-22 19:00:22 -0700649}
650
Brad Fitzpatricka877cd82010-07-07 16:06:39 -0700651bool Parcel::enforceInterface(const String16& interface,
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700652 IPCThreadState* threadState) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700653{
Daniel Colascione759af972019-10-29 16:44:19 -0700654 return enforceInterface(interface.string(), interface.size(), threadState);
655}
656
657bool Parcel::enforceInterface(const char16_t* interface,
658 size_t len,
659 IPCThreadState* threadState) const
660{
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100661 // StrictModePolicy.
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700662 int32_t strictPolicy = readInt32();
Yi Kong91635562018-06-07 14:38:36 -0700663 if (threadState == nullptr) {
Brad Fitzpatrick70081a12010-07-27 09:49:11 -0700664 threadState = IPCThreadState::self();
Brad Fitzpatricka877cd82010-07-07 16:06:39 -0700665 }
Brad Fitzpatrick52736032010-08-30 16:01:16 -0700666 if ((threadState->getLastTransactionBinderFlags() &
667 IBinder::FLAG_ONEWAY) != 0) {
668 // For one-way calls, the callee is running entirely
669 // disconnected from the caller, so disable StrictMode entirely.
670 // Not only does disk/network usage not impact the caller, but
671 // there's no way to commuicate back any violations anyway.
672 threadState->setStrictModePolicy(0);
673 } else {
674 threadState->setStrictModePolicy(strictPolicy);
675 }
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100676 // WorkSource.
Olivier Gaillarddc848a02019-01-30 17:10:44 +0000677 updateWorkSourceRequestHeaderPosition();
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100678 int32_t workSource = readInt32();
Olivier Gaillard91a04802018-11-14 17:32:41 +0000679 threadState->setCallingWorkSourceUidWithoutPropagation(workSource);
Olivier Gaillard0e0f1de2018-08-16 14:04:09 +0100680 // Interface descriptor.
Daniel Colascione759af972019-10-29 16:44:19 -0700681 size_t parcel_interface_len;
682 const char16_t* parcel_interface = readString16Inplace(&parcel_interface_len);
683 if (len == parcel_interface_len &&
684 (!len || !memcmp(parcel_interface, interface, len * sizeof (char16_t)))) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700685 return true;
686 } else {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700687 ALOGW("**** enforceInterface() expected '%s' but read '%s'",
Daniel Colascione759af972019-10-29 16:44:19 -0700688 String8(interface, len).string(),
689 String8(parcel_interface, parcel_interface_len).string());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700690 return false;
691 }
Brad Fitzpatrick702ea9d2010-06-18 13:07:53 -0700692}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700693
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -0800694const binder_size_t* Parcel::objects() const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700695{
696 return mObjects;
697}
698
699size_t Parcel::objectsCount() const
700{
701 return mObjectsSize;
702}
703
704status_t Parcel::errorCheck() const
705{
706 return mError;
707}
708
709void Parcel::setError(status_t err)
710{
711 mError = err;
712}
713
714status_t Parcel::finishWrite(size_t len)
715{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700716 if (len > INT32_MAX) {
717 // don't accept size_t values which may have come from an
718 // inadvertent conversion from a negative int.
719 return BAD_VALUE;
720 }
721
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700722 //printf("Finish write of %d\n", len);
723 mDataPos += len;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700724 ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700725 if (mDataPos > mDataSize) {
726 mDataSize = mDataPos;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -0700727 ALOGV("finishWrite Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700728 }
729 //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
730 return NO_ERROR;
731}
732
733status_t Parcel::writeUnpadded(const void* data, size_t len)
734{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700735 if (len > INT32_MAX) {
736 // don't accept size_t values which may have come from an
737 // inadvertent conversion from a negative int.
738 return BAD_VALUE;
739 }
740
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700741 size_t end = mDataPos + len;
742 if (end < mDataPos) {
743 // integer overflow
744 return BAD_VALUE;
745 }
746
747 if (end <= mDataCapacity) {
748restart_write:
749 memcpy(mData+mDataPos, data, len);
750 return finishWrite(len);
751 }
752
753 status_t err = growData(len);
754 if (err == NO_ERROR) goto restart_write;
755 return err;
756}
757
758status_t Parcel::write(const void* data, size_t len)
759{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700760 if (len > INT32_MAX) {
761 // don't accept size_t values which may have come from an
762 // inadvertent conversion from a negative int.
763 return BAD_VALUE;
764 }
765
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700766 void* const d = writeInplace(len);
767 if (d) {
768 memcpy(d, data, len);
769 return NO_ERROR;
770 }
771 return mError;
772}
773
774void* Parcel::writeInplace(size_t len)
775{
Nick Kralevichb6b14232015-04-02 09:36:02 -0700776 if (len > INT32_MAX) {
777 // don't accept size_t values which may have come from an
778 // inadvertent conversion from a negative int.
Yi Kong91635562018-06-07 14:38:36 -0700779 return nullptr;
Nick Kralevichb6b14232015-04-02 09:36:02 -0700780 }
781
782 const size_t padded = pad_size(len);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700783
784 // sanity check for integer overflow
785 if (mDataPos+padded < mDataPos) {
Yi Kong91635562018-06-07 14:38:36 -0700786 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700787 }
788
789 if ((mDataPos+padded) <= mDataCapacity) {
790restart_write:
791 //printf("Writing %ld bytes, padded to %ld\n", len, padded);
792 uint8_t* const data = mData+mDataPos;
793
794 // Need to pad at end?
795 if (padded != len) {
796#if BYTE_ORDER == BIG_ENDIAN
797 static const uint32_t mask[4] = {
798 0x00000000, 0xffffff00, 0xffff0000, 0xff000000
799 };
800#endif
801#if BYTE_ORDER == LITTLE_ENDIAN
802 static const uint32_t mask[4] = {
803 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
804 };
805#endif
806 //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
807 // *reinterpret_cast<void**>(data+padded-4));
808 *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
809 }
810
811 finishWrite(padded);
812 return data;
813 }
814
815 status_t err = growData(padded);
816 if (err == NO_ERROR) goto restart_write;
Yi Kong91635562018-06-07 14:38:36 -0700817 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700818}
819
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800820status_t Parcel::writeUtf8AsUtf16(const std::string& str) {
821 const uint8_t* strData = (uint8_t*)str.data();
822 const size_t strLen= str.length();
823 const ssize_t utf16Len = utf8_to_utf16_length(strData, strLen);
Sergio Girof4607432016-07-21 14:46:35 +0100824 if (utf16Len < 0 || utf16Len > std::numeric_limits<int32_t>::max()) {
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800825 return BAD_VALUE;
826 }
827
828 status_t err = writeInt32(utf16Len);
829 if (err) {
830 return err;
831 }
832
833 // Allocate enough bytes to hold our converted string and its terminating NULL.
834 void* dst = writeInplace((utf16Len + 1) * sizeof(char16_t));
835 if (!dst) {
836 return NO_MEMORY;
837 }
838
Sergio Girof4607432016-07-21 14:46:35 +0100839 utf8_to_utf16(strData, strLen, (char16_t*)dst, (size_t) utf16Len + 1);
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800840
841 return NO_ERROR;
842}
843
844status_t Parcel::writeUtf8AsUtf16(const std::unique_ptr<std::string>& str) {
845 if (!str) {
846 return writeInt32(-1);
847 }
848 return writeUtf8AsUtf16(*str);
849}
850
Casey Dahlin185d3442016-02-09 11:08:35 -0800851namespace {
Casey Dahlinb9872622015-11-25 15:09:45 -0800852
Casey Dahlin185d3442016-02-09 11:08:35 -0800853template<typename T>
854status_t writeByteVectorInternal(Parcel* parcel, const std::vector<T>& val)
Casey Dahlin451ff582015-10-19 18:12:18 -0700855{
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700856 status_t status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700857 if (val.size() > std::numeric_limits<int32_t>::max()) {
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700858 status = BAD_VALUE;
859 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700860 }
861
Casey Dahlin185d3442016-02-09 11:08:35 -0800862 status = parcel->writeInt32(val.size());
Casey Dahlin451ff582015-10-19 18:12:18 -0700863 if (status != OK) {
864 return status;
865 }
866
Casey Dahlin185d3442016-02-09 11:08:35 -0800867 void* data = parcel->writeInplace(val.size());
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700868 if (!data) {
869 status = BAD_VALUE;
870 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700871 }
872
Christopher Wileyf0fc52b2015-10-31 13:22:15 -0700873 memcpy(data, val.data(), val.size());
874 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -0700875}
876
Casey Dahlin185d3442016-02-09 11:08:35 -0800877template<typename T>
878status_t writeByteVectorInternalPtr(Parcel* parcel,
879 const std::unique_ptr<std::vector<T>>& val)
880{
881 if (!val) {
882 return parcel->writeInt32(-1);
883 }
884
885 return writeByteVectorInternal(parcel, *val);
886}
887
888} // namespace
889
890status_t Parcel::writeByteVector(const std::vector<int8_t>& val) {
891 return writeByteVectorInternal(this, val);
892}
893
894status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<int8_t>>& val)
895{
896 return writeByteVectorInternalPtr(this, val);
897}
898
899status_t Parcel::writeByteVector(const std::vector<uint8_t>& val) {
900 return writeByteVectorInternal(this, val);
901}
902
903status_t Parcel::writeByteVector(const std::unique_ptr<std::vector<uint8_t>>& val)
904{
905 return writeByteVectorInternalPtr(this, val);
906}
907
Casey Dahlin451ff582015-10-19 18:12:18 -0700908status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val)
909{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800910 return writeTypedVector(val, &Parcel::writeInt32);
Casey Dahlin451ff582015-10-19 18:12:18 -0700911}
912
Casey Dahlinb9872622015-11-25 15:09:45 -0800913status_t Parcel::writeInt32Vector(const std::unique_ptr<std::vector<int32_t>>& val)
914{
915 return writeNullableTypedVector(val, &Parcel::writeInt32);
916}
917
Casey Dahlin451ff582015-10-19 18:12:18 -0700918status_t Parcel::writeInt64Vector(const std::vector<int64_t>& val)
919{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800920 return writeTypedVector(val, &Parcel::writeInt64);
Casey Dahlin451ff582015-10-19 18:12:18 -0700921}
922
Casey Dahlinb9872622015-11-25 15:09:45 -0800923status_t Parcel::writeInt64Vector(const std::unique_ptr<std::vector<int64_t>>& val)
924{
925 return writeNullableTypedVector(val, &Parcel::writeInt64);
926}
927
Kevin DuBois2f82d5b2018-12-05 12:56:10 -0800928status_t Parcel::writeUint64Vector(const std::vector<uint64_t>& val)
929{
930 return writeTypedVector(val, &Parcel::writeUint64);
931}
932
933status_t Parcel::writeUint64Vector(const std::unique_ptr<std::vector<uint64_t>>& val)
934{
935 return writeNullableTypedVector(val, &Parcel::writeUint64);
936}
937
Casey Dahlin451ff582015-10-19 18:12:18 -0700938status_t Parcel::writeFloatVector(const std::vector<float>& val)
939{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800940 return writeTypedVector(val, &Parcel::writeFloat);
Casey Dahlin451ff582015-10-19 18:12:18 -0700941}
942
Casey Dahlinb9872622015-11-25 15:09:45 -0800943status_t Parcel::writeFloatVector(const std::unique_ptr<std::vector<float>>& val)
944{
945 return writeNullableTypedVector(val, &Parcel::writeFloat);
946}
947
Casey Dahlin451ff582015-10-19 18:12:18 -0700948status_t Parcel::writeDoubleVector(const std::vector<double>& val)
949{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800950 return writeTypedVector(val, &Parcel::writeDouble);
Casey Dahlin451ff582015-10-19 18:12:18 -0700951}
952
Casey Dahlinb9872622015-11-25 15:09:45 -0800953status_t Parcel::writeDoubleVector(const std::unique_ptr<std::vector<double>>& val)
954{
955 return writeNullableTypedVector(val, &Parcel::writeDouble);
956}
957
Casey Dahlin451ff582015-10-19 18:12:18 -0700958status_t Parcel::writeBoolVector(const std::vector<bool>& val)
959{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800960 return writeTypedVector(val, &Parcel::writeBool);
Casey Dahlin451ff582015-10-19 18:12:18 -0700961}
962
Casey Dahlinb9872622015-11-25 15:09:45 -0800963status_t Parcel::writeBoolVector(const std::unique_ptr<std::vector<bool>>& val)
964{
965 return writeNullableTypedVector(val, &Parcel::writeBool);
966}
967
Casey Dahlin451ff582015-10-19 18:12:18 -0700968status_t Parcel::writeCharVector(const std::vector<char16_t>& val)
969{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800970 return writeTypedVector(val, &Parcel::writeChar);
Casey Dahlin451ff582015-10-19 18:12:18 -0700971}
972
Casey Dahlinb9872622015-11-25 15:09:45 -0800973status_t Parcel::writeCharVector(const std::unique_ptr<std::vector<char16_t>>& val)
974{
975 return writeNullableTypedVector(val, &Parcel::writeChar);
976}
977
Casey Dahlin451ff582015-10-19 18:12:18 -0700978status_t Parcel::writeString16Vector(const std::vector<String16>& val)
979{
Christopher Wiley03d1eb62015-11-19 06:42:40 -0800980 return writeTypedVector(val, &Parcel::writeString16);
Casey Dahlin451ff582015-10-19 18:12:18 -0700981}
982
Casey Dahlinb9872622015-11-25 15:09:45 -0800983status_t Parcel::writeString16Vector(
984 const std::unique_ptr<std::vector<std::unique_ptr<String16>>>& val)
985{
986 return writeNullableTypedVector(val, &Parcel::writeString16);
987}
988
Christopher Wiley9a5e32f2016-01-28 16:56:53 -0800989status_t Parcel::writeUtf8VectorAsUtf16Vector(
990 const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& val) {
991 return writeNullableTypedVector(val, &Parcel::writeUtf8AsUtf16);
992}
993
994status_t Parcel::writeUtf8VectorAsUtf16Vector(const std::vector<std::string>& val) {
995 return writeTypedVector(val, &Parcel::writeUtf8AsUtf16);
996}
997
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -0700998status_t Parcel::writeInt32(int32_t val)
999{
Andreas Huber84a6d042009-08-17 13:33:27 -07001000 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001001}
Dan Stoza41a0f2f2014-12-01 10:01:10 -08001002
1003status_t Parcel::writeUint32(uint32_t val)
1004{
1005 return writeAligned(val);
1006}
1007
Marco Nelissen5c0106e2013-10-16 10:57:51 -07001008status_t Parcel::writeInt32Array(size_t len, const int32_t *val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001009 if (len > INT32_MAX) {
1010 // don't accept size_t values which may have come from an
1011 // inadvertent conversion from a negative int.
1012 return BAD_VALUE;
1013 }
1014
Marco Nelissen5c0106e2013-10-16 10:57:51 -07001015 if (!val) {
Chad Brubakere59cb432015-06-30 14:03:55 -07001016 return writeInt32(-1);
Marco Nelissen5c0106e2013-10-16 10:57:51 -07001017 }
Chad Brubakere59cb432015-06-30 14:03:55 -07001018 status_t ret = writeInt32(static_cast<uint32_t>(len));
Marco Nelissen5c0106e2013-10-16 10:57:51 -07001019 if (ret == NO_ERROR) {
1020 ret = write(val, len * sizeof(*val));
1021 }
1022 return ret;
1023}
Marco Nelissenf0190bf2014-03-13 14:17:40 -07001024status_t Parcel::writeByteArray(size_t len, const uint8_t *val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001025 if (len > INT32_MAX) {
1026 // don't accept size_t values which may have come from an
1027 // inadvertent conversion from a negative int.
1028 return BAD_VALUE;
1029 }
1030
Marco Nelissenf0190bf2014-03-13 14:17:40 -07001031 if (!val) {
Chad Brubakere59cb432015-06-30 14:03:55 -07001032 return writeInt32(-1);
Marco Nelissenf0190bf2014-03-13 14:17:40 -07001033 }
Chad Brubakere59cb432015-06-30 14:03:55 -07001034 status_t ret = writeInt32(static_cast<uint32_t>(len));
Marco Nelissenf0190bf2014-03-13 14:17:40 -07001035 if (ret == NO_ERROR) {
1036 ret = write(val, len * sizeof(*val));
1037 }
1038 return ret;
1039}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001040
Casey Dahlind6848f52015-10-15 15:44:59 -07001041status_t Parcel::writeBool(bool val)
1042{
1043 return writeInt32(int32_t(val));
1044}
1045
1046status_t Parcel::writeChar(char16_t val)
1047{
1048 return writeInt32(int32_t(val));
1049}
1050
1051status_t Parcel::writeByte(int8_t val)
1052{
1053 return writeInt32(int32_t(val));
1054}
1055
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001056status_t Parcel::writeInt64(int64_t val)
1057{
Andreas Huber84a6d042009-08-17 13:33:27 -07001058 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001059}
1060
Ronghua Wu2d13afd2015-03-16 11:11:07 -07001061status_t Parcel::writeUint64(uint64_t val)
1062{
1063 return writeAligned(val);
1064}
1065
Serban Constantinescuf683e012013-11-05 16:53:55 +00001066status_t Parcel::writePointer(uintptr_t val)
1067{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001068 return writeAligned<binder_uintptr_t>(val);
Serban Constantinescuf683e012013-11-05 16:53:55 +00001069}
1070
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001071status_t Parcel::writeFloat(float val)
1072{
Andreas Huber84a6d042009-08-17 13:33:27 -07001073 return writeAligned(val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001074}
1075
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001076#if defined(__mips__) && defined(__mips_hard_float)
1077
1078status_t Parcel::writeDouble(double val)
1079{
1080 union {
1081 double d;
1082 unsigned long long ll;
1083 } u;
1084 u.d = val;
1085 return writeAligned(u.ll);
1086}
1087
1088#else
1089
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001090status_t Parcel::writeDouble(double val)
1091{
Andreas Huber84a6d042009-08-17 13:33:27 -07001092 return writeAligned(val);
1093}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001094
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001095#endif
1096
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001097status_t Parcel::writeCString(const char* str)
1098{
1099 return write(str, strlen(str)+1);
1100}
1101
1102status_t Parcel::writeString8(const String8& str)
1103{
1104 status_t err = writeInt32(str.bytes());
Pravat Dalbeherad1dff8d2010-12-15 08:40:00 +01001105 // only write string if its length is more than zero characters,
1106 // as readString8 will only read if the length field is non-zero.
1107 // this is slightly different from how writeString16 works.
1108 if (str.bytes() > 0 && err == NO_ERROR) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001109 err = write(str.string(), str.bytes()+1);
1110 }
1111 return err;
1112}
1113
Casey Dahlinb9872622015-11-25 15:09:45 -08001114status_t Parcel::writeString16(const std::unique_ptr<String16>& str)
1115{
1116 if (!str) {
1117 return writeInt32(-1);
1118 }
1119
1120 return writeString16(*str);
1121}
1122
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001123status_t Parcel::writeString16(const String16& str)
1124{
1125 return writeString16(str.string(), str.size());
1126}
1127
1128status_t Parcel::writeString16(const char16_t* str, size_t len)
1129{
Yi Kong91635562018-06-07 14:38:36 -07001130 if (str == nullptr) return writeInt32(-1);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001131
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001132 status_t err = writeInt32(len);
1133 if (err == NO_ERROR) {
1134 len *= sizeof(char16_t);
1135 uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
1136 if (data) {
1137 memcpy(data, str, len);
1138 *reinterpret_cast<char16_t*>(data+len) = 0;
1139 return NO_ERROR;
1140 }
1141 err = mError;
1142 }
1143 return err;
1144}
1145
1146status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
1147{
1148 return flatten_binder(ProcessState::self(), val, this);
1149}
1150
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001151status_t Parcel::writeStrongBinderVector(const std::vector<sp<IBinder>>& val)
1152{
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001153 return writeTypedVector(val, &Parcel::writeStrongBinder);
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001154}
1155
Casey Dahlinb9872622015-11-25 15:09:45 -08001156status_t Parcel::writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val)
1157{
1158 return writeNullableTypedVector(val, &Parcel::writeStrongBinder);
1159}
1160
1161status_t Parcel::readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const {
Christopher Wiley35d77ca2016-03-08 10:49:51 -08001162 return readNullableTypedVector(val, &Parcel::readNullableStrongBinder);
Casey Dahlinb9872622015-11-25 15:09:45 -08001163}
1164
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001165status_t Parcel::readStrongBinderVector(std::vector<sp<IBinder>>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001166 return readTypedVector(val, &Parcel::readStrongBinder);
Casey Dahlineb8e15f2015-11-03 13:50:37 -08001167}
1168
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001169status_t Parcel::writeWeakBinder(const wp<IBinder>& val)
1170{
1171 return flatten_binder(ProcessState::self(), val, this);
1172}
1173
Casey Dahlinb9872622015-11-25 15:09:45 -08001174status_t Parcel::writeRawNullableParcelable(const Parcelable* parcelable) {
1175 if (!parcelable) {
1176 return writeInt32(0);
1177 }
1178
1179 return writeParcelable(*parcelable);
1180}
1181
Christopher Wiley97f048d2015-11-19 06:49:05 -08001182status_t Parcel::writeParcelable(const Parcelable& parcelable) {
1183 status_t status = writeInt32(1); // parcelable is not null.
1184 if (status != OK) {
1185 return status;
1186 }
1187 return parcelable.writeToParcel(this);
1188}
1189
Robert Quattlebaum6316f5b2017-01-04 13:25:14 -08001190status_t Parcel::writeValue(const binder::Value& value) {
1191 return value.writeToParcel(this);
1192}
1193
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001194status_t Parcel::writeNativeHandle(const native_handle* handle)
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001195{
Mathias Agopian1d0a95b2009-07-31 16:12:13 -07001196 if (!handle || handle->version != sizeof(native_handle))
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001197 return BAD_TYPE;
1198
1199 status_t err;
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001200 err = writeInt32(handle->numFds);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001201 if (err != NO_ERROR) return err;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001202
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001203 err = writeInt32(handle->numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001204 if (err != NO_ERROR) return err;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001205
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001206 for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)
1207 err = writeDupFileDescriptor(handle->data[i]);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001208
1209 if (err != NO_ERROR) {
Steve Block9d453682011-12-20 16:23:08 +00001210 ALOGD("write native handle, write dup fd failed");
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001211 return err;
1212 }
Mathias Agopiana47f02a2009-05-21 16:29:38 -07001213 err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08001214 return err;
1215}
1216
Jeff Brown93ff1f92011-11-04 19:01:44 -07001217status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001218{
1219 flat_binder_object obj;
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07001220 obj.hdr.type = BINDER_TYPE_FD;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001221 obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
Arve Hjønnevåg07fd0f12014-02-18 21:10:29 -08001222 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001223 obj.handle = fd;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001224 obj.cookie = takeOwnership ? 1 : 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001225 return writeObject(obj, true);
1226}
1227
1228status_t Parcel::writeDupFileDescriptor(int fd)
1229{
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08001230 int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
Jeff Brownd341c712011-11-04 20:19:33 -07001231 if (dupFd < 0) {
1232 return -errno;
1233 }
1234 status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/);
Casey Dahlin06673e32015-11-23 13:24:23 -08001235 if (err != OK) {
Jeff Brownd341c712011-11-04 20:19:33 -07001236 close(dupFd);
1237 }
1238 return err;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001239}
1240
Dianne Hackborn1941a402016-08-29 12:30:43 -07001241status_t Parcel::writeParcelFileDescriptor(int fd, bool takeOwnership)
1242{
1243 writeInt32(0);
1244 return writeFileDescriptor(fd, takeOwnership);
1245}
1246
Ryo Hashimotobf551892018-05-31 16:58:35 +09001247status_t Parcel::writeDupParcelFileDescriptor(int fd)
1248{
1249 int dupFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
1250 if (dupFd < 0) {
1251 return -errno;
1252 }
1253 status_t err = writeParcelFileDescriptor(dupFd, true /*takeOwnership*/);
1254 if (err != OK) {
1255 close(dupFd);
1256 }
1257 return err;
1258}
1259
Christopher Wiley2cf19952016-04-11 11:09:37 -07001260status_t Parcel::writeUniqueFileDescriptor(const base::unique_fd& fd) {
Casey Dahlin06673e32015-11-23 13:24:23 -08001261 return writeDupFileDescriptor(fd.get());
1262}
1263
Christopher Wiley2cf19952016-04-11 11:09:37 -07001264status_t Parcel::writeUniqueFileDescriptorVector(const std::vector<base::unique_fd>& val) {
Casey Dahlin06673e32015-11-23 13:24:23 -08001265 return writeTypedVector(val, &Parcel::writeUniqueFileDescriptor);
1266}
1267
Christopher Wiley2cf19952016-04-11 11:09:37 -07001268status_t Parcel::writeUniqueFileDescriptorVector(const std::unique_ptr<std::vector<base::unique_fd>>& val) {
Casey Dahlinb9872622015-11-25 15:09:45 -08001269 return writeNullableTypedVector(val, &Parcel::writeUniqueFileDescriptor);
1270}
1271
Jeff Brown13b16042014-11-11 16:44:25 -08001272status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob)
Jeff Brown5707dbf2011-09-23 21:17:56 -07001273{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001274 if (len > INT32_MAX) {
1275 // don't accept size_t values which may have come from an
1276 // inadvertent conversion from a negative int.
1277 return BAD_VALUE;
1278 }
1279
Jeff Brown13b16042014-11-11 16:44:25 -08001280 status_t status;
1281 if (!mAllowFds || len <= BLOB_INPLACE_LIMIT) {
Steve Block6807e592011-10-20 11:56:00 +01001282 ALOGV("writeBlob: write in place");
Jeff Brown13b16042014-11-11 16:44:25 -08001283 status = writeInt32(BLOB_INPLACE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001284 if (status) return status;
1285
1286 void* ptr = writeInplace(len);
1287 if (!ptr) return NO_MEMORY;
1288
Jeff Brown13b16042014-11-11 16:44:25 -08001289 outBlob->init(-1, ptr, len, false);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001290 return NO_ERROR;
1291 }
1292
Steve Block6807e592011-10-20 11:56:00 +01001293 ALOGV("writeBlob: write to ashmem");
Jeff Brown5707dbf2011-09-23 21:17:56 -07001294 int fd = ashmem_create_region("Parcel Blob", len);
1295 if (fd < 0) return NO_MEMORY;
1296
1297 int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
1298 if (result < 0) {
Jeff Brownec4e0062011-10-10 14:50:10 -07001299 status = result;
Jeff Brown5707dbf2011-09-23 21:17:56 -07001300 } else {
Yi Kong91635562018-06-07 14:38:36 -07001301 void* ptr = ::mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001302 if (ptr == MAP_FAILED) {
1303 status = -errno;
1304 } else {
Jeff Brown13b16042014-11-11 16:44:25 -08001305 if (!mutableCopy) {
1306 result = ashmem_set_prot_region(fd, PROT_READ);
1307 }
Jeff Brown5707dbf2011-09-23 21:17:56 -07001308 if (result < 0) {
Jeff Brownec4e0062011-10-10 14:50:10 -07001309 status = result;
Jeff Brown5707dbf2011-09-23 21:17:56 -07001310 } else {
Jeff Brown13b16042014-11-11 16:44:25 -08001311 status = writeInt32(mutableCopy ? BLOB_ASHMEM_MUTABLE : BLOB_ASHMEM_IMMUTABLE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001312 if (!status) {
Jeff Brown93ff1f92011-11-04 19:01:44 -07001313 status = writeFileDescriptor(fd, true /*takeOwnership*/);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001314 if (!status) {
Jeff Brown13b16042014-11-11 16:44:25 -08001315 outBlob->init(fd, ptr, len, mutableCopy);
Jeff Brown5707dbf2011-09-23 21:17:56 -07001316 return NO_ERROR;
1317 }
1318 }
1319 }
1320 }
1321 ::munmap(ptr, len);
1322 }
1323 ::close(fd);
1324 return status;
1325}
1326
Jeff Brown13b16042014-11-11 16:44:25 -08001327status_t Parcel::writeDupImmutableBlobFileDescriptor(int fd)
1328{
1329 // Must match up with what's done in writeBlob.
1330 if (!mAllowFds) return FDS_NOT_ALLOWED;
1331 status_t status = writeInt32(BLOB_ASHMEM_IMMUTABLE);
1332 if (status) return status;
1333 return writeDupFileDescriptor(fd);
1334}
1335
Mathias Agopiane1424282013-07-29 21:24:40 -07001336status_t Parcel::write(const FlattenableHelperInterface& val)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001337{
1338 status_t err;
1339
1340 // size if needed
Mathias Agopiane1424282013-07-29 21:24:40 -07001341 const size_t len = val.getFlattenedSize();
1342 const size_t fd_count = val.getFdCount();
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001343
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001344 if ((len > INT32_MAX) || (fd_count >= gMaxFds)) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001345 // don't accept size_t values which may have come from an
1346 // inadvertent conversion from a negative int.
1347 return BAD_VALUE;
1348 }
1349
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001350 err = this->writeInt32(len);
1351 if (err) return err;
1352
1353 err = this->writeInt32(fd_count);
1354 if (err) return err;
1355
1356 // payload
Martijn Coenenf8542382018-04-04 11:46:56 +02001357 void* const buf = this->writeInplace(len);
Yi Kong91635562018-06-07 14:38:36 -07001358 if (buf == nullptr)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001359 return BAD_VALUE;
1360
Yi Kong91635562018-06-07 14:38:36 -07001361 int* fds = nullptr;
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001362 if (fd_count) {
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001363 fds = new (std::nothrow) int[fd_count];
1364 if (fds == nullptr) {
1365 ALOGE("write: failed to allocate requested %zu fds", fd_count);
1366 return BAD_VALUE;
1367 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08001368 }
1369
1370 err = val.flatten(buf, len, fds, fd_count);
1371 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
1372 err = this->writeDupFileDescriptor( fds[i] );
1373 }
1374
1375 if (fd_count) {
1376 delete [] fds;
1377 }
1378
1379 return err;
1380}
1381
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001382status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
1383{
1384 const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
1385 const bool enoughObjects = mObjectsSize < mObjectsCapacity;
1386 if (enoughData && enoughObjects) {
1387restart_write:
1388 *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001389
Christopher Tate98e67d32015-06-03 18:44:15 -07001390 // remember if it's a file descriptor
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07001391 if (val.hdr.type == BINDER_TYPE_FD) {
Christopher Tate98e67d32015-06-03 18:44:15 -07001392 if (!mAllowFds) {
1393 // fail before modifying our object index
1394 return FDS_NOT_ALLOWED;
1395 }
1396 mHasFds = mFdsKnown = true;
1397 }
1398
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001399 // Need to write meta-data?
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001400 if (nullMetaData || val.binder != 0) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001401 mObjects[mObjectsSize] = mDataPos;
Adrian Rooscbf37262015-10-22 16:12:53 -07001402 acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001403 mObjectsSize++;
1404 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001405
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001406 return finishWrite(sizeof(flat_binder_object));
1407 }
1408
1409 if (!enoughData) {
1410 const status_t err = growData(sizeof(val));
1411 if (err != NO_ERROR) return err;
1412 }
1413 if (!enoughObjects) {
Martijn Coenen93fe5182020-01-22 10:46:25 +01001414 if (mObjectsSize > SIZE_MAX - 2) return NO_MEMORY; // overflow
1415 if ((mObjectsSize + 2) > SIZE_MAX / 3) return NO_MEMORY; // overflow
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001416 size_t newSize = ((mObjectsSize+2)*3)/2;
Martijn Coenen93fe5182020-01-22 10:46:25 +01001417 if (newSize > SIZE_MAX / sizeof(binder_size_t)) return NO_MEMORY; // overflow
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001418 binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
Yi Kong91635562018-06-07 14:38:36 -07001419 if (objects == nullptr) return NO_MEMORY;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001420 mObjects = objects;
1421 mObjectsCapacity = newSize;
1422 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001423
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001424 goto restart_write;
1425}
1426
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07001427status_t Parcel::writeNoException()
1428{
Christopher Wiley09eb7492015-11-09 15:06:15 -08001429 binder::Status status;
1430 return status.writeToParcel(this);
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07001431}
1432
Robert Quattlebaum6316f5b2017-01-04 13:25:14 -08001433status_t Parcel::writeMap(const ::android::binder::Map& map_in)
1434{
1435 using ::std::map;
1436 using ::android::binder::Value;
1437 using ::android::binder::Map;
1438
1439 Map::const_iterator iter;
1440 status_t ret;
1441
1442 ret = writeInt32(map_in.size());
1443
1444 if (ret != NO_ERROR) {
1445 return ret;
1446 }
1447
1448 for (iter = map_in.begin(); iter != map_in.end(); ++iter) {
1449 ret = writeValue(Value(iter->first));
1450 if (ret != NO_ERROR) {
1451 return ret;
1452 }
1453
1454 ret = writeValue(iter->second);
1455 if (ret != NO_ERROR) {
1456 return ret;
1457 }
1458 }
1459
1460 return ret;
1461}
1462
1463status_t Parcel::writeNullableMap(const std::unique_ptr<binder::Map>& map)
1464{
Yi Kong91635562018-06-07 14:38:36 -07001465 if (map == nullptr) {
Robert Quattlebaum6316f5b2017-01-04 13:25:14 -08001466 return writeInt32(-1);
1467 }
1468
1469 return writeMap(*map.get());
1470}
1471
1472status_t Parcel::readMap(::android::binder::Map* map_out)const
1473{
1474 using ::std::map;
1475 using ::android::String16;
1476 using ::android::String8;
1477 using ::android::binder::Value;
1478 using ::android::binder::Map;
1479
1480 status_t ret = NO_ERROR;
1481 int32_t count;
1482
1483 ret = readInt32(&count);
1484 if (ret != NO_ERROR) {
1485 return ret;
1486 }
1487
1488 if (count < 0) {
1489 ALOGE("readMap: Unexpected count: %d", count);
1490 return (count == -1)
1491 ? UNEXPECTED_NULL
1492 : BAD_VALUE;
1493 }
1494
1495 map_out->clear();
1496
1497 while (count--) {
1498 Map::key_type key;
1499 Value value;
1500
1501 ret = readValue(&value);
1502 if (ret != NO_ERROR) {
1503 return ret;
1504 }
1505
1506 if (!value.getString(&key)) {
1507 ALOGE("readMap: Key type not a string (parcelType = %d)", value.parcelType());
1508 return BAD_VALUE;
1509 }
1510
1511 ret = readValue(&value);
1512 if (ret != NO_ERROR) {
1513 return ret;
1514 }
1515
1516 (*map_out)[key] = value;
1517 }
1518
1519 return ret;
1520}
1521
1522status_t Parcel::readNullableMap(std::unique_ptr<binder::Map>* map) const
1523{
1524 const size_t start = dataPosition();
1525 int32_t count;
1526 status_t status = readInt32(&count);
1527 map->reset();
1528
1529 if (status != OK || count == -1) {
1530 return status;
1531 }
1532
1533 setDataPosition(start);
1534 map->reset(new binder::Map());
1535
1536 status = readMap(map->get());
1537
1538 if (status != OK) {
1539 map->reset();
1540 }
1541
1542 return status;
1543}
1544
1545
1546
Colin Cross6f4f3ab2014-02-05 17:42:44 -08001547void Parcel::remove(size_t /*start*/, size_t /*amt*/)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001548{
1549 LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
1550}
1551
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001552status_t Parcel::validateReadData(size_t upperBound) const
1553{
1554 // Don't allow non-object reads on object data
1555 if (mObjectsSorted || mObjectsSize <= 1) {
1556data_sorted:
1557 // Expect to check only against the next object
1558 if (mNextObjectHint < mObjectsSize && upperBound > mObjects[mNextObjectHint]) {
1559 // For some reason the current read position is greater than the next object
1560 // hint. Iterate until we find the right object
1561 size_t nextObject = mNextObjectHint;
1562 do {
1563 if (mDataPos < mObjects[nextObject] + sizeof(flat_binder_object)) {
1564 // Requested info overlaps with an object
1565 ALOGE("Attempt to read from protected data in Parcel %p", this);
1566 return PERMISSION_DENIED;
1567 }
1568 nextObject++;
1569 } while (nextObject < mObjectsSize && upperBound > mObjects[nextObject]);
1570 mNextObjectHint = nextObject;
1571 }
1572 return NO_ERROR;
1573 }
1574 // Quickly determine if mObjects is sorted.
1575 binder_size_t* currObj = mObjects + mObjectsSize - 1;
1576 binder_size_t* prevObj = currObj;
1577 while (currObj > mObjects) {
1578 prevObj--;
1579 if(*prevObj > *currObj) {
1580 goto data_unsorted;
1581 }
1582 currObj--;
1583 }
1584 mObjectsSorted = true;
1585 goto data_sorted;
1586
1587data_unsorted:
1588 // Insertion Sort mObjects
1589 // Great for mostly sorted lists. If randomly sorted or reverse ordered mObjects become common,
1590 // switch to std::sort(mObjects, mObjects + mObjectsSize);
1591 for (binder_size_t* iter0 = mObjects + 1; iter0 < mObjects + mObjectsSize; iter0++) {
1592 binder_size_t temp = *iter0;
1593 binder_size_t* iter1 = iter0 - 1;
1594 while (iter1 >= mObjects && *iter1 > temp) {
1595 *(iter1 + 1) = *iter1;
1596 iter1--;
1597 }
1598 *(iter1 + 1) = temp;
1599 }
1600 mNextObjectHint = 0;
1601 mObjectsSorted = true;
1602 goto data_sorted;
1603}
1604
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001605status_t Parcel::read(void* outData, size_t len) const
1606{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001607 if (len > INT32_MAX) {
1608 // don't accept size_t values which may have come from an
1609 // inadvertent conversion from a negative int.
1610 return BAD_VALUE;
1611 }
1612
1613 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1614 && len <= pad_size(len)) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001615 if (mObjectsSize > 0) {
1616 status_t err = validateReadData(mDataPos + pad_size(len));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001617 if(err != NO_ERROR) {
1618 // Still increment the data position by the expected length
1619 mDataPos += pad_size(len);
1620 ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
1621 return err;
1622 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001623 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001624 memcpy(outData, mData+mDataPos, len);
Nick Kralevichb6b14232015-04-02 09:36:02 -07001625 mDataPos += pad_size(len);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001626 ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001627 return NO_ERROR;
1628 }
1629 return NOT_ENOUGH_DATA;
1630}
1631
1632const void* Parcel::readInplace(size_t len) const
1633{
Nick Kralevichb6b14232015-04-02 09:36:02 -07001634 if (len > INT32_MAX) {
1635 // don't accept size_t values which may have come from an
1636 // inadvertent conversion from a negative int.
Yi Kong91635562018-06-07 14:38:36 -07001637 return nullptr;
Nick Kralevichb6b14232015-04-02 09:36:02 -07001638 }
1639
1640 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
1641 && len <= pad_size(len)) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001642 if (mObjectsSize > 0) {
1643 status_t err = validateReadData(mDataPos + pad_size(len));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001644 if(err != NO_ERROR) {
1645 // Still increment the data position by the expected length
1646 mDataPos += pad_size(len);
1647 ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
Yi Kong91635562018-06-07 14:38:36 -07001648 return nullptr;
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001649 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001650 }
1651
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001652 const void* data = mData+mDataPos;
Nick Kralevichb6b14232015-04-02 09:36:02 -07001653 mDataPos += pad_size(len);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07001654 ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001655 return data;
1656 }
Yi Kong91635562018-06-07 14:38:36 -07001657 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001658}
1659
Andreas Huber84a6d042009-08-17 13:33:27 -07001660template<class T>
1661status_t Parcel::readAligned(T *pArg) const {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001662 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
Andreas Huber84a6d042009-08-17 13:33:27 -07001663
1664 if ((mDataPos+sizeof(T)) <= mDataSize) {
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001665 if (mObjectsSize > 0) {
1666 status_t err = validateReadData(mDataPos + sizeof(T));
Michael Wachenschwanza17f0222018-04-17 16:52:40 -07001667 if(err != NO_ERROR) {
1668 // Still increment the data position by the expected length
1669 mDataPos += sizeof(T);
1670 return err;
1671 }
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08001672 }
1673
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001674 const void* data = mData+mDataPos;
Andreas Huber84a6d042009-08-17 13:33:27 -07001675 mDataPos += sizeof(T);
1676 *pArg = *reinterpret_cast<const T*>(data);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001677 return NO_ERROR;
1678 } else {
1679 return NOT_ENOUGH_DATA;
1680 }
1681}
1682
Andreas Huber84a6d042009-08-17 13:33:27 -07001683template<class T>
1684T Parcel::readAligned() const {
1685 T result;
1686 if (readAligned(&result) != NO_ERROR) {
1687 result = 0;
1688 }
1689
1690 return result;
1691}
1692
1693template<class T>
1694status_t Parcel::writeAligned(T val) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07001695 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
Andreas Huber84a6d042009-08-17 13:33:27 -07001696
1697 if ((mDataPos+sizeof(val)) <= mDataCapacity) {
1698restart_write:
1699 *reinterpret_cast<T*>(mData+mDataPos) = val;
1700 return finishWrite(sizeof(val));
1701 }
1702
1703 status_t err = growData(sizeof(val));
1704 if (err == NO_ERROR) goto restart_write;
1705 return err;
1706}
1707
Casey Dahlin185d3442016-02-09 11:08:35 -08001708namespace {
1709
1710template<typename T>
1711status_t readByteVectorInternal(const Parcel* parcel,
1712 std::vector<T>* val) {
Casey Dahlin451ff582015-10-19 18:12:18 -07001713 val->clear();
1714
1715 int32_t size;
Casey Dahlin185d3442016-02-09 11:08:35 -08001716 status_t status = parcel->readInt32(&size);
Casey Dahlin451ff582015-10-19 18:12:18 -07001717
1718 if (status != OK) {
1719 return status;
1720 }
1721
Christopher Wiley4db672d2015-11-10 09:44:30 -08001722 if (size < 0) {
1723 status = UNEXPECTED_NULL;
1724 return status;
1725 }
Casey Dahlin185d3442016-02-09 11:08:35 -08001726 if (size_t(size) > parcel->dataAvail()) {
Christopher Wileyf0fc52b2015-10-31 13:22:15 -07001727 status = BAD_VALUE;
1728 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -07001729 }
Christopher Wiley4db672d2015-11-10 09:44:30 -08001730
Paul Lietar433e87b2016-09-16 10:39:32 -07001731 T* data = const_cast<T*>(reinterpret_cast<const T*>(parcel->readInplace(size)));
Christopher Wileyf0fc52b2015-10-31 13:22:15 -07001732 if (!data) {
1733 status = BAD_VALUE;
1734 return status;
1735 }
Paul Lietar433e87b2016-09-16 10:39:32 -07001736 val->reserve(size);
1737 val->insert(val->end(), data, data + size);
Casey Dahlin451ff582015-10-19 18:12:18 -07001738
Christopher Wileyf0fc52b2015-10-31 13:22:15 -07001739 return status;
Casey Dahlin451ff582015-10-19 18:12:18 -07001740}
1741
Casey Dahlin185d3442016-02-09 11:08:35 -08001742template<typename T>
1743status_t readByteVectorInternalPtr(
1744 const Parcel* parcel,
1745 std::unique_ptr<std::vector<T>>* val) {
1746 const int32_t start = parcel->dataPosition();
Casey Dahlinb9872622015-11-25 15:09:45 -08001747 int32_t size;
Casey Dahlin185d3442016-02-09 11:08:35 -08001748 status_t status = parcel->readInt32(&size);
Casey Dahlinb9872622015-11-25 15:09:45 -08001749 val->reset();
1750
1751 if (status != OK || size < 0) {
1752 return status;
1753 }
1754
Casey Dahlin185d3442016-02-09 11:08:35 -08001755 parcel->setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001756 val->reset(new (std::nothrow) std::vector<T>());
Casey Dahlinb9872622015-11-25 15:09:45 -08001757
Casey Dahlin185d3442016-02-09 11:08:35 -08001758 status = readByteVectorInternal(parcel, val->get());
Casey Dahlinb9872622015-11-25 15:09:45 -08001759
1760 if (status != OK) {
1761 val->reset();
1762 }
1763
1764 return status;
1765}
1766
Casey Dahlin185d3442016-02-09 11:08:35 -08001767} // namespace
1768
1769status_t Parcel::readByteVector(std::vector<int8_t>* val) const {
1770 return readByteVectorInternal(this, val);
1771}
1772
1773status_t Parcel::readByteVector(std::vector<uint8_t>* val) const {
1774 return readByteVectorInternal(this, val);
1775}
1776
1777status_t Parcel::readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const {
1778 return readByteVectorInternalPtr(this, val);
1779}
1780
1781status_t Parcel::readByteVector(std::unique_ptr<std::vector<uint8_t>>* val) const {
1782 return readByteVectorInternalPtr(this, val);
1783}
1784
Casey Dahlinb9872622015-11-25 15:09:45 -08001785status_t Parcel::readInt32Vector(std::unique_ptr<std::vector<int32_t>>* val) const {
1786 return readNullableTypedVector(val, &Parcel::readInt32);
1787}
1788
Casey Dahlin451ff582015-10-19 18:12:18 -07001789status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001790 return readTypedVector(val, &Parcel::readInt32);
Casey Dahlin451ff582015-10-19 18:12:18 -07001791}
1792
Casey Dahlinb9872622015-11-25 15:09:45 -08001793status_t Parcel::readInt64Vector(std::unique_ptr<std::vector<int64_t>>* val) const {
1794 return readNullableTypedVector(val, &Parcel::readInt64);
1795}
1796
Casey Dahlin451ff582015-10-19 18:12:18 -07001797status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001798 return readTypedVector(val, &Parcel::readInt64);
Casey Dahlin451ff582015-10-19 18:12:18 -07001799}
1800
Kevin DuBois2f82d5b2018-12-05 12:56:10 -08001801status_t Parcel::readUint64Vector(std::unique_ptr<std::vector<uint64_t>>* val) const {
1802 return readNullableTypedVector(val, &Parcel::readUint64);
1803}
1804
1805status_t Parcel::readUint64Vector(std::vector<uint64_t>* val) const {
1806 return readTypedVector(val, &Parcel::readUint64);
1807}
1808
Casey Dahlinb9872622015-11-25 15:09:45 -08001809status_t Parcel::readFloatVector(std::unique_ptr<std::vector<float>>* val) const {
1810 return readNullableTypedVector(val, &Parcel::readFloat);
1811}
1812
Casey Dahlin451ff582015-10-19 18:12:18 -07001813status_t Parcel::readFloatVector(std::vector<float>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001814 return readTypedVector(val, &Parcel::readFloat);
Casey Dahlin451ff582015-10-19 18:12:18 -07001815}
1816
Casey Dahlinb9872622015-11-25 15:09:45 -08001817status_t Parcel::readDoubleVector(std::unique_ptr<std::vector<double>>* val) const {
1818 return readNullableTypedVector(val, &Parcel::readDouble);
1819}
1820
Casey Dahlin451ff582015-10-19 18:12:18 -07001821status_t Parcel::readDoubleVector(std::vector<double>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001822 return readTypedVector(val, &Parcel::readDouble);
Casey Dahlin451ff582015-10-19 18:12:18 -07001823}
1824
Casey Dahlinb9872622015-11-25 15:09:45 -08001825status_t Parcel::readBoolVector(std::unique_ptr<std::vector<bool>>* val) const {
1826 const int32_t start = dataPosition();
1827 int32_t size;
1828 status_t status = readInt32(&size);
1829 val->reset();
Casey Dahlin451ff582015-10-19 18:12:18 -07001830
Casey Dahlinb9872622015-11-25 15:09:45 -08001831 if (status != OK || size < 0) {
1832 return status;
1833 }
1834
1835 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07001836 val->reset(new (std::nothrow) std::vector<bool>());
Casey Dahlinb9872622015-11-25 15:09:45 -08001837
1838 status = readBoolVector(val->get());
1839
1840 if (status != OK) {
1841 val->reset();
1842 }
1843
1844 return status;
1845}
1846
1847status_t Parcel::readBoolVector(std::vector<bool>* val) const {
Casey Dahlin451ff582015-10-19 18:12:18 -07001848 int32_t size;
1849 status_t status = readInt32(&size);
1850
1851 if (status != OK) {
1852 return status;
1853 }
1854
1855 if (size < 0) {
Christopher Wiley4db672d2015-11-10 09:44:30 -08001856 return UNEXPECTED_NULL;
Casey Dahlin451ff582015-10-19 18:12:18 -07001857 }
1858
1859 val->resize(size);
1860
1861 /* C++ bool handling means a vector of bools isn't necessarily addressable
1862 * (we might use individual bits)
1863 */
Christopher Wiley97887982015-10-27 16:33:47 -07001864 bool data;
1865 for (int32_t i = 0; i < size; ++i) {
Casey Dahlin451ff582015-10-19 18:12:18 -07001866 status = readBool(&data);
1867 (*val)[i] = data;
1868
1869 if (status != OK) {
1870 return status;
1871 }
1872 }
1873
1874 return OK;
1875}
1876
Casey Dahlinb9872622015-11-25 15:09:45 -08001877status_t Parcel::readCharVector(std::unique_ptr<std::vector<char16_t>>* val) const {
1878 return readNullableTypedVector(val, &Parcel::readChar);
1879}
1880
Casey Dahlin451ff582015-10-19 18:12:18 -07001881status_t Parcel::readCharVector(std::vector<char16_t>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001882 return readTypedVector(val, &Parcel::readChar);
Casey Dahlin451ff582015-10-19 18:12:18 -07001883}
1884
Casey Dahlinb9872622015-11-25 15:09:45 -08001885status_t Parcel::readString16Vector(
1886 std::unique_ptr<std::vector<std::unique_ptr<String16>>>* val) const {
1887 return readNullableTypedVector(val, &Parcel::readString16);
1888}
1889
Casey Dahlin451ff582015-10-19 18:12:18 -07001890status_t Parcel::readString16Vector(std::vector<String16>* val) const {
Christopher Wiley03d1eb62015-11-19 06:42:40 -08001891 return readTypedVector(val, &Parcel::readString16);
Casey Dahlin451ff582015-10-19 18:12:18 -07001892}
1893
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08001894status_t Parcel::readUtf8VectorFromUtf16Vector(
1895 std::unique_ptr<std::vector<std::unique_ptr<std::string>>>* val) const {
1896 return readNullableTypedVector(val, &Parcel::readUtf8FromUtf16);
1897}
1898
1899status_t Parcel::readUtf8VectorFromUtf16Vector(std::vector<std::string>* val) const {
1900 return readTypedVector(val, &Parcel::readUtf8FromUtf16);
1901}
Casey Dahlin451ff582015-10-19 18:12:18 -07001902
Andreas Huber84a6d042009-08-17 13:33:27 -07001903status_t Parcel::readInt32(int32_t *pArg) const
1904{
1905 return readAligned(pArg);
1906}
1907
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001908int32_t Parcel::readInt32() const
1909{
Andreas Huber84a6d042009-08-17 13:33:27 -07001910 return readAligned<int32_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001911}
1912
Dan Stoza41a0f2f2014-12-01 10:01:10 -08001913status_t Parcel::readUint32(uint32_t *pArg) const
1914{
1915 return readAligned(pArg);
1916}
1917
1918uint32_t Parcel::readUint32() const
1919{
1920 return readAligned<uint32_t>();
1921}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001922
1923status_t Parcel::readInt64(int64_t *pArg) const
1924{
Andreas Huber84a6d042009-08-17 13:33:27 -07001925 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001926}
1927
1928
1929int64_t Parcel::readInt64() const
1930{
Andreas Huber84a6d042009-08-17 13:33:27 -07001931 return readAligned<int64_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001932}
1933
Ronghua Wu2d13afd2015-03-16 11:11:07 -07001934status_t Parcel::readUint64(uint64_t *pArg) const
1935{
1936 return readAligned(pArg);
1937}
1938
1939uint64_t Parcel::readUint64() const
1940{
1941 return readAligned<uint64_t>();
1942}
1943
Serban Constantinescuf683e012013-11-05 16:53:55 +00001944status_t Parcel::readPointer(uintptr_t *pArg) const
1945{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001946 status_t ret;
1947 binder_uintptr_t ptr;
1948 ret = readAligned(&ptr);
1949 if (!ret)
1950 *pArg = ptr;
1951 return ret;
Serban Constantinescuf683e012013-11-05 16:53:55 +00001952}
1953
1954uintptr_t Parcel::readPointer() const
1955{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08001956 return readAligned<binder_uintptr_t>();
Serban Constantinescuf683e012013-11-05 16:53:55 +00001957}
1958
1959
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001960status_t Parcel::readFloat(float *pArg) const
1961{
Andreas Huber84a6d042009-08-17 13:33:27 -07001962 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001963}
1964
1965
1966float Parcel::readFloat() const
1967{
Andreas Huber84a6d042009-08-17 13:33:27 -07001968 return readAligned<float>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001969}
1970
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001971#if defined(__mips__) && defined(__mips_hard_float)
1972
1973status_t Parcel::readDouble(double *pArg) const
1974{
1975 union {
1976 double d;
1977 unsigned long long ll;
1978 } u;
Narayan Kamath2c68d382014-06-04 15:04:29 +01001979 u.d = 0;
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08001980 status_t status;
1981 status = readAligned(&u.ll);
1982 *pArg = u.d;
1983 return status;
1984}
1985
1986double Parcel::readDouble() const
1987{
1988 union {
1989 double d;
1990 unsigned long long ll;
1991 } u;
1992 u.ll = readAligned<unsigned long long>();
1993 return u.d;
1994}
1995
1996#else
1997
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001998status_t Parcel::readDouble(double *pArg) const
1999{
Andreas Huber84a6d042009-08-17 13:33:27 -07002000 return readAligned(pArg);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002001}
2002
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002003double Parcel::readDouble() const
2004{
Andreas Huber84a6d042009-08-17 13:33:27 -07002005 return readAligned<double>();
2006}
2007
Douglas Leungcc1a4bb2013-01-11 15:00:55 -08002008#endif
2009
Andreas Huber84a6d042009-08-17 13:33:27 -07002010status_t Parcel::readIntPtr(intptr_t *pArg) const
2011{
2012 return readAligned(pArg);
2013}
2014
2015
2016intptr_t Parcel::readIntPtr() const
2017{
2018 return readAligned<intptr_t>();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002019}
2020
Casey Dahlind6848f52015-10-15 15:44:59 -07002021status_t Parcel::readBool(bool *pArg) const
2022{
Manoj Gupta6eb62052017-07-12 10:29:15 -07002023 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07002024 status_t ret = readInt32(&tmp);
2025 *pArg = (tmp != 0);
2026 return ret;
2027}
2028
2029bool Parcel::readBool() const
2030{
2031 return readInt32() != 0;
2032}
2033
2034status_t Parcel::readChar(char16_t *pArg) const
2035{
Manoj Gupta6eb62052017-07-12 10:29:15 -07002036 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07002037 status_t ret = readInt32(&tmp);
2038 *pArg = char16_t(tmp);
2039 return ret;
2040}
2041
2042char16_t Parcel::readChar() const
2043{
2044 return char16_t(readInt32());
2045}
2046
2047status_t Parcel::readByte(int8_t *pArg) const
2048{
Manoj Gupta6eb62052017-07-12 10:29:15 -07002049 int32_t tmp = 0;
Casey Dahlind6848f52015-10-15 15:44:59 -07002050 status_t ret = readInt32(&tmp);
2051 *pArg = int8_t(tmp);
2052 return ret;
2053}
2054
2055int8_t Parcel::readByte() const
2056{
2057 return int8_t(readInt32());
2058}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002059
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08002060status_t Parcel::readUtf8FromUtf16(std::string* str) const {
2061 size_t utf16Size = 0;
2062 const char16_t* src = readString16Inplace(&utf16Size);
2063 if (!src) {
2064 return UNEXPECTED_NULL;
2065 }
2066
2067 // Save ourselves the trouble, we're done.
2068 if (utf16Size == 0u) {
2069 str->clear();
2070 return NO_ERROR;
2071 }
2072
Sergio Giro9b39ebe2016-06-28 18:19:33 +01002073 // Allow for closing '\0'
2074 ssize_t utf8Size = utf16_to_utf8_length(src, utf16Size) + 1;
2075 if (utf8Size < 1) {
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08002076 return BAD_VALUE;
2077 }
2078 // Note that while it is probably safe to assume string::resize keeps a
Sergio Giro9b39ebe2016-06-28 18:19:33 +01002079 // spare byte around for the trailing null, we still pass the size including the trailing null
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08002080 str->resize(utf8Size);
Sergio Giro9b39ebe2016-06-28 18:19:33 +01002081 utf16_to_utf8(src, utf16Size, &((*str)[0]), utf8Size);
2082 str->resize(utf8Size - 1);
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08002083 return NO_ERROR;
2084}
2085
2086status_t Parcel::readUtf8FromUtf16(std::unique_ptr<std::string>* str) const {
2087 const int32_t start = dataPosition();
2088 int32_t size;
2089 status_t status = readInt32(&size);
2090 str->reset();
2091
2092 if (status != OK || size < 0) {
2093 return status;
2094 }
2095
2096 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002097 str->reset(new (std::nothrow) std::string());
Christopher Wiley9a5e32f2016-01-28 16:56:53 -08002098 return readUtf8FromUtf16(str->get());
2099}
2100
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002101const char* Parcel::readCString() const
2102{
Steven Morelandd0d4b582019-05-17 13:14:06 -07002103 if (mDataPos < mDataSize) {
2104 const size_t avail = mDataSize-mDataPos;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002105 const char* str = reinterpret_cast<const char*>(mData+mDataPos);
2106 // is the string's trailing NUL within the parcel's valid bounds?
2107 const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
2108 if (eos) {
2109 const size_t len = eos - str;
Nick Kralevichb6b14232015-04-02 09:36:02 -07002110 mDataPos += pad_size(len+1);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002111 ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002112 return str;
2113 }
2114 }
Yi Kong91635562018-06-07 14:38:36 -07002115 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002116}
2117
2118String8 Parcel::readString8() const
2119{
Roshan Pius87b64d22016-07-18 12:51:02 -07002120 String8 retString;
2121 status_t status = readString8(&retString);
2122 if (status != OK) {
2123 // We don't care about errors here, so just return an empty string.
2124 return String8();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002125 }
Roshan Pius87b64d22016-07-18 12:51:02 -07002126 return retString;
2127}
2128
2129status_t Parcel::readString8(String8* pArg) const
2130{
2131 int32_t size;
2132 status_t status = readInt32(&size);
2133 if (status != OK) {
2134 return status;
2135 }
2136 // watch for potential int overflow from size+1
2137 if (size < 0 || size >= INT32_MAX) {
2138 return BAD_VALUE;
2139 }
2140 // |writeString8| writes nothing for empty string.
2141 if (size == 0) {
2142 *pArg = String8();
2143 return OK;
2144 }
2145 const char* str = (const char*)readInplace(size + 1);
Yi Kong91635562018-06-07 14:38:36 -07002146 if (str == nullptr) {
Roshan Pius87b64d22016-07-18 12:51:02 -07002147 return BAD_VALUE;
2148 }
2149 pArg->setTo(str, size);
2150 return OK;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002151}
2152
2153String16 Parcel::readString16() const
2154{
2155 size_t len;
2156 const char16_t* str = readString16Inplace(&len);
2157 if (str) return String16(str, len);
Steve Blocke6f43dd2012-01-06 19:20:56 +00002158 ALOGE("Reading a NULL string not supported here.");
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002159 return String16();
2160}
2161
Casey Dahlinb9872622015-11-25 15:09:45 -08002162status_t Parcel::readString16(std::unique_ptr<String16>* pArg) const
2163{
2164 const int32_t start = dataPosition();
2165 int32_t size;
2166 status_t status = readInt32(&size);
2167 pArg->reset();
2168
2169 if (status != OK || size < 0) {
2170 return status;
2171 }
2172
2173 setDataPosition(start);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002174 pArg->reset(new (std::nothrow) String16());
Casey Dahlinb9872622015-11-25 15:09:45 -08002175
2176 status = readString16(pArg->get());
2177
2178 if (status != OK) {
2179 pArg->reset();
2180 }
2181
2182 return status;
2183}
2184
Casey Dahlin451ff582015-10-19 18:12:18 -07002185status_t Parcel::readString16(String16* pArg) const
2186{
2187 size_t len;
2188 const char16_t* str = readString16Inplace(&len);
2189 if (str) {
Casey Dahlin1515ea12015-10-20 16:26:23 -07002190 pArg->setTo(str, len);
Casey Dahlin451ff582015-10-19 18:12:18 -07002191 return 0;
2192 } else {
2193 *pArg = String16();
Christopher Wiley4db672d2015-11-10 09:44:30 -08002194 return UNEXPECTED_NULL;
Casey Dahlin451ff582015-10-19 18:12:18 -07002195 }
2196}
2197
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002198const char16_t* Parcel::readString16Inplace(size_t* outLen) const
2199{
2200 int32_t size = readInt32();
2201 // watch for potential int overflow from size+1
2202 if (size >= 0 && size < INT32_MAX) {
2203 *outLen = size;
2204 const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
Yi Kong91635562018-06-07 14:38:36 -07002205 if (str != nullptr) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002206 return str;
2207 }
2208 }
2209 *outLen = 0;
Yi Kong91635562018-06-07 14:38:36 -07002210 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002211}
2212
Casey Dahlinf0c13772015-10-27 18:33:56 -07002213status_t Parcel::readStrongBinder(sp<IBinder>* val) const
2214{
Christopher Wiley35d77ca2016-03-08 10:49:51 -08002215 status_t status = readNullableStrongBinder(val);
2216 if (status == OK && !val->get()) {
2217 status = UNEXPECTED_NULL;
2218 }
2219 return status;
2220}
2221
2222status_t Parcel::readNullableStrongBinder(sp<IBinder>* val) const
2223{
Casey Dahlinf0c13772015-10-27 18:33:56 -07002224 return unflatten_binder(ProcessState::self(), *this, val);
2225}
2226
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002227sp<IBinder> Parcel::readStrongBinder() const
2228{
2229 sp<IBinder> val;
Christopher Wiley35d77ca2016-03-08 10:49:51 -08002230 // Note that a lot of code in Android reads binders by hand with this
2231 // method, and that code has historically been ok with getting nullptr
2232 // back (while ignoring error codes).
2233 readNullableStrongBinder(&val);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002234 return val;
2235}
2236
2237wp<IBinder> Parcel::readWeakBinder() const
2238{
2239 wp<IBinder> val;
2240 unflatten_binder(ProcessState::self(), *this, &val);
2241 return val;
2242}
2243
Christopher Wiley97f048d2015-11-19 06:49:05 -08002244status_t Parcel::readParcelable(Parcelable* parcelable) const {
2245 int32_t have_parcelable = 0;
2246 status_t status = readInt32(&have_parcelable);
2247 if (status != OK) {
2248 return status;
2249 }
2250 if (!have_parcelable) {
2251 return UNEXPECTED_NULL;
2252 }
2253 return parcelable->readFromParcel(this);
2254}
2255
Robert Quattlebaum6316f5b2017-01-04 13:25:14 -08002256status_t Parcel::readValue(binder::Value* value) const {
2257 return value->readFromParcel(this);
2258}
2259
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07002260int32_t Parcel::readExceptionCode() const
2261{
Christopher Wiley09eb7492015-11-09 15:06:15 -08002262 binder::Status status;
2263 status.readFromParcel(*this);
2264 return status.exceptionCode();
Brad Fitzpatrick837a0d02010-07-13 15:33:35 -07002265}
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002266
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002267native_handle* Parcel::readNativeHandle() const
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002268{
2269 int numFds, numInts;
2270 status_t err;
2271 err = readInt32(&numFds);
Yi Kong91635562018-06-07 14:38:36 -07002272 if (err != NO_ERROR) return nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002273 err = readInt32(&numInts);
Yi Kong91635562018-06-07 14:38:36 -07002274 if (err != NO_ERROR) return nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002275
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002276 native_handle* h = native_handle_create(numFds, numInts);
Adam Lesinskieaac99a2015-05-12 17:35:48 -07002277 if (!h) {
Yi Kong91635562018-06-07 14:38:36 -07002278 return nullptr;
Adam Lesinskieaac99a2015-05-12 17:35:48 -07002279 }
2280
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002281 for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002282 h->data[i] = fcntl(readFileDescriptor(), F_DUPFD_CLOEXEC, 0);
Marco Nelissen1de79662016-04-26 08:44:09 -07002283 if (h->data[i] < 0) {
2284 for (int j = 0; j < i; j++) {
2285 close(h->data[j]);
2286 }
2287 native_handle_delete(h);
Yi Kong91635562018-06-07 14:38:36 -07002288 return nullptr;
Marco Nelissen1de79662016-04-26 08:44:09 -07002289 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002290 }
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002291 err = read(h->data + numFds, sizeof(int)*numInts);
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002292 if (err != NO_ERROR) {
Mathias Agopiana47f02a2009-05-21 16:29:38 -07002293 native_handle_close(h);
2294 native_handle_delete(h);
Yi Kong91635562018-06-07 14:38:36 -07002295 h = nullptr;
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002296 }
2297 return h;
2298}
2299
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002300int Parcel::readFileDescriptor() const
2301{
2302 const flat_binder_object* flat = readObject(true);
Casey Dahlin06673e32015-11-23 13:24:23 -08002303
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002304 if (flat && flat->hdr.type == BINDER_TYPE_FD) {
Casey Dahlin06673e32015-11-23 13:24:23 -08002305 return flat->handle;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002306 }
Casey Dahlin06673e32015-11-23 13:24:23 -08002307
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002308 return BAD_TYPE;
2309}
2310
Dianne Hackborn1941a402016-08-29 12:30:43 -07002311int Parcel::readParcelFileDescriptor() const
2312{
2313 int32_t hasComm = readInt32();
2314 int fd = readFileDescriptor();
2315 if (hasComm != 0) {
Steven Morelandb73806a2018-11-12 19:35:47 -08002316 // detach (owned by the binder driver)
2317 int comm = readFileDescriptor();
2318
2319 // warning: this must be kept in sync with:
2320 // frameworks/base/core/java/android/os/ParcelFileDescriptor.java
2321 enum ParcelFileDescriptorStatus {
2322 DETACHED = 2,
2323 };
2324
2325#if BYTE_ORDER == BIG_ENDIAN
2326 const int32_t message = ParcelFileDescriptorStatus::DETACHED;
2327#endif
2328#if BYTE_ORDER == LITTLE_ENDIAN
2329 const int32_t message = __builtin_bswap32(ParcelFileDescriptorStatus::DETACHED);
2330#endif
2331
2332 ssize_t written = TEMP_FAILURE_RETRY(
2333 ::write(comm, &message, sizeof(message)));
2334
2335 if (written == -1 || written != sizeof(message)) {
2336 ALOGW("Failed to detach ParcelFileDescriptor written: %zd err: %s",
2337 written, strerror(errno));
2338 return BAD_TYPE;
2339 }
Dianne Hackborn1941a402016-08-29 12:30:43 -07002340 }
2341 return fd;
2342}
2343
Christopher Wiley2cf19952016-04-11 11:09:37 -07002344status_t Parcel::readUniqueFileDescriptor(base::unique_fd* val) const
Casey Dahlin06673e32015-11-23 13:24:23 -08002345{
2346 int got = readFileDescriptor();
2347
2348 if (got == BAD_TYPE) {
2349 return BAD_TYPE;
2350 }
2351
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002352 val->reset(fcntl(got, F_DUPFD_CLOEXEC, 0));
Casey Dahlin06673e32015-11-23 13:24:23 -08002353
2354 if (val->get() < 0) {
2355 return BAD_VALUE;
2356 }
2357
2358 return OK;
2359}
2360
Ryo Hashimotobf551892018-05-31 16:58:35 +09002361status_t Parcel::readUniqueParcelFileDescriptor(base::unique_fd* val) const
2362{
2363 int got = readParcelFileDescriptor();
2364
2365 if (got == BAD_TYPE) {
2366 return BAD_TYPE;
2367 }
2368
2369 val->reset(fcntl(got, F_DUPFD_CLOEXEC, 0));
2370
2371 if (val->get() < 0) {
2372 return BAD_VALUE;
2373 }
2374
2375 return OK;
2376}
Casey Dahlin06673e32015-11-23 13:24:23 -08002377
Christopher Wiley2cf19952016-04-11 11:09:37 -07002378status_t Parcel::readUniqueFileDescriptorVector(std::unique_ptr<std::vector<base::unique_fd>>* val) const {
Casey Dahlinb9872622015-11-25 15:09:45 -08002379 return readNullableTypedVector(val, &Parcel::readUniqueFileDescriptor);
2380}
2381
Christopher Wiley2cf19952016-04-11 11:09:37 -07002382status_t Parcel::readUniqueFileDescriptorVector(std::vector<base::unique_fd>* val) const {
Casey Dahlin06673e32015-11-23 13:24:23 -08002383 return readTypedVector(val, &Parcel::readUniqueFileDescriptor);
2384}
2385
Jeff Brown5707dbf2011-09-23 21:17:56 -07002386status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
2387{
Jeff Brown13b16042014-11-11 16:44:25 -08002388 int32_t blobType;
2389 status_t status = readInt32(&blobType);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002390 if (status) return status;
2391
Jeff Brown13b16042014-11-11 16:44:25 -08002392 if (blobType == BLOB_INPLACE) {
Steve Block6807e592011-10-20 11:56:00 +01002393 ALOGV("readBlob: read in place");
Jeff Brown5707dbf2011-09-23 21:17:56 -07002394 const void* ptr = readInplace(len);
2395 if (!ptr) return BAD_VALUE;
2396
Jeff Brown13b16042014-11-11 16:44:25 -08002397 outBlob->init(-1, const_cast<void*>(ptr), len, false);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002398 return NO_ERROR;
2399 }
2400
Steve Block6807e592011-10-20 11:56:00 +01002401 ALOGV("readBlob: read from ashmem");
Jeff Brown13b16042014-11-11 16:44:25 -08002402 bool isMutable = (blobType == BLOB_ASHMEM_MUTABLE);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002403 int fd = readFileDescriptor();
2404 if (fd == int(BAD_TYPE)) return BAD_VALUE;
2405
Jorim Jaggi150b4ef2018-07-13 11:18:30 +00002406 if (!ashmem_valid(fd)) {
2407 ALOGE("invalid fd");
2408 return BAD_VALUE;
2409 }
Marco Nelissen7a96ec42018-06-06 07:37:46 -07002410 int size = ashmem_get_size_region(fd);
2411 if (size < 0 || size_t(size) < len) {
Jorim Jaggi150b4ef2018-07-13 11:18:30 +00002412 ALOGE("request size %zu does not match fd size %d", len, size);
Marco Nelissen7a96ec42018-06-06 07:37:46 -07002413 return BAD_VALUE;
2414 }
Yi Kong91635562018-06-07 14:38:36 -07002415 void* ptr = ::mmap(nullptr, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ,
Jeff Brown13b16042014-11-11 16:44:25 -08002416 MAP_SHARED, fd, 0);
Narayan Kamath9ea09752014-10-08 17:35:45 +01002417 if (ptr == MAP_FAILED) return NO_MEMORY;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002418
Jeff Brown13b16042014-11-11 16:44:25 -08002419 outBlob->init(fd, ptr, len, isMutable);
Jeff Brown5707dbf2011-09-23 21:17:56 -07002420 return NO_ERROR;
2421}
2422
Mathias Agopiane1424282013-07-29 21:24:40 -07002423status_t Parcel::read(FlattenableHelperInterface& val) const
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002424{
2425 // size
2426 const size_t len = this->readInt32();
2427 const size_t fd_count = this->readInt32();
2428
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002429 if ((len > INT32_MAX) || (fd_count >= gMaxFds)) {
Nick Kralevichb6b14232015-04-02 09:36:02 -07002430 // don't accept size_t values which may have come from an
2431 // inadvertent conversion from a negative int.
2432 return BAD_VALUE;
2433 }
2434
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002435 // payload
Nick Kralevichb6b14232015-04-02 09:36:02 -07002436 void const* const buf = this->readInplace(pad_size(len));
Yi Kong91635562018-06-07 14:38:36 -07002437 if (buf == nullptr)
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002438 return BAD_VALUE;
2439
Yi Kong91635562018-06-07 14:38:36 -07002440 int* fds = nullptr;
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002441 if (fd_count) {
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002442 fds = new (std::nothrow) int[fd_count];
2443 if (fds == nullptr) {
2444 ALOGE("read: failed to allocate requested %zu fds", fd_count);
2445 return BAD_VALUE;
2446 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002447 }
2448
2449 status_t err = NO_ERROR;
2450 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
Fabien Sanglardd84ff312016-10-21 10:58:26 -07002451 int fd = this->readFileDescriptor();
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002452 if (fd < 0 || ((fds[i] = fcntl(fd, F_DUPFD_CLOEXEC, 0)) < 0)) {
Jun Jiangabf8a2c2014-04-29 14:22:10 +08002453 err = BAD_VALUE;
Nick Kralevichec9ec7d2016-12-17 19:47:27 -08002454 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 -07002455 i, fds[i], fd_count, strerror(fd < 0 ? -fd : errno));
2456 // Close all the file descriptors that were dup-ed.
2457 for (size_t j=0; j<i ;j++) {
2458 close(fds[j]);
2459 }
Jun Jiangabf8a2c2014-04-29 14:22:10 +08002460 }
Mathias Agopian98e71dd2010-02-11 17:30:52 -08002461 }
2462
2463 if (err == NO_ERROR) {
2464 err = val.unflatten(buf, len, fds, fd_count);
2465 }
2466
2467 if (fd_count) {
2468 delete [] fds;
2469 }
2470
2471 return err;
2472}
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002473const flat_binder_object* Parcel::readObject(bool nullMetaData) const
2474{
2475 const size_t DPOS = mDataPos;
2476 if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
2477 const flat_binder_object* obj
2478 = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
2479 mDataPos = DPOS + sizeof(flat_binder_object);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002480 if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) {
The Android Open Source Project5f78a482009-01-20 14:03:58 -08002481 // When transferring a NULL object, we don't write it into
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002482 // the object list, so we don't want to check for it when
2483 // reading.
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002484 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002485 return obj;
2486 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002487
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002488 // Ensure that this object is valid...
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002489 binder_size_t* const OBJS = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002490 const size_t N = mObjectsSize;
2491 size_t opos = mNextObjectHint;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002492
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002493 if (N > 0) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002494 ALOGV("Parcel %p looking for obj at %zu, hint=%zu",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002495 this, DPOS, opos);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002496
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002497 // Start at the current hint position, looking for an object at
2498 // the current data position.
2499 if (opos < N) {
2500 while (opos < (N-1) && OBJS[opos] < DPOS) {
2501 opos++;
2502 }
2503 } else {
2504 opos = N-1;
2505 }
2506 if (OBJS[opos] == DPOS) {
2507 // Found it!
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002508 ALOGV("Parcel %p found obj %zu at index %zu with forward search",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002509 this, DPOS, opos);
2510 mNextObjectHint = opos+1;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002511 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002512 return obj;
2513 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002514
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002515 // Look backwards for it...
2516 while (opos > 0 && OBJS[opos] > DPOS) {
2517 opos--;
2518 }
2519 if (OBJS[opos] == DPOS) {
2520 // Found it!
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002521 ALOGV("Parcel %p found obj %zu at index %zu with backward search",
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002522 this, DPOS, opos);
2523 mNextObjectHint = opos+1;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002524 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002525 return obj;
2526 }
2527 }
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002528 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 -07002529 this, DPOS);
2530 }
Yi Kong91635562018-06-07 14:38:36 -07002531 return nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002532}
2533
2534void Parcel::closeFileDescriptors()
2535{
2536 size_t i = mObjectsSize;
2537 if (i > 0) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002538 //ALOGI("Closing file descriptors for %zu objects...", i);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002539 }
2540 while (i > 0) {
2541 i--;
2542 const flat_binder_object* flat
2543 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002544 if (flat->hdr.type == BINDER_TYPE_FD) {
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002545 //ALOGI("Closing fd: %ld", flat->handle);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002546 close(flat->handle);
2547 }
2548 }
2549}
2550
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002551uintptr_t Parcel::ipcData() const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002552{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002553 return reinterpret_cast<uintptr_t>(mData);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002554}
2555
2556size_t Parcel::ipcDataSize() const
2557{
2558 return (mDataSize > mDataPos ? mDataSize : mDataPos);
2559}
2560
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002561uintptr_t Parcel::ipcObjects() const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002562{
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002563 return reinterpret_cast<uintptr_t>(mObjects);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002564}
2565
2566size_t Parcel::ipcObjectsCount() const
2567{
2568 return mObjectsSize;
2569}
2570
2571void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002572 const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002573{
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002574 binder_size_t minOffset = 0;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002575 freeDataNoInit();
2576 mError = NO_ERROR;
2577 mData = const_cast<uint8_t*>(data);
2578 mDataSize = mDataCapacity = dataSize;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002579 //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)", this, mDataSize, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002580 mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002581 ALOGV("setDataReference Setting data pos of %p to %zu", this, mDataPos);
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002582 mObjects = const_cast<binder_size_t*>(objects);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002583 mObjectsSize = mObjectsCapacity = objectsCount;
2584 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002585 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002586 mOwner = relFunc;
2587 mOwnerCookie = relCookie;
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002588 for (size_t i = 0; i < mObjectsSize; i++) {
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002589 binder_size_t offset = mObjects[i];
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002590 if (offset < minOffset) {
Dan Albert3bdc5b82014-11-20 11:50:23 -08002591 ALOGE("%s: bad object offset %" PRIu64 " < %" PRIu64 "\n",
Arve Hjønnevåg6f286112014-02-19 20:42:13 -08002592 __func__, (uint64_t)offset, (uint64_t)minOffset);
Arve Hjønnevågf50b9ea2014-02-13 19:22:08 -08002593 mObjectsSize = 0;
2594 break;
2595 }
2596 minOffset = offset + sizeof(flat_binder_object);
2597 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002598 scanForFds();
2599}
2600
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002601void Parcel::print(TextOutput& to, uint32_t /*flags*/) const
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002602{
2603 to << "Parcel(";
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002604
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002605 if (errorCheck() != NO_ERROR) {
2606 const status_t err = errorCheck();
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002607 to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\"";
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002608 } else if (dataSize() > 0) {
2609 const uint8_t* DATA = data();
2610 to << indent << HexDump(DATA, dataSize()) << dedent;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002611 const binder_size_t* OBJS = objects();
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002612 const size_t N = objectsCount();
2613 for (size_t i=0; i<N; i++) {
2614 const flat_binder_object* flat
2615 = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
2616 to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002617 << TypeCode(flat->hdr.type & 0x7f7f7f00)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002618 << " = " << flat->binder;
2619 }
2620 } else {
2621 to << "NULL";
2622 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002623
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002624 to << ")";
2625}
2626
2627void Parcel::releaseObjects()
2628{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002629 size_t i = mObjectsSize;
Martijn Coenen69390d42018-10-22 15:18:10 +02002630 if (i == 0) {
2631 return;
2632 }
2633 sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002634 uint8_t* const data = mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002635 binder_size_t* const objects = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002636 while (i > 0) {
2637 i--;
2638 const flat_binder_object* flat
2639 = reinterpret_cast<flat_binder_object*>(data+objects[i]);
Adrian Rooscbf37262015-10-22 16:12:53 -07002640 release_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002641 }
2642}
2643
2644void Parcel::acquireObjects()
2645{
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002646 size_t i = mObjectsSize;
Martijn Coenen69390d42018-10-22 15:18:10 +02002647 if (i == 0) {
2648 return;
2649 }
2650 const sp<ProcessState> proc(ProcessState::self());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002651 uint8_t* const data = mData;
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002652 binder_size_t* const objects = mObjects;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002653 while (i > 0) {
2654 i--;
2655 const flat_binder_object* flat
2656 = reinterpret_cast<flat_binder_object*>(data+objects[i]);
Adrian Rooscbf37262015-10-22 16:12:53 -07002657 acquire_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002658 }
2659}
2660
2661void Parcel::freeData()
2662{
2663 freeDataNoInit();
2664 initState();
2665}
2666
2667void Parcel::freeDataNoInit()
2668{
2669 if (mOwner) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002670 LOG_ALLOC("Parcel %p: freeing other owner data", this);
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002671 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002672 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
2673 } else {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002674 LOG_ALLOC("Parcel %p: freeing allocated data", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002675 releaseObjects();
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002676 if (mData) {
2677 LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002678 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dan Austin48fd7b42015-09-10 13:46:02 -07002679 if (mDataCapacity <= gParcelGlobalAllocSize) {
2680 gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity;
2681 } else {
2682 gParcelGlobalAllocSize = 0;
2683 }
2684 if (gParcelGlobalAllocCount > 0) {
2685 gParcelGlobalAllocCount--;
2686 }
Dianne Hackborna4cff882014-11-13 17:07:40 -08002687 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002688 free(mData);
2689 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002690 if (mObjects) free(mObjects);
2691 }
2692}
2693
2694status_t Parcel::growData(size_t len)
2695{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002696 if (len > INT32_MAX) {
2697 // don't accept size_t values which may have come from an
2698 // inadvertent conversion from a negative int.
2699 return BAD_VALUE;
2700 }
2701
Martijn Coenen93fe5182020-01-22 10:46:25 +01002702 if (len > SIZE_MAX - mDataSize) return NO_MEMORY; // overflow
2703 if (mDataSize + len > SIZE_MAX / 3) return NO_MEMORY; // overflow
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002704 size_t newSize = ((mDataSize+len)*3)/2;
2705 return (newSize <= mDataSize)
2706 ? (status_t) NO_MEMORY
Steven Moreland340f73b2020-05-27 17:45:17 +00002707 : continueWrite(std::max(newSize, (size_t) 128));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002708}
2709
2710status_t Parcel::restartWrite(size_t desired)
2711{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002712 if (desired > INT32_MAX) {
2713 // don't accept size_t values which may have come from an
2714 // inadvertent conversion from a negative int.
2715 return BAD_VALUE;
2716 }
2717
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002718 if (mOwner) {
2719 freeData();
2720 return continueWrite(desired);
2721 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002722
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002723 uint8_t* data = (uint8_t*)realloc(mData, desired);
2724 if (!data && desired > mDataCapacity) {
2725 mError = NO_MEMORY;
2726 return NO_MEMORY;
2727 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002728
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002729 releaseObjects();
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002730
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002731 if (data) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002732 LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002733 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002734 gParcelGlobalAllocSize += desired;
2735 gParcelGlobalAllocSize -= mDataCapacity;
Colin Cross83ec65e2015-12-08 17:15:50 -08002736 if (!mData) {
2737 gParcelGlobalAllocCount++;
2738 }
Dianne Hackborna4cff882014-11-13 17:07:40 -08002739 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002740 mData = data;
2741 mDataCapacity = desired;
2742 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002743
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002744 mDataSize = mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002745 ALOGV("restartWrite Setting data size of %p to %zu", this, mDataSize);
2746 ALOGV("restartWrite Setting data pos of %p to %zu", this, mDataPos);
2747
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002748 free(mObjects);
Yi Kong91635562018-06-07 14:38:36 -07002749 mObjects = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002750 mObjectsSize = mObjectsCapacity = 0;
2751 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002752 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002753 mHasFds = false;
2754 mFdsKnown = true;
Dianne Hackborn8938ed22011-09-28 23:19:47 -04002755 mAllowFds = true;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002756
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002757 return NO_ERROR;
2758}
2759
2760status_t Parcel::continueWrite(size_t desired)
2761{
Nick Kralevichb6b14232015-04-02 09:36:02 -07002762 if (desired > INT32_MAX) {
2763 // don't accept size_t values which may have come from an
2764 // inadvertent conversion from a negative int.
2765 return BAD_VALUE;
2766 }
2767
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002768 // If shrinking, first adjust for any objects that appear
2769 // after the new data size.
2770 size_t objectsSize = mObjectsSize;
2771 if (desired < mDataSize) {
2772 if (desired == 0) {
2773 objectsSize = 0;
2774 } else {
2775 while (objectsSize > 0) {
Michael Wachenschwanza6541632017-05-18 22:08:32 +00002776 if (mObjects[objectsSize-1] < desired)
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002777 break;
2778 objectsSize--;
2779 }
2780 }
2781 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002782
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002783 if (mOwner) {
2784 // If the size is going to zero, just release the owner's data.
2785 if (desired == 0) {
2786 freeData();
2787 return NO_ERROR;
2788 }
2789
2790 // If there is a different owner, we need to take
2791 // posession.
2792 uint8_t* data = (uint8_t*)malloc(desired);
2793 if (!data) {
2794 mError = NO_MEMORY;
2795 return NO_MEMORY;
2796 }
Yi Kong91635562018-06-07 14:38:36 -07002797 binder_size_t* objects = nullptr;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002798
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002799 if (objectsSize) {
Nick Kraleviche9881a32015-04-28 16:21:30 -07002800 objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002801 if (!objects) {
Hyejin Kim3f727c02013-03-09 11:28:54 +09002802 free(data);
2803
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002804 mError = NO_MEMORY;
2805 return NO_MEMORY;
2806 }
2807
2808 // Little hack to only acquire references on objects
2809 // we will be keeping.
2810 size_t oldObjectsSize = mObjectsSize;
2811 mObjectsSize = objectsSize;
2812 acquireObjects();
2813 mObjectsSize = oldObjectsSize;
2814 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002815
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002816 if (mData) {
2817 memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
2818 }
2819 if (objects && mObjects) {
Arve Hjønnevåg84e625a2014-01-28 20:12:59 -08002820 memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002821 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002822 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002823 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
Yi Kong91635562018-06-07 14:38:36 -07002824 mOwner = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002825
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002826 LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002827 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002828 gParcelGlobalAllocSize += desired;
2829 gParcelGlobalAllocCount++;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002830 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002831
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002832 mData = data;
2833 mObjects = objects;
2834 mDataSize = (mDataSize < desired) ? mDataSize : desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002835 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002836 mDataCapacity = desired;
2837 mObjectsSize = mObjectsCapacity = objectsSize;
2838 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002839 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002840
2841 } else if (mData) {
2842 if (objectsSize < mObjectsSize) {
2843 // Need to release refs on any objects we are dropping.
2844 const sp<ProcessState> proc(ProcessState::self());
2845 for (size_t i=objectsSize; i<mObjectsSize; i++) {
2846 const flat_binder_object* flat
2847 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002848 if (flat->hdr.type == BINDER_TYPE_FD) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002849 // will need to rescan because we may have lopped off the only FDs
2850 mFdsKnown = false;
2851 }
Adrian Rooscbf37262015-10-22 16:12:53 -07002852 release_object(proc, *flat, this, &mOpenAshmemSize);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002853 }
Michael Wachenschwanz6af27a82019-06-03 17:24:51 -07002854
2855 if (objectsSize == 0) {
2856 free(mObjects);
2857 mObjects = nullptr;
Michael Wachenschwanzd9d10db2019-10-15 11:49:22 -07002858 mObjectsCapacity = 0;
Michael Wachenschwanz6af27a82019-06-03 17:24:51 -07002859 } else {
2860 binder_size_t* objects =
2861 (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
2862 if (objects) {
2863 mObjects = objects;
Michael Wachenschwanzd9d10db2019-10-15 11:49:22 -07002864 mObjectsCapacity = objectsSize;
Michael Wachenschwanz6af27a82019-06-03 17:24:51 -07002865 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002866 }
2867 mObjectsSize = objectsSize;
2868 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002869 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002870 }
2871
2872 // We own the data, so we can just do a realloc().
2873 if (desired > mDataCapacity) {
2874 uint8_t* data = (uint8_t*)realloc(mData, desired);
2875 if (data) {
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002876 LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity,
2877 desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002878 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002879 gParcelGlobalAllocSize += desired;
2880 gParcelGlobalAllocSize -= mDataCapacity;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002881 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002882 mData = data;
2883 mDataCapacity = desired;
Ganesh Mahendranade89892017-09-28 16:56:03 +08002884 } else {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002885 mError = NO_MEMORY;
2886 return NO_MEMORY;
2887 }
2888 } else {
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -07002889 if (mDataSize > desired) {
2890 mDataSize = desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002891 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
Dianne Hackborn97e2bcd2011-04-13 18:15:56 -07002892 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002893 if (mDataPos > desired) {
2894 mDataPos = desired;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002895 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002896 }
2897 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002898
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002899 } else {
2900 // This is the first data. Easy!
2901 uint8_t* data = (uint8_t*)malloc(desired);
2902 if (!data) {
2903 mError = NO_MEMORY;
2904 return NO_MEMORY;
2905 }
Hyejin Kim3f727c02013-03-09 11:28:54 +09002906
Yi Kong91635562018-06-07 14:38:36 -07002907 if(!(mDataCapacity == 0 && mObjects == nullptr
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002908 && mObjectsCapacity == 0)) {
Colin Cross6f4f3ab2014-02-05 17:42:44 -08002909 ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002910 }
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002911
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002912 LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired);
Dianne Hackborna4cff882014-11-13 17:07:40 -08002913 pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002914 gParcelGlobalAllocSize += desired;
2915 gParcelGlobalAllocCount++;
Dianne Hackborna4cff882014-11-13 17:07:40 -08002916 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002917
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002918 mData = data;
2919 mDataSize = mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002920 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
2921 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002922 mDataCapacity = desired;
2923 }
2924
2925 return NO_ERROR;
2926}
2927
2928void Parcel::initState()
2929{
Dianne Hackborn7e790af2014-11-11 12:22:53 -08002930 LOG_ALLOC("Parcel %p: initState", this);
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002931 mError = NO_ERROR;
Yi Kong91635562018-06-07 14:38:36 -07002932 mData = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002933 mDataSize = 0;
2934 mDataCapacity = 0;
2935 mDataPos = 0;
Mark Salyzynd4ecccf2014-05-30 16:35:57 -07002936 ALOGV("initState Setting data size of %p to %zu", this, mDataSize);
2937 ALOGV("initState Setting data pos of %p to %zu", this, mDataPos);
Yi Kong91635562018-06-07 14:38:36 -07002938 mObjects = nullptr;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002939 mObjectsSize = 0;
2940 mObjectsCapacity = 0;
2941 mNextObjectHint = 0;
Michael Wachenschwanzc5176812017-11-17 18:25:05 -08002942 mObjectsSorted = false;
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002943 mHasFds = false;
2944 mFdsKnown = true;
Dianne Hackborn8938ed22011-09-28 23:19:47 -04002945 mAllowFds = true;
Yi Kong91635562018-06-07 14:38:36 -07002946 mOwner = nullptr;
Adrian Rooscbf37262015-10-22 16:12:53 -07002947 mOpenAshmemSize = 0;
Olivier Gaillarddc848a02019-01-30 17:10:44 +00002948 mWorkSourceRequestHeaderPosition = 0;
2949 mRequestHeaderPresent = false;
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002950
2951 // racing multiple init leads only to multiple identical write
2952 if (gMaxFds == 0) {
2953 struct rlimit result;
2954 if (!getrlimit(RLIMIT_NOFILE, &result)) {
2955 gMaxFds = (size_t)result.rlim_cur;
Christopher Tatebf14e942016-03-25 14:16:24 -07002956 //ALOGI("parcel fd limit set to %zu", gMaxFds);
Christopher Tatee4e0ae82016-03-24 16:03:44 -07002957 } else {
2958 ALOGW("Unable to getrlimit: %s", strerror(errno));
2959 gMaxFds = 1024;
2960 }
2961 }
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002962}
2963
2964void Parcel::scanForFds() const
2965{
2966 bool hasFds = false;
2967 for (size_t i=0; i<mObjectsSize; i++) {
2968 const flat_binder_object* flat
2969 = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
Christopher Ferrisdbaa22a2017-07-27 10:38:45 -07002970 if (flat->hdr.type == BINDER_TYPE_FD) {
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07002971 hasFds = true;
2972 break;
2973 }
2974 }
2975 mHasFds = hasFds;
2976 mFdsKnown = true;
2977}
2978
Dan Sandleraa5c2342015-04-10 10:08:45 -04002979size_t Parcel::getBlobAshmemSize() const
2980{
Adrian Roos6bb31142015-10-22 16:46:12 -07002981 // This used to return the size of all blobs that were written to ashmem, now we're returning
2982 // the ashmem currently referenced by this Parcel, which should be equivalent.
2983 // TODO: Remove method once ABI can be changed.
2984 return mOpenAshmemSize;
Dan Sandleraa5c2342015-04-10 10:08:45 -04002985}
2986
Adrian Rooscbf37262015-10-22 16:12:53 -07002987size_t Parcel::getOpenAshmemSize() const
2988{
2989 return mOpenAshmemSize;
Jeff Brown5707dbf2011-09-23 21:17:56 -07002990}
2991
2992// --- Parcel::Blob ---
2993
2994Parcel::Blob::Blob() :
Yi Kong91635562018-06-07 14:38:36 -07002995 mFd(-1), mData(nullptr), mSize(0), mMutable(false) {
Jeff Brown5707dbf2011-09-23 21:17:56 -07002996}
2997
2998Parcel::Blob::~Blob() {
2999 release();
3000}
3001
3002void Parcel::Blob::release() {
Jeff Brown13b16042014-11-11 16:44:25 -08003003 if (mFd != -1 && mData) {
Jeff Brown5707dbf2011-09-23 21:17:56 -07003004 ::munmap(mData, mSize);
3005 }
3006 clear();
3007}
3008
Jeff Brown13b16042014-11-11 16:44:25 -08003009void Parcel::Blob::init(int fd, void* data, size_t size, bool isMutable) {
3010 mFd = fd;
Jeff Brown5707dbf2011-09-23 21:17:56 -07003011 mData = data;
3012 mSize = size;
Jeff Brown13b16042014-11-11 16:44:25 -08003013 mMutable = isMutable;
Jeff Brown5707dbf2011-09-23 21:17:56 -07003014}
3015
3016void Parcel::Blob::clear() {
Jeff Brown13b16042014-11-11 16:44:25 -08003017 mFd = -1;
Yi Kong91635562018-06-07 14:38:36 -07003018 mData = nullptr;
Jeff Brown5707dbf2011-09-23 21:17:56 -07003019 mSize = 0;
Jeff Brown13b16042014-11-11 16:44:25 -08003020 mMutable = false;
Jeff Brown5707dbf2011-09-23 21:17:56 -07003021}
3022
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07003023}; // namespace android