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