Parcel.cpp revision 4b5d182fd5055a4052237785164f543fe49b8f1d
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 "Parcel" 18//#define LOG_NDEBUG 0 19 20#include <binder/Parcel.h> 21 22#include <binder/IPCThreadState.h> 23#include <binder/Binder.h> 24#include <binder/BpBinder.h> 25#include <binder/ProcessState.h> 26#include <binder/Status.h> 27#include <binder/TextOutput.h> 28 29#include <errno.h> 30#include <utils/Debug.h> 31#include <utils/Log.h> 32#include <utils/String8.h> 33#include <utils/String16.h> 34#include <utils/misc.h> 35#include <utils/Flattenable.h> 36#include <cutils/ashmem.h> 37 38#include <private/binder/binder_module.h> 39#include <private/binder/Static.h> 40 41#include <inttypes.h> 42#include <stdio.h> 43#include <stdlib.h> 44#include <stdint.h> 45#include <sys/mman.h> 46 47#ifndef INT32_MAX 48#define INT32_MAX ((int32_t)(2147483647)) 49#endif 50 51#define LOG_REFS(...) 52//#define LOG_REFS(...) ALOG(LOG_DEBUG, "Parcel", __VA_ARGS__) 53#define LOG_ALLOC(...) 54//#define LOG_ALLOC(...) ALOG(LOG_DEBUG, "Parcel", __VA_ARGS__) 55 56// --------------------------------------------------------------------------- 57 58// This macro should never be used at runtime, as a too large value 59// of s could cause an integer overflow. Instead, you should always 60// use the wrapper function pad_size() 61#define PAD_SIZE_UNSAFE(s) (((s)+3)&~3) 62 63static size_t pad_size(size_t s) { 64 if (s > (SIZE_T_MAX - 3)) { 65 abort(); 66 } 67 return PAD_SIZE_UNSAFE(s); 68} 69 70// Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER 71#define STRICT_MODE_PENALTY_GATHER (0x40 << 16) 72 73// XXX This can be made public if we want to provide 74// support for typed data. 75struct small_flat_data 76{ 77 uint32_t type; 78 uint32_t data; 79}; 80 81namespace android { 82 83static pthread_mutex_t gParcelGlobalAllocSizeLock = PTHREAD_MUTEX_INITIALIZER; 84static size_t gParcelGlobalAllocSize = 0; 85static size_t gParcelGlobalAllocCount = 0; 86 87// Maximum size of a blob to transfer in-place. 88static const size_t BLOB_INPLACE_LIMIT = 16 * 1024; 89 90enum { 91 BLOB_INPLACE = 0, 92 BLOB_ASHMEM_IMMUTABLE = 1, 93 BLOB_ASHMEM_MUTABLE = 2, 94}; 95 96void acquire_object(const sp<ProcessState>& proc, 97 const flat_binder_object& obj, const void* who, size_t* outAshmemSize) 98{ 99 switch (obj.type) { 100 case BINDER_TYPE_BINDER: 101 if (obj.binder) { 102 LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie); 103 reinterpret_cast<IBinder*>(obj.cookie)->incStrong(who); 104 } 105 return; 106 case BINDER_TYPE_WEAK_BINDER: 107 if (obj.binder) 108 reinterpret_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who); 109 return; 110 case BINDER_TYPE_HANDLE: { 111 const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle); 112 if (b != NULL) { 113 LOG_REFS("Parcel %p acquiring reference on remote %p", who, b.get()); 114 b->incStrong(who); 115 } 116 return; 117 } 118 case BINDER_TYPE_WEAK_HANDLE: { 119 const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle); 120 if (b != NULL) b.get_refs()->incWeak(who); 121 return; 122 } 123 case BINDER_TYPE_FD: { 124 if (obj.cookie != 0) { 125 if (outAshmemSize != NULL) { 126 // If we own an ashmem fd, keep track of how much memory it refers to. 127 int size = ashmem_get_size_region(obj.handle); 128 if (size > 0) { 129 *outAshmemSize += size; 130 } 131 } 132 } 133 return; 134 } 135 } 136 137 ALOGD("Invalid object type 0x%08x", obj.type); 138} 139 140void acquire_object(const sp<ProcessState>& proc, 141 const flat_binder_object& obj, const void* who) 142{ 143 acquire_object(proc, obj, who, NULL); 144} 145 146static void release_object(const sp<ProcessState>& proc, 147 const flat_binder_object& obj, const void* who, size_t* outAshmemSize) 148{ 149 switch (obj.type) { 150 case BINDER_TYPE_BINDER: 151 if (obj.binder) { 152 LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie); 153 reinterpret_cast<IBinder*>(obj.cookie)->decStrong(who); 154 } 155 return; 156 case BINDER_TYPE_WEAK_BINDER: 157 if (obj.binder) 158 reinterpret_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who); 159 return; 160 case BINDER_TYPE_HANDLE: { 161 const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle); 162 if (b != NULL) { 163 LOG_REFS("Parcel %p releasing reference on remote %p", who, b.get()); 164 b->decStrong(who); 165 } 166 return; 167 } 168 case BINDER_TYPE_WEAK_HANDLE: { 169 const wp<IBinder> b = proc->getWeakProxyForHandle(obj.handle); 170 if (b != NULL) b.get_refs()->decWeak(who); 171 return; 172 } 173 case BINDER_TYPE_FD: { 174 if (outAshmemSize != NULL) { 175 if (obj.cookie != 0) { 176 int size = ashmem_get_size_region(obj.handle); 177 if (size > 0) { 178 *outAshmemSize -= size; 179 } 180 181 close(obj.handle); 182 } 183 } 184 return; 185 } 186 } 187 188 ALOGE("Invalid object type 0x%08x", obj.type); 189} 190 191void release_object(const sp<ProcessState>& proc, 192 const flat_binder_object& obj, const void* who) 193{ 194 release_object(proc, obj, who, NULL); 195} 196 197inline static status_t finish_flatten_binder( 198 const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out) 199{ 200 return out->writeObject(flat, false); 201} 202 203status_t flatten_binder(const sp<ProcessState>& /*proc*/, 204 const sp<IBinder>& binder, Parcel* out) 205{ 206 flat_binder_object obj; 207 208 obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; 209 if (binder != NULL) { 210 IBinder *local = binder->localBinder(); 211 if (!local) { 212 BpBinder *proxy = binder->remoteBinder(); 213 if (proxy == NULL) { 214 ALOGE("null proxy"); 215 } 216 const int32_t handle = proxy ? proxy->handle() : 0; 217 obj.type = BINDER_TYPE_HANDLE; 218 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */ 219 obj.handle = handle; 220 obj.cookie = 0; 221 } else { 222 obj.type = BINDER_TYPE_BINDER; 223 obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs()); 224 obj.cookie = reinterpret_cast<uintptr_t>(local); 225 } 226 } else { 227 obj.type = BINDER_TYPE_BINDER; 228 obj.binder = 0; 229 obj.cookie = 0; 230 } 231 232 return finish_flatten_binder(binder, obj, out); 233} 234 235status_t flatten_binder(const sp<ProcessState>& /*proc*/, 236 const wp<IBinder>& binder, Parcel* out) 237{ 238 flat_binder_object obj; 239 240 obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; 241 if (binder != NULL) { 242 sp<IBinder> real = binder.promote(); 243 if (real != NULL) { 244 IBinder *local = real->localBinder(); 245 if (!local) { 246 BpBinder *proxy = real->remoteBinder(); 247 if (proxy == NULL) { 248 ALOGE("null proxy"); 249 } 250 const int32_t handle = proxy ? proxy->handle() : 0; 251 obj.type = BINDER_TYPE_WEAK_HANDLE; 252 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */ 253 obj.handle = handle; 254 obj.cookie = 0; 255 } else { 256 obj.type = BINDER_TYPE_WEAK_BINDER; 257 obj.binder = reinterpret_cast<uintptr_t>(binder.get_refs()); 258 obj.cookie = reinterpret_cast<uintptr_t>(binder.unsafe_get()); 259 } 260 return finish_flatten_binder(real, obj, out); 261 } 262 263 // XXX How to deal? In order to flatten the given binder, 264 // we need to probe it for information, which requires a primary 265 // reference... but we don't have one. 266 // 267 // The OpenBinder implementation uses a dynamic_cast<> here, 268 // but we can't do that with the different reference counting 269 // implementation we are using. 270 ALOGE("Unable to unflatten Binder weak reference!"); 271 obj.type = BINDER_TYPE_BINDER; 272 obj.binder = 0; 273 obj.cookie = 0; 274 return finish_flatten_binder(NULL, obj, out); 275 276 } else { 277 obj.type = BINDER_TYPE_BINDER; 278 obj.binder = 0; 279 obj.cookie = 0; 280 return finish_flatten_binder(NULL, obj, out); 281 } 282} 283 284inline static status_t finish_unflatten_binder( 285 BpBinder* /*proxy*/, const flat_binder_object& /*flat*/, 286 const Parcel& /*in*/) 287{ 288 return NO_ERROR; 289} 290 291status_t unflatten_binder(const sp<ProcessState>& proc, 292 const Parcel& in, sp<IBinder>* out) 293{ 294 const flat_binder_object* flat = in.readObject(false); 295 296 if (flat) { 297 switch (flat->type) { 298 case BINDER_TYPE_BINDER: 299 *out = reinterpret_cast<IBinder*>(flat->cookie); 300 return finish_unflatten_binder(NULL, *flat, in); 301 case BINDER_TYPE_HANDLE: 302 *out = proc->getStrongProxyForHandle(flat->handle); 303 return finish_unflatten_binder( 304 static_cast<BpBinder*>(out->get()), *flat, in); 305 } 306 } 307 return BAD_TYPE; 308} 309 310status_t unflatten_binder(const sp<ProcessState>& proc, 311 const Parcel& in, wp<IBinder>* out) 312{ 313 const flat_binder_object* flat = in.readObject(false); 314 315 if (flat) { 316 switch (flat->type) { 317 case BINDER_TYPE_BINDER: 318 *out = reinterpret_cast<IBinder*>(flat->cookie); 319 return finish_unflatten_binder(NULL, *flat, in); 320 case BINDER_TYPE_WEAK_BINDER: 321 if (flat->binder != 0) { 322 out->set_object_and_refs( 323 reinterpret_cast<IBinder*>(flat->cookie), 324 reinterpret_cast<RefBase::weakref_type*>(flat->binder)); 325 } else { 326 *out = NULL; 327 } 328 return finish_unflatten_binder(NULL, *flat, in); 329 case BINDER_TYPE_HANDLE: 330 case BINDER_TYPE_WEAK_HANDLE: 331 *out = proc->getWeakProxyForHandle(flat->handle); 332 return finish_unflatten_binder( 333 static_cast<BpBinder*>(out->unsafe_get()), *flat, in); 334 } 335 } 336 return BAD_TYPE; 337} 338 339// --------------------------------------------------------------------------- 340 341Parcel::Parcel() 342{ 343 LOG_ALLOC("Parcel %p: constructing", this); 344 initState(); 345} 346 347Parcel::~Parcel() 348{ 349 freeDataNoInit(); 350 LOG_ALLOC("Parcel %p: destroyed", this); 351} 352 353size_t Parcel::getGlobalAllocSize() { 354 pthread_mutex_lock(&gParcelGlobalAllocSizeLock); 355 size_t size = gParcelGlobalAllocSize; 356 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); 357 return size; 358} 359 360size_t Parcel::getGlobalAllocCount() { 361 pthread_mutex_lock(&gParcelGlobalAllocSizeLock); 362 size_t count = gParcelGlobalAllocCount; 363 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); 364 return count; 365} 366 367const uint8_t* Parcel::data() const 368{ 369 return mData; 370} 371 372size_t Parcel::dataSize() const 373{ 374 return (mDataSize > mDataPos ? mDataSize : mDataPos); 375} 376 377size_t Parcel::dataAvail() const 378{ 379 size_t result = dataSize() - dataPosition(); 380 if (result > INT32_MAX) { 381 abort(); 382 } 383 return result; 384} 385 386size_t Parcel::dataPosition() const 387{ 388 return mDataPos; 389} 390 391size_t Parcel::dataCapacity() const 392{ 393 return mDataCapacity; 394} 395 396status_t Parcel::setDataSize(size_t size) 397{ 398 if (size > INT32_MAX) { 399 // don't accept size_t values which may have come from an 400 // inadvertent conversion from a negative int. 401 return BAD_VALUE; 402 } 403 404 status_t err; 405 err = continueWrite(size); 406 if (err == NO_ERROR) { 407 mDataSize = size; 408 ALOGV("setDataSize Setting data size of %p to %zu", this, mDataSize); 409 } 410 return err; 411} 412 413void Parcel::setDataPosition(size_t pos) const 414{ 415 if (pos > INT32_MAX) { 416 // don't accept size_t values which may have come from an 417 // inadvertent conversion from a negative int. 418 abort(); 419 } 420 421 mDataPos = pos; 422 mNextObjectHint = 0; 423} 424 425status_t Parcel::setDataCapacity(size_t size) 426{ 427 if (size > INT32_MAX) { 428 // don't accept size_t values which may have come from an 429 // inadvertent conversion from a negative int. 430 return BAD_VALUE; 431 } 432 433 if (size > mDataCapacity) return continueWrite(size); 434 return NO_ERROR; 435} 436 437status_t Parcel::setData(const uint8_t* buffer, size_t len) 438{ 439 if (len > INT32_MAX) { 440 // don't accept size_t values which may have come from an 441 // inadvertent conversion from a negative int. 442 return BAD_VALUE; 443 } 444 445 status_t err = restartWrite(len); 446 if (err == NO_ERROR) { 447 memcpy(const_cast<uint8_t*>(data()), buffer, len); 448 mDataSize = len; 449 mFdsKnown = false; 450 } 451 return err; 452} 453 454status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len) 455{ 456 const sp<ProcessState> proc(ProcessState::self()); 457 status_t err; 458 const uint8_t *data = parcel->mData; 459 const binder_size_t *objects = parcel->mObjects; 460 size_t size = parcel->mObjectsSize; 461 int startPos = mDataPos; 462 int firstIndex = -1, lastIndex = -2; 463 464 if (len == 0) { 465 return NO_ERROR; 466 } 467 468 if (len > INT32_MAX) { 469 // don't accept size_t values which may have come from an 470 // inadvertent conversion from a negative int. 471 return BAD_VALUE; 472 } 473 474 // range checks against the source parcel size 475 if ((offset > parcel->mDataSize) 476 || (len > parcel->mDataSize) 477 || (offset + len > parcel->mDataSize)) { 478 return BAD_VALUE; 479 } 480 481 // Count objects in range 482 for (int i = 0; i < (int) size; i++) { 483 size_t off = objects[i]; 484 if ((off >= offset) && (off + sizeof(flat_binder_object) <= offset + len)) { 485 if (firstIndex == -1) { 486 firstIndex = i; 487 } 488 lastIndex = i; 489 } 490 } 491 int numObjects = lastIndex - firstIndex + 1; 492 493 if ((mDataSize+len) > mDataCapacity) { 494 // grow data 495 err = growData(len); 496 if (err != NO_ERROR) { 497 return err; 498 } 499 } 500 501 // append data 502 memcpy(mData + mDataPos, data + offset, len); 503 mDataPos += len; 504 mDataSize += len; 505 506 err = NO_ERROR; 507 508 if (numObjects > 0) { 509 // grow objects 510 if (mObjectsCapacity < mObjectsSize + numObjects) { 511 size_t newSize = ((mObjectsSize + numObjects)*3)/2; 512 if (newSize < mObjectsSize) return NO_MEMORY; // overflow 513 binder_size_t *objects = 514 (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t)); 515 if (objects == (binder_size_t*)0) { 516 return NO_MEMORY; 517 } 518 mObjects = objects; 519 mObjectsCapacity = newSize; 520 } 521 522 // append and acquire objects 523 int idx = mObjectsSize; 524 for (int i = firstIndex; i <= lastIndex; i++) { 525 size_t off = objects[i] - offset + startPos; 526 mObjects[idx++] = off; 527 mObjectsSize++; 528 529 flat_binder_object* flat 530 = reinterpret_cast<flat_binder_object*>(mData + off); 531 acquire_object(proc, *flat, this, &mOpenAshmemSize); 532 533 if (flat->type == BINDER_TYPE_FD) { 534 // If this is a file descriptor, we need to dup it so the 535 // new Parcel now owns its own fd, and can declare that we 536 // officially know we have fds. 537 flat->handle = dup(flat->handle); 538 flat->cookie = 1; 539 mHasFds = mFdsKnown = true; 540 if (!mAllowFds) { 541 err = FDS_NOT_ALLOWED; 542 } 543 } 544 } 545 } 546 547 return err; 548} 549 550bool Parcel::allowFds() const 551{ 552 return mAllowFds; 553} 554 555bool Parcel::pushAllowFds(bool allowFds) 556{ 557 const bool origValue = mAllowFds; 558 if (!allowFds) { 559 mAllowFds = false; 560 } 561 return origValue; 562} 563 564void Parcel::restoreAllowFds(bool lastValue) 565{ 566 mAllowFds = lastValue; 567} 568 569bool Parcel::hasFileDescriptors() const 570{ 571 if (!mFdsKnown) { 572 scanForFds(); 573 } 574 return mHasFds; 575} 576 577// Write RPC headers. (previously just the interface token) 578status_t Parcel::writeInterfaceToken(const String16& interface) 579{ 580 writeInt32(IPCThreadState::self()->getStrictModePolicy() | 581 STRICT_MODE_PENALTY_GATHER); 582 // currently the interface identification token is just its name as a string 583 return writeString16(interface); 584} 585 586bool Parcel::checkInterface(IBinder* binder) const 587{ 588 return enforceInterface(binder->getInterfaceDescriptor()); 589} 590 591bool Parcel::enforceInterface(const String16& interface, 592 IPCThreadState* threadState) const 593{ 594 int32_t strictPolicy = readInt32(); 595 if (threadState == NULL) { 596 threadState = IPCThreadState::self(); 597 } 598 if ((threadState->getLastTransactionBinderFlags() & 599 IBinder::FLAG_ONEWAY) != 0) { 600 // For one-way calls, the callee is running entirely 601 // disconnected from the caller, so disable StrictMode entirely. 602 // Not only does disk/network usage not impact the caller, but 603 // there's no way to commuicate back any violations anyway. 604 threadState->setStrictModePolicy(0); 605 } else { 606 threadState->setStrictModePolicy(strictPolicy); 607 } 608 const String16 str(readString16()); 609 if (str == interface) { 610 return true; 611 } else { 612 ALOGW("**** enforceInterface() expected '%s' but read '%s'", 613 String8(interface).string(), String8(str).string()); 614 return false; 615 } 616} 617 618const binder_size_t* Parcel::objects() const 619{ 620 return mObjects; 621} 622 623size_t Parcel::objectsCount() const 624{ 625 return mObjectsSize; 626} 627 628status_t Parcel::errorCheck() const 629{ 630 return mError; 631} 632 633void Parcel::setError(status_t err) 634{ 635 mError = err; 636} 637 638status_t Parcel::finishWrite(size_t len) 639{ 640 if (len > INT32_MAX) { 641 // don't accept size_t values which may have come from an 642 // inadvertent conversion from a negative int. 643 return BAD_VALUE; 644 } 645 646 //printf("Finish write of %d\n", len); 647 mDataPos += len; 648 ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos); 649 if (mDataPos > mDataSize) { 650 mDataSize = mDataPos; 651 ALOGV("finishWrite Setting data size of %p to %zu", this, mDataSize); 652 } 653 //printf("New pos=%d, size=%d\n", mDataPos, mDataSize); 654 return NO_ERROR; 655} 656 657status_t Parcel::writeUnpadded(const void* data, size_t len) 658{ 659 if (len > INT32_MAX) { 660 // don't accept size_t values which may have come from an 661 // inadvertent conversion from a negative int. 662 return BAD_VALUE; 663 } 664 665 size_t end = mDataPos + len; 666 if (end < mDataPos) { 667 // integer overflow 668 return BAD_VALUE; 669 } 670 671 if (end <= mDataCapacity) { 672restart_write: 673 memcpy(mData+mDataPos, data, len); 674 return finishWrite(len); 675 } 676 677 status_t err = growData(len); 678 if (err == NO_ERROR) goto restart_write; 679 return err; 680} 681 682status_t Parcel::write(const void* data, size_t len) 683{ 684 if (len > INT32_MAX) { 685 // don't accept size_t values which may have come from an 686 // inadvertent conversion from a negative int. 687 return BAD_VALUE; 688 } 689 690 void* const d = writeInplace(len); 691 if (d) { 692 memcpy(d, data, len); 693 return NO_ERROR; 694 } 695 return mError; 696} 697 698void* Parcel::writeInplace(size_t len) 699{ 700 if (len > INT32_MAX) { 701 // don't accept size_t values which may have come from an 702 // inadvertent conversion from a negative int. 703 return NULL; 704 } 705 706 const size_t padded = pad_size(len); 707 708 // sanity check for integer overflow 709 if (mDataPos+padded < mDataPos) { 710 return NULL; 711 } 712 713 if ((mDataPos+padded) <= mDataCapacity) { 714restart_write: 715 //printf("Writing %ld bytes, padded to %ld\n", len, padded); 716 uint8_t* const data = mData+mDataPos; 717 718 // Need to pad at end? 719 if (padded != len) { 720#if BYTE_ORDER == BIG_ENDIAN 721 static const uint32_t mask[4] = { 722 0x00000000, 0xffffff00, 0xffff0000, 0xff000000 723 }; 724#endif 725#if BYTE_ORDER == LITTLE_ENDIAN 726 static const uint32_t mask[4] = { 727 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff 728 }; 729#endif 730 //printf("Applying pad mask: %p to %p\n", (void*)mask[padded-len], 731 // *reinterpret_cast<void**>(data+padded-4)); 732 *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len]; 733 } 734 735 finishWrite(padded); 736 return data; 737 } 738 739 status_t err = growData(padded); 740 if (err == NO_ERROR) goto restart_write; 741 return NULL; 742} 743 744status_t Parcel::writeByteVector(const std::vector<int8_t>& val) 745{ 746 status_t status; 747 if (val.size() > std::numeric_limits<int32_t>::max()) { 748 status = BAD_VALUE; 749 return status; 750 } 751 752 status = writeInt32(val.size()); 753 if (status != OK) { 754 return status; 755 } 756 757 void* data = writeInplace(val.size()); 758 if (!data) { 759 status = BAD_VALUE; 760 return status; 761 } 762 763 memcpy(data, val.data(), val.size()); 764 return status; 765} 766 767status_t Parcel::writeInt32Vector(const std::vector<int32_t>& val) 768{ 769 return writeTypedVector(val, &Parcel::writeInt32); 770} 771 772status_t Parcel::writeInt64Vector(const std::vector<int64_t>& val) 773{ 774 return writeTypedVector(val, &Parcel::writeInt64); 775} 776 777status_t Parcel::writeFloatVector(const std::vector<float>& val) 778{ 779 return writeTypedVector(val, &Parcel::writeFloat); 780} 781 782status_t Parcel::writeDoubleVector(const std::vector<double>& val) 783{ 784 return writeTypedVector(val, &Parcel::writeDouble); 785} 786 787status_t Parcel::writeBoolVector(const std::vector<bool>& val) 788{ 789 return writeTypedVector(val, &Parcel::writeBool); 790} 791 792status_t Parcel::writeCharVector(const std::vector<char16_t>& val) 793{ 794 return writeTypedVector(val, &Parcel::writeChar); 795} 796 797status_t Parcel::writeString16Vector(const std::vector<String16>& val) 798{ 799 return writeTypedVector(val, &Parcel::writeString16); 800} 801 802status_t Parcel::writeInt32(int32_t val) 803{ 804 return writeAligned(val); 805} 806 807status_t Parcel::writeUint32(uint32_t val) 808{ 809 return writeAligned(val); 810} 811 812status_t Parcel::writeInt32Array(size_t len, const int32_t *val) { 813 if (len > INT32_MAX) { 814 // don't accept size_t values which may have come from an 815 // inadvertent conversion from a negative int. 816 return BAD_VALUE; 817 } 818 819 if (!val) { 820 return writeInt32(-1); 821 } 822 status_t ret = writeInt32(static_cast<uint32_t>(len)); 823 if (ret == NO_ERROR) { 824 ret = write(val, len * sizeof(*val)); 825 } 826 return ret; 827} 828status_t Parcel::writeByteArray(size_t len, const uint8_t *val) { 829 if (len > INT32_MAX) { 830 // don't accept size_t values which may have come from an 831 // inadvertent conversion from a negative int. 832 return BAD_VALUE; 833 } 834 835 if (!val) { 836 return writeInt32(-1); 837 } 838 status_t ret = writeInt32(static_cast<uint32_t>(len)); 839 if (ret == NO_ERROR) { 840 ret = write(val, len * sizeof(*val)); 841 } 842 return ret; 843} 844 845status_t Parcel::writeBool(bool val) 846{ 847 return writeInt32(int32_t(val)); 848} 849 850status_t Parcel::writeChar(char16_t val) 851{ 852 return writeInt32(int32_t(val)); 853} 854 855status_t Parcel::writeByte(int8_t val) 856{ 857 return writeInt32(int32_t(val)); 858} 859 860status_t Parcel::writeInt64(int64_t val) 861{ 862 return writeAligned(val); 863} 864 865status_t Parcel::writeUint64(uint64_t val) 866{ 867 return writeAligned(val); 868} 869 870status_t Parcel::writePointer(uintptr_t val) 871{ 872 return writeAligned<binder_uintptr_t>(val); 873} 874 875status_t Parcel::writeFloat(float val) 876{ 877 return writeAligned(val); 878} 879 880#if defined(__mips__) && defined(__mips_hard_float) 881 882status_t Parcel::writeDouble(double val) 883{ 884 union { 885 double d; 886 unsigned long long ll; 887 } u; 888 u.d = val; 889 return writeAligned(u.ll); 890} 891 892#else 893 894status_t Parcel::writeDouble(double val) 895{ 896 return writeAligned(val); 897} 898 899#endif 900 901status_t Parcel::writeCString(const char* str) 902{ 903 return write(str, strlen(str)+1); 904} 905 906status_t Parcel::writeString8(const String8& str) 907{ 908 status_t err = writeInt32(str.bytes()); 909 // only write string if its length is more than zero characters, 910 // as readString8 will only read if the length field is non-zero. 911 // this is slightly different from how writeString16 works. 912 if (str.bytes() > 0 && err == NO_ERROR) { 913 err = write(str.string(), str.bytes()+1); 914 } 915 return err; 916} 917 918status_t Parcel::writeString16(const String16& str) 919{ 920 return writeString16(str.string(), str.size()); 921} 922 923status_t Parcel::writeString16(const char16_t* str, size_t len) 924{ 925 if (str == NULL) return writeInt32(-1); 926 927 status_t err = writeInt32(len); 928 if (err == NO_ERROR) { 929 len *= sizeof(char16_t); 930 uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t)); 931 if (data) { 932 memcpy(data, str, len); 933 *reinterpret_cast<char16_t*>(data+len) = 0; 934 return NO_ERROR; 935 } 936 err = mError; 937 } 938 return err; 939} 940 941status_t Parcel::writeStrongBinder(const sp<IBinder>& val) 942{ 943 return flatten_binder(ProcessState::self(), val, this); 944} 945 946status_t Parcel::writeStrongBinderVector(const std::vector<sp<IBinder>>& val) 947{ 948 return writeTypedVector(val, &Parcel::writeStrongBinder); 949} 950 951status_t Parcel::readStrongBinderVector(std::vector<sp<IBinder>>* val) const { 952 return readTypedVector(val, &Parcel::readStrongBinder); 953} 954 955status_t Parcel::writeWeakBinder(const wp<IBinder>& val) 956{ 957 return flatten_binder(ProcessState::self(), val, this); 958} 959 960status_t Parcel::writeParcelable(const Parcelable& parcelable) { 961 status_t status = writeInt32(1); // parcelable is not null. 962 if (status != OK) { 963 return status; 964 } 965 return parcelable.writeToParcel(this); 966} 967 968status_t Parcel::writeNativeHandle(const native_handle* handle) 969{ 970 if (!handle || handle->version != sizeof(native_handle)) 971 return BAD_TYPE; 972 973 status_t err; 974 err = writeInt32(handle->numFds); 975 if (err != NO_ERROR) return err; 976 977 err = writeInt32(handle->numInts); 978 if (err != NO_ERROR) return err; 979 980 for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++) 981 err = writeDupFileDescriptor(handle->data[i]); 982 983 if (err != NO_ERROR) { 984 ALOGD("write native handle, write dup fd failed"); 985 return err; 986 } 987 err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts); 988 return err; 989} 990 991status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership) 992{ 993 flat_binder_object obj; 994 obj.type = BINDER_TYPE_FD; 995 obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; 996 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */ 997 obj.handle = fd; 998 obj.cookie = takeOwnership ? 1 : 0; 999 return writeObject(obj, true); 1000} 1001 1002status_t Parcel::writeDupFileDescriptor(int fd) 1003{ 1004 int dupFd = dup(fd); 1005 if (dupFd < 0) { 1006 return -errno; 1007 } 1008 status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/); 1009 if (err != OK) { 1010 close(dupFd); 1011 } 1012 return err; 1013} 1014 1015status_t Parcel::writeUniqueFileDescriptor(const ScopedFd& fd) { 1016 return writeDupFileDescriptor(fd.get()); 1017} 1018 1019status_t Parcel::writeUniqueFileDescriptorVector(const std::vector<ScopedFd>& val) { 1020 return writeTypedVector(val, &Parcel::writeUniqueFileDescriptor); 1021} 1022 1023status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob) 1024{ 1025 if (len > INT32_MAX) { 1026 // don't accept size_t values which may have come from an 1027 // inadvertent conversion from a negative int. 1028 return BAD_VALUE; 1029 } 1030 1031 status_t status; 1032 if (!mAllowFds || len <= BLOB_INPLACE_LIMIT) { 1033 ALOGV("writeBlob: write in place"); 1034 status = writeInt32(BLOB_INPLACE); 1035 if (status) return status; 1036 1037 void* ptr = writeInplace(len); 1038 if (!ptr) return NO_MEMORY; 1039 1040 outBlob->init(-1, ptr, len, false); 1041 return NO_ERROR; 1042 } 1043 1044 ALOGV("writeBlob: write to ashmem"); 1045 int fd = ashmem_create_region("Parcel Blob", len); 1046 if (fd < 0) return NO_MEMORY; 1047 1048 int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE); 1049 if (result < 0) { 1050 status = result; 1051 } else { 1052 void* ptr = ::mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 1053 if (ptr == MAP_FAILED) { 1054 status = -errno; 1055 } else { 1056 if (!mutableCopy) { 1057 result = ashmem_set_prot_region(fd, PROT_READ); 1058 } 1059 if (result < 0) { 1060 status = result; 1061 } else { 1062 status = writeInt32(mutableCopy ? BLOB_ASHMEM_MUTABLE : BLOB_ASHMEM_IMMUTABLE); 1063 if (!status) { 1064 status = writeFileDescriptor(fd, true /*takeOwnership*/); 1065 if (!status) { 1066 outBlob->init(fd, ptr, len, mutableCopy); 1067 return NO_ERROR; 1068 } 1069 } 1070 } 1071 } 1072 ::munmap(ptr, len); 1073 } 1074 ::close(fd); 1075 return status; 1076} 1077 1078status_t Parcel::writeDupImmutableBlobFileDescriptor(int fd) 1079{ 1080 // Must match up with what's done in writeBlob. 1081 if (!mAllowFds) return FDS_NOT_ALLOWED; 1082 status_t status = writeInt32(BLOB_ASHMEM_IMMUTABLE); 1083 if (status) return status; 1084 return writeDupFileDescriptor(fd); 1085} 1086 1087status_t Parcel::write(const FlattenableHelperInterface& val) 1088{ 1089 status_t err; 1090 1091 // size if needed 1092 const size_t len = val.getFlattenedSize(); 1093 const size_t fd_count = val.getFdCount(); 1094 1095 if ((len > INT32_MAX) || (fd_count > INT32_MAX)) { 1096 // don't accept size_t values which may have come from an 1097 // inadvertent conversion from a negative int. 1098 return BAD_VALUE; 1099 } 1100 1101 err = this->writeInt32(len); 1102 if (err) return err; 1103 1104 err = this->writeInt32(fd_count); 1105 if (err) return err; 1106 1107 // payload 1108 void* const buf = this->writeInplace(pad_size(len)); 1109 if (buf == NULL) 1110 return BAD_VALUE; 1111 1112 int* fds = NULL; 1113 if (fd_count) { 1114 fds = new int[fd_count]; 1115 } 1116 1117 err = val.flatten(buf, len, fds, fd_count); 1118 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) { 1119 err = this->writeDupFileDescriptor( fds[i] ); 1120 } 1121 1122 if (fd_count) { 1123 delete [] fds; 1124 } 1125 1126 return err; 1127} 1128 1129status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData) 1130{ 1131 const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity; 1132 const bool enoughObjects = mObjectsSize < mObjectsCapacity; 1133 if (enoughData && enoughObjects) { 1134restart_write: 1135 *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val; 1136 1137 // remember if it's a file descriptor 1138 if (val.type == BINDER_TYPE_FD) { 1139 if (!mAllowFds) { 1140 // fail before modifying our object index 1141 return FDS_NOT_ALLOWED; 1142 } 1143 mHasFds = mFdsKnown = true; 1144 } 1145 1146 // Need to write meta-data? 1147 if (nullMetaData || val.binder != 0) { 1148 mObjects[mObjectsSize] = mDataPos; 1149 acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize); 1150 mObjectsSize++; 1151 } 1152 1153 return finishWrite(sizeof(flat_binder_object)); 1154 } 1155 1156 if (!enoughData) { 1157 const status_t err = growData(sizeof(val)); 1158 if (err != NO_ERROR) return err; 1159 } 1160 if (!enoughObjects) { 1161 size_t newSize = ((mObjectsSize+2)*3)/2; 1162 if (newSize < mObjectsSize) return NO_MEMORY; // overflow 1163 binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t)); 1164 if (objects == NULL) return NO_MEMORY; 1165 mObjects = objects; 1166 mObjectsCapacity = newSize; 1167 } 1168 1169 goto restart_write; 1170} 1171 1172status_t Parcel::writeNoException() 1173{ 1174 binder::Status status; 1175 return status.writeToParcel(this); 1176} 1177 1178void Parcel::remove(size_t /*start*/, size_t /*amt*/) 1179{ 1180 LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!"); 1181} 1182 1183status_t Parcel::read(void* outData, size_t len) const 1184{ 1185 if (len > INT32_MAX) { 1186 // don't accept size_t values which may have come from an 1187 // inadvertent conversion from a negative int. 1188 return BAD_VALUE; 1189 } 1190 1191 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize 1192 && len <= pad_size(len)) { 1193 memcpy(outData, mData+mDataPos, len); 1194 mDataPos += pad_size(len); 1195 ALOGV("read Setting data pos of %p to %zu", this, mDataPos); 1196 return NO_ERROR; 1197 } 1198 return NOT_ENOUGH_DATA; 1199} 1200 1201const void* Parcel::readInplace(size_t len) const 1202{ 1203 if (len > INT32_MAX) { 1204 // don't accept size_t values which may have come from an 1205 // inadvertent conversion from a negative int. 1206 return NULL; 1207 } 1208 1209 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize 1210 && len <= pad_size(len)) { 1211 const void* data = mData+mDataPos; 1212 mDataPos += pad_size(len); 1213 ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos); 1214 return data; 1215 } 1216 return NULL; 1217} 1218 1219template<class T> 1220status_t Parcel::readAligned(T *pArg) const { 1221 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T)); 1222 1223 if ((mDataPos+sizeof(T)) <= mDataSize) { 1224 const void* data = mData+mDataPos; 1225 mDataPos += sizeof(T); 1226 *pArg = *reinterpret_cast<const T*>(data); 1227 return NO_ERROR; 1228 } else { 1229 return NOT_ENOUGH_DATA; 1230 } 1231} 1232 1233template<class T> 1234T Parcel::readAligned() const { 1235 T result; 1236 if (readAligned(&result) != NO_ERROR) { 1237 result = 0; 1238 } 1239 1240 return result; 1241} 1242 1243template<class T> 1244status_t Parcel::writeAligned(T val) { 1245 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T)); 1246 1247 if ((mDataPos+sizeof(val)) <= mDataCapacity) { 1248restart_write: 1249 *reinterpret_cast<T*>(mData+mDataPos) = val; 1250 return finishWrite(sizeof(val)); 1251 } 1252 1253 status_t err = growData(sizeof(val)); 1254 if (err == NO_ERROR) goto restart_write; 1255 return err; 1256} 1257 1258status_t Parcel::readByteVector(std::vector<int8_t>* val) const { 1259 val->clear(); 1260 1261 int32_t size; 1262 status_t status = readInt32(&size); 1263 1264 if (status != OK) { 1265 return status; 1266 } 1267 1268 if (size < 0) { 1269 status = UNEXPECTED_NULL; 1270 return status; 1271 } 1272 if (size_t(size) > dataAvail()) { 1273 status = BAD_VALUE; 1274 return status; 1275 } 1276 1277 const void* data = readInplace(size); 1278 if (!data) { 1279 status = BAD_VALUE; 1280 return status; 1281 } 1282 val->resize(size); 1283 memcpy(val->data(), data, size); 1284 1285 return status; 1286} 1287 1288status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const { 1289 return readTypedVector(val, &Parcel::readInt32); 1290} 1291 1292status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const { 1293 return readTypedVector(val, &Parcel::readInt64); 1294} 1295 1296status_t Parcel::readFloatVector(std::vector<float>* val) const { 1297 return readTypedVector(val, &Parcel::readFloat); 1298} 1299 1300status_t Parcel::readDoubleVector(std::vector<double>* val) const { 1301 return readTypedVector(val, &Parcel::readDouble); 1302} 1303 1304status_t Parcel::readBoolVector(std::vector<bool>* val) const { 1305 val->clear(); 1306 1307 int32_t size; 1308 status_t status = readInt32(&size); 1309 1310 if (status != OK) { 1311 return status; 1312 } 1313 1314 if (size < 0) { 1315 return UNEXPECTED_NULL; 1316 } 1317 1318 val->resize(size); 1319 1320 /* C++ bool handling means a vector of bools isn't necessarily addressable 1321 * (we might use individual bits) 1322 */ 1323 bool data; 1324 for (int32_t i = 0; i < size; ++i) { 1325 status = readBool(&data); 1326 (*val)[i] = data; 1327 1328 if (status != OK) { 1329 return status; 1330 } 1331 } 1332 1333 return OK; 1334} 1335 1336status_t Parcel::readCharVector(std::vector<char16_t>* val) const { 1337 return readTypedVector(val, &Parcel::readChar); 1338} 1339 1340status_t Parcel::readString16Vector(std::vector<String16>* val) const { 1341 return readTypedVector(val, &Parcel::readString16); 1342} 1343 1344 1345status_t Parcel::readInt32(int32_t *pArg) const 1346{ 1347 return readAligned(pArg); 1348} 1349 1350int32_t Parcel::readInt32() const 1351{ 1352 return readAligned<int32_t>(); 1353} 1354 1355status_t Parcel::readUint32(uint32_t *pArg) const 1356{ 1357 return readAligned(pArg); 1358} 1359 1360uint32_t Parcel::readUint32() const 1361{ 1362 return readAligned<uint32_t>(); 1363} 1364 1365status_t Parcel::readInt64(int64_t *pArg) const 1366{ 1367 return readAligned(pArg); 1368} 1369 1370 1371int64_t Parcel::readInt64() const 1372{ 1373 return readAligned<int64_t>(); 1374} 1375 1376status_t Parcel::readUint64(uint64_t *pArg) const 1377{ 1378 return readAligned(pArg); 1379} 1380 1381uint64_t Parcel::readUint64() const 1382{ 1383 return readAligned<uint64_t>(); 1384} 1385 1386status_t Parcel::readPointer(uintptr_t *pArg) const 1387{ 1388 status_t ret; 1389 binder_uintptr_t ptr; 1390 ret = readAligned(&ptr); 1391 if (!ret) 1392 *pArg = ptr; 1393 return ret; 1394} 1395 1396uintptr_t Parcel::readPointer() const 1397{ 1398 return readAligned<binder_uintptr_t>(); 1399} 1400 1401 1402status_t Parcel::readFloat(float *pArg) const 1403{ 1404 return readAligned(pArg); 1405} 1406 1407 1408float Parcel::readFloat() const 1409{ 1410 return readAligned<float>(); 1411} 1412 1413#if defined(__mips__) && defined(__mips_hard_float) 1414 1415status_t Parcel::readDouble(double *pArg) const 1416{ 1417 union { 1418 double d; 1419 unsigned long long ll; 1420 } u; 1421 u.d = 0; 1422 status_t status; 1423 status = readAligned(&u.ll); 1424 *pArg = u.d; 1425 return status; 1426} 1427 1428double Parcel::readDouble() const 1429{ 1430 union { 1431 double d; 1432 unsigned long long ll; 1433 } u; 1434 u.ll = readAligned<unsigned long long>(); 1435 return u.d; 1436} 1437 1438#else 1439 1440status_t Parcel::readDouble(double *pArg) const 1441{ 1442 return readAligned(pArg); 1443} 1444 1445double Parcel::readDouble() const 1446{ 1447 return readAligned<double>(); 1448} 1449 1450#endif 1451 1452status_t Parcel::readIntPtr(intptr_t *pArg) const 1453{ 1454 return readAligned(pArg); 1455} 1456 1457 1458intptr_t Parcel::readIntPtr() const 1459{ 1460 return readAligned<intptr_t>(); 1461} 1462 1463status_t Parcel::readBool(bool *pArg) const 1464{ 1465 int32_t tmp; 1466 status_t ret = readInt32(&tmp); 1467 *pArg = (tmp != 0); 1468 return ret; 1469} 1470 1471bool Parcel::readBool() const 1472{ 1473 return readInt32() != 0; 1474} 1475 1476status_t Parcel::readChar(char16_t *pArg) const 1477{ 1478 int32_t tmp; 1479 status_t ret = readInt32(&tmp); 1480 *pArg = char16_t(tmp); 1481 return ret; 1482} 1483 1484char16_t Parcel::readChar() const 1485{ 1486 return char16_t(readInt32()); 1487} 1488 1489status_t Parcel::readByte(int8_t *pArg) const 1490{ 1491 int32_t tmp; 1492 status_t ret = readInt32(&tmp); 1493 *pArg = int8_t(tmp); 1494 return ret; 1495} 1496 1497int8_t Parcel::readByte() const 1498{ 1499 return int8_t(readInt32()); 1500} 1501 1502const char* Parcel::readCString() const 1503{ 1504 const size_t avail = mDataSize-mDataPos; 1505 if (avail > 0) { 1506 const char* str = reinterpret_cast<const char*>(mData+mDataPos); 1507 // is the string's trailing NUL within the parcel's valid bounds? 1508 const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail)); 1509 if (eos) { 1510 const size_t len = eos - str; 1511 mDataPos += pad_size(len+1); 1512 ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos); 1513 return str; 1514 } 1515 } 1516 return NULL; 1517} 1518 1519String8 Parcel::readString8() const 1520{ 1521 int32_t size = readInt32(); 1522 // watch for potential int overflow adding 1 for trailing NUL 1523 if (size > 0 && size < INT32_MAX) { 1524 const char* str = (const char*)readInplace(size+1); 1525 if (str) return String8(str, size); 1526 } 1527 return String8(); 1528} 1529 1530String16 Parcel::readString16() const 1531{ 1532 size_t len; 1533 const char16_t* str = readString16Inplace(&len); 1534 if (str) return String16(str, len); 1535 ALOGE("Reading a NULL string not supported here."); 1536 return String16(); 1537} 1538 1539status_t Parcel::readString16(String16* pArg) const 1540{ 1541 size_t len; 1542 const char16_t* str = readString16Inplace(&len); 1543 if (str) { 1544 pArg->setTo(str, len); 1545 return 0; 1546 } else { 1547 *pArg = String16(); 1548 return UNEXPECTED_NULL; 1549 } 1550} 1551 1552const char16_t* Parcel::readString16Inplace(size_t* outLen) const 1553{ 1554 int32_t size = readInt32(); 1555 // watch for potential int overflow from size+1 1556 if (size >= 0 && size < INT32_MAX) { 1557 *outLen = size; 1558 const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t)); 1559 if (str != NULL) { 1560 return str; 1561 } 1562 } 1563 *outLen = 0; 1564 return NULL; 1565} 1566 1567status_t Parcel::readStrongBinder(sp<IBinder>* val) const 1568{ 1569 return unflatten_binder(ProcessState::self(), *this, val); 1570} 1571 1572sp<IBinder> Parcel::readStrongBinder() const 1573{ 1574 sp<IBinder> val; 1575 readStrongBinder(&val); 1576 return val; 1577} 1578 1579wp<IBinder> Parcel::readWeakBinder() const 1580{ 1581 wp<IBinder> val; 1582 unflatten_binder(ProcessState::self(), *this, &val); 1583 return val; 1584} 1585 1586status_t Parcel::readParcelable(Parcelable* parcelable) const { 1587 int32_t have_parcelable = 0; 1588 status_t status = readInt32(&have_parcelable); 1589 if (status != OK) { 1590 return status; 1591 } 1592 if (!have_parcelable) { 1593 return UNEXPECTED_NULL; 1594 } 1595 return parcelable->readFromParcel(this); 1596} 1597 1598int32_t Parcel::readExceptionCode() const 1599{ 1600 binder::Status status; 1601 status.readFromParcel(*this); 1602 return status.exceptionCode(); 1603} 1604 1605native_handle* Parcel::readNativeHandle() const 1606{ 1607 int numFds, numInts; 1608 status_t err; 1609 err = readInt32(&numFds); 1610 if (err != NO_ERROR) return 0; 1611 err = readInt32(&numInts); 1612 if (err != NO_ERROR) return 0; 1613 1614 native_handle* h = native_handle_create(numFds, numInts); 1615 if (!h) { 1616 return 0; 1617 } 1618 1619 for (int i=0 ; err==NO_ERROR && i<numFds ; i++) { 1620 h->data[i] = dup(readFileDescriptor()); 1621 if (h->data[i] < 0) err = BAD_VALUE; 1622 } 1623 err = read(h->data + numFds, sizeof(int)*numInts); 1624 if (err != NO_ERROR) { 1625 native_handle_close(h); 1626 native_handle_delete(h); 1627 h = 0; 1628 } 1629 return h; 1630} 1631 1632 1633int Parcel::readFileDescriptor() const 1634{ 1635 const flat_binder_object* flat = readObject(true); 1636 1637 if (flat && flat->type == BINDER_TYPE_FD) { 1638 return flat->handle; 1639 } 1640 1641 return BAD_TYPE; 1642} 1643 1644status_t Parcel::readUniqueFileDescriptor(ScopedFd* val) const 1645{ 1646 int got = readFileDescriptor(); 1647 1648 if (got == BAD_TYPE) { 1649 return BAD_TYPE; 1650 } 1651 1652 val->reset(dup(got)); 1653 1654 if (val->get() < 0) { 1655 return BAD_VALUE; 1656 } 1657 1658 return OK; 1659} 1660 1661 1662status_t Parcel::readUniqueFileDescriptorVector(std::vector<ScopedFd>* val) const { 1663 return readTypedVector(val, &Parcel::readUniqueFileDescriptor); 1664} 1665 1666status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const 1667{ 1668 int32_t blobType; 1669 status_t status = readInt32(&blobType); 1670 if (status) return status; 1671 1672 if (blobType == BLOB_INPLACE) { 1673 ALOGV("readBlob: read in place"); 1674 const void* ptr = readInplace(len); 1675 if (!ptr) return BAD_VALUE; 1676 1677 outBlob->init(-1, const_cast<void*>(ptr), len, false); 1678 return NO_ERROR; 1679 } 1680 1681 ALOGV("readBlob: read from ashmem"); 1682 bool isMutable = (blobType == BLOB_ASHMEM_MUTABLE); 1683 int fd = readFileDescriptor(); 1684 if (fd == int(BAD_TYPE)) return BAD_VALUE; 1685 1686 void* ptr = ::mmap(NULL, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ, 1687 MAP_SHARED, fd, 0); 1688 if (ptr == MAP_FAILED) return NO_MEMORY; 1689 1690 outBlob->init(fd, ptr, len, isMutable); 1691 return NO_ERROR; 1692} 1693 1694status_t Parcel::read(FlattenableHelperInterface& val) const 1695{ 1696 // size 1697 const size_t len = this->readInt32(); 1698 const size_t fd_count = this->readInt32(); 1699 1700 if (len > INT32_MAX) { 1701 // don't accept size_t values which may have come from an 1702 // inadvertent conversion from a negative int. 1703 return BAD_VALUE; 1704 } 1705 1706 // payload 1707 void const* const buf = this->readInplace(pad_size(len)); 1708 if (buf == NULL) 1709 return BAD_VALUE; 1710 1711 int* fds = NULL; 1712 if (fd_count) { 1713 fds = new int[fd_count]; 1714 } 1715 1716 status_t err = NO_ERROR; 1717 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) { 1718 fds[i] = dup(this->readFileDescriptor()); 1719 if (fds[i] < 0) { 1720 err = BAD_VALUE; 1721 ALOGE("dup() failed in Parcel::read, i is %zu, fds[i] is %d, fd_count is %zu, error: %s", 1722 i, fds[i], fd_count, strerror(errno)); 1723 } 1724 } 1725 1726 if (err == NO_ERROR) { 1727 err = val.unflatten(buf, len, fds, fd_count); 1728 } 1729 1730 if (fd_count) { 1731 delete [] fds; 1732 } 1733 1734 return err; 1735} 1736const flat_binder_object* Parcel::readObject(bool nullMetaData) const 1737{ 1738 const size_t DPOS = mDataPos; 1739 if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) { 1740 const flat_binder_object* obj 1741 = reinterpret_cast<const flat_binder_object*>(mData+DPOS); 1742 mDataPos = DPOS + sizeof(flat_binder_object); 1743 if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) { 1744 // When transferring a NULL object, we don't write it into 1745 // the object list, so we don't want to check for it when 1746 // reading. 1747 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos); 1748 return obj; 1749 } 1750 1751 // Ensure that this object is valid... 1752 binder_size_t* const OBJS = mObjects; 1753 const size_t N = mObjectsSize; 1754 size_t opos = mNextObjectHint; 1755 1756 if (N > 0) { 1757 ALOGV("Parcel %p looking for obj at %zu, hint=%zu", 1758 this, DPOS, opos); 1759 1760 // Start at the current hint position, looking for an object at 1761 // the current data position. 1762 if (opos < N) { 1763 while (opos < (N-1) && OBJS[opos] < DPOS) { 1764 opos++; 1765 } 1766 } else { 1767 opos = N-1; 1768 } 1769 if (OBJS[opos] == DPOS) { 1770 // Found it! 1771 ALOGV("Parcel %p found obj %zu at index %zu with forward search", 1772 this, DPOS, opos); 1773 mNextObjectHint = opos+1; 1774 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos); 1775 return obj; 1776 } 1777 1778 // Look backwards for it... 1779 while (opos > 0 && OBJS[opos] > DPOS) { 1780 opos--; 1781 } 1782 if (OBJS[opos] == DPOS) { 1783 // Found it! 1784 ALOGV("Parcel %p found obj %zu at index %zu with backward search", 1785 this, DPOS, opos); 1786 mNextObjectHint = opos+1; 1787 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos); 1788 return obj; 1789 } 1790 } 1791 ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object list", 1792 this, DPOS); 1793 } 1794 return NULL; 1795} 1796 1797void Parcel::closeFileDescriptors() 1798{ 1799 size_t i = mObjectsSize; 1800 if (i > 0) { 1801 //ALOGI("Closing file descriptors for %zu objects...", i); 1802 } 1803 while (i > 0) { 1804 i--; 1805 const flat_binder_object* flat 1806 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]); 1807 if (flat->type == BINDER_TYPE_FD) { 1808 //ALOGI("Closing fd: %ld", flat->handle); 1809 close(flat->handle); 1810 } 1811 } 1812} 1813 1814uintptr_t Parcel::ipcData() const 1815{ 1816 return reinterpret_cast<uintptr_t>(mData); 1817} 1818 1819size_t Parcel::ipcDataSize() const 1820{ 1821 return (mDataSize > mDataPos ? mDataSize : mDataPos); 1822} 1823 1824uintptr_t Parcel::ipcObjects() const 1825{ 1826 return reinterpret_cast<uintptr_t>(mObjects); 1827} 1828 1829size_t Parcel::ipcObjectsCount() const 1830{ 1831 return mObjectsSize; 1832} 1833 1834void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize, 1835 const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie) 1836{ 1837 binder_size_t minOffset = 0; 1838 freeDataNoInit(); 1839 mError = NO_ERROR; 1840 mData = const_cast<uint8_t*>(data); 1841 mDataSize = mDataCapacity = dataSize; 1842 //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)", this, mDataSize, getpid()); 1843 mDataPos = 0; 1844 ALOGV("setDataReference Setting data pos of %p to %zu", this, mDataPos); 1845 mObjects = const_cast<binder_size_t*>(objects); 1846 mObjectsSize = mObjectsCapacity = objectsCount; 1847 mNextObjectHint = 0; 1848 mOwner = relFunc; 1849 mOwnerCookie = relCookie; 1850 for (size_t i = 0; i < mObjectsSize; i++) { 1851 binder_size_t offset = mObjects[i]; 1852 if (offset < minOffset) { 1853 ALOGE("%s: bad object offset %" PRIu64 " < %" PRIu64 "\n", 1854 __func__, (uint64_t)offset, (uint64_t)minOffset); 1855 mObjectsSize = 0; 1856 break; 1857 } 1858 minOffset = offset + sizeof(flat_binder_object); 1859 } 1860 scanForFds(); 1861} 1862 1863void Parcel::print(TextOutput& to, uint32_t /*flags*/) const 1864{ 1865 to << "Parcel("; 1866 1867 if (errorCheck() != NO_ERROR) { 1868 const status_t err = errorCheck(); 1869 to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\""; 1870 } else if (dataSize() > 0) { 1871 const uint8_t* DATA = data(); 1872 to << indent << HexDump(DATA, dataSize()) << dedent; 1873 const binder_size_t* OBJS = objects(); 1874 const size_t N = objectsCount(); 1875 for (size_t i=0; i<N; i++) { 1876 const flat_binder_object* flat 1877 = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]); 1878 to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": " 1879 << TypeCode(flat->type & 0x7f7f7f00) 1880 << " = " << flat->binder; 1881 } 1882 } else { 1883 to << "NULL"; 1884 } 1885 1886 to << ")"; 1887} 1888 1889void Parcel::releaseObjects() 1890{ 1891 const sp<ProcessState> proc(ProcessState::self()); 1892 size_t i = mObjectsSize; 1893 uint8_t* const data = mData; 1894 binder_size_t* const objects = mObjects; 1895 while (i > 0) { 1896 i--; 1897 const flat_binder_object* flat 1898 = reinterpret_cast<flat_binder_object*>(data+objects[i]); 1899 release_object(proc, *flat, this, &mOpenAshmemSize); 1900 } 1901} 1902 1903void Parcel::acquireObjects() 1904{ 1905 const sp<ProcessState> proc(ProcessState::self()); 1906 size_t i = mObjectsSize; 1907 uint8_t* const data = mData; 1908 binder_size_t* const objects = mObjects; 1909 while (i > 0) { 1910 i--; 1911 const flat_binder_object* flat 1912 = reinterpret_cast<flat_binder_object*>(data+objects[i]); 1913 acquire_object(proc, *flat, this, &mOpenAshmemSize); 1914 } 1915} 1916 1917void Parcel::freeData() 1918{ 1919 freeDataNoInit(); 1920 initState(); 1921} 1922 1923void Parcel::freeDataNoInit() 1924{ 1925 if (mOwner) { 1926 LOG_ALLOC("Parcel %p: freeing other owner data", this); 1927 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid()); 1928 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie); 1929 } else { 1930 LOG_ALLOC("Parcel %p: freeing allocated data", this); 1931 releaseObjects(); 1932 if (mData) { 1933 LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity); 1934 pthread_mutex_lock(&gParcelGlobalAllocSizeLock); 1935 if (mDataCapacity <= gParcelGlobalAllocSize) { 1936 gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity; 1937 } else { 1938 gParcelGlobalAllocSize = 0; 1939 } 1940 if (gParcelGlobalAllocCount > 0) { 1941 gParcelGlobalAllocCount--; 1942 } 1943 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); 1944 free(mData); 1945 } 1946 if (mObjects) free(mObjects); 1947 } 1948} 1949 1950status_t Parcel::growData(size_t len) 1951{ 1952 if (len > INT32_MAX) { 1953 // don't accept size_t values which may have come from an 1954 // inadvertent conversion from a negative int. 1955 return BAD_VALUE; 1956 } 1957 1958 size_t newSize = ((mDataSize+len)*3)/2; 1959 return (newSize <= mDataSize) 1960 ? (status_t) NO_MEMORY 1961 : continueWrite(newSize); 1962} 1963 1964status_t Parcel::restartWrite(size_t desired) 1965{ 1966 if (desired > INT32_MAX) { 1967 // don't accept size_t values which may have come from an 1968 // inadvertent conversion from a negative int. 1969 return BAD_VALUE; 1970 } 1971 1972 if (mOwner) { 1973 freeData(); 1974 return continueWrite(desired); 1975 } 1976 1977 uint8_t* data = (uint8_t*)realloc(mData, desired); 1978 if (!data && desired > mDataCapacity) { 1979 mError = NO_MEMORY; 1980 return NO_MEMORY; 1981 } 1982 1983 releaseObjects(); 1984 1985 if (data) { 1986 LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired); 1987 pthread_mutex_lock(&gParcelGlobalAllocSizeLock); 1988 gParcelGlobalAllocSize += desired; 1989 gParcelGlobalAllocSize -= mDataCapacity; 1990 if (!mData) { 1991 gParcelGlobalAllocCount++; 1992 } 1993 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); 1994 mData = data; 1995 mDataCapacity = desired; 1996 } 1997 1998 mDataSize = mDataPos = 0; 1999 ALOGV("restartWrite Setting data size of %p to %zu", this, mDataSize); 2000 ALOGV("restartWrite Setting data pos of %p to %zu", this, mDataPos); 2001 2002 free(mObjects); 2003 mObjects = NULL; 2004 mObjectsSize = mObjectsCapacity = 0; 2005 mNextObjectHint = 0; 2006 mHasFds = false; 2007 mFdsKnown = true; 2008 mAllowFds = true; 2009 2010 return NO_ERROR; 2011} 2012 2013status_t Parcel::continueWrite(size_t desired) 2014{ 2015 if (desired > INT32_MAX) { 2016 // don't accept size_t values which may have come from an 2017 // inadvertent conversion from a negative int. 2018 return BAD_VALUE; 2019 } 2020 2021 // If shrinking, first adjust for any objects that appear 2022 // after the new data size. 2023 size_t objectsSize = mObjectsSize; 2024 if (desired < mDataSize) { 2025 if (desired == 0) { 2026 objectsSize = 0; 2027 } else { 2028 while (objectsSize > 0) { 2029 if (mObjects[objectsSize-1] < desired) 2030 break; 2031 objectsSize--; 2032 } 2033 } 2034 } 2035 2036 if (mOwner) { 2037 // If the size is going to zero, just release the owner's data. 2038 if (desired == 0) { 2039 freeData(); 2040 return NO_ERROR; 2041 } 2042 2043 // If there is a different owner, we need to take 2044 // posession. 2045 uint8_t* data = (uint8_t*)malloc(desired); 2046 if (!data) { 2047 mError = NO_MEMORY; 2048 return NO_MEMORY; 2049 } 2050 binder_size_t* objects = NULL; 2051 2052 if (objectsSize) { 2053 objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t)); 2054 if (!objects) { 2055 free(data); 2056 2057 mError = NO_MEMORY; 2058 return NO_MEMORY; 2059 } 2060 2061 // Little hack to only acquire references on objects 2062 // we will be keeping. 2063 size_t oldObjectsSize = mObjectsSize; 2064 mObjectsSize = objectsSize; 2065 acquireObjects(); 2066 mObjectsSize = oldObjectsSize; 2067 } 2068 2069 if (mData) { 2070 memcpy(data, mData, mDataSize < desired ? mDataSize : desired); 2071 } 2072 if (objects && mObjects) { 2073 memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t)); 2074 } 2075 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid()); 2076 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie); 2077 mOwner = NULL; 2078 2079 LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired); 2080 pthread_mutex_lock(&gParcelGlobalAllocSizeLock); 2081 gParcelGlobalAllocSize += desired; 2082 gParcelGlobalAllocCount++; 2083 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); 2084 2085 mData = data; 2086 mObjects = objects; 2087 mDataSize = (mDataSize < desired) ? mDataSize : desired; 2088 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize); 2089 mDataCapacity = desired; 2090 mObjectsSize = mObjectsCapacity = objectsSize; 2091 mNextObjectHint = 0; 2092 2093 } else if (mData) { 2094 if (objectsSize < mObjectsSize) { 2095 // Need to release refs on any objects we are dropping. 2096 const sp<ProcessState> proc(ProcessState::self()); 2097 for (size_t i=objectsSize; i<mObjectsSize; i++) { 2098 const flat_binder_object* flat 2099 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]); 2100 if (flat->type == BINDER_TYPE_FD) { 2101 // will need to rescan because we may have lopped off the only FDs 2102 mFdsKnown = false; 2103 } 2104 release_object(proc, *flat, this, &mOpenAshmemSize); 2105 } 2106 binder_size_t* objects = 2107 (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t)); 2108 if (objects) { 2109 mObjects = objects; 2110 } 2111 mObjectsSize = objectsSize; 2112 mNextObjectHint = 0; 2113 } 2114 2115 // We own the data, so we can just do a realloc(). 2116 if (desired > mDataCapacity) { 2117 uint8_t* data = (uint8_t*)realloc(mData, desired); 2118 if (data) { 2119 LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity, 2120 desired); 2121 pthread_mutex_lock(&gParcelGlobalAllocSizeLock); 2122 gParcelGlobalAllocSize += desired; 2123 gParcelGlobalAllocSize -= mDataCapacity; 2124 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); 2125 mData = data; 2126 mDataCapacity = desired; 2127 } else if (desired > mDataCapacity) { 2128 mError = NO_MEMORY; 2129 return NO_MEMORY; 2130 } 2131 } else { 2132 if (mDataSize > desired) { 2133 mDataSize = desired; 2134 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize); 2135 } 2136 if (mDataPos > desired) { 2137 mDataPos = desired; 2138 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos); 2139 } 2140 } 2141 2142 } else { 2143 // This is the first data. Easy! 2144 uint8_t* data = (uint8_t*)malloc(desired); 2145 if (!data) { 2146 mError = NO_MEMORY; 2147 return NO_MEMORY; 2148 } 2149 2150 if(!(mDataCapacity == 0 && mObjects == NULL 2151 && mObjectsCapacity == 0)) { 2152 ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired); 2153 } 2154 2155 LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired); 2156 pthread_mutex_lock(&gParcelGlobalAllocSizeLock); 2157 gParcelGlobalAllocSize += desired; 2158 gParcelGlobalAllocCount++; 2159 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); 2160 2161 mData = data; 2162 mDataSize = mDataPos = 0; 2163 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize); 2164 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos); 2165 mDataCapacity = desired; 2166 } 2167 2168 return NO_ERROR; 2169} 2170 2171void Parcel::initState() 2172{ 2173 LOG_ALLOC("Parcel %p: initState", this); 2174 mError = NO_ERROR; 2175 mData = 0; 2176 mDataSize = 0; 2177 mDataCapacity = 0; 2178 mDataPos = 0; 2179 ALOGV("initState Setting data size of %p to %zu", this, mDataSize); 2180 ALOGV("initState Setting data pos of %p to %zu", this, mDataPos); 2181 mObjects = NULL; 2182 mObjectsSize = 0; 2183 mObjectsCapacity = 0; 2184 mNextObjectHint = 0; 2185 mHasFds = false; 2186 mFdsKnown = true; 2187 mAllowFds = true; 2188 mOwner = NULL; 2189 mOpenAshmemSize = 0; 2190} 2191 2192void Parcel::scanForFds() const 2193{ 2194 bool hasFds = false; 2195 for (size_t i=0; i<mObjectsSize; i++) { 2196 const flat_binder_object* flat 2197 = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]); 2198 if (flat->type == BINDER_TYPE_FD) { 2199 hasFds = true; 2200 break; 2201 } 2202 } 2203 mHasFds = hasFds; 2204 mFdsKnown = true; 2205} 2206 2207size_t Parcel::getBlobAshmemSize() const 2208{ 2209 // This used to return the size of all blobs that were written to ashmem, now we're returning 2210 // the ashmem currently referenced by this Parcel, which should be equivalent. 2211 // TODO: Remove method once ABI can be changed. 2212 return mOpenAshmemSize; 2213} 2214 2215size_t Parcel::getOpenAshmemSize() const 2216{ 2217 return mOpenAshmemSize; 2218} 2219 2220// --- Parcel::Blob --- 2221 2222Parcel::Blob::Blob() : 2223 mFd(-1), mData(NULL), mSize(0), mMutable(false) { 2224} 2225 2226Parcel::Blob::~Blob() { 2227 release(); 2228} 2229 2230void Parcel::Blob::release() { 2231 if (mFd != -1 && mData) { 2232 ::munmap(mData, mSize); 2233 } 2234 clear(); 2235} 2236 2237void Parcel::Blob::init(int fd, void* data, size_t size, bool isMutable) { 2238 mFd = fd; 2239 mData = data; 2240 mSize = size; 2241 mMutable = isMutable; 2242} 2243 2244void Parcel::Blob::clear() { 2245 mFd = -1; 2246 mData = NULL; 2247 mSize = 0; 2248 mMutable = false; 2249} 2250 2251}; // namespace android 2252