1*77b80299SAndroid Build Coastguard Worker /*
2*77b80299SAndroid Build Coastguard Worker * Copyright (C) 2005 The Android Open Source Project
3*77b80299SAndroid Build Coastguard Worker *
4*77b80299SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*77b80299SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*77b80299SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*77b80299SAndroid Build Coastguard Worker *
8*77b80299SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*77b80299SAndroid Build Coastguard Worker *
10*77b80299SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*77b80299SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*77b80299SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*77b80299SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*77b80299SAndroid Build Coastguard Worker * limitations under the License.
15*77b80299SAndroid Build Coastguard Worker */
16*77b80299SAndroid Build Coastguard Worker
17*77b80299SAndroid Build Coastguard Worker #define LOG_TAG "hw-Parcel"
18*77b80299SAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*77b80299SAndroid Build Coastguard Worker
20*77b80299SAndroid Build Coastguard Worker #include <errno.h>
21*77b80299SAndroid Build Coastguard Worker #include <fcntl.h>
22*77b80299SAndroid Build Coastguard Worker #include <inttypes.h>
23*77b80299SAndroid Build Coastguard Worker #include <pthread.h>
24*77b80299SAndroid Build Coastguard Worker #include <stdint.h>
25*77b80299SAndroid Build Coastguard Worker #include <stdio.h>
26*77b80299SAndroid Build Coastguard Worker #include <stdlib.h>
27*77b80299SAndroid Build Coastguard Worker #include <sys/mman.h>
28*77b80299SAndroid Build Coastguard Worker #include <sys/stat.h>
29*77b80299SAndroid Build Coastguard Worker #include <sys/types.h>
30*77b80299SAndroid Build Coastguard Worker #include <sys/resource.h>
31*77b80299SAndroid Build Coastguard Worker #include <unistd.h>
32*77b80299SAndroid Build Coastguard Worker
33*77b80299SAndroid Build Coastguard Worker #include <hwbinder/Binder.h>
34*77b80299SAndroid Build Coastguard Worker #include <hwbinder/BpHwBinder.h>
35*77b80299SAndroid Build Coastguard Worker #include <hwbinder/IPCThreadState.h>
36*77b80299SAndroid Build Coastguard Worker #include <hwbinder/Parcel.h>
37*77b80299SAndroid Build Coastguard Worker #include <hwbinder/ProcessState.h>
38*77b80299SAndroid Build Coastguard Worker
39*77b80299SAndroid Build Coastguard Worker #include <cutils/ashmem.h>
40*77b80299SAndroid Build Coastguard Worker #include <utils/Log.h>
41*77b80299SAndroid Build Coastguard Worker #include <utils/misc.h>
42*77b80299SAndroid Build Coastguard Worker #include <utils/String8.h>
43*77b80299SAndroid Build Coastguard Worker #include <utils/String16.h>
44*77b80299SAndroid Build Coastguard Worker
45*77b80299SAndroid Build Coastguard Worker #include "binder_kernel.h"
46*77b80299SAndroid Build Coastguard Worker #include <hwbinder/Static.h>
47*77b80299SAndroid Build Coastguard Worker #include "TextOutput.h"
48*77b80299SAndroid Build Coastguard Worker #include "Utils.h"
49*77b80299SAndroid Build Coastguard Worker
50*77b80299SAndroid Build Coastguard Worker #include <atomic>
51*77b80299SAndroid Build Coastguard Worker
52*77b80299SAndroid Build Coastguard Worker #define LOG_REFS(...)
53*77b80299SAndroid Build Coastguard Worker //#define LOG_REFS(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
54*77b80299SAndroid Build Coastguard Worker #define LOG_ALLOC(...)
55*77b80299SAndroid Build Coastguard Worker //#define LOG_ALLOC(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
56*77b80299SAndroid Build Coastguard Worker #define LOG_BUFFER(...)
57*77b80299SAndroid Build Coastguard Worker // #define LOG_BUFFER(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
58*77b80299SAndroid Build Coastguard Worker
59*77b80299SAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
60*77b80299SAndroid Build Coastguard Worker
61*77b80299SAndroid Build Coastguard Worker // This macro should never be used at runtime, as a too large value
62*77b80299SAndroid Build Coastguard Worker // of s could cause an integer overflow. Instead, you should always
63*77b80299SAndroid Build Coastguard Worker // use the wrapper function pad_size()
64*77b80299SAndroid Build Coastguard Worker #define PAD_SIZE_UNSAFE(s) (((s)+3)&~3)
65*77b80299SAndroid Build Coastguard Worker
pad_size(size_t s)66*77b80299SAndroid Build Coastguard Worker static size_t pad_size(size_t s) {
67*77b80299SAndroid Build Coastguard Worker if (s > (std::numeric_limits<size_t>::max() - 3)) {
68*77b80299SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL("pad size too big %zu", s);
69*77b80299SAndroid Build Coastguard Worker }
70*77b80299SAndroid Build Coastguard Worker return PAD_SIZE_UNSAFE(s);
71*77b80299SAndroid Build Coastguard Worker }
72*77b80299SAndroid Build Coastguard Worker
73*77b80299SAndroid Build Coastguard Worker // Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
74*77b80299SAndroid Build Coastguard Worker #define STRICT_MODE_PENALTY_GATHER (0x40 << 16)
75*77b80299SAndroid Build Coastguard Worker
76*77b80299SAndroid Build Coastguard Worker namespace android {
77*77b80299SAndroid Build Coastguard Worker namespace hardware {
78*77b80299SAndroid Build Coastguard Worker
79*77b80299SAndroid Build Coastguard Worker static std::atomic<size_t> gParcelGlobalAllocCount;
80*77b80299SAndroid Build Coastguard Worker static std::atomic<size_t> gParcelGlobalAllocSize;
81*77b80299SAndroid Build Coastguard Worker
82*77b80299SAndroid Build Coastguard Worker static size_t gMaxFds = 0;
83*77b80299SAndroid Build Coastguard Worker
acquire_binder_object(const sp<ProcessState> & proc,const flat_binder_object & obj,const void * who)84*77b80299SAndroid Build Coastguard Worker void acquire_binder_object(const sp<ProcessState>& proc,
85*77b80299SAndroid Build Coastguard Worker const flat_binder_object& obj, const void* who)
86*77b80299SAndroid Build Coastguard Worker {
87*77b80299SAndroid Build Coastguard Worker switch (obj.hdr.type) {
88*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_BINDER:
89*77b80299SAndroid Build Coastguard Worker if (obj.binder) {
90*77b80299SAndroid Build Coastguard Worker LOG_REFS("Parcel %p acquiring reference on local %llu", who, obj.cookie);
91*77b80299SAndroid Build Coastguard Worker reinterpret_cast<IBinder*>(obj.cookie)->incStrong(who);
92*77b80299SAndroid Build Coastguard Worker }
93*77b80299SAndroid Build Coastguard Worker return;
94*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_WEAK_BINDER:
95*77b80299SAndroid Build Coastguard Worker if (obj.binder)
96*77b80299SAndroid Build Coastguard Worker reinterpret_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
97*77b80299SAndroid Build Coastguard Worker return;
98*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_HANDLE: {
99*77b80299SAndroid Build Coastguard Worker const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
100*77b80299SAndroid Build Coastguard Worker if (b != nullptr) {
101*77b80299SAndroid Build Coastguard Worker LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get());
102*77b80299SAndroid Build Coastguard Worker b->incStrong(who);
103*77b80299SAndroid Build Coastguard Worker }
104*77b80299SAndroid Build Coastguard Worker return;
105*77b80299SAndroid Build Coastguard Worker }
106*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_WEAK_HANDLE: {
107*77b80299SAndroid Build Coastguard Worker const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
108*77b80299SAndroid Build Coastguard Worker if (b != nullptr) b.get_refs()->incWeak(who);
109*77b80299SAndroid Build Coastguard Worker return;
110*77b80299SAndroid Build Coastguard Worker }
111*77b80299SAndroid Build Coastguard Worker }
112*77b80299SAndroid Build Coastguard Worker
113*77b80299SAndroid Build Coastguard Worker ALOGD("Invalid object type 0x%08x", obj.hdr.type);
114*77b80299SAndroid Build Coastguard Worker }
115*77b80299SAndroid Build Coastguard Worker
acquire_object(const sp<ProcessState> & proc,const binder_object_header & obj,const void * who)116*77b80299SAndroid Build Coastguard Worker void acquire_object(const sp<ProcessState>& proc, const binder_object_header& obj,
117*77b80299SAndroid Build Coastguard Worker const void *who) {
118*77b80299SAndroid Build Coastguard Worker switch (obj.type) {
119*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_BINDER:
120*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_WEAK_BINDER:
121*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_HANDLE:
122*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_WEAK_HANDLE: {
123*77b80299SAndroid Build Coastguard Worker const flat_binder_object& fbo = reinterpret_cast<const flat_binder_object&>(obj);
124*77b80299SAndroid Build Coastguard Worker acquire_binder_object(proc, fbo, who);
125*77b80299SAndroid Build Coastguard Worker break;
126*77b80299SAndroid Build Coastguard Worker }
127*77b80299SAndroid Build Coastguard Worker }
128*77b80299SAndroid Build Coastguard Worker }
129*77b80299SAndroid Build Coastguard Worker
release_object(const sp<ProcessState> & proc,const flat_binder_object & obj,const void * who)130*77b80299SAndroid Build Coastguard Worker void release_object(const sp<ProcessState>& proc,
131*77b80299SAndroid Build Coastguard Worker const flat_binder_object& obj, const void* who)
132*77b80299SAndroid Build Coastguard Worker {
133*77b80299SAndroid Build Coastguard Worker switch (obj.hdr.type) {
134*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_BINDER:
135*77b80299SAndroid Build Coastguard Worker if (obj.binder) {
136*77b80299SAndroid Build Coastguard Worker LOG_REFS("Parcel %p releasing reference on local %llu", who, obj.cookie);
137*77b80299SAndroid Build Coastguard Worker reinterpret_cast<IBinder*>(obj.cookie)->decStrong(who);
138*77b80299SAndroid Build Coastguard Worker }
139*77b80299SAndroid Build Coastguard Worker return;
140*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_WEAK_BINDER:
141*77b80299SAndroid Build Coastguard Worker if (obj.binder)
142*77b80299SAndroid Build Coastguard Worker reinterpret_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
143*77b80299SAndroid Build Coastguard Worker return;
144*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_HANDLE: {
145*77b80299SAndroid Build Coastguard Worker const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
146*77b80299SAndroid Build Coastguard Worker if (b != nullptr) {
147*77b80299SAndroid Build Coastguard Worker LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get());
148*77b80299SAndroid Build Coastguard Worker b->decStrong(who);
149*77b80299SAndroid Build Coastguard Worker }
150*77b80299SAndroid Build Coastguard Worker return;
151*77b80299SAndroid Build Coastguard Worker }
152*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_WEAK_HANDLE: {
153*77b80299SAndroid Build Coastguard Worker const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle);
154*77b80299SAndroid Build Coastguard Worker if (b != nullptr) b.get_refs()->decWeak(who);
155*77b80299SAndroid Build Coastguard Worker return;
156*77b80299SAndroid Build Coastguard Worker }
157*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_FD: {
158*77b80299SAndroid Build Coastguard Worker if (obj.cookie != 0) { // owned
159*77b80299SAndroid Build Coastguard Worker close(obj.handle);
160*77b80299SAndroid Build Coastguard Worker }
161*77b80299SAndroid Build Coastguard Worker return;
162*77b80299SAndroid Build Coastguard Worker }
163*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_PTR: {
164*77b80299SAndroid Build Coastguard Worker // The relevant buffer is part of the transaction buffer and will be freed that way
165*77b80299SAndroid Build Coastguard Worker return;
166*77b80299SAndroid Build Coastguard Worker }
167*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_FDA: {
168*77b80299SAndroid Build Coastguard Worker // The enclosed file descriptors are closed in the kernel
169*77b80299SAndroid Build Coastguard Worker return;
170*77b80299SAndroid Build Coastguard Worker }
171*77b80299SAndroid Build Coastguard Worker }
172*77b80299SAndroid Build Coastguard Worker
173*77b80299SAndroid Build Coastguard Worker ALOGE("Invalid object type 0x%08x", obj.hdr.type);
174*77b80299SAndroid Build Coastguard Worker }
175*77b80299SAndroid Build Coastguard Worker
finish_flatten_binder(const sp<IBinder> &,const flat_binder_object & flat,Parcel * out)176*77b80299SAndroid Build Coastguard Worker inline static status_t finish_flatten_binder(
177*77b80299SAndroid Build Coastguard Worker const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out)
178*77b80299SAndroid Build Coastguard Worker {
179*77b80299SAndroid Build Coastguard Worker return out->writeObject(flat);
180*77b80299SAndroid Build Coastguard Worker }
181*77b80299SAndroid Build Coastguard Worker
flatten_binder(const sp<ProcessState> &,const sp<IBinder> & binder,Parcel * out)182*77b80299SAndroid Build Coastguard Worker status_t flatten_binder(const sp<ProcessState>& /*proc*/,
183*77b80299SAndroid Build Coastguard Worker const sp<IBinder>& binder, Parcel* out)
184*77b80299SAndroid Build Coastguard Worker {
185*77b80299SAndroid Build Coastguard Worker flat_binder_object obj = {};
186*77b80299SAndroid Build Coastguard Worker
187*77b80299SAndroid Build Coastguard Worker if (binder != nullptr) {
188*77b80299SAndroid Build Coastguard Worker BHwBinder *local = binder->localBinder();
189*77b80299SAndroid Build Coastguard Worker if (!local) {
190*77b80299SAndroid Build Coastguard Worker BpHwBinder *proxy = binder->remoteBinder();
191*77b80299SAndroid Build Coastguard Worker if (proxy == nullptr) {
192*77b80299SAndroid Build Coastguard Worker ALOGE("null proxy");
193*77b80299SAndroid Build Coastguard Worker }
194*77b80299SAndroid Build Coastguard Worker const int32_t handle = proxy ? proxy->handle() : 0;
195*77b80299SAndroid Build Coastguard Worker obj.hdr.type = BINDER_TYPE_HANDLE;
196*77b80299SAndroid Build Coastguard Worker obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;
197*77b80299SAndroid Build Coastguard Worker obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
198*77b80299SAndroid Build Coastguard Worker obj.handle = handle;
199*77b80299SAndroid Build Coastguard Worker obj.cookie = 0;
200*77b80299SAndroid Build Coastguard Worker } else {
201*77b80299SAndroid Build Coastguard Worker // Get policy and convert it
202*77b80299SAndroid Build Coastguard Worker int policy = local->getMinSchedulingPolicy();
203*77b80299SAndroid Build Coastguard Worker int priority = local->getMinSchedulingPriority();
204*77b80299SAndroid Build Coastguard Worker
205*77b80299SAndroid Build Coastguard Worker obj.flags = priority & FLAT_BINDER_FLAG_PRIORITY_MASK;
206*77b80299SAndroid Build Coastguard Worker obj.flags |= FLAT_BINDER_FLAG_ACCEPTS_FDS | FLAT_BINDER_FLAG_INHERIT_RT;
207*77b80299SAndroid Build Coastguard Worker obj.flags |= (policy & 3) << FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT;
208*77b80299SAndroid Build Coastguard Worker if (local->isRequestingSid()) {
209*77b80299SAndroid Build Coastguard Worker obj.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
210*77b80299SAndroid Build Coastguard Worker }
211*77b80299SAndroid Build Coastguard Worker obj.hdr.type = BINDER_TYPE_BINDER;
212*77b80299SAndroid Build Coastguard Worker obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
213*77b80299SAndroid Build Coastguard Worker obj.cookie = reinterpret_cast<uintptr_t>(local);
214*77b80299SAndroid Build Coastguard Worker }
215*77b80299SAndroid Build Coastguard Worker } else {
216*77b80299SAndroid Build Coastguard Worker obj.hdr.type = BINDER_TYPE_BINDER;
217*77b80299SAndroid Build Coastguard Worker obj.binder = 0;
218*77b80299SAndroid Build Coastguard Worker obj.cookie = 0;
219*77b80299SAndroid Build Coastguard Worker }
220*77b80299SAndroid Build Coastguard Worker
221*77b80299SAndroid Build Coastguard Worker return finish_flatten_binder(binder, obj, out);
222*77b80299SAndroid Build Coastguard Worker }
223*77b80299SAndroid Build Coastguard Worker
finish_unflatten_binder(BpHwBinder *,const flat_binder_object &,const Parcel &)224*77b80299SAndroid Build Coastguard Worker inline static status_t finish_unflatten_binder(
225*77b80299SAndroid Build Coastguard Worker BpHwBinder* /*proxy*/, const flat_binder_object& /*flat*/,
226*77b80299SAndroid Build Coastguard Worker const Parcel& /*in*/)
227*77b80299SAndroid Build Coastguard Worker {
228*77b80299SAndroid Build Coastguard Worker return NO_ERROR;
229*77b80299SAndroid Build Coastguard Worker }
230*77b80299SAndroid Build Coastguard Worker
unflatten_binder(const sp<ProcessState> & proc,const Parcel & in,sp<IBinder> * out)231*77b80299SAndroid Build Coastguard Worker status_t unflatten_binder(const sp<ProcessState>& proc,
232*77b80299SAndroid Build Coastguard Worker const Parcel& in, sp<IBinder>* out)
233*77b80299SAndroid Build Coastguard Worker {
234*77b80299SAndroid Build Coastguard Worker const flat_binder_object* flat = in.readObject<flat_binder_object>();
235*77b80299SAndroid Build Coastguard Worker
236*77b80299SAndroid Build Coastguard Worker if (flat) {
237*77b80299SAndroid Build Coastguard Worker switch (flat->hdr.type) {
238*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_BINDER:
239*77b80299SAndroid Build Coastguard Worker *out = reinterpret_cast<IBinder*>(flat->cookie);
240*77b80299SAndroid Build Coastguard Worker return finish_unflatten_binder(nullptr, *flat, in);
241*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_HANDLE:
242*77b80299SAndroid Build Coastguard Worker *out = proc->getStrongProxyForHandle(flat->handle);
243*77b80299SAndroid Build Coastguard Worker return finish_unflatten_binder(
244*77b80299SAndroid Build Coastguard Worker static_cast<BpHwBinder*>(out->get()), *flat, in);
245*77b80299SAndroid Build Coastguard Worker }
246*77b80299SAndroid Build Coastguard Worker }
247*77b80299SAndroid Build Coastguard Worker return BAD_TYPE;
248*77b80299SAndroid Build Coastguard Worker }
249*77b80299SAndroid Build Coastguard Worker
250*77b80299SAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
251*77b80299SAndroid Build Coastguard Worker
Parcel()252*77b80299SAndroid Build Coastguard Worker Parcel::Parcel()
253*77b80299SAndroid Build Coastguard Worker {
254*77b80299SAndroid Build Coastguard Worker LOG_ALLOC("Parcel %p: constructing", this);
255*77b80299SAndroid Build Coastguard Worker initState();
256*77b80299SAndroid Build Coastguard Worker }
257*77b80299SAndroid Build Coastguard Worker
~Parcel()258*77b80299SAndroid Build Coastguard Worker Parcel::~Parcel()
259*77b80299SAndroid Build Coastguard Worker {
260*77b80299SAndroid Build Coastguard Worker freeDataNoInit();
261*77b80299SAndroid Build Coastguard Worker LOG_ALLOC("Parcel %p: destroyed", this);
262*77b80299SAndroid Build Coastguard Worker }
263*77b80299SAndroid Build Coastguard Worker
getGlobalAllocSize()264*77b80299SAndroid Build Coastguard Worker size_t Parcel::getGlobalAllocSize() {
265*77b80299SAndroid Build Coastguard Worker return gParcelGlobalAllocSize.load();
266*77b80299SAndroid Build Coastguard Worker }
267*77b80299SAndroid Build Coastguard Worker
getGlobalAllocCount()268*77b80299SAndroid Build Coastguard Worker size_t Parcel::getGlobalAllocCount() {
269*77b80299SAndroid Build Coastguard Worker return gParcelGlobalAllocCount.load();
270*77b80299SAndroid Build Coastguard Worker }
271*77b80299SAndroid Build Coastguard Worker
data() const272*77b80299SAndroid Build Coastguard Worker const uint8_t* Parcel::data() const
273*77b80299SAndroid Build Coastguard Worker {
274*77b80299SAndroid Build Coastguard Worker return mData;
275*77b80299SAndroid Build Coastguard Worker }
276*77b80299SAndroid Build Coastguard Worker
dataSize() const277*77b80299SAndroid Build Coastguard Worker size_t Parcel::dataSize() const
278*77b80299SAndroid Build Coastguard Worker {
279*77b80299SAndroid Build Coastguard Worker return (mDataSize > mDataPos ? mDataSize : mDataPos);
280*77b80299SAndroid Build Coastguard Worker }
281*77b80299SAndroid Build Coastguard Worker
dataAvail() const282*77b80299SAndroid Build Coastguard Worker size_t Parcel::dataAvail() const
283*77b80299SAndroid Build Coastguard Worker {
284*77b80299SAndroid Build Coastguard Worker size_t result = dataSize() - dataPosition();
285*77b80299SAndroid Build Coastguard Worker if (result > INT32_MAX) {
286*77b80299SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL("result too big: %zu", result);
287*77b80299SAndroid Build Coastguard Worker }
288*77b80299SAndroid Build Coastguard Worker return result;
289*77b80299SAndroid Build Coastguard Worker }
290*77b80299SAndroid Build Coastguard Worker
dataPosition() const291*77b80299SAndroid Build Coastguard Worker size_t Parcel::dataPosition() const
292*77b80299SAndroid Build Coastguard Worker {
293*77b80299SAndroid Build Coastguard Worker return mDataPos;
294*77b80299SAndroid Build Coastguard Worker }
295*77b80299SAndroid Build Coastguard Worker
dataCapacity() const296*77b80299SAndroid Build Coastguard Worker size_t Parcel::dataCapacity() const
297*77b80299SAndroid Build Coastguard Worker {
298*77b80299SAndroid Build Coastguard Worker return mDataCapacity;
299*77b80299SAndroid Build Coastguard Worker }
300*77b80299SAndroid Build Coastguard Worker
setDataSize(size_t size)301*77b80299SAndroid Build Coastguard Worker status_t Parcel::setDataSize(size_t size)
302*77b80299SAndroid Build Coastguard Worker {
303*77b80299SAndroid Build Coastguard Worker if (size > INT32_MAX) {
304*77b80299SAndroid Build Coastguard Worker // don't accept size_t values which may have come from an
305*77b80299SAndroid Build Coastguard Worker // inadvertent conversion from a negative int.
306*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
307*77b80299SAndroid Build Coastguard Worker }
308*77b80299SAndroid Build Coastguard Worker
309*77b80299SAndroid Build Coastguard Worker status_t err;
310*77b80299SAndroid Build Coastguard Worker err = continueWrite(size);
311*77b80299SAndroid Build Coastguard Worker if (err == NO_ERROR) {
312*77b80299SAndroid Build Coastguard Worker mDataSize = size;
313*77b80299SAndroid Build Coastguard Worker ALOGV("setDataSize Setting data size of %p to %zu", this, mDataSize);
314*77b80299SAndroid Build Coastguard Worker }
315*77b80299SAndroid Build Coastguard Worker return err;
316*77b80299SAndroid Build Coastguard Worker }
317*77b80299SAndroid Build Coastguard Worker
setDataPosition(size_t pos) const318*77b80299SAndroid Build Coastguard Worker void Parcel::setDataPosition(size_t pos) const
319*77b80299SAndroid Build Coastguard Worker {
320*77b80299SAndroid Build Coastguard Worker if (pos > INT32_MAX) {
321*77b80299SAndroid Build Coastguard Worker // don't accept size_t values which may have come from an
322*77b80299SAndroid Build Coastguard Worker // inadvertent conversion from a negative int.
323*77b80299SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL("pos too big: %zu", pos);
324*77b80299SAndroid Build Coastguard Worker }
325*77b80299SAndroid Build Coastguard Worker
326*77b80299SAndroid Build Coastguard Worker mDataPos = pos;
327*77b80299SAndroid Build Coastguard Worker mNextObjectHint = 0;
328*77b80299SAndroid Build Coastguard Worker }
329*77b80299SAndroid Build Coastguard Worker
setDataCapacity(size_t size)330*77b80299SAndroid Build Coastguard Worker status_t Parcel::setDataCapacity(size_t size)
331*77b80299SAndroid Build Coastguard Worker {
332*77b80299SAndroid Build Coastguard Worker if (size > INT32_MAX) {
333*77b80299SAndroid Build Coastguard Worker // don't accept size_t values which may have come from an
334*77b80299SAndroid Build Coastguard Worker // inadvertent conversion from a negative int.
335*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
336*77b80299SAndroid Build Coastguard Worker }
337*77b80299SAndroid Build Coastguard Worker
338*77b80299SAndroid Build Coastguard Worker if (size > mDataCapacity) return continueWrite(size);
339*77b80299SAndroid Build Coastguard Worker return NO_ERROR;
340*77b80299SAndroid Build Coastguard Worker }
341*77b80299SAndroid Build Coastguard Worker
markSensitive() const342*77b80299SAndroid Build Coastguard Worker void Parcel::markSensitive() const
343*77b80299SAndroid Build Coastguard Worker {
344*77b80299SAndroid Build Coastguard Worker mDeallocZero = true;
345*77b80299SAndroid Build Coastguard Worker }
346*77b80299SAndroid Build Coastguard Worker
347*77b80299SAndroid Build Coastguard Worker // Write RPC headers. (previously just the interface token)
writeInterfaceToken(const char * interface)348*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeInterfaceToken(const char* interface)
349*77b80299SAndroid Build Coastguard Worker {
350*77b80299SAndroid Build Coastguard Worker // currently the interface identification token is just its name as a string
351*77b80299SAndroid Build Coastguard Worker return writeCString(interface);
352*77b80299SAndroid Build Coastguard Worker }
353*77b80299SAndroid Build Coastguard Worker
enforceInterface(const char * interface) const354*77b80299SAndroid Build Coastguard Worker bool Parcel::enforceInterface(const char* interface) const
355*77b80299SAndroid Build Coastguard Worker {
356*77b80299SAndroid Build Coastguard Worker const char* str = readCString();
357*77b80299SAndroid Build Coastguard Worker if (str != nullptr && strcmp(str, interface) == 0) {
358*77b80299SAndroid Build Coastguard Worker return true;
359*77b80299SAndroid Build Coastguard Worker } else {
360*77b80299SAndroid Build Coastguard Worker ALOGW("**** enforceInterface() expected '%s' but read '%s'",
361*77b80299SAndroid Build Coastguard Worker interface, (str ? str : "<empty string>"));
362*77b80299SAndroid Build Coastguard Worker return false;
363*77b80299SAndroid Build Coastguard Worker }
364*77b80299SAndroid Build Coastguard Worker }
365*77b80299SAndroid Build Coastguard Worker
objects() const366*77b80299SAndroid Build Coastguard Worker const binder_size_t* Parcel::objects() const
367*77b80299SAndroid Build Coastguard Worker {
368*77b80299SAndroid Build Coastguard Worker return mObjects;
369*77b80299SAndroid Build Coastguard Worker }
370*77b80299SAndroid Build Coastguard Worker
objectsCount() const371*77b80299SAndroid Build Coastguard Worker size_t Parcel::objectsCount() const
372*77b80299SAndroid Build Coastguard Worker {
373*77b80299SAndroid Build Coastguard Worker return mObjectsSize;
374*77b80299SAndroid Build Coastguard Worker }
375*77b80299SAndroid Build Coastguard Worker
errorCheck() const376*77b80299SAndroid Build Coastguard Worker status_t Parcel::errorCheck() const
377*77b80299SAndroid Build Coastguard Worker {
378*77b80299SAndroid Build Coastguard Worker return mError;
379*77b80299SAndroid Build Coastguard Worker }
380*77b80299SAndroid Build Coastguard Worker
setError(status_t err)381*77b80299SAndroid Build Coastguard Worker void Parcel::setError(status_t err)
382*77b80299SAndroid Build Coastguard Worker {
383*77b80299SAndroid Build Coastguard Worker mError = err;
384*77b80299SAndroid Build Coastguard Worker }
385*77b80299SAndroid Build Coastguard Worker
finishWrite(size_t len)386*77b80299SAndroid Build Coastguard Worker status_t Parcel::finishWrite(size_t len)
387*77b80299SAndroid Build Coastguard Worker {
388*77b80299SAndroid Build Coastguard Worker if (len > INT32_MAX) {
389*77b80299SAndroid Build Coastguard Worker // don't accept size_t values which may have come from an
390*77b80299SAndroid Build Coastguard Worker // inadvertent conversion from a negative int.
391*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
392*77b80299SAndroid Build Coastguard Worker }
393*77b80299SAndroid Build Coastguard Worker
394*77b80299SAndroid Build Coastguard Worker //printf("Finish write of %d\n", len);
395*77b80299SAndroid Build Coastguard Worker mDataPos += len;
396*77b80299SAndroid Build Coastguard Worker ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos);
397*77b80299SAndroid Build Coastguard Worker if (mDataPos > mDataSize) {
398*77b80299SAndroid Build Coastguard Worker mDataSize = mDataPos;
399*77b80299SAndroid Build Coastguard Worker ALOGV("finishWrite Setting data size of %p to %zu", this, mDataSize);
400*77b80299SAndroid Build Coastguard Worker }
401*77b80299SAndroid Build Coastguard Worker //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
402*77b80299SAndroid Build Coastguard Worker return NO_ERROR;
403*77b80299SAndroid Build Coastguard Worker }
404*77b80299SAndroid Build Coastguard Worker
write(const void * data,size_t len)405*77b80299SAndroid Build Coastguard Worker status_t Parcel::write(const void* data, size_t len)
406*77b80299SAndroid Build Coastguard Worker {
407*77b80299SAndroid Build Coastguard Worker if (len > INT32_MAX) {
408*77b80299SAndroid Build Coastguard Worker // don't accept size_t values which may have come from an
409*77b80299SAndroid Build Coastguard Worker // inadvertent conversion from a negative int.
410*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
411*77b80299SAndroid Build Coastguard Worker }
412*77b80299SAndroid Build Coastguard Worker
413*77b80299SAndroid Build Coastguard Worker void* const d = writeInplace(len);
414*77b80299SAndroid Build Coastguard Worker if (d) {
415*77b80299SAndroid Build Coastguard Worker memcpy(d, data, len);
416*77b80299SAndroid Build Coastguard Worker return NO_ERROR;
417*77b80299SAndroid Build Coastguard Worker }
418*77b80299SAndroid Build Coastguard Worker return mError;
419*77b80299SAndroid Build Coastguard Worker }
420*77b80299SAndroid Build Coastguard Worker
writeInplace(size_t len)421*77b80299SAndroid Build Coastguard Worker void* Parcel::writeInplace(size_t len)
422*77b80299SAndroid Build Coastguard Worker {
423*77b80299SAndroid Build Coastguard Worker if (len > INT32_MAX) {
424*77b80299SAndroid Build Coastguard Worker // don't accept size_t values which may have come from an
425*77b80299SAndroid Build Coastguard Worker // inadvertent conversion from a negative int.
426*77b80299SAndroid Build Coastguard Worker return nullptr;
427*77b80299SAndroid Build Coastguard Worker }
428*77b80299SAndroid Build Coastguard Worker
429*77b80299SAndroid Build Coastguard Worker const size_t padded = pad_size(len);
430*77b80299SAndroid Build Coastguard Worker
431*77b80299SAndroid Build Coastguard Worker // validate for integer overflow
432*77b80299SAndroid Build Coastguard Worker if (mDataPos+padded < mDataPos) {
433*77b80299SAndroid Build Coastguard Worker return nullptr;
434*77b80299SAndroid Build Coastguard Worker }
435*77b80299SAndroid Build Coastguard Worker
436*77b80299SAndroid Build Coastguard Worker if ((mDataPos+padded) <= mDataCapacity) {
437*77b80299SAndroid Build Coastguard Worker restart_write:
438*77b80299SAndroid Build Coastguard Worker //printf("Writing %ld bytes, padded to %ld\n", len, padded);
439*77b80299SAndroid Build Coastguard Worker uint8_t* const data = mData+mDataPos;
440*77b80299SAndroid Build Coastguard Worker
441*77b80299SAndroid Build Coastguard Worker // Need to pad at end?
442*77b80299SAndroid Build Coastguard Worker if (padded != len) {
443*77b80299SAndroid Build Coastguard Worker #if BYTE_ORDER == BIG_ENDIAN
444*77b80299SAndroid Build Coastguard Worker static const uint32_t mask[4] = {
445*77b80299SAndroid Build Coastguard Worker 0x00000000, 0xffffff00, 0xffff0000, 0xff000000
446*77b80299SAndroid Build Coastguard Worker };
447*77b80299SAndroid Build Coastguard Worker #endif
448*77b80299SAndroid Build Coastguard Worker #if BYTE_ORDER == LITTLE_ENDIAN
449*77b80299SAndroid Build Coastguard Worker static const uint32_t mask[4] = {
450*77b80299SAndroid Build Coastguard Worker 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
451*77b80299SAndroid Build Coastguard Worker };
452*77b80299SAndroid Build Coastguard Worker #endif
453*77b80299SAndroid Build Coastguard Worker //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len],
454*77b80299SAndroid Build Coastguard Worker // *reinterpret_cast<void**>(data+padded-4));
455*77b80299SAndroid Build Coastguard Worker *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
456*77b80299SAndroid Build Coastguard Worker }
457*77b80299SAndroid Build Coastguard Worker
458*77b80299SAndroid Build Coastguard Worker finishWrite(padded);
459*77b80299SAndroid Build Coastguard Worker return data;
460*77b80299SAndroid Build Coastguard Worker }
461*77b80299SAndroid Build Coastguard Worker
462*77b80299SAndroid Build Coastguard Worker status_t err = growData(padded);
463*77b80299SAndroid Build Coastguard Worker if (err == NO_ERROR) goto restart_write;
464*77b80299SAndroid Build Coastguard Worker return nullptr;
465*77b80299SAndroid Build Coastguard Worker }
466*77b80299SAndroid Build Coastguard Worker
writeInt8(int8_t val)467*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeInt8(int8_t val)
468*77b80299SAndroid Build Coastguard Worker {
469*77b80299SAndroid Build Coastguard Worker return write(&val, sizeof(val));
470*77b80299SAndroid Build Coastguard Worker }
471*77b80299SAndroid Build Coastguard Worker
writeUint8(uint8_t val)472*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeUint8(uint8_t val)
473*77b80299SAndroid Build Coastguard Worker {
474*77b80299SAndroid Build Coastguard Worker return write(&val, sizeof(val));
475*77b80299SAndroid Build Coastguard Worker }
476*77b80299SAndroid Build Coastguard Worker
writeInt16(int16_t val)477*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeInt16(int16_t val)
478*77b80299SAndroid Build Coastguard Worker {
479*77b80299SAndroid Build Coastguard Worker return write(&val, sizeof(val));
480*77b80299SAndroid Build Coastguard Worker }
481*77b80299SAndroid Build Coastguard Worker
writeUint16(uint16_t val)482*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeUint16(uint16_t val)
483*77b80299SAndroid Build Coastguard Worker {
484*77b80299SAndroid Build Coastguard Worker return write(&val, sizeof(val));
485*77b80299SAndroid Build Coastguard Worker }
486*77b80299SAndroid Build Coastguard Worker
writeInt32(int32_t val)487*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeInt32(int32_t val)
488*77b80299SAndroid Build Coastguard Worker {
489*77b80299SAndroid Build Coastguard Worker return writeAligned(val);
490*77b80299SAndroid Build Coastguard Worker }
491*77b80299SAndroid Build Coastguard Worker
writeUint32(uint32_t val)492*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeUint32(uint32_t val)
493*77b80299SAndroid Build Coastguard Worker {
494*77b80299SAndroid Build Coastguard Worker return writeAligned(val);
495*77b80299SAndroid Build Coastguard Worker }
496*77b80299SAndroid Build Coastguard Worker
writeBool(bool val)497*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeBool(bool val)
498*77b80299SAndroid Build Coastguard Worker {
499*77b80299SAndroid Build Coastguard Worker return writeInt8(int8_t(val));
500*77b80299SAndroid Build Coastguard Worker }
writeInt64(int64_t val)501*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeInt64(int64_t val)
502*77b80299SAndroid Build Coastguard Worker {
503*77b80299SAndroid Build Coastguard Worker return writeAligned(val);
504*77b80299SAndroid Build Coastguard Worker }
505*77b80299SAndroid Build Coastguard Worker
writeUint64(uint64_t val)506*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeUint64(uint64_t val)
507*77b80299SAndroid Build Coastguard Worker {
508*77b80299SAndroid Build Coastguard Worker return writeAligned(val);
509*77b80299SAndroid Build Coastguard Worker }
510*77b80299SAndroid Build Coastguard Worker
writePointer(uintptr_t val)511*77b80299SAndroid Build Coastguard Worker status_t Parcel::writePointer(uintptr_t val)
512*77b80299SAndroid Build Coastguard Worker {
513*77b80299SAndroid Build Coastguard Worker return writeAligned<binder_uintptr_t>(val);
514*77b80299SAndroid Build Coastguard Worker }
515*77b80299SAndroid Build Coastguard Worker
writeFloat(float val)516*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeFloat(float val)
517*77b80299SAndroid Build Coastguard Worker {
518*77b80299SAndroid Build Coastguard Worker return writeAligned(val);
519*77b80299SAndroid Build Coastguard Worker }
520*77b80299SAndroid Build Coastguard Worker
521*77b80299SAndroid Build Coastguard Worker #if defined(__mips__) && defined(__mips_hard_float)
522*77b80299SAndroid Build Coastguard Worker
writeDouble(double val)523*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeDouble(double val)
524*77b80299SAndroid Build Coastguard Worker {
525*77b80299SAndroid Build Coastguard Worker union {
526*77b80299SAndroid Build Coastguard Worker double d;
527*77b80299SAndroid Build Coastguard Worker unsigned long long ll;
528*77b80299SAndroid Build Coastguard Worker } u;
529*77b80299SAndroid Build Coastguard Worker u.d = val;
530*77b80299SAndroid Build Coastguard Worker return writeAligned(u.ll);
531*77b80299SAndroid Build Coastguard Worker }
532*77b80299SAndroid Build Coastguard Worker
533*77b80299SAndroid Build Coastguard Worker #else
534*77b80299SAndroid Build Coastguard Worker
writeDouble(double val)535*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeDouble(double val)
536*77b80299SAndroid Build Coastguard Worker {
537*77b80299SAndroid Build Coastguard Worker return writeAligned(val);
538*77b80299SAndroid Build Coastguard Worker }
539*77b80299SAndroid Build Coastguard Worker
540*77b80299SAndroid Build Coastguard Worker #endif
541*77b80299SAndroid Build Coastguard Worker
writeCString(const char * str)542*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeCString(const char* str)
543*77b80299SAndroid Build Coastguard Worker {
544*77b80299SAndroid Build Coastguard Worker return write(str, strlen(str)+1);
545*77b80299SAndroid Build Coastguard Worker }
writeString16(const std::unique_ptr<String16> & str)546*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeString16(const std::unique_ptr<String16>& str)
547*77b80299SAndroid Build Coastguard Worker {
548*77b80299SAndroid Build Coastguard Worker if (!str) {
549*77b80299SAndroid Build Coastguard Worker return writeInt32(-1);
550*77b80299SAndroid Build Coastguard Worker }
551*77b80299SAndroid Build Coastguard Worker
552*77b80299SAndroid Build Coastguard Worker return writeString16(*str);
553*77b80299SAndroid Build Coastguard Worker }
554*77b80299SAndroid Build Coastguard Worker
writeString16(const String16 & str)555*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeString16(const String16& str)
556*77b80299SAndroid Build Coastguard Worker {
557*77b80299SAndroid Build Coastguard Worker return writeString16(str.c_str(), str.size());
558*77b80299SAndroid Build Coastguard Worker }
559*77b80299SAndroid Build Coastguard Worker
writeString16(const char16_t * str,size_t len)560*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeString16(const char16_t* str, size_t len)
561*77b80299SAndroid Build Coastguard Worker {
562*77b80299SAndroid Build Coastguard Worker if (str == nullptr) return writeInt32(-1);
563*77b80299SAndroid Build Coastguard Worker
564*77b80299SAndroid Build Coastguard Worker status_t err = writeInt32(len);
565*77b80299SAndroid Build Coastguard Worker if (err == NO_ERROR) {
566*77b80299SAndroid Build Coastguard Worker len *= sizeof(char16_t);
567*77b80299SAndroid Build Coastguard Worker uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
568*77b80299SAndroid Build Coastguard Worker if (data) {
569*77b80299SAndroid Build Coastguard Worker memcpy(data, str, len);
570*77b80299SAndroid Build Coastguard Worker *reinterpret_cast<char16_t*>(data+len) = 0;
571*77b80299SAndroid Build Coastguard Worker return NO_ERROR;
572*77b80299SAndroid Build Coastguard Worker }
573*77b80299SAndroid Build Coastguard Worker err = mError;
574*77b80299SAndroid Build Coastguard Worker }
575*77b80299SAndroid Build Coastguard Worker return err;
576*77b80299SAndroid Build Coastguard Worker }
writeStrongBinder(const sp<IBinder> & val)577*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
578*77b80299SAndroid Build Coastguard Worker {
579*77b80299SAndroid Build Coastguard Worker return flatten_binder(ProcessState::self(), val, this);
580*77b80299SAndroid Build Coastguard Worker }
581*77b80299SAndroid Build Coastguard Worker
582*77b80299SAndroid Build Coastguard Worker template <typename T>
writeObject(const T & val)583*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeObject(const T& val)
584*77b80299SAndroid Build Coastguard Worker {
585*77b80299SAndroid Build Coastguard Worker const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
586*77b80299SAndroid Build Coastguard Worker const bool enoughObjects = mObjectsSize < mObjectsCapacity;
587*77b80299SAndroid Build Coastguard Worker if (enoughData && enoughObjects) {
588*77b80299SAndroid Build Coastguard Worker restart_write:
589*77b80299SAndroid Build Coastguard Worker *reinterpret_cast<T*>(mData+mDataPos) = val;
590*77b80299SAndroid Build Coastguard Worker
591*77b80299SAndroid Build Coastguard Worker const binder_object_header* hdr = reinterpret_cast<binder_object_header*>(mData+mDataPos);
592*77b80299SAndroid Build Coastguard Worker switch (hdr->type) {
593*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_BINDER:
594*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_WEAK_BINDER:
595*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_HANDLE:
596*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_WEAK_HANDLE: {
597*77b80299SAndroid Build Coastguard Worker const flat_binder_object *fbo = reinterpret_cast<const flat_binder_object*>(hdr);
598*77b80299SAndroid Build Coastguard Worker if (fbo->binder != 0) {
599*77b80299SAndroid Build Coastguard Worker mObjects[mObjectsSize++] = mDataPos;
600*77b80299SAndroid Build Coastguard Worker acquire_binder_object(ProcessState::self(), *fbo, this);
601*77b80299SAndroid Build Coastguard Worker }
602*77b80299SAndroid Build Coastguard Worker break;
603*77b80299SAndroid Build Coastguard Worker }
604*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_FD: {
605*77b80299SAndroid Build Coastguard Worker // remember if it's a file descriptor
606*77b80299SAndroid Build Coastguard Worker if (!mAllowFds) {
607*77b80299SAndroid Build Coastguard Worker // fail before modifying our object index
608*77b80299SAndroid Build Coastguard Worker return FDS_NOT_ALLOWED;
609*77b80299SAndroid Build Coastguard Worker }
610*77b80299SAndroid Build Coastguard Worker mHasFds = mFdsKnown = true;
611*77b80299SAndroid Build Coastguard Worker mObjects[mObjectsSize++] = mDataPos;
612*77b80299SAndroid Build Coastguard Worker break;
613*77b80299SAndroid Build Coastguard Worker }
614*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_FDA:
615*77b80299SAndroid Build Coastguard Worker mObjects[mObjectsSize++] = mDataPos;
616*77b80299SAndroid Build Coastguard Worker break;
617*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_PTR: {
618*77b80299SAndroid Build Coastguard Worker const binder_buffer_object *buffer_obj = reinterpret_cast<
619*77b80299SAndroid Build Coastguard Worker const binder_buffer_object*>(hdr);
620*77b80299SAndroid Build Coastguard Worker if ((void *)buffer_obj->buffer != nullptr) {
621*77b80299SAndroid Build Coastguard Worker mObjects[mObjectsSize++] = mDataPos;
622*77b80299SAndroid Build Coastguard Worker }
623*77b80299SAndroid Build Coastguard Worker break;
624*77b80299SAndroid Build Coastguard Worker }
625*77b80299SAndroid Build Coastguard Worker default: {
626*77b80299SAndroid Build Coastguard Worker ALOGE("writeObject: unknown type %d", hdr->type);
627*77b80299SAndroid Build Coastguard Worker break;
628*77b80299SAndroid Build Coastguard Worker }
629*77b80299SAndroid Build Coastguard Worker }
630*77b80299SAndroid Build Coastguard Worker return finishWrite(sizeof(val));
631*77b80299SAndroid Build Coastguard Worker }
632*77b80299SAndroid Build Coastguard Worker
633*77b80299SAndroid Build Coastguard Worker if (!enoughData) {
634*77b80299SAndroid Build Coastguard Worker const status_t err = growData(sizeof(val));
635*77b80299SAndroid Build Coastguard Worker if (err != NO_ERROR) return err;
636*77b80299SAndroid Build Coastguard Worker }
637*77b80299SAndroid Build Coastguard Worker if (!enoughObjects) {
638*77b80299SAndroid Build Coastguard Worker if (mObjectsSize > SIZE_MAX - 2) return NO_MEMORY; // overflow
639*77b80299SAndroid Build Coastguard Worker if (mObjectsSize + 2 > SIZE_MAX / 3) return NO_MEMORY; // overflow
640*77b80299SAndroid Build Coastguard Worker size_t newSize = ((mObjectsSize+2)*3)/2;
641*77b80299SAndroid Build Coastguard Worker if (newSize > SIZE_MAX / sizeof(binder_size_t)) return NO_MEMORY; // overflow
642*77b80299SAndroid Build Coastguard Worker binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
643*77b80299SAndroid Build Coastguard Worker if (objects == nullptr) return NO_MEMORY;
644*77b80299SAndroid Build Coastguard Worker mObjects = objects;
645*77b80299SAndroid Build Coastguard Worker mObjectsCapacity = newSize;
646*77b80299SAndroid Build Coastguard Worker }
647*77b80299SAndroid Build Coastguard Worker
648*77b80299SAndroid Build Coastguard Worker goto restart_write;
649*77b80299SAndroid Build Coastguard Worker }
650*77b80299SAndroid Build Coastguard Worker
651*77b80299SAndroid Build Coastguard Worker template status_t Parcel::writeObject<flat_binder_object>(const flat_binder_object& val);
652*77b80299SAndroid Build Coastguard Worker template status_t Parcel::writeObject<binder_fd_object>(const binder_fd_object& val);
653*77b80299SAndroid Build Coastguard Worker template status_t Parcel::writeObject<binder_buffer_object>(const binder_buffer_object& val);
654*77b80299SAndroid Build Coastguard Worker template status_t Parcel::writeObject<binder_fd_array_object>(const binder_fd_array_object& val);
655*77b80299SAndroid Build Coastguard Worker
validateBufferChild(size_t child_buffer_handle,size_t child_offset) const656*77b80299SAndroid Build Coastguard Worker bool Parcel::validateBufferChild(size_t child_buffer_handle,
657*77b80299SAndroid Build Coastguard Worker size_t child_offset) const {
658*77b80299SAndroid Build Coastguard Worker if (child_buffer_handle >= mObjectsSize)
659*77b80299SAndroid Build Coastguard Worker return false;
660*77b80299SAndroid Build Coastguard Worker binder_buffer_object *child = reinterpret_cast<binder_buffer_object*>
661*77b80299SAndroid Build Coastguard Worker (mData + mObjects[child_buffer_handle]);
662*77b80299SAndroid Build Coastguard Worker if (child->hdr.type != BINDER_TYPE_PTR || child_offset > child->length) {
663*77b80299SAndroid Build Coastguard Worker // Parent object not a buffer, or not large enough
664*77b80299SAndroid Build Coastguard Worker LOG_BUFFER("writeEmbeddedReference found weird child. "
665*77b80299SAndroid Build Coastguard Worker "child_offset = %zu, child->length = %zu",
666*77b80299SAndroid Build Coastguard Worker child_offset, (size_t)child->length);
667*77b80299SAndroid Build Coastguard Worker return false;
668*77b80299SAndroid Build Coastguard Worker }
669*77b80299SAndroid Build Coastguard Worker return true;
670*77b80299SAndroid Build Coastguard Worker }
671*77b80299SAndroid Build Coastguard Worker
validateBufferParent(size_t parent_buffer_handle,size_t parent_offset) const672*77b80299SAndroid Build Coastguard Worker bool Parcel::validateBufferParent(size_t parent_buffer_handle,
673*77b80299SAndroid Build Coastguard Worker size_t parent_offset) const {
674*77b80299SAndroid Build Coastguard Worker if (parent_buffer_handle >= mObjectsSize)
675*77b80299SAndroid Build Coastguard Worker return false;
676*77b80299SAndroid Build Coastguard Worker binder_buffer_object *parent = reinterpret_cast<binder_buffer_object*>
677*77b80299SAndroid Build Coastguard Worker (mData + mObjects[parent_buffer_handle]);
678*77b80299SAndroid Build Coastguard Worker if (parent->hdr.type != BINDER_TYPE_PTR ||
679*77b80299SAndroid Build Coastguard Worker sizeof(binder_uintptr_t) > parent->length ||
680*77b80299SAndroid Build Coastguard Worker parent_offset > parent->length - sizeof(binder_uintptr_t)) {
681*77b80299SAndroid Build Coastguard Worker // Parent object not a buffer, or not large enough
682*77b80299SAndroid Build Coastguard Worker return false;
683*77b80299SAndroid Build Coastguard Worker }
684*77b80299SAndroid Build Coastguard Worker return true;
685*77b80299SAndroid Build Coastguard Worker }
writeEmbeddedBuffer(const void * buffer,size_t length,size_t * handle,size_t parent_buffer_handle,size_t parent_offset)686*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeEmbeddedBuffer(
687*77b80299SAndroid Build Coastguard Worker const void *buffer, size_t length, size_t *handle,
688*77b80299SAndroid Build Coastguard Worker size_t parent_buffer_handle, size_t parent_offset) {
689*77b80299SAndroid Build Coastguard Worker LOG_BUFFER("writeEmbeddedBuffer(%p, %zu, parent = (%zu, %zu)) -> %zu",
690*77b80299SAndroid Build Coastguard Worker buffer, length, parent_buffer_handle,
691*77b80299SAndroid Build Coastguard Worker parent_offset, mObjectsSize);
692*77b80299SAndroid Build Coastguard Worker if(!validateBufferParent(parent_buffer_handle, parent_offset))
693*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
694*77b80299SAndroid Build Coastguard Worker binder_buffer_object obj = {
695*77b80299SAndroid Build Coastguard Worker .hdr = { .type = BINDER_TYPE_PTR },
696*77b80299SAndroid Build Coastguard Worker .flags = BINDER_BUFFER_FLAG_HAS_PARENT,
697*77b80299SAndroid Build Coastguard Worker .buffer = reinterpret_cast<binder_uintptr_t>(buffer),
698*77b80299SAndroid Build Coastguard Worker .length = length,
699*77b80299SAndroid Build Coastguard Worker .parent = parent_buffer_handle,
700*77b80299SAndroid Build Coastguard Worker .parent_offset = parent_offset,
701*77b80299SAndroid Build Coastguard Worker };
702*77b80299SAndroid Build Coastguard Worker if (handle != nullptr) {
703*77b80299SAndroid Build Coastguard Worker // We use an index into mObjects as a handle
704*77b80299SAndroid Build Coastguard Worker *handle = mObjectsSize;
705*77b80299SAndroid Build Coastguard Worker }
706*77b80299SAndroid Build Coastguard Worker return writeObject(obj);
707*77b80299SAndroid Build Coastguard Worker }
708*77b80299SAndroid Build Coastguard Worker
writeBuffer(const void * buffer,size_t length,size_t * handle)709*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeBuffer(const void *buffer, size_t length, size_t *handle)
710*77b80299SAndroid Build Coastguard Worker {
711*77b80299SAndroid Build Coastguard Worker LOG_BUFFER("writeBuffer(%p, %zu) -> %zu",
712*77b80299SAndroid Build Coastguard Worker buffer, length, mObjectsSize);
713*77b80299SAndroid Build Coastguard Worker binder_buffer_object obj {
714*77b80299SAndroid Build Coastguard Worker .hdr = { .type = BINDER_TYPE_PTR },
715*77b80299SAndroid Build Coastguard Worker .flags = 0,
716*77b80299SAndroid Build Coastguard Worker .buffer = reinterpret_cast<binder_uintptr_t>(buffer),
717*77b80299SAndroid Build Coastguard Worker .length = length,
718*77b80299SAndroid Build Coastguard Worker };
719*77b80299SAndroid Build Coastguard Worker if (handle != nullptr) {
720*77b80299SAndroid Build Coastguard Worker // We use an index into mObjects as a handle
721*77b80299SAndroid Build Coastguard Worker *handle = mObjectsSize;
722*77b80299SAndroid Build Coastguard Worker }
723*77b80299SAndroid Build Coastguard Worker return writeObject(obj);
724*77b80299SAndroid Build Coastguard Worker }
725*77b80299SAndroid Build Coastguard Worker
clearCache() const726*77b80299SAndroid Build Coastguard Worker void Parcel::clearCache() const {
727*77b80299SAndroid Build Coastguard Worker LOG_BUFFER("clearing cache.");
728*77b80299SAndroid Build Coastguard Worker mBufCachePos = 0;
729*77b80299SAndroid Build Coastguard Worker mBufCache.clear();
730*77b80299SAndroid Build Coastguard Worker }
731*77b80299SAndroid Build Coastguard Worker
updateCache() const732*77b80299SAndroid Build Coastguard Worker void Parcel::updateCache() const {
733*77b80299SAndroid Build Coastguard Worker if(mBufCachePos == mObjectsSize)
734*77b80299SAndroid Build Coastguard Worker return;
735*77b80299SAndroid Build Coastguard Worker LOG_BUFFER("updating cache from %zu to %zu", mBufCachePos, mObjectsSize);
736*77b80299SAndroid Build Coastguard Worker for(size_t i = mBufCachePos; i < mObjectsSize; i++) {
737*77b80299SAndroid Build Coastguard Worker binder_size_t dataPos = mObjects[i];
738*77b80299SAndroid Build Coastguard Worker binder_buffer_object *obj =
739*77b80299SAndroid Build Coastguard Worker reinterpret_cast<binder_buffer_object*>(mData+dataPos);
740*77b80299SAndroid Build Coastguard Worker if(obj->hdr.type != BINDER_TYPE_PTR)
741*77b80299SAndroid Build Coastguard Worker continue;
742*77b80299SAndroid Build Coastguard Worker BufferInfo ifo;
743*77b80299SAndroid Build Coastguard Worker ifo.index = i;
744*77b80299SAndroid Build Coastguard Worker ifo.buffer = obj->buffer;
745*77b80299SAndroid Build Coastguard Worker ifo.bufend = obj->buffer + obj->length;
746*77b80299SAndroid Build Coastguard Worker mBufCache.push_back(ifo);
747*77b80299SAndroid Build Coastguard Worker }
748*77b80299SAndroid Build Coastguard Worker mBufCachePos = mObjectsSize;
749*77b80299SAndroid Build Coastguard Worker }
750*77b80299SAndroid Build Coastguard Worker
751*77b80299SAndroid Build Coastguard Worker /* O(n) (n=#buffers) to find a buffer that contains the given addr */
findBuffer(const void * ptr,size_t length,bool * found,size_t * handle,size_t * offset) const752*77b80299SAndroid Build Coastguard Worker status_t Parcel::findBuffer(const void *ptr, size_t length, bool *found,
753*77b80299SAndroid Build Coastguard Worker size_t *handle, size_t *offset) const {
754*77b80299SAndroid Build Coastguard Worker if(found == nullptr)
755*77b80299SAndroid Build Coastguard Worker return UNKNOWN_ERROR;
756*77b80299SAndroid Build Coastguard Worker updateCache();
757*77b80299SAndroid Build Coastguard Worker binder_uintptr_t ptrVal = reinterpret_cast<binder_uintptr_t>(ptr);
758*77b80299SAndroid Build Coastguard Worker // true if the pointer is in some buffer, but the length is too big
759*77b80299SAndroid Build Coastguard Worker // so that ptr + length doesn't fit into the buffer.
760*77b80299SAndroid Build Coastguard Worker bool suspectRejectBadPointer = false;
761*77b80299SAndroid Build Coastguard Worker LOG_BUFFER("findBuffer examining %zu objects.", mObjectsSize);
762*77b80299SAndroid Build Coastguard Worker for(auto entry = mBufCache.rbegin(); entry != mBufCache.rend(); ++entry ) {
763*77b80299SAndroid Build Coastguard Worker if(entry->buffer <= ptrVal && ptrVal < entry->bufend) {
764*77b80299SAndroid Build Coastguard Worker // might have found it.
765*77b80299SAndroid Build Coastguard Worker if(ptrVal + length <= entry->bufend) {
766*77b80299SAndroid Build Coastguard Worker *found = true;
767*77b80299SAndroid Build Coastguard Worker if(handle != nullptr) *handle = entry->index;
768*77b80299SAndroid Build Coastguard Worker if(offset != nullptr) *offset = ptrVal - entry->buffer;
769*77b80299SAndroid Build Coastguard Worker LOG_BUFFER(" findBuffer has a match at %zu!", entry->index);
770*77b80299SAndroid Build Coastguard Worker return OK;
771*77b80299SAndroid Build Coastguard Worker } else {
772*77b80299SAndroid Build Coastguard Worker suspectRejectBadPointer = true;
773*77b80299SAndroid Build Coastguard Worker }
774*77b80299SAndroid Build Coastguard Worker }
775*77b80299SAndroid Build Coastguard Worker }
776*77b80299SAndroid Build Coastguard Worker LOG_BUFFER("findBuffer did not find for ptr = %p.", ptr);
777*77b80299SAndroid Build Coastguard Worker *found = false;
778*77b80299SAndroid Build Coastguard Worker return suspectRejectBadPointer ? BAD_VALUE : OK;
779*77b80299SAndroid Build Coastguard Worker }
780*77b80299SAndroid Build Coastguard Worker
781*77b80299SAndroid Build Coastguard Worker /* findBuffer with the assumption that ptr = .buffer (so it points to top
782*77b80299SAndroid Build Coastguard Worker * of the buffer, aka offset 0).
783*77b80299SAndroid Build Coastguard Worker * */
quickFindBuffer(const void * ptr,size_t * handle) const784*77b80299SAndroid Build Coastguard Worker status_t Parcel::quickFindBuffer(const void *ptr, size_t *handle) const {
785*77b80299SAndroid Build Coastguard Worker updateCache();
786*77b80299SAndroid Build Coastguard Worker binder_uintptr_t ptrVal = reinterpret_cast<binder_uintptr_t>(ptr);
787*77b80299SAndroid Build Coastguard Worker LOG_BUFFER("quickFindBuffer examining %zu objects.", mObjectsSize);
788*77b80299SAndroid Build Coastguard Worker for(auto entry = mBufCache.rbegin(); entry != mBufCache.rend(); ++entry ) {
789*77b80299SAndroid Build Coastguard Worker if(entry->buffer == ptrVal) {
790*77b80299SAndroid Build Coastguard Worker if(handle != nullptr) *handle = entry->index;
791*77b80299SAndroid Build Coastguard Worker return OK;
792*77b80299SAndroid Build Coastguard Worker }
793*77b80299SAndroid Build Coastguard Worker }
794*77b80299SAndroid Build Coastguard Worker LOG_BUFFER("quickFindBuffer did not find for ptr = %p.", ptr);
795*77b80299SAndroid Build Coastguard Worker return NO_INIT;
796*77b80299SAndroid Build Coastguard Worker }
797*77b80299SAndroid Build Coastguard Worker
writeNativeHandleNoDup(const native_handle_t * handle,bool embedded,size_t parent_buffer_handle,size_t parent_offset)798*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeNativeHandleNoDup(const native_handle_t *handle,
799*77b80299SAndroid Build Coastguard Worker bool embedded,
800*77b80299SAndroid Build Coastguard Worker size_t parent_buffer_handle,
801*77b80299SAndroid Build Coastguard Worker size_t parent_offset)
802*77b80299SAndroid Build Coastguard Worker {
803*77b80299SAndroid Build Coastguard Worker size_t buffer_handle;
804*77b80299SAndroid Build Coastguard Worker status_t status = OK;
805*77b80299SAndroid Build Coastguard Worker
806*77b80299SAndroid Build Coastguard Worker if (handle == nullptr) {
807*77b80299SAndroid Build Coastguard Worker status = writeUint64(0);
808*77b80299SAndroid Build Coastguard Worker return status;
809*77b80299SAndroid Build Coastguard Worker }
810*77b80299SAndroid Build Coastguard Worker
811*77b80299SAndroid Build Coastguard Worker size_t native_handle_size = sizeof(native_handle_t)
812*77b80299SAndroid Build Coastguard Worker + handle->numFds * sizeof(int) + handle->numInts * sizeof(int);
813*77b80299SAndroid Build Coastguard Worker writeUint64(native_handle_size);
814*77b80299SAndroid Build Coastguard Worker
815*77b80299SAndroid Build Coastguard Worker if (embedded) {
816*77b80299SAndroid Build Coastguard Worker status = writeEmbeddedBuffer((void*) handle,
817*77b80299SAndroid Build Coastguard Worker native_handle_size, &buffer_handle,
818*77b80299SAndroid Build Coastguard Worker parent_buffer_handle, parent_offset);
819*77b80299SAndroid Build Coastguard Worker } else {
820*77b80299SAndroid Build Coastguard Worker status = writeBuffer((void*) handle, native_handle_size, &buffer_handle);
821*77b80299SAndroid Build Coastguard Worker }
822*77b80299SAndroid Build Coastguard Worker
823*77b80299SAndroid Build Coastguard Worker if (status != OK) {
824*77b80299SAndroid Build Coastguard Worker return status;
825*77b80299SAndroid Build Coastguard Worker }
826*77b80299SAndroid Build Coastguard Worker
827*77b80299SAndroid Build Coastguard Worker struct binder_fd_array_object fd_array {
828*77b80299SAndroid Build Coastguard Worker .hdr = { .type = BINDER_TYPE_FDA },
829*77b80299SAndroid Build Coastguard Worker .num_fds = static_cast<binder_size_t>(handle->numFds),
830*77b80299SAndroid Build Coastguard Worker .parent = buffer_handle,
831*77b80299SAndroid Build Coastguard Worker .parent_offset = offsetof(native_handle_t, data),
832*77b80299SAndroid Build Coastguard Worker };
833*77b80299SAndroid Build Coastguard Worker
834*77b80299SAndroid Build Coastguard Worker return writeObject(fd_array);
835*77b80299SAndroid Build Coastguard Worker }
836*77b80299SAndroid Build Coastguard Worker
writeNativeHandleNoDup(const native_handle_t * handle)837*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeNativeHandleNoDup(const native_handle_t *handle)
838*77b80299SAndroid Build Coastguard Worker {
839*77b80299SAndroid Build Coastguard Worker return writeNativeHandleNoDup(handle, false /* embedded */);
840*77b80299SAndroid Build Coastguard Worker }
841*77b80299SAndroid Build Coastguard Worker
writeEmbeddedNativeHandle(const native_handle_t * handle,size_t parent_buffer_handle,size_t parent_offset)842*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeEmbeddedNativeHandle(const native_handle_t *handle,
843*77b80299SAndroid Build Coastguard Worker size_t parent_buffer_handle,
844*77b80299SAndroid Build Coastguard Worker size_t parent_offset)
845*77b80299SAndroid Build Coastguard Worker {
846*77b80299SAndroid Build Coastguard Worker return writeNativeHandleNoDup(handle, true /* embedded */,
847*77b80299SAndroid Build Coastguard Worker parent_buffer_handle, parent_offset);
848*77b80299SAndroid Build Coastguard Worker }
849*77b80299SAndroid Build Coastguard Worker
read(void * outData,size_t len) const850*77b80299SAndroid Build Coastguard Worker status_t Parcel::read(void* outData, size_t len) const
851*77b80299SAndroid Build Coastguard Worker {
852*77b80299SAndroid Build Coastguard Worker if (len > INT32_MAX) {
853*77b80299SAndroid Build Coastguard Worker // don't accept size_t values which may have come from an
854*77b80299SAndroid Build Coastguard Worker // inadvertent conversion from a negative int.
855*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
856*77b80299SAndroid Build Coastguard Worker }
857*77b80299SAndroid Build Coastguard Worker
858*77b80299SAndroid Build Coastguard Worker if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
859*77b80299SAndroid Build Coastguard Worker && len <= pad_size(len)) {
860*77b80299SAndroid Build Coastguard Worker memcpy(outData, mData+mDataPos, len);
861*77b80299SAndroid Build Coastguard Worker mDataPos += pad_size(len);
862*77b80299SAndroid Build Coastguard Worker ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
863*77b80299SAndroid Build Coastguard Worker return NO_ERROR;
864*77b80299SAndroid Build Coastguard Worker }
865*77b80299SAndroid Build Coastguard Worker return NOT_ENOUGH_DATA;
866*77b80299SAndroid Build Coastguard Worker }
867*77b80299SAndroid Build Coastguard Worker
readInplace(size_t len) const868*77b80299SAndroid Build Coastguard Worker const void* Parcel::readInplace(size_t len) const
869*77b80299SAndroid Build Coastguard Worker {
870*77b80299SAndroid Build Coastguard Worker if (len > INT32_MAX) {
871*77b80299SAndroid Build Coastguard Worker // don't accept size_t values which may have come from an
872*77b80299SAndroid Build Coastguard Worker // inadvertent conversion from a negative int.
873*77b80299SAndroid Build Coastguard Worker return nullptr;
874*77b80299SAndroid Build Coastguard Worker }
875*77b80299SAndroid Build Coastguard Worker
876*77b80299SAndroid Build Coastguard Worker if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize
877*77b80299SAndroid Build Coastguard Worker && len <= pad_size(len)) {
878*77b80299SAndroid Build Coastguard Worker const void* data = mData+mDataPos;
879*77b80299SAndroid Build Coastguard Worker mDataPos += pad_size(len);
880*77b80299SAndroid Build Coastguard Worker ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
881*77b80299SAndroid Build Coastguard Worker return data;
882*77b80299SAndroid Build Coastguard Worker }
883*77b80299SAndroid Build Coastguard Worker return nullptr;
884*77b80299SAndroid Build Coastguard Worker }
885*77b80299SAndroid Build Coastguard Worker
886*77b80299SAndroid Build Coastguard Worker template<class T>
readAligned(T * pArg) const887*77b80299SAndroid Build Coastguard Worker status_t Parcel::readAligned(T *pArg) const {
888*77b80299SAndroid Build Coastguard Worker static_assert(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
889*77b80299SAndroid Build Coastguard Worker
890*77b80299SAndroid Build Coastguard Worker if ((mDataPos+sizeof(T)) <= mDataSize) {
891*77b80299SAndroid Build Coastguard Worker const void* data = mData+mDataPos;
892*77b80299SAndroid Build Coastguard Worker mDataPos += sizeof(T);
893*77b80299SAndroid Build Coastguard Worker *pArg = *reinterpret_cast<const T*>(data);
894*77b80299SAndroid Build Coastguard Worker return NO_ERROR;
895*77b80299SAndroid Build Coastguard Worker } else {
896*77b80299SAndroid Build Coastguard Worker return NOT_ENOUGH_DATA;
897*77b80299SAndroid Build Coastguard Worker }
898*77b80299SAndroid Build Coastguard Worker }
899*77b80299SAndroid Build Coastguard Worker
900*77b80299SAndroid Build Coastguard Worker template<class T>
readAligned() const901*77b80299SAndroid Build Coastguard Worker T Parcel::readAligned() const {
902*77b80299SAndroid Build Coastguard Worker T result;
903*77b80299SAndroid Build Coastguard Worker if (readAligned(&result) != NO_ERROR) {
904*77b80299SAndroid Build Coastguard Worker result = 0;
905*77b80299SAndroid Build Coastguard Worker }
906*77b80299SAndroid Build Coastguard Worker
907*77b80299SAndroid Build Coastguard Worker return result;
908*77b80299SAndroid Build Coastguard Worker }
909*77b80299SAndroid Build Coastguard Worker
910*77b80299SAndroid Build Coastguard Worker template<class T>
writeAligned(T val)911*77b80299SAndroid Build Coastguard Worker status_t Parcel::writeAligned(T val) {
912*77b80299SAndroid Build Coastguard Worker static_assert(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
913*77b80299SAndroid Build Coastguard Worker
914*77b80299SAndroid Build Coastguard Worker if ((mDataPos+sizeof(val)) <= mDataCapacity) {
915*77b80299SAndroid Build Coastguard Worker restart_write:
916*77b80299SAndroid Build Coastguard Worker *reinterpret_cast<T*>(mData+mDataPos) = val;
917*77b80299SAndroid Build Coastguard Worker return finishWrite(sizeof(val));
918*77b80299SAndroid Build Coastguard Worker }
919*77b80299SAndroid Build Coastguard Worker
920*77b80299SAndroid Build Coastguard Worker status_t err = growData(sizeof(val));
921*77b80299SAndroid Build Coastguard Worker if (err == NO_ERROR) goto restart_write;
922*77b80299SAndroid Build Coastguard Worker return err;
923*77b80299SAndroid Build Coastguard Worker }
924*77b80299SAndroid Build Coastguard Worker
readInt8(int8_t * pArg) const925*77b80299SAndroid Build Coastguard Worker status_t Parcel::readInt8(int8_t *pArg) const
926*77b80299SAndroid Build Coastguard Worker {
927*77b80299SAndroid Build Coastguard Worker return read(pArg, sizeof(*pArg));
928*77b80299SAndroid Build Coastguard Worker }
929*77b80299SAndroid Build Coastguard Worker
readUint8(uint8_t * pArg) const930*77b80299SAndroid Build Coastguard Worker status_t Parcel::readUint8(uint8_t *pArg) const
931*77b80299SAndroid Build Coastguard Worker {
932*77b80299SAndroid Build Coastguard Worker return read(pArg, sizeof(*pArg));
933*77b80299SAndroid Build Coastguard Worker }
934*77b80299SAndroid Build Coastguard Worker
readInt16(int16_t * pArg) const935*77b80299SAndroid Build Coastguard Worker status_t Parcel::readInt16(int16_t *pArg) const
936*77b80299SAndroid Build Coastguard Worker {
937*77b80299SAndroid Build Coastguard Worker return read(pArg, sizeof(*pArg));
938*77b80299SAndroid Build Coastguard Worker }
939*77b80299SAndroid Build Coastguard Worker
readUint16(uint16_t * pArg) const940*77b80299SAndroid Build Coastguard Worker status_t Parcel::readUint16(uint16_t *pArg) const
941*77b80299SAndroid Build Coastguard Worker {
942*77b80299SAndroid Build Coastguard Worker return read(pArg, sizeof(*pArg));
943*77b80299SAndroid Build Coastguard Worker }
944*77b80299SAndroid Build Coastguard Worker
readInt32(int32_t * pArg) const945*77b80299SAndroid Build Coastguard Worker status_t Parcel::readInt32(int32_t *pArg) const
946*77b80299SAndroid Build Coastguard Worker {
947*77b80299SAndroid Build Coastguard Worker return readAligned(pArg);
948*77b80299SAndroid Build Coastguard Worker }
949*77b80299SAndroid Build Coastguard Worker
readInt32() const950*77b80299SAndroid Build Coastguard Worker int32_t Parcel::readInt32() const
951*77b80299SAndroid Build Coastguard Worker {
952*77b80299SAndroid Build Coastguard Worker return readAligned<int32_t>();
953*77b80299SAndroid Build Coastguard Worker }
954*77b80299SAndroid Build Coastguard Worker
readUint32(uint32_t * pArg) const955*77b80299SAndroid Build Coastguard Worker status_t Parcel::readUint32(uint32_t *pArg) const
956*77b80299SAndroid Build Coastguard Worker {
957*77b80299SAndroid Build Coastguard Worker return readAligned(pArg);
958*77b80299SAndroid Build Coastguard Worker }
959*77b80299SAndroid Build Coastguard Worker
readUint32() const960*77b80299SAndroid Build Coastguard Worker uint32_t Parcel::readUint32() const
961*77b80299SAndroid Build Coastguard Worker {
962*77b80299SAndroid Build Coastguard Worker return readAligned<uint32_t>();
963*77b80299SAndroid Build Coastguard Worker }
964*77b80299SAndroid Build Coastguard Worker
readInt64(int64_t * pArg) const965*77b80299SAndroid Build Coastguard Worker status_t Parcel::readInt64(int64_t *pArg) const
966*77b80299SAndroid Build Coastguard Worker {
967*77b80299SAndroid Build Coastguard Worker return readAligned(pArg);
968*77b80299SAndroid Build Coastguard Worker }
969*77b80299SAndroid Build Coastguard Worker
readInt64() const970*77b80299SAndroid Build Coastguard Worker int64_t Parcel::readInt64() const
971*77b80299SAndroid Build Coastguard Worker {
972*77b80299SAndroid Build Coastguard Worker return readAligned<int64_t>();
973*77b80299SAndroid Build Coastguard Worker }
974*77b80299SAndroid Build Coastguard Worker
readUint64(uint64_t * pArg) const975*77b80299SAndroid Build Coastguard Worker status_t Parcel::readUint64(uint64_t *pArg) const
976*77b80299SAndroid Build Coastguard Worker {
977*77b80299SAndroid Build Coastguard Worker return readAligned(pArg);
978*77b80299SAndroid Build Coastguard Worker }
979*77b80299SAndroid Build Coastguard Worker
readUint64() const980*77b80299SAndroid Build Coastguard Worker uint64_t Parcel::readUint64() const
981*77b80299SAndroid Build Coastguard Worker {
982*77b80299SAndroid Build Coastguard Worker return readAligned<uint64_t>();
983*77b80299SAndroid Build Coastguard Worker }
984*77b80299SAndroid Build Coastguard Worker
readPointer(uintptr_t * pArg) const985*77b80299SAndroid Build Coastguard Worker status_t Parcel::readPointer(uintptr_t *pArg) const
986*77b80299SAndroid Build Coastguard Worker {
987*77b80299SAndroid Build Coastguard Worker status_t ret;
988*77b80299SAndroid Build Coastguard Worker binder_uintptr_t ptr;
989*77b80299SAndroid Build Coastguard Worker ret = readAligned(&ptr);
990*77b80299SAndroid Build Coastguard Worker if (!ret)
991*77b80299SAndroid Build Coastguard Worker *pArg = ptr;
992*77b80299SAndroid Build Coastguard Worker return ret;
993*77b80299SAndroid Build Coastguard Worker }
994*77b80299SAndroid Build Coastguard Worker
readPointer() const995*77b80299SAndroid Build Coastguard Worker uintptr_t Parcel::readPointer() const
996*77b80299SAndroid Build Coastguard Worker {
997*77b80299SAndroid Build Coastguard Worker return readAligned<binder_uintptr_t>();
998*77b80299SAndroid Build Coastguard Worker }
999*77b80299SAndroid Build Coastguard Worker
1000*77b80299SAndroid Build Coastguard Worker
readFloat(float * pArg) const1001*77b80299SAndroid Build Coastguard Worker status_t Parcel::readFloat(float *pArg) const
1002*77b80299SAndroid Build Coastguard Worker {
1003*77b80299SAndroid Build Coastguard Worker return readAligned(pArg);
1004*77b80299SAndroid Build Coastguard Worker }
1005*77b80299SAndroid Build Coastguard Worker
1006*77b80299SAndroid Build Coastguard Worker
readFloat() const1007*77b80299SAndroid Build Coastguard Worker float Parcel::readFloat() const
1008*77b80299SAndroid Build Coastguard Worker {
1009*77b80299SAndroid Build Coastguard Worker return readAligned<float>();
1010*77b80299SAndroid Build Coastguard Worker }
1011*77b80299SAndroid Build Coastguard Worker
1012*77b80299SAndroid Build Coastguard Worker #if defined(__mips__) && defined(__mips_hard_float)
1013*77b80299SAndroid Build Coastguard Worker
readDouble(double * pArg) const1014*77b80299SAndroid Build Coastguard Worker status_t Parcel::readDouble(double *pArg) const
1015*77b80299SAndroid Build Coastguard Worker {
1016*77b80299SAndroid Build Coastguard Worker union {
1017*77b80299SAndroid Build Coastguard Worker double d;
1018*77b80299SAndroid Build Coastguard Worker unsigned long long ll;
1019*77b80299SAndroid Build Coastguard Worker } u;
1020*77b80299SAndroid Build Coastguard Worker u.d = 0;
1021*77b80299SAndroid Build Coastguard Worker status_t status;
1022*77b80299SAndroid Build Coastguard Worker status = readAligned(&u.ll);
1023*77b80299SAndroid Build Coastguard Worker *pArg = u.d;
1024*77b80299SAndroid Build Coastguard Worker return status;
1025*77b80299SAndroid Build Coastguard Worker }
1026*77b80299SAndroid Build Coastguard Worker
readDouble() const1027*77b80299SAndroid Build Coastguard Worker double Parcel::readDouble() const
1028*77b80299SAndroid Build Coastguard Worker {
1029*77b80299SAndroid Build Coastguard Worker union {
1030*77b80299SAndroid Build Coastguard Worker double d;
1031*77b80299SAndroid Build Coastguard Worker unsigned long long ll;
1032*77b80299SAndroid Build Coastguard Worker } u;
1033*77b80299SAndroid Build Coastguard Worker u.ll = readAligned<unsigned long long>();
1034*77b80299SAndroid Build Coastguard Worker return u.d;
1035*77b80299SAndroid Build Coastguard Worker }
1036*77b80299SAndroid Build Coastguard Worker
1037*77b80299SAndroid Build Coastguard Worker #else
1038*77b80299SAndroid Build Coastguard Worker
readDouble(double * pArg) const1039*77b80299SAndroid Build Coastguard Worker status_t Parcel::readDouble(double *pArg) const
1040*77b80299SAndroid Build Coastguard Worker {
1041*77b80299SAndroid Build Coastguard Worker return readAligned(pArg);
1042*77b80299SAndroid Build Coastguard Worker }
1043*77b80299SAndroid Build Coastguard Worker
readDouble() const1044*77b80299SAndroid Build Coastguard Worker double Parcel::readDouble() const
1045*77b80299SAndroid Build Coastguard Worker {
1046*77b80299SAndroid Build Coastguard Worker return readAligned<double>();
1047*77b80299SAndroid Build Coastguard Worker }
1048*77b80299SAndroid Build Coastguard Worker
1049*77b80299SAndroid Build Coastguard Worker #endif
1050*77b80299SAndroid Build Coastguard Worker
readBool(bool * pArg) const1051*77b80299SAndroid Build Coastguard Worker status_t Parcel::readBool(bool *pArg) const
1052*77b80299SAndroid Build Coastguard Worker {
1053*77b80299SAndroid Build Coastguard Worker int8_t tmp;
1054*77b80299SAndroid Build Coastguard Worker status_t ret = readInt8(&tmp);
1055*77b80299SAndroid Build Coastguard Worker *pArg = (tmp != 0);
1056*77b80299SAndroid Build Coastguard Worker return ret;
1057*77b80299SAndroid Build Coastguard Worker }
1058*77b80299SAndroid Build Coastguard Worker
readBool() const1059*77b80299SAndroid Build Coastguard Worker bool Parcel::readBool() const
1060*77b80299SAndroid Build Coastguard Worker {
1061*77b80299SAndroid Build Coastguard Worker int8_t tmp;
1062*77b80299SAndroid Build Coastguard Worker status_t err = readInt8(&tmp);
1063*77b80299SAndroid Build Coastguard Worker
1064*77b80299SAndroid Build Coastguard Worker if (err != OK) {
1065*77b80299SAndroid Build Coastguard Worker return 0;
1066*77b80299SAndroid Build Coastguard Worker }
1067*77b80299SAndroid Build Coastguard Worker
1068*77b80299SAndroid Build Coastguard Worker return tmp != 0;
1069*77b80299SAndroid Build Coastguard Worker }
1070*77b80299SAndroid Build Coastguard Worker
readCString() const1071*77b80299SAndroid Build Coastguard Worker const char* Parcel::readCString() const
1072*77b80299SAndroid Build Coastguard Worker {
1073*77b80299SAndroid Build Coastguard Worker if (mDataPos < mDataSize) {
1074*77b80299SAndroid Build Coastguard Worker const size_t avail = mDataSize-mDataPos;
1075*77b80299SAndroid Build Coastguard Worker const char* str = reinterpret_cast<const char*>(mData+mDataPos);
1076*77b80299SAndroid Build Coastguard Worker // is the string's trailing NUL within the parcel's valid bounds?
1077*77b80299SAndroid Build Coastguard Worker const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
1078*77b80299SAndroid Build Coastguard Worker if (eos) {
1079*77b80299SAndroid Build Coastguard Worker const size_t len = eos - str;
1080*77b80299SAndroid Build Coastguard Worker mDataPos += pad_size(len+1);
1081*77b80299SAndroid Build Coastguard Worker ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos);
1082*77b80299SAndroid Build Coastguard Worker return str;
1083*77b80299SAndroid Build Coastguard Worker }
1084*77b80299SAndroid Build Coastguard Worker }
1085*77b80299SAndroid Build Coastguard Worker return nullptr;
1086*77b80299SAndroid Build Coastguard Worker }
readString16() const1087*77b80299SAndroid Build Coastguard Worker String16 Parcel::readString16() const
1088*77b80299SAndroid Build Coastguard Worker {
1089*77b80299SAndroid Build Coastguard Worker size_t len;
1090*77b80299SAndroid Build Coastguard Worker const char16_t* str = readString16Inplace(&len);
1091*77b80299SAndroid Build Coastguard Worker if (str) return String16(str, len);
1092*77b80299SAndroid Build Coastguard Worker ALOGE("Reading a NULL string not supported here.");
1093*77b80299SAndroid Build Coastguard Worker return String16();
1094*77b80299SAndroid Build Coastguard Worker }
1095*77b80299SAndroid Build Coastguard Worker
readString16(std::unique_ptr<String16> * pArg) const1096*77b80299SAndroid Build Coastguard Worker status_t Parcel::readString16(std::unique_ptr<String16>* pArg) const
1097*77b80299SAndroid Build Coastguard Worker {
1098*77b80299SAndroid Build Coastguard Worker const int32_t start = dataPosition();
1099*77b80299SAndroid Build Coastguard Worker int32_t size;
1100*77b80299SAndroid Build Coastguard Worker status_t status = readInt32(&size);
1101*77b80299SAndroid Build Coastguard Worker pArg->reset();
1102*77b80299SAndroid Build Coastguard Worker
1103*77b80299SAndroid Build Coastguard Worker if (status != OK || size < 0) {
1104*77b80299SAndroid Build Coastguard Worker return status;
1105*77b80299SAndroid Build Coastguard Worker }
1106*77b80299SAndroid Build Coastguard Worker
1107*77b80299SAndroid Build Coastguard Worker setDataPosition(start);
1108*77b80299SAndroid Build Coastguard Worker pArg->reset(new (std::nothrow) String16());
1109*77b80299SAndroid Build Coastguard Worker
1110*77b80299SAndroid Build Coastguard Worker status = readString16(pArg->get());
1111*77b80299SAndroid Build Coastguard Worker
1112*77b80299SAndroid Build Coastguard Worker if (status != OK) {
1113*77b80299SAndroid Build Coastguard Worker pArg->reset();
1114*77b80299SAndroid Build Coastguard Worker }
1115*77b80299SAndroid Build Coastguard Worker
1116*77b80299SAndroid Build Coastguard Worker return status;
1117*77b80299SAndroid Build Coastguard Worker }
1118*77b80299SAndroid Build Coastguard Worker
readString16(String16 * pArg) const1119*77b80299SAndroid Build Coastguard Worker status_t Parcel::readString16(String16* pArg) const
1120*77b80299SAndroid Build Coastguard Worker {
1121*77b80299SAndroid Build Coastguard Worker size_t len;
1122*77b80299SAndroid Build Coastguard Worker const char16_t* str = readString16Inplace(&len);
1123*77b80299SAndroid Build Coastguard Worker if (str) {
1124*77b80299SAndroid Build Coastguard Worker pArg->setTo(str, len);
1125*77b80299SAndroid Build Coastguard Worker return 0;
1126*77b80299SAndroid Build Coastguard Worker } else {
1127*77b80299SAndroid Build Coastguard Worker *pArg = String16();
1128*77b80299SAndroid Build Coastguard Worker return UNEXPECTED_NULL;
1129*77b80299SAndroid Build Coastguard Worker }
1130*77b80299SAndroid Build Coastguard Worker }
1131*77b80299SAndroid Build Coastguard Worker
readString16Inplace(size_t * outLen) const1132*77b80299SAndroid Build Coastguard Worker const char16_t* Parcel::readString16Inplace(size_t* outLen) const
1133*77b80299SAndroid Build Coastguard Worker {
1134*77b80299SAndroid Build Coastguard Worker int32_t size = readInt32();
1135*77b80299SAndroid Build Coastguard Worker // watch for potential int overflow from size+1
1136*77b80299SAndroid Build Coastguard Worker if (size >= 0 && size < INT32_MAX) {
1137*77b80299SAndroid Build Coastguard Worker *outLen = size;
1138*77b80299SAndroid Build Coastguard Worker const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
1139*77b80299SAndroid Build Coastguard Worker if (str != nullptr) {
1140*77b80299SAndroid Build Coastguard Worker return str;
1141*77b80299SAndroid Build Coastguard Worker }
1142*77b80299SAndroid Build Coastguard Worker }
1143*77b80299SAndroid Build Coastguard Worker *outLen = 0;
1144*77b80299SAndroid Build Coastguard Worker return nullptr;
1145*77b80299SAndroid Build Coastguard Worker }
readStrongBinder(sp<IBinder> * val) const1146*77b80299SAndroid Build Coastguard Worker status_t Parcel::readStrongBinder(sp<IBinder>* val) const
1147*77b80299SAndroid Build Coastguard Worker {
1148*77b80299SAndroid Build Coastguard Worker status_t status = readNullableStrongBinder(val);
1149*77b80299SAndroid Build Coastguard Worker if (status == OK && !val->get()) {
1150*77b80299SAndroid Build Coastguard Worker status = UNEXPECTED_NULL;
1151*77b80299SAndroid Build Coastguard Worker }
1152*77b80299SAndroid Build Coastguard Worker return status;
1153*77b80299SAndroid Build Coastguard Worker }
1154*77b80299SAndroid Build Coastguard Worker
readNullableStrongBinder(sp<IBinder> * val) const1155*77b80299SAndroid Build Coastguard Worker status_t Parcel::readNullableStrongBinder(sp<IBinder>* val) const
1156*77b80299SAndroid Build Coastguard Worker {
1157*77b80299SAndroid Build Coastguard Worker return unflatten_binder(ProcessState::self(), *this, val);
1158*77b80299SAndroid Build Coastguard Worker }
1159*77b80299SAndroid Build Coastguard Worker
readStrongBinder() const1160*77b80299SAndroid Build Coastguard Worker sp<IBinder> Parcel::readStrongBinder() const
1161*77b80299SAndroid Build Coastguard Worker {
1162*77b80299SAndroid Build Coastguard Worker sp<IBinder> val;
1163*77b80299SAndroid Build Coastguard Worker // Note that a lot of code in Android reads binders by hand with this
1164*77b80299SAndroid Build Coastguard Worker // method, and that code has historically been ok with getting nullptr
1165*77b80299SAndroid Build Coastguard Worker // back (while ignoring error codes).
1166*77b80299SAndroid Build Coastguard Worker readNullableStrongBinder(&val);
1167*77b80299SAndroid Build Coastguard Worker return val;
1168*77b80299SAndroid Build Coastguard Worker }
1169*77b80299SAndroid Build Coastguard Worker
1170*77b80299SAndroid Build Coastguard Worker template<typename T>
readObject(size_t * objects_offset) const1171*77b80299SAndroid Build Coastguard Worker const T* Parcel::readObject(size_t *objects_offset) const
1172*77b80299SAndroid Build Coastguard Worker {
1173*77b80299SAndroid Build Coastguard Worker const size_t DPOS = mDataPos;
1174*77b80299SAndroid Build Coastguard Worker if (objects_offset != nullptr) {
1175*77b80299SAndroid Build Coastguard Worker *objects_offset = 0;
1176*77b80299SAndroid Build Coastguard Worker }
1177*77b80299SAndroid Build Coastguard Worker
1178*77b80299SAndroid Build Coastguard Worker if ((DPOS+sizeof(T)) <= mDataSize) {
1179*77b80299SAndroid Build Coastguard Worker const T* obj = reinterpret_cast<const T*>(mData+DPOS);
1180*77b80299SAndroid Build Coastguard Worker mDataPos = DPOS + sizeof(T);
1181*77b80299SAndroid Build Coastguard Worker const binder_object_header *hdr = reinterpret_cast<const binder_object_header*>(obj);
1182*77b80299SAndroid Build Coastguard Worker switch (hdr->type) {
1183*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_BINDER:
1184*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_WEAK_BINDER:
1185*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_HANDLE:
1186*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_WEAK_HANDLE: {
1187*77b80299SAndroid Build Coastguard Worker const flat_binder_object *flat_obj =
1188*77b80299SAndroid Build Coastguard Worker reinterpret_cast<const flat_binder_object*>(hdr);
1189*77b80299SAndroid Build Coastguard Worker if (flat_obj->cookie == 0 && flat_obj->binder == 0) {
1190*77b80299SAndroid Build Coastguard Worker // When transferring a NULL binder object, we don't write it into
1191*77b80299SAndroid Build Coastguard Worker // the object list, so we don't want to check for it when
1192*77b80299SAndroid Build Coastguard Worker // reading.
1193*77b80299SAndroid Build Coastguard Worker ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
1194*77b80299SAndroid Build Coastguard Worker return obj;
1195*77b80299SAndroid Build Coastguard Worker }
1196*77b80299SAndroid Build Coastguard Worker break;
1197*77b80299SAndroid Build Coastguard Worker }
1198*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_FD:
1199*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_FDA:
1200*77b80299SAndroid Build Coastguard Worker // fd (-arrays) must always appear in the meta-data list (eg touched by the kernel)
1201*77b80299SAndroid Build Coastguard Worker break;
1202*77b80299SAndroid Build Coastguard Worker case BINDER_TYPE_PTR: {
1203*77b80299SAndroid Build Coastguard Worker const binder_buffer_object *buffer_obj =
1204*77b80299SAndroid Build Coastguard Worker reinterpret_cast<const binder_buffer_object*>(hdr);
1205*77b80299SAndroid Build Coastguard Worker if ((void *)buffer_obj->buffer == nullptr) {
1206*77b80299SAndroid Build Coastguard Worker // null pointers can be returned directly - they're not written in the
1207*77b80299SAndroid Build Coastguard Worker // object list. All non-null buffers must appear in the objects list.
1208*77b80299SAndroid Build Coastguard Worker return obj;
1209*77b80299SAndroid Build Coastguard Worker }
1210*77b80299SAndroid Build Coastguard Worker break;
1211*77b80299SAndroid Build Coastguard Worker }
1212*77b80299SAndroid Build Coastguard Worker }
1213*77b80299SAndroid Build Coastguard Worker // Ensure that this object is valid...
1214*77b80299SAndroid Build Coastguard Worker binder_size_t* const OBJS = mObjects;
1215*77b80299SAndroid Build Coastguard Worker const size_t N = mObjectsSize;
1216*77b80299SAndroid Build Coastguard Worker size_t opos = mNextObjectHint;
1217*77b80299SAndroid Build Coastguard Worker
1218*77b80299SAndroid Build Coastguard Worker if (N > 0) {
1219*77b80299SAndroid Build Coastguard Worker ALOGV("Parcel %p looking for obj at %zu, hint=%zu",
1220*77b80299SAndroid Build Coastguard Worker this, DPOS, opos);
1221*77b80299SAndroid Build Coastguard Worker
1222*77b80299SAndroid Build Coastguard Worker // Start at the current hint position, looking for an object at
1223*77b80299SAndroid Build Coastguard Worker // the current data position.
1224*77b80299SAndroid Build Coastguard Worker if (opos < N) {
1225*77b80299SAndroid Build Coastguard Worker while (opos < (N-1) && OBJS[opos] < DPOS) {
1226*77b80299SAndroid Build Coastguard Worker opos++;
1227*77b80299SAndroid Build Coastguard Worker }
1228*77b80299SAndroid Build Coastguard Worker } else {
1229*77b80299SAndroid Build Coastguard Worker opos = N-1;
1230*77b80299SAndroid Build Coastguard Worker }
1231*77b80299SAndroid Build Coastguard Worker if (OBJS[opos] == DPOS) {
1232*77b80299SAndroid Build Coastguard Worker // Found it!
1233*77b80299SAndroid Build Coastguard Worker ALOGV("Parcel %p found obj %zu at index %zu with forward search",
1234*77b80299SAndroid Build Coastguard Worker this, DPOS, opos);
1235*77b80299SAndroid Build Coastguard Worker mNextObjectHint = opos+1;
1236*77b80299SAndroid Build Coastguard Worker ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
1237*77b80299SAndroid Build Coastguard Worker if (objects_offset != nullptr) {
1238*77b80299SAndroid Build Coastguard Worker *objects_offset = opos;
1239*77b80299SAndroid Build Coastguard Worker }
1240*77b80299SAndroid Build Coastguard Worker return obj;
1241*77b80299SAndroid Build Coastguard Worker }
1242*77b80299SAndroid Build Coastguard Worker
1243*77b80299SAndroid Build Coastguard Worker // Look backwards for it...
1244*77b80299SAndroid Build Coastguard Worker while (opos > 0 && OBJS[opos] > DPOS) {
1245*77b80299SAndroid Build Coastguard Worker opos--;
1246*77b80299SAndroid Build Coastguard Worker }
1247*77b80299SAndroid Build Coastguard Worker if (OBJS[opos] == DPOS) {
1248*77b80299SAndroid Build Coastguard Worker // Found it!
1249*77b80299SAndroid Build Coastguard Worker ALOGV("Parcel %p found obj %zu at index %zu with backward search",
1250*77b80299SAndroid Build Coastguard Worker this, DPOS, opos);
1251*77b80299SAndroid Build Coastguard Worker mNextObjectHint = opos+1;
1252*77b80299SAndroid Build Coastguard Worker ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
1253*77b80299SAndroid Build Coastguard Worker if (objects_offset != nullptr) {
1254*77b80299SAndroid Build Coastguard Worker *objects_offset = opos;
1255*77b80299SAndroid Build Coastguard Worker }
1256*77b80299SAndroid Build Coastguard Worker return obj;
1257*77b80299SAndroid Build Coastguard Worker }
1258*77b80299SAndroid Build Coastguard Worker }
1259*77b80299SAndroid Build Coastguard Worker ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object list",
1260*77b80299SAndroid Build Coastguard Worker this, DPOS);
1261*77b80299SAndroid Build Coastguard Worker }
1262*77b80299SAndroid Build Coastguard Worker return nullptr;
1263*77b80299SAndroid Build Coastguard Worker }
1264*77b80299SAndroid Build Coastguard Worker
1265*77b80299SAndroid Build Coastguard Worker template const flat_binder_object* Parcel::readObject<flat_binder_object>(size_t *objects_offset) const;
1266*77b80299SAndroid Build Coastguard Worker
1267*77b80299SAndroid Build Coastguard Worker template const binder_fd_object* Parcel::readObject<binder_fd_object>(size_t *objects_offset) const;
1268*77b80299SAndroid Build Coastguard Worker
1269*77b80299SAndroid Build Coastguard Worker template const binder_buffer_object* Parcel::readObject<binder_buffer_object>(size_t *objects_offset) const;
1270*77b80299SAndroid Build Coastguard Worker
1271*77b80299SAndroid Build Coastguard Worker template const binder_fd_array_object* Parcel::readObject<binder_fd_array_object>(size_t *objects_offset) const;
1272*77b80299SAndroid Build Coastguard Worker
verifyBufferObject(const binder_buffer_object * buffer_obj,size_t size,uint32_t flags,size_t parent,size_t parentOffset) const1273*77b80299SAndroid Build Coastguard Worker bool Parcel::verifyBufferObject(const binder_buffer_object *buffer_obj,
1274*77b80299SAndroid Build Coastguard Worker size_t size, uint32_t flags, size_t parent,
1275*77b80299SAndroid Build Coastguard Worker size_t parentOffset) const {
1276*77b80299SAndroid Build Coastguard Worker if (buffer_obj->length != size) {
1277*77b80299SAndroid Build Coastguard Worker ALOGE("Buffer length %" PRIu64 " does not match expected size %zu.",
1278*77b80299SAndroid Build Coastguard Worker static_cast<uint64_t>(buffer_obj->length), size);
1279*77b80299SAndroid Build Coastguard Worker return false;
1280*77b80299SAndroid Build Coastguard Worker }
1281*77b80299SAndroid Build Coastguard Worker
1282*77b80299SAndroid Build Coastguard Worker if (buffer_obj->flags != flags) {
1283*77b80299SAndroid Build Coastguard Worker ALOGE("Buffer flags 0x%02X do not match expected flags 0x%02X.", buffer_obj->flags, flags);
1284*77b80299SAndroid Build Coastguard Worker return false;
1285*77b80299SAndroid Build Coastguard Worker }
1286*77b80299SAndroid Build Coastguard Worker
1287*77b80299SAndroid Build Coastguard Worker if (flags & BINDER_BUFFER_FLAG_HAS_PARENT) {
1288*77b80299SAndroid Build Coastguard Worker if (buffer_obj->parent != parent) {
1289*77b80299SAndroid Build Coastguard Worker ALOGE("Buffer parent %" PRIu64 " does not match expected parent %zu.",
1290*77b80299SAndroid Build Coastguard Worker static_cast<uint64_t>(buffer_obj->parent), parent);
1291*77b80299SAndroid Build Coastguard Worker return false;
1292*77b80299SAndroid Build Coastguard Worker }
1293*77b80299SAndroid Build Coastguard Worker if (buffer_obj->parent_offset != parentOffset) {
1294*77b80299SAndroid Build Coastguard Worker ALOGE("Buffer parent offset %" PRIu64 " does not match expected offset %zu.",
1295*77b80299SAndroid Build Coastguard Worker static_cast<uint64_t>(buffer_obj->parent_offset), parentOffset);
1296*77b80299SAndroid Build Coastguard Worker return false;
1297*77b80299SAndroid Build Coastguard Worker }
1298*77b80299SAndroid Build Coastguard Worker
1299*77b80299SAndroid Build Coastguard Worker // checked by kernel driver, but needed for fuzzer
1300*77b80299SAndroid Build Coastguard Worker if (parent >= mObjectsSize) {
1301*77b80299SAndroid Build Coastguard Worker ALOGE("Parent index %zu but only have %zu objects", parent, mObjectsSize);
1302*77b80299SAndroid Build Coastguard Worker return false;
1303*77b80299SAndroid Build Coastguard Worker }
1304*77b80299SAndroid Build Coastguard Worker
1305*77b80299SAndroid Build Coastguard Worker binder_buffer_object *parentBuffer =
1306*77b80299SAndroid Build Coastguard Worker reinterpret_cast<binder_buffer_object*>(mData + mObjects[parent]);
1307*77b80299SAndroid Build Coastguard Worker void* bufferInParent = *reinterpret_cast<void**>(
1308*77b80299SAndroid Build Coastguard Worker reinterpret_cast<uint8_t*>(parentBuffer->buffer) + parentOffset);
1309*77b80299SAndroid Build Coastguard Worker void* childBuffer = reinterpret_cast<void*>(buffer_obj->buffer);
1310*77b80299SAndroid Build Coastguard Worker
1311*77b80299SAndroid Build Coastguard Worker if (bufferInParent != childBuffer) {
1312*77b80299SAndroid Build Coastguard Worker ALOGE("Buffer in parent %p differs from embedded buffer %p",
1313*77b80299SAndroid Build Coastguard Worker bufferInParent, childBuffer);
1314*77b80299SAndroid Build Coastguard Worker android_errorWriteLog(0x534e4554, "179289794");
1315*77b80299SAndroid Build Coastguard Worker return false;
1316*77b80299SAndroid Build Coastguard Worker }
1317*77b80299SAndroid Build Coastguard Worker }
1318*77b80299SAndroid Build Coastguard Worker
1319*77b80299SAndroid Build Coastguard Worker return true;
1320*77b80299SAndroid Build Coastguard Worker }
1321*77b80299SAndroid Build Coastguard Worker
readBuffer(size_t buffer_size,size_t * buffer_handle,uint32_t flags,size_t parent,size_t parentOffset,const void ** buffer_out) const1322*77b80299SAndroid Build Coastguard Worker status_t Parcel::readBuffer(size_t buffer_size, size_t *buffer_handle,
1323*77b80299SAndroid Build Coastguard Worker uint32_t flags, size_t parent, size_t parentOffset,
1324*77b80299SAndroid Build Coastguard Worker const void **buffer_out) const {
1325*77b80299SAndroid Build Coastguard Worker
1326*77b80299SAndroid Build Coastguard Worker const binder_buffer_object* buffer_obj = readObject<binder_buffer_object>(buffer_handle);
1327*77b80299SAndroid Build Coastguard Worker
1328*77b80299SAndroid Build Coastguard Worker if (buffer_obj == nullptr || buffer_obj->hdr.type != BINDER_TYPE_PTR) {
1329*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
1330*77b80299SAndroid Build Coastguard Worker }
1331*77b80299SAndroid Build Coastguard Worker
1332*77b80299SAndroid Build Coastguard Worker if (!verifyBufferObject(buffer_obj, buffer_size, flags, parent, parentOffset)) {
1333*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
1334*77b80299SAndroid Build Coastguard Worker }
1335*77b80299SAndroid Build Coastguard Worker
1336*77b80299SAndroid Build Coastguard Worker // in read side, always use .buffer and .length.
1337*77b80299SAndroid Build Coastguard Worker *buffer_out = reinterpret_cast<void*>(buffer_obj->buffer);
1338*77b80299SAndroid Build Coastguard Worker
1339*77b80299SAndroid Build Coastguard Worker return OK;
1340*77b80299SAndroid Build Coastguard Worker }
1341*77b80299SAndroid Build Coastguard Worker
readNullableBuffer(size_t buffer_size,size_t * buffer_handle,const void ** buffer_out) const1342*77b80299SAndroid Build Coastguard Worker status_t Parcel::readNullableBuffer(size_t buffer_size, size_t *buffer_handle,
1343*77b80299SAndroid Build Coastguard Worker const void **buffer_out) const
1344*77b80299SAndroid Build Coastguard Worker {
1345*77b80299SAndroid Build Coastguard Worker return readBuffer(buffer_size, buffer_handle,
1346*77b80299SAndroid Build Coastguard Worker 0 /* flags */, 0 /* parent */, 0 /* parentOffset */,
1347*77b80299SAndroid Build Coastguard Worker buffer_out);
1348*77b80299SAndroid Build Coastguard Worker }
1349*77b80299SAndroid Build Coastguard Worker
readBuffer(size_t buffer_size,size_t * buffer_handle,const void ** buffer_out) const1350*77b80299SAndroid Build Coastguard Worker status_t Parcel::readBuffer(size_t buffer_size, size_t *buffer_handle,
1351*77b80299SAndroid Build Coastguard Worker const void **buffer_out) const
1352*77b80299SAndroid Build Coastguard Worker {
1353*77b80299SAndroid Build Coastguard Worker status_t status = readNullableBuffer(buffer_size, buffer_handle, buffer_out);
1354*77b80299SAndroid Build Coastguard Worker if (status == OK && *buffer_out == nullptr) {
1355*77b80299SAndroid Build Coastguard Worker return UNEXPECTED_NULL;
1356*77b80299SAndroid Build Coastguard Worker }
1357*77b80299SAndroid Build Coastguard Worker return status;
1358*77b80299SAndroid Build Coastguard Worker }
1359*77b80299SAndroid Build Coastguard Worker
1360*77b80299SAndroid Build Coastguard Worker
readEmbeddedBuffer(size_t buffer_size,size_t * buffer_handle,size_t parent_buffer_handle,size_t parent_offset,const void ** buffer_out) const1361*77b80299SAndroid Build Coastguard Worker status_t Parcel::readEmbeddedBuffer(size_t buffer_size,
1362*77b80299SAndroid Build Coastguard Worker size_t *buffer_handle,
1363*77b80299SAndroid Build Coastguard Worker size_t parent_buffer_handle,
1364*77b80299SAndroid Build Coastguard Worker size_t parent_offset,
1365*77b80299SAndroid Build Coastguard Worker const void **buffer_out) const
1366*77b80299SAndroid Build Coastguard Worker {
1367*77b80299SAndroid Build Coastguard Worker status_t status = readNullableEmbeddedBuffer(buffer_size, buffer_handle,
1368*77b80299SAndroid Build Coastguard Worker parent_buffer_handle,
1369*77b80299SAndroid Build Coastguard Worker parent_offset, buffer_out);
1370*77b80299SAndroid Build Coastguard Worker if (status == OK && *buffer_out == nullptr) {
1371*77b80299SAndroid Build Coastguard Worker return UNEXPECTED_NULL;
1372*77b80299SAndroid Build Coastguard Worker }
1373*77b80299SAndroid Build Coastguard Worker return status;
1374*77b80299SAndroid Build Coastguard Worker }
1375*77b80299SAndroid Build Coastguard Worker
readNullableEmbeddedBuffer(size_t buffer_size,size_t * buffer_handle,size_t parent_buffer_handle,size_t parent_offset,const void ** buffer_out) const1376*77b80299SAndroid Build Coastguard Worker status_t Parcel::readNullableEmbeddedBuffer(size_t buffer_size,
1377*77b80299SAndroid Build Coastguard Worker size_t *buffer_handle,
1378*77b80299SAndroid Build Coastguard Worker size_t parent_buffer_handle,
1379*77b80299SAndroid Build Coastguard Worker size_t parent_offset,
1380*77b80299SAndroid Build Coastguard Worker const void **buffer_out) const
1381*77b80299SAndroid Build Coastguard Worker {
1382*77b80299SAndroid Build Coastguard Worker return readBuffer(buffer_size, buffer_handle, BINDER_BUFFER_FLAG_HAS_PARENT,
1383*77b80299SAndroid Build Coastguard Worker parent_buffer_handle, parent_offset, buffer_out);
1384*77b80299SAndroid Build Coastguard Worker }
1385*77b80299SAndroid Build Coastguard Worker
readEmbeddedNativeHandle(size_t parent_buffer_handle,size_t parent_offset,const native_handle_t ** handle) const1386*77b80299SAndroid Build Coastguard Worker status_t Parcel::readEmbeddedNativeHandle(size_t parent_buffer_handle,
1387*77b80299SAndroid Build Coastguard Worker size_t parent_offset,
1388*77b80299SAndroid Build Coastguard Worker const native_handle_t **handle) const
1389*77b80299SAndroid Build Coastguard Worker {
1390*77b80299SAndroid Build Coastguard Worker status_t status = readNullableEmbeddedNativeHandle(parent_buffer_handle, parent_offset, handle);
1391*77b80299SAndroid Build Coastguard Worker if (status == OK && *handle == nullptr) {
1392*77b80299SAndroid Build Coastguard Worker return UNEXPECTED_NULL;
1393*77b80299SAndroid Build Coastguard Worker }
1394*77b80299SAndroid Build Coastguard Worker return status;
1395*77b80299SAndroid Build Coastguard Worker }
1396*77b80299SAndroid Build Coastguard Worker
readNullableNativeHandleNoDup(const native_handle_t ** handle,bool embedded,size_t parent_buffer_handle,size_t parent_offset) const1397*77b80299SAndroid Build Coastguard Worker status_t Parcel::readNullableNativeHandleNoDup(const native_handle_t **handle,
1398*77b80299SAndroid Build Coastguard Worker bool embedded,
1399*77b80299SAndroid Build Coastguard Worker size_t parent_buffer_handle,
1400*77b80299SAndroid Build Coastguard Worker size_t parent_offset) const
1401*77b80299SAndroid Build Coastguard Worker {
1402*77b80299SAndroid Build Coastguard Worker uint64_t nativeHandleSize;
1403*77b80299SAndroid Build Coastguard Worker status_t status = readUint64(&nativeHandleSize);
1404*77b80299SAndroid Build Coastguard Worker if (status != OK) {
1405*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
1406*77b80299SAndroid Build Coastguard Worker }
1407*77b80299SAndroid Build Coastguard Worker
1408*77b80299SAndroid Build Coastguard Worker if (nativeHandleSize == 0) {
1409*77b80299SAndroid Build Coastguard Worker // If !embedded, then parent_* vars are 0 and don't actually correspond
1410*77b80299SAndroid Build Coastguard Worker // to anything. In that case, we're actually reading this data into
1411*77b80299SAndroid Build Coastguard Worker // writable memory, and the handle returned from here will actually be
1412*77b80299SAndroid Build Coastguard Worker // used (rather than be ignored).
1413*77b80299SAndroid Build Coastguard Worker if (embedded) {
1414*77b80299SAndroid Build Coastguard Worker if(!validateBufferParent(parent_buffer_handle, parent_offset)) {
1415*77b80299SAndroid Build Coastguard Worker ALOGE("Buffer in parent %zu offset %zu invalid.", parent_buffer_handle, parent_offset);
1416*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
1417*77b80299SAndroid Build Coastguard Worker }
1418*77b80299SAndroid Build Coastguard Worker
1419*77b80299SAndroid Build Coastguard Worker binder_buffer_object *parentBuffer =
1420*77b80299SAndroid Build Coastguard Worker reinterpret_cast<binder_buffer_object*>(mData + mObjects[parent_buffer_handle]);
1421*77b80299SAndroid Build Coastguard Worker
1422*77b80299SAndroid Build Coastguard Worker void* bufferInParent = *reinterpret_cast<void**>(
1423*77b80299SAndroid Build Coastguard Worker reinterpret_cast<uint8_t*>(parentBuffer->buffer) + parent_offset);
1424*77b80299SAndroid Build Coastguard Worker
1425*77b80299SAndroid Build Coastguard Worker if (bufferInParent != nullptr) {
1426*77b80299SAndroid Build Coastguard Worker ALOGE("Buffer in (handle) parent %p is not nullptr.", bufferInParent);
1427*77b80299SAndroid Build Coastguard Worker android_errorWriteLog(0x534e4554, "179289794");
1428*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
1429*77b80299SAndroid Build Coastguard Worker }
1430*77b80299SAndroid Build Coastguard Worker }
1431*77b80299SAndroid Build Coastguard Worker
1432*77b80299SAndroid Build Coastguard Worker *handle = nullptr;
1433*77b80299SAndroid Build Coastguard Worker return status;
1434*77b80299SAndroid Build Coastguard Worker }
1435*77b80299SAndroid Build Coastguard Worker
1436*77b80299SAndroid Build Coastguard Worker if (nativeHandleSize < sizeof(native_handle_t) || nativeHandleSize > std::numeric_limits<uint32_t>::max()) {
1437*77b80299SAndroid Build Coastguard Worker ALOGE("Invalid native_handle_t size: %" PRIu64, nativeHandleSize);
1438*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
1439*77b80299SAndroid Build Coastguard Worker }
1440*77b80299SAndroid Build Coastguard Worker
1441*77b80299SAndroid Build Coastguard Worker size_t fdaParent;
1442*77b80299SAndroid Build Coastguard Worker if (embedded) {
1443*77b80299SAndroid Build Coastguard Worker status = readNullableEmbeddedBuffer(nativeHandleSize, &fdaParent,
1444*77b80299SAndroid Build Coastguard Worker parent_buffer_handle, parent_offset,
1445*77b80299SAndroid Build Coastguard Worker reinterpret_cast<const void**>(handle));
1446*77b80299SAndroid Build Coastguard Worker } else {
1447*77b80299SAndroid Build Coastguard Worker status = readNullableBuffer(nativeHandleSize, &fdaParent,
1448*77b80299SAndroid Build Coastguard Worker reinterpret_cast<const void**>(handle));
1449*77b80299SAndroid Build Coastguard Worker }
1450*77b80299SAndroid Build Coastguard Worker
1451*77b80299SAndroid Build Coastguard Worker if (status != OK) {
1452*77b80299SAndroid Build Coastguard Worker return status;
1453*77b80299SAndroid Build Coastguard Worker }
1454*77b80299SAndroid Build Coastguard Worker
1455*77b80299SAndroid Build Coastguard Worker if (*handle == nullptr) {
1456*77b80299SAndroid Build Coastguard Worker // null handle already read above
1457*77b80299SAndroid Build Coastguard Worker ALOGE("Expecting non-null handle buffer");
1458*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
1459*77b80299SAndroid Build Coastguard Worker }
1460*77b80299SAndroid Build Coastguard Worker
1461*77b80299SAndroid Build Coastguard Worker int numFds = (*handle)->numFds;
1462*77b80299SAndroid Build Coastguard Worker int numInts = (*handle)->numInts;
1463*77b80299SAndroid Build Coastguard Worker
1464*77b80299SAndroid Build Coastguard Worker if (numFds < 0 || numFds > NATIVE_HANDLE_MAX_FDS) {
1465*77b80299SAndroid Build Coastguard Worker ALOGE("Received native_handle with invalid number of fds.");
1466*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
1467*77b80299SAndroid Build Coastguard Worker }
1468*77b80299SAndroid Build Coastguard Worker
1469*77b80299SAndroid Build Coastguard Worker if (numInts < 0 || numInts > NATIVE_HANDLE_MAX_INTS) {
1470*77b80299SAndroid Build Coastguard Worker ALOGE("Received native_handle with invalid number of ints.");
1471*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
1472*77b80299SAndroid Build Coastguard Worker }
1473*77b80299SAndroid Build Coastguard Worker
1474*77b80299SAndroid Build Coastguard Worker if (nativeHandleSize != (sizeof(native_handle_t) + ((numFds + numInts) * sizeof(int)))) {
1475*77b80299SAndroid Build Coastguard Worker ALOGE("Size of native_handle doesn't match.");
1476*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
1477*77b80299SAndroid Build Coastguard Worker }
1478*77b80299SAndroid Build Coastguard Worker
1479*77b80299SAndroid Build Coastguard Worker const binder_fd_array_object* fd_array_obj = readObject<binder_fd_array_object>();
1480*77b80299SAndroid Build Coastguard Worker
1481*77b80299SAndroid Build Coastguard Worker if (fd_array_obj == nullptr || fd_array_obj->hdr.type != BINDER_TYPE_FDA) {
1482*77b80299SAndroid Build Coastguard Worker ALOGE("Can't find file-descriptor array object.");
1483*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
1484*77b80299SAndroid Build Coastguard Worker }
1485*77b80299SAndroid Build Coastguard Worker
1486*77b80299SAndroid Build Coastguard Worker if (static_cast<int>(fd_array_obj->num_fds) != numFds) {
1487*77b80299SAndroid Build Coastguard Worker ALOGE("Number of native handles does not match.");
1488*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
1489*77b80299SAndroid Build Coastguard Worker }
1490*77b80299SAndroid Build Coastguard Worker
1491*77b80299SAndroid Build Coastguard Worker if (fd_array_obj->parent != fdaParent) {
1492*77b80299SAndroid Build Coastguard Worker ALOGE("Parent handle of file-descriptor array not correct.");
1493*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
1494*77b80299SAndroid Build Coastguard Worker }
1495*77b80299SAndroid Build Coastguard Worker
1496*77b80299SAndroid Build Coastguard Worker if (fd_array_obj->parent_offset != offsetof(native_handle_t, data)) {
1497*77b80299SAndroid Build Coastguard Worker ALOGE("FD array object not properly offset in parent.");
1498*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
1499*77b80299SAndroid Build Coastguard Worker }
1500*77b80299SAndroid Build Coastguard Worker
1501*77b80299SAndroid Build Coastguard Worker return OK;
1502*77b80299SAndroid Build Coastguard Worker }
1503*77b80299SAndroid Build Coastguard Worker
readNullableEmbeddedNativeHandle(size_t parent_buffer_handle,size_t parent_offset,const native_handle_t ** handle) const1504*77b80299SAndroid Build Coastguard Worker status_t Parcel::readNullableEmbeddedNativeHandle(size_t parent_buffer_handle,
1505*77b80299SAndroid Build Coastguard Worker size_t parent_offset,
1506*77b80299SAndroid Build Coastguard Worker const native_handle_t **handle) const
1507*77b80299SAndroid Build Coastguard Worker {
1508*77b80299SAndroid Build Coastguard Worker return readNullableNativeHandleNoDup(handle, true /* embedded */, parent_buffer_handle,
1509*77b80299SAndroid Build Coastguard Worker parent_offset);
1510*77b80299SAndroid Build Coastguard Worker }
1511*77b80299SAndroid Build Coastguard Worker
readNativeHandleNoDup(const native_handle_t ** handle) const1512*77b80299SAndroid Build Coastguard Worker status_t Parcel::readNativeHandleNoDup(const native_handle_t **handle) const
1513*77b80299SAndroid Build Coastguard Worker {
1514*77b80299SAndroid Build Coastguard Worker status_t status = readNullableNativeHandleNoDup(handle);
1515*77b80299SAndroid Build Coastguard Worker if (status == OK && *handle == nullptr) {
1516*77b80299SAndroid Build Coastguard Worker return UNEXPECTED_NULL;
1517*77b80299SAndroid Build Coastguard Worker }
1518*77b80299SAndroid Build Coastguard Worker return status;
1519*77b80299SAndroid Build Coastguard Worker }
1520*77b80299SAndroid Build Coastguard Worker
readNullableNativeHandleNoDup(const native_handle_t ** handle) const1521*77b80299SAndroid Build Coastguard Worker status_t Parcel::readNullableNativeHandleNoDup(const native_handle_t **handle) const
1522*77b80299SAndroid Build Coastguard Worker {
1523*77b80299SAndroid Build Coastguard Worker return readNullableNativeHandleNoDup(handle, false /* embedded */);
1524*77b80299SAndroid Build Coastguard Worker }
1525*77b80299SAndroid Build Coastguard Worker
closeFileDescriptors()1526*77b80299SAndroid Build Coastguard Worker void Parcel::closeFileDescriptors()
1527*77b80299SAndroid Build Coastguard Worker {
1528*77b80299SAndroid Build Coastguard Worker size_t i = mObjectsSize;
1529*77b80299SAndroid Build Coastguard Worker if (i > 0) {
1530*77b80299SAndroid Build Coastguard Worker //ALOGI("Closing file descriptors for %zu objects...", i);
1531*77b80299SAndroid Build Coastguard Worker }
1532*77b80299SAndroid Build Coastguard Worker while (i > 0) {
1533*77b80299SAndroid Build Coastguard Worker i--;
1534*77b80299SAndroid Build Coastguard Worker const flat_binder_object* flat
1535*77b80299SAndroid Build Coastguard Worker = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
1536*77b80299SAndroid Build Coastguard Worker if (flat->hdr.type == BINDER_TYPE_FD) {
1537*77b80299SAndroid Build Coastguard Worker //ALOGI("Closing fd: %ld", flat->handle);
1538*77b80299SAndroid Build Coastguard Worker close(flat->handle);
1539*77b80299SAndroid Build Coastguard Worker }
1540*77b80299SAndroid Build Coastguard Worker }
1541*77b80299SAndroid Build Coastguard Worker }
1542*77b80299SAndroid Build Coastguard Worker
ipcData() const1543*77b80299SAndroid Build Coastguard Worker uintptr_t Parcel::ipcData() const
1544*77b80299SAndroid Build Coastguard Worker {
1545*77b80299SAndroid Build Coastguard Worker return reinterpret_cast<uintptr_t>(mData);
1546*77b80299SAndroid Build Coastguard Worker }
1547*77b80299SAndroid Build Coastguard Worker
ipcDataSize() const1548*77b80299SAndroid Build Coastguard Worker size_t Parcel::ipcDataSize() const
1549*77b80299SAndroid Build Coastguard Worker {
1550*77b80299SAndroid Build Coastguard Worker return mDataSize > mDataPos ? mDataSize : mDataPos;
1551*77b80299SAndroid Build Coastguard Worker }
1552*77b80299SAndroid Build Coastguard Worker
ipcObjects() const1553*77b80299SAndroid Build Coastguard Worker uintptr_t Parcel::ipcObjects() const
1554*77b80299SAndroid Build Coastguard Worker {
1555*77b80299SAndroid Build Coastguard Worker return reinterpret_cast<uintptr_t>(mObjects);
1556*77b80299SAndroid Build Coastguard Worker }
1557*77b80299SAndroid Build Coastguard Worker
ipcObjectsCount() const1558*77b80299SAndroid Build Coastguard Worker size_t Parcel::ipcObjectsCount() const
1559*77b80299SAndroid Build Coastguard Worker {
1560*77b80299SAndroid Build Coastguard Worker return mObjectsSize;
1561*77b80299SAndroid Build Coastguard Worker }
1562*77b80299SAndroid Build Coastguard Worker
1563*77b80299SAndroid Build Coastguard Worker #define BUFFER_ALIGNMENT_BYTES 8
ipcBufferSize() const1564*77b80299SAndroid Build Coastguard Worker size_t Parcel::ipcBufferSize() const
1565*77b80299SAndroid Build Coastguard Worker {
1566*77b80299SAndroid Build Coastguard Worker size_t totalBuffersSize = 0;
1567*77b80299SAndroid Build Coastguard Worker // Add size for BINDER_TYPE_PTR
1568*77b80299SAndroid Build Coastguard Worker size_t i = mObjectsSize;
1569*77b80299SAndroid Build Coastguard Worker while (i > 0) {
1570*77b80299SAndroid Build Coastguard Worker i--;
1571*77b80299SAndroid Build Coastguard Worker const binder_buffer_object* buffer
1572*77b80299SAndroid Build Coastguard Worker = reinterpret_cast<binder_buffer_object*>(mData+mObjects[i]);
1573*77b80299SAndroid Build Coastguard Worker if (buffer->hdr.type == BINDER_TYPE_PTR) {
1574*77b80299SAndroid Build Coastguard Worker /* The binder kernel driver requires each buffer to be 8-byte
1575*77b80299SAndroid Build Coastguard Worker * aligned */
1576*77b80299SAndroid Build Coastguard Worker size_t alignedSize = (buffer->length + (BUFFER_ALIGNMENT_BYTES - 1))
1577*77b80299SAndroid Build Coastguard Worker & ~(BUFFER_ALIGNMENT_BYTES - 1);
1578*77b80299SAndroid Build Coastguard Worker if (alignedSize > SIZE_MAX - totalBuffersSize) {
1579*77b80299SAndroid Build Coastguard Worker ALOGE("ipcBuffersSize(): invalid buffer sizes.");
1580*77b80299SAndroid Build Coastguard Worker return 0;
1581*77b80299SAndroid Build Coastguard Worker }
1582*77b80299SAndroid Build Coastguard Worker totalBuffersSize += alignedSize;
1583*77b80299SAndroid Build Coastguard Worker }
1584*77b80299SAndroid Build Coastguard Worker }
1585*77b80299SAndroid Build Coastguard Worker return totalBuffersSize;
1586*77b80299SAndroid Build Coastguard Worker }
1587*77b80299SAndroid Build Coastguard Worker
ipcSetDataReference(const uint8_t * data,size_t dataSize,const binder_size_t * objects,size_t objectsCount,release_func relFunc,void * relCookie)1588*77b80299SAndroid Build Coastguard Worker void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
1589*77b80299SAndroid Build Coastguard Worker const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
1590*77b80299SAndroid Build Coastguard Worker {
1591*77b80299SAndroid Build Coastguard Worker binder_size_t minOffset = 0;
1592*77b80299SAndroid Build Coastguard Worker freeDataNoInit();
1593*77b80299SAndroid Build Coastguard Worker mError = NO_ERROR;
1594*77b80299SAndroid Build Coastguard Worker mData = const_cast<uint8_t*>(data);
1595*77b80299SAndroid Build Coastguard Worker mDataSize = mDataCapacity = dataSize;
1596*77b80299SAndroid Build Coastguard Worker //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)", this, mDataSize, getpid());
1597*77b80299SAndroid Build Coastguard Worker mDataPos = 0;
1598*77b80299SAndroid Build Coastguard Worker ALOGV("setDataReference Setting data pos of %p to %zu", this, mDataPos);
1599*77b80299SAndroid Build Coastguard Worker mObjects = const_cast<binder_size_t*>(objects);
1600*77b80299SAndroid Build Coastguard Worker mObjectsSize = mObjectsCapacity = objectsCount;
1601*77b80299SAndroid Build Coastguard Worker mNextObjectHint = 0;
1602*77b80299SAndroid Build Coastguard Worker clearCache();
1603*77b80299SAndroid Build Coastguard Worker mOwner = relFunc;
1604*77b80299SAndroid Build Coastguard Worker mOwnerCookie = relCookie;
1605*77b80299SAndroid Build Coastguard Worker for (size_t i = 0; i < mObjectsSize; i++) {
1606*77b80299SAndroid Build Coastguard Worker binder_size_t offset = mObjects[i];
1607*77b80299SAndroid Build Coastguard Worker if (offset < minOffset) {
1608*77b80299SAndroid Build Coastguard Worker ALOGE("%s: bad object offset %" PRIu64 " < %" PRIu64 "\n",
1609*77b80299SAndroid Build Coastguard Worker __func__, (uint64_t)offset, (uint64_t)minOffset);
1610*77b80299SAndroid Build Coastguard Worker mObjectsSize = 0;
1611*77b80299SAndroid Build Coastguard Worker break;
1612*77b80299SAndroid Build Coastguard Worker }
1613*77b80299SAndroid Build Coastguard Worker minOffset = offset + sizeof(flat_binder_object);
1614*77b80299SAndroid Build Coastguard Worker }
1615*77b80299SAndroid Build Coastguard Worker scanForFds();
1616*77b80299SAndroid Build Coastguard Worker }
1617*77b80299SAndroid Build Coastguard Worker
print(TextOutput & to,uint32_t) const1618*77b80299SAndroid Build Coastguard Worker void Parcel::print(TextOutput& to, uint32_t /*flags*/) const
1619*77b80299SAndroid Build Coastguard Worker {
1620*77b80299SAndroid Build Coastguard Worker to << "Parcel(";
1621*77b80299SAndroid Build Coastguard Worker
1622*77b80299SAndroid Build Coastguard Worker if (errorCheck() != NO_ERROR) {
1623*77b80299SAndroid Build Coastguard Worker const status_t err = errorCheck();
1624*77b80299SAndroid Build Coastguard Worker to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\"";
1625*77b80299SAndroid Build Coastguard Worker } else if (dataSize() > 0) {
1626*77b80299SAndroid Build Coastguard Worker const uint8_t* DATA = data();
1627*77b80299SAndroid Build Coastguard Worker to << indent << HexDump(DATA, dataSize()) << dedent;
1628*77b80299SAndroid Build Coastguard Worker const binder_size_t* OBJS = objects();
1629*77b80299SAndroid Build Coastguard Worker const size_t N = objectsCount();
1630*77b80299SAndroid Build Coastguard Worker for (size_t i=0; i<N; i++) {
1631*77b80299SAndroid Build Coastguard Worker const flat_binder_object* flat
1632*77b80299SAndroid Build Coastguard Worker = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]);
1633*77b80299SAndroid Build Coastguard Worker if (flat->hdr.type == BINDER_TYPE_PTR) {
1634*77b80299SAndroid Build Coastguard Worker const binder_buffer_object* buffer
1635*77b80299SAndroid Build Coastguard Worker = reinterpret_cast<const binder_buffer_object*>(DATA+OBJS[i]);
1636*77b80299SAndroid Build Coastguard Worker HexDump bufferDump((const uint8_t*)buffer->buffer, (size_t)buffer->length);
1637*77b80299SAndroid Build Coastguard Worker bufferDump.setSingleLineCutoff(0);
1638*77b80299SAndroid Build Coastguard Worker to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << " (buffer size " << buffer->length << "):";
1639*77b80299SAndroid Build Coastguard Worker to << indent << bufferDump << dedent;
1640*77b80299SAndroid Build Coastguard Worker } else {
1641*77b80299SAndroid Build Coastguard Worker to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": "
1642*77b80299SAndroid Build Coastguard Worker << TypeCode(flat->hdr.type & 0x7f7f7f00)
1643*77b80299SAndroid Build Coastguard Worker << " = " << flat->binder;
1644*77b80299SAndroid Build Coastguard Worker }
1645*77b80299SAndroid Build Coastguard Worker }
1646*77b80299SAndroid Build Coastguard Worker } else {
1647*77b80299SAndroid Build Coastguard Worker to << "NULL";
1648*77b80299SAndroid Build Coastguard Worker }
1649*77b80299SAndroid Build Coastguard Worker
1650*77b80299SAndroid Build Coastguard Worker to << ")";
1651*77b80299SAndroid Build Coastguard Worker }
1652*77b80299SAndroid Build Coastguard Worker
releaseObjects()1653*77b80299SAndroid Build Coastguard Worker void Parcel::releaseObjects()
1654*77b80299SAndroid Build Coastguard Worker {
1655*77b80299SAndroid Build Coastguard Worker const sp<ProcessState> proc(ProcessState::self());
1656*77b80299SAndroid Build Coastguard Worker size_t i = mObjectsSize;
1657*77b80299SAndroid Build Coastguard Worker uint8_t* const data = mData;
1658*77b80299SAndroid Build Coastguard Worker binder_size_t* const objects = mObjects;
1659*77b80299SAndroid Build Coastguard Worker while (i > 0) {
1660*77b80299SAndroid Build Coastguard Worker i--;
1661*77b80299SAndroid Build Coastguard Worker const flat_binder_object* flat
1662*77b80299SAndroid Build Coastguard Worker = reinterpret_cast<flat_binder_object*>(data+objects[i]);
1663*77b80299SAndroid Build Coastguard Worker release_object(proc, *flat, this);
1664*77b80299SAndroid Build Coastguard Worker }
1665*77b80299SAndroid Build Coastguard Worker }
1666*77b80299SAndroid Build Coastguard Worker
acquireObjects()1667*77b80299SAndroid Build Coastguard Worker void Parcel::acquireObjects()
1668*77b80299SAndroid Build Coastguard Worker {
1669*77b80299SAndroid Build Coastguard Worker const sp<ProcessState> proc(ProcessState::self());
1670*77b80299SAndroid Build Coastguard Worker size_t i = mObjectsSize;
1671*77b80299SAndroid Build Coastguard Worker uint8_t* const data = mData;
1672*77b80299SAndroid Build Coastguard Worker binder_size_t* const objects = mObjects;
1673*77b80299SAndroid Build Coastguard Worker while (i > 0) {
1674*77b80299SAndroid Build Coastguard Worker i--;
1675*77b80299SAndroid Build Coastguard Worker const binder_object_header* flat
1676*77b80299SAndroid Build Coastguard Worker = reinterpret_cast<binder_object_header*>(data+objects[i]);
1677*77b80299SAndroid Build Coastguard Worker acquire_object(proc, *flat, this);
1678*77b80299SAndroid Build Coastguard Worker }
1679*77b80299SAndroid Build Coastguard Worker }
1680*77b80299SAndroid Build Coastguard Worker
freeData()1681*77b80299SAndroid Build Coastguard Worker void Parcel::freeData()
1682*77b80299SAndroid Build Coastguard Worker {
1683*77b80299SAndroid Build Coastguard Worker freeDataNoInit();
1684*77b80299SAndroid Build Coastguard Worker initState();
1685*77b80299SAndroid Build Coastguard Worker }
1686*77b80299SAndroid Build Coastguard Worker
freeDataNoInit()1687*77b80299SAndroid Build Coastguard Worker void Parcel::freeDataNoInit()
1688*77b80299SAndroid Build Coastguard Worker {
1689*77b80299SAndroid Build Coastguard Worker if (mOwner) {
1690*77b80299SAndroid Build Coastguard Worker LOG_ALLOC("Parcel %p: freeing other owner data", this);
1691*77b80299SAndroid Build Coastguard Worker //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
1692*77b80299SAndroid Build Coastguard Worker mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
1693*77b80299SAndroid Build Coastguard Worker } else {
1694*77b80299SAndroid Build Coastguard Worker LOG_ALLOC("Parcel %p: freeing allocated data", this);
1695*77b80299SAndroid Build Coastguard Worker releaseObjects();
1696*77b80299SAndroid Build Coastguard Worker if (mData) {
1697*77b80299SAndroid Build Coastguard Worker LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity);
1698*77b80299SAndroid Build Coastguard Worker gParcelGlobalAllocSize -= mDataCapacity;
1699*77b80299SAndroid Build Coastguard Worker gParcelGlobalAllocCount--;
1700*77b80299SAndroid Build Coastguard Worker if (mDeallocZero) {
1701*77b80299SAndroid Build Coastguard Worker zeroMemory(mData, mDataSize);
1702*77b80299SAndroid Build Coastguard Worker }
1703*77b80299SAndroid Build Coastguard Worker free(mData);
1704*77b80299SAndroid Build Coastguard Worker }
1705*77b80299SAndroid Build Coastguard Worker if (mObjects) free(mObjects);
1706*77b80299SAndroid Build Coastguard Worker }
1707*77b80299SAndroid Build Coastguard Worker }
1708*77b80299SAndroid Build Coastguard Worker
growData(size_t len)1709*77b80299SAndroid Build Coastguard Worker status_t Parcel::growData(size_t len)
1710*77b80299SAndroid Build Coastguard Worker {
1711*77b80299SAndroid Build Coastguard Worker if (len > INT32_MAX) {
1712*77b80299SAndroid Build Coastguard Worker // don't accept size_t values which may have come from an
1713*77b80299SAndroid Build Coastguard Worker // inadvertent conversion from a negative int.
1714*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
1715*77b80299SAndroid Build Coastguard Worker }
1716*77b80299SAndroid Build Coastguard Worker if (len > SIZE_MAX - mDataSize) return NO_MEMORY; // overflow
1717*77b80299SAndroid Build Coastguard Worker if (mDataSize + len > SIZE_MAX / 3) return NO_MEMORY; // overflow
1718*77b80299SAndroid Build Coastguard Worker size_t newSize = ((mDataSize+len)*3)/2;
1719*77b80299SAndroid Build Coastguard Worker return continueWrite(newSize);
1720*77b80299SAndroid Build Coastguard Worker }
1721*77b80299SAndroid Build Coastguard Worker
reallocZeroFree(uint8_t * data,size_t oldCapacity,size_t newCapacity,bool zero)1722*77b80299SAndroid Build Coastguard Worker static uint8_t* reallocZeroFree(uint8_t* data, size_t oldCapacity, size_t newCapacity, bool zero) {
1723*77b80299SAndroid Build Coastguard Worker if (!zero) {
1724*77b80299SAndroid Build Coastguard Worker return (uint8_t*)realloc(data, newCapacity);
1725*77b80299SAndroid Build Coastguard Worker }
1726*77b80299SAndroid Build Coastguard Worker uint8_t* newData = (uint8_t*)malloc(newCapacity);
1727*77b80299SAndroid Build Coastguard Worker if (!newData) {
1728*77b80299SAndroid Build Coastguard Worker return nullptr;
1729*77b80299SAndroid Build Coastguard Worker }
1730*77b80299SAndroid Build Coastguard Worker
1731*77b80299SAndroid Build Coastguard Worker memcpy(newData, data, std::min(oldCapacity, newCapacity));
1732*77b80299SAndroid Build Coastguard Worker zeroMemory(data, oldCapacity);
1733*77b80299SAndroid Build Coastguard Worker free(data);
1734*77b80299SAndroid Build Coastguard Worker return newData;
1735*77b80299SAndroid Build Coastguard Worker }
1736*77b80299SAndroid Build Coastguard Worker
continueWrite(size_t desired)1737*77b80299SAndroid Build Coastguard Worker status_t Parcel::continueWrite(size_t desired)
1738*77b80299SAndroid Build Coastguard Worker {
1739*77b80299SAndroid Build Coastguard Worker if (desired > INT32_MAX) {
1740*77b80299SAndroid Build Coastguard Worker // don't accept size_t values which may have come from an
1741*77b80299SAndroid Build Coastguard Worker // inadvertent conversion from a negative int.
1742*77b80299SAndroid Build Coastguard Worker return BAD_VALUE;
1743*77b80299SAndroid Build Coastguard Worker }
1744*77b80299SAndroid Build Coastguard Worker
1745*77b80299SAndroid Build Coastguard Worker // If shrinking, first adjust for any objects that appear
1746*77b80299SAndroid Build Coastguard Worker // after the new data size.
1747*77b80299SAndroid Build Coastguard Worker size_t objectsSize = mObjectsSize;
1748*77b80299SAndroid Build Coastguard Worker if (desired < mDataSize) {
1749*77b80299SAndroid Build Coastguard Worker if (desired == 0) {
1750*77b80299SAndroid Build Coastguard Worker objectsSize = 0;
1751*77b80299SAndroid Build Coastguard Worker } else {
1752*77b80299SAndroid Build Coastguard Worker while (objectsSize > 0) {
1753*77b80299SAndroid Build Coastguard Worker if (mObjects[objectsSize-1] < desired)
1754*77b80299SAndroid Build Coastguard Worker break;
1755*77b80299SAndroid Build Coastguard Worker objectsSize--;
1756*77b80299SAndroid Build Coastguard Worker }
1757*77b80299SAndroid Build Coastguard Worker }
1758*77b80299SAndroid Build Coastguard Worker }
1759*77b80299SAndroid Build Coastguard Worker
1760*77b80299SAndroid Build Coastguard Worker if (mOwner) {
1761*77b80299SAndroid Build Coastguard Worker // If the size is going to zero, just release the owner's data.
1762*77b80299SAndroid Build Coastguard Worker if (desired == 0) {
1763*77b80299SAndroid Build Coastguard Worker freeData();
1764*77b80299SAndroid Build Coastguard Worker return NO_ERROR;
1765*77b80299SAndroid Build Coastguard Worker }
1766*77b80299SAndroid Build Coastguard Worker
1767*77b80299SAndroid Build Coastguard Worker // If there is a different owner, we need to take
1768*77b80299SAndroid Build Coastguard Worker // posession.
1769*77b80299SAndroid Build Coastguard Worker uint8_t* data = (uint8_t*)malloc(desired);
1770*77b80299SAndroid Build Coastguard Worker if (!data) {
1771*77b80299SAndroid Build Coastguard Worker mError = NO_MEMORY;
1772*77b80299SAndroid Build Coastguard Worker return NO_MEMORY;
1773*77b80299SAndroid Build Coastguard Worker }
1774*77b80299SAndroid Build Coastguard Worker binder_size_t* objects = nullptr;
1775*77b80299SAndroid Build Coastguard Worker
1776*77b80299SAndroid Build Coastguard Worker if (objectsSize) {
1777*77b80299SAndroid Build Coastguard Worker objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t));
1778*77b80299SAndroid Build Coastguard Worker if (!objects) {
1779*77b80299SAndroid Build Coastguard Worker free(data);
1780*77b80299SAndroid Build Coastguard Worker
1781*77b80299SAndroid Build Coastguard Worker mError = NO_MEMORY;
1782*77b80299SAndroid Build Coastguard Worker return NO_MEMORY;
1783*77b80299SAndroid Build Coastguard Worker }
1784*77b80299SAndroid Build Coastguard Worker
1785*77b80299SAndroid Build Coastguard Worker // Little hack to only acquire references on objects
1786*77b80299SAndroid Build Coastguard Worker // we will be keeping.
1787*77b80299SAndroid Build Coastguard Worker size_t oldObjectsSize = mObjectsSize;
1788*77b80299SAndroid Build Coastguard Worker mObjectsSize = objectsSize;
1789*77b80299SAndroid Build Coastguard Worker acquireObjects();
1790*77b80299SAndroid Build Coastguard Worker mObjectsSize = oldObjectsSize;
1791*77b80299SAndroid Build Coastguard Worker }
1792*77b80299SAndroid Build Coastguard Worker
1793*77b80299SAndroid Build Coastguard Worker if (mData) {
1794*77b80299SAndroid Build Coastguard Worker memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
1795*77b80299SAndroid Build Coastguard Worker }
1796*77b80299SAndroid Build Coastguard Worker if (objects && mObjects) {
1797*77b80299SAndroid Build Coastguard Worker memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
1798*77b80299SAndroid Build Coastguard Worker }
1799*77b80299SAndroid Build Coastguard Worker //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
1800*77b80299SAndroid Build Coastguard Worker mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
1801*77b80299SAndroid Build Coastguard Worker mOwner = nullptr;
1802*77b80299SAndroid Build Coastguard Worker
1803*77b80299SAndroid Build Coastguard Worker LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired);
1804*77b80299SAndroid Build Coastguard Worker gParcelGlobalAllocSize += desired;
1805*77b80299SAndroid Build Coastguard Worker gParcelGlobalAllocCount++;
1806*77b80299SAndroid Build Coastguard Worker
1807*77b80299SAndroid Build Coastguard Worker mData = data;
1808*77b80299SAndroid Build Coastguard Worker mObjects = objects;
1809*77b80299SAndroid Build Coastguard Worker mDataSize = (mDataSize < desired) ? mDataSize : desired;
1810*77b80299SAndroid Build Coastguard Worker ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
1811*77b80299SAndroid Build Coastguard Worker mDataCapacity = desired;
1812*77b80299SAndroid Build Coastguard Worker mObjectsSize = mObjectsCapacity = objectsSize;
1813*77b80299SAndroid Build Coastguard Worker mNextObjectHint = 0;
1814*77b80299SAndroid Build Coastguard Worker
1815*77b80299SAndroid Build Coastguard Worker clearCache();
1816*77b80299SAndroid Build Coastguard Worker } else if (mData) {
1817*77b80299SAndroid Build Coastguard Worker if (objectsSize < mObjectsSize) {
1818*77b80299SAndroid Build Coastguard Worker // Need to release refs on any objects we are dropping.
1819*77b80299SAndroid Build Coastguard Worker const sp<ProcessState> proc(ProcessState::self());
1820*77b80299SAndroid Build Coastguard Worker for (size_t i=objectsSize; i<mObjectsSize; i++) {
1821*77b80299SAndroid Build Coastguard Worker const flat_binder_object* flat
1822*77b80299SAndroid Build Coastguard Worker = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
1823*77b80299SAndroid Build Coastguard Worker if (flat->hdr.type == BINDER_TYPE_FD) {
1824*77b80299SAndroid Build Coastguard Worker // will need to rescan because we may have lopped off the only FDs
1825*77b80299SAndroid Build Coastguard Worker mFdsKnown = false;
1826*77b80299SAndroid Build Coastguard Worker }
1827*77b80299SAndroid Build Coastguard Worker release_object(proc, *flat, this);
1828*77b80299SAndroid Build Coastguard Worker }
1829*77b80299SAndroid Build Coastguard Worker
1830*77b80299SAndroid Build Coastguard Worker if (objectsSize == 0) {
1831*77b80299SAndroid Build Coastguard Worker free(mObjects);
1832*77b80299SAndroid Build Coastguard Worker mObjects = nullptr;
1833*77b80299SAndroid Build Coastguard Worker } else {
1834*77b80299SAndroid Build Coastguard Worker binder_size_t* objects =
1835*77b80299SAndroid Build Coastguard Worker (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
1836*77b80299SAndroid Build Coastguard Worker if (objects) {
1837*77b80299SAndroid Build Coastguard Worker mObjects = objects;
1838*77b80299SAndroid Build Coastguard Worker }
1839*77b80299SAndroid Build Coastguard Worker }
1840*77b80299SAndroid Build Coastguard Worker mObjectsSize = objectsSize;
1841*77b80299SAndroid Build Coastguard Worker mNextObjectHint = 0;
1842*77b80299SAndroid Build Coastguard Worker
1843*77b80299SAndroid Build Coastguard Worker clearCache();
1844*77b80299SAndroid Build Coastguard Worker }
1845*77b80299SAndroid Build Coastguard Worker
1846*77b80299SAndroid Build Coastguard Worker // We own the data, so we can just do a realloc().
1847*77b80299SAndroid Build Coastguard Worker if (desired > mDataCapacity) {
1848*77b80299SAndroid Build Coastguard Worker uint8_t* data = reallocZeroFree(mData, mDataCapacity, desired, mDeallocZero);
1849*77b80299SAndroid Build Coastguard Worker if (data) {
1850*77b80299SAndroid Build Coastguard Worker LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity,
1851*77b80299SAndroid Build Coastguard Worker desired);
1852*77b80299SAndroid Build Coastguard Worker gParcelGlobalAllocSize += desired;
1853*77b80299SAndroid Build Coastguard Worker gParcelGlobalAllocSize -= mDataCapacity;
1854*77b80299SAndroid Build Coastguard Worker mData = data;
1855*77b80299SAndroid Build Coastguard Worker mDataCapacity = desired;
1856*77b80299SAndroid Build Coastguard Worker } else {
1857*77b80299SAndroid Build Coastguard Worker mError = NO_MEMORY;
1858*77b80299SAndroid Build Coastguard Worker return NO_MEMORY;
1859*77b80299SAndroid Build Coastguard Worker }
1860*77b80299SAndroid Build Coastguard Worker } else {
1861*77b80299SAndroid Build Coastguard Worker if (mDataSize > desired) {
1862*77b80299SAndroid Build Coastguard Worker mDataSize = desired;
1863*77b80299SAndroid Build Coastguard Worker ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
1864*77b80299SAndroid Build Coastguard Worker }
1865*77b80299SAndroid Build Coastguard Worker if (mDataPos > desired) {
1866*77b80299SAndroid Build Coastguard Worker mDataPos = desired;
1867*77b80299SAndroid Build Coastguard Worker ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
1868*77b80299SAndroid Build Coastguard Worker }
1869*77b80299SAndroid Build Coastguard Worker }
1870*77b80299SAndroid Build Coastguard Worker
1871*77b80299SAndroid Build Coastguard Worker } else {
1872*77b80299SAndroid Build Coastguard Worker // This is the first data. Easy!
1873*77b80299SAndroid Build Coastguard Worker uint8_t* data = (uint8_t*)malloc(desired);
1874*77b80299SAndroid Build Coastguard Worker if (!data) {
1875*77b80299SAndroid Build Coastguard Worker mError = NO_MEMORY;
1876*77b80299SAndroid Build Coastguard Worker return NO_MEMORY;
1877*77b80299SAndroid Build Coastguard Worker }
1878*77b80299SAndroid Build Coastguard Worker
1879*77b80299SAndroid Build Coastguard Worker if(!(mDataCapacity == 0 && mObjects == nullptr
1880*77b80299SAndroid Build Coastguard Worker && mObjectsCapacity == 0)) {
1881*77b80299SAndroid Build Coastguard Worker ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
1882*77b80299SAndroid Build Coastguard Worker }
1883*77b80299SAndroid Build Coastguard Worker
1884*77b80299SAndroid Build Coastguard Worker LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired);
1885*77b80299SAndroid Build Coastguard Worker gParcelGlobalAllocSize += desired;
1886*77b80299SAndroid Build Coastguard Worker gParcelGlobalAllocCount++;
1887*77b80299SAndroid Build Coastguard Worker
1888*77b80299SAndroid Build Coastguard Worker mData = data;
1889*77b80299SAndroid Build Coastguard Worker mDataSize = mDataPos = 0;
1890*77b80299SAndroid Build Coastguard Worker ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
1891*77b80299SAndroid Build Coastguard Worker ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
1892*77b80299SAndroid Build Coastguard Worker mDataCapacity = desired;
1893*77b80299SAndroid Build Coastguard Worker }
1894*77b80299SAndroid Build Coastguard Worker
1895*77b80299SAndroid Build Coastguard Worker return NO_ERROR;
1896*77b80299SAndroid Build Coastguard Worker }
1897*77b80299SAndroid Build Coastguard Worker
initState()1898*77b80299SAndroid Build Coastguard Worker void Parcel::initState()
1899*77b80299SAndroid Build Coastguard Worker {
1900*77b80299SAndroid Build Coastguard Worker LOG_ALLOC("Parcel %p: initState", this);
1901*77b80299SAndroid Build Coastguard Worker mError = NO_ERROR;
1902*77b80299SAndroid Build Coastguard Worker mData = nullptr;
1903*77b80299SAndroid Build Coastguard Worker mDataSize = 0;
1904*77b80299SAndroid Build Coastguard Worker mDataCapacity = 0;
1905*77b80299SAndroid Build Coastguard Worker mDataPos = 0;
1906*77b80299SAndroid Build Coastguard Worker ALOGV("initState Setting data size of %p to %zu", this, mDataSize);
1907*77b80299SAndroid Build Coastguard Worker ALOGV("initState Setting data pos of %p to %zu", this, mDataPos);
1908*77b80299SAndroid Build Coastguard Worker mObjects = nullptr;
1909*77b80299SAndroid Build Coastguard Worker mObjectsSize = 0;
1910*77b80299SAndroid Build Coastguard Worker mObjectsCapacity = 0;
1911*77b80299SAndroid Build Coastguard Worker mNextObjectHint = 0;
1912*77b80299SAndroid Build Coastguard Worker mHasFds = false;
1913*77b80299SAndroid Build Coastguard Worker mFdsKnown = true;
1914*77b80299SAndroid Build Coastguard Worker mAllowFds = true;
1915*77b80299SAndroid Build Coastguard Worker mDeallocZero = false;
1916*77b80299SAndroid Build Coastguard Worker mOwner = nullptr;
1917*77b80299SAndroid Build Coastguard Worker clearCache();
1918*77b80299SAndroid Build Coastguard Worker
1919*77b80299SAndroid Build Coastguard Worker // racing multiple init leads only to multiple identical write
1920*77b80299SAndroid Build Coastguard Worker if (gMaxFds == 0) {
1921*77b80299SAndroid Build Coastguard Worker struct rlimit result;
1922*77b80299SAndroid Build Coastguard Worker if (!getrlimit(RLIMIT_NOFILE, &result)) {
1923*77b80299SAndroid Build Coastguard Worker gMaxFds = (size_t)result.rlim_cur;
1924*77b80299SAndroid Build Coastguard Worker //ALOGI("parcel fd limit set to %zu", gMaxFds);
1925*77b80299SAndroid Build Coastguard Worker } else {
1926*77b80299SAndroid Build Coastguard Worker ALOGW("Unable to getrlimit: %s", strerror(errno));
1927*77b80299SAndroid Build Coastguard Worker gMaxFds = 1024;
1928*77b80299SAndroid Build Coastguard Worker }
1929*77b80299SAndroid Build Coastguard Worker }
1930*77b80299SAndroid Build Coastguard Worker }
1931*77b80299SAndroid Build Coastguard Worker
scanForFds() const1932*77b80299SAndroid Build Coastguard Worker void Parcel::scanForFds() const
1933*77b80299SAndroid Build Coastguard Worker {
1934*77b80299SAndroid Build Coastguard Worker bool hasFds = false;
1935*77b80299SAndroid Build Coastguard Worker for (size_t i=0; i<mObjectsSize; i++) {
1936*77b80299SAndroid Build Coastguard Worker const flat_binder_object* flat
1937*77b80299SAndroid Build Coastguard Worker = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
1938*77b80299SAndroid Build Coastguard Worker if (flat->hdr.type == BINDER_TYPE_FD) {
1939*77b80299SAndroid Build Coastguard Worker hasFds = true;
1940*77b80299SAndroid Build Coastguard Worker break;
1941*77b80299SAndroid Build Coastguard Worker }
1942*77b80299SAndroid Build Coastguard Worker }
1943*77b80299SAndroid Build Coastguard Worker mHasFds = hasFds;
1944*77b80299SAndroid Build Coastguard Worker mFdsKnown = true;
1945*77b80299SAndroid Build Coastguard Worker }
1946*77b80299SAndroid Build Coastguard Worker
1947*77b80299SAndroid Build Coastguard Worker } // namespace hardware
1948*77b80299SAndroid Build Coastguard Worker } // namespace android
1949