Parcel.cpp revision 14b02baadaa7143c5e059ab0e58c48c1a39de14b
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::writeNativeHandle(const native_handle* handle) 961{ 962 if (!handle || handle->version != sizeof(native_handle)) 963 return BAD_TYPE; 964 965 status_t err; 966 err = writeInt32(handle->numFds); 967 if (err != NO_ERROR) return err; 968 969 err = writeInt32(handle->numInts); 970 if (err != NO_ERROR) return err; 971 972 for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++) 973 err = writeDupFileDescriptor(handle->data[i]); 974 975 if (err != NO_ERROR) { 976 ALOGD("write native handle, write dup fd failed"); 977 return err; 978 } 979 err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts); 980 return err; 981} 982 983status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership) 984{ 985 flat_binder_object obj; 986 obj.type = BINDER_TYPE_FD; 987 obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; 988 obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */ 989 obj.handle = fd; 990 obj.cookie = takeOwnership ? 1 : 0; 991 return writeObject(obj, true); 992} 993 994status_t Parcel::writeDupFileDescriptor(int fd) 995{ 996 int dupFd = dup(fd); 997 if (dupFd < 0) { 998 return -errno; 999 } 1000 status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/); 1001 if (err) { 1002 close(dupFd); 1003 } 1004 return err; 1005} 1006 1007status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob) 1008{ 1009 if (len > INT32_MAX) { 1010 // don't accept size_t values which may have come from an 1011 // inadvertent conversion from a negative int. 1012 return BAD_VALUE; 1013 } 1014 1015 status_t status; 1016 if (!mAllowFds || len <= BLOB_INPLACE_LIMIT) { 1017 ALOGV("writeBlob: write in place"); 1018 status = writeInt32(BLOB_INPLACE); 1019 if (status) return status; 1020 1021 void* ptr = writeInplace(len); 1022 if (!ptr) return NO_MEMORY; 1023 1024 outBlob->init(-1, ptr, len, false); 1025 return NO_ERROR; 1026 } 1027 1028 ALOGV("writeBlob: write to ashmem"); 1029 int fd = ashmem_create_region("Parcel Blob", len); 1030 if (fd < 0) return NO_MEMORY; 1031 1032 int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE); 1033 if (result < 0) { 1034 status = result; 1035 } else { 1036 void* ptr = ::mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 1037 if (ptr == MAP_FAILED) { 1038 status = -errno; 1039 } else { 1040 if (!mutableCopy) { 1041 result = ashmem_set_prot_region(fd, PROT_READ); 1042 } 1043 if (result < 0) { 1044 status = result; 1045 } else { 1046 status = writeInt32(mutableCopy ? BLOB_ASHMEM_MUTABLE : BLOB_ASHMEM_IMMUTABLE); 1047 if (!status) { 1048 status = writeFileDescriptor(fd, true /*takeOwnership*/); 1049 if (!status) { 1050 outBlob->init(fd, ptr, len, mutableCopy); 1051 return NO_ERROR; 1052 } 1053 } 1054 } 1055 } 1056 ::munmap(ptr, len); 1057 } 1058 ::close(fd); 1059 return status; 1060} 1061 1062status_t Parcel::writeDupImmutableBlobFileDescriptor(int fd) 1063{ 1064 // Must match up with what's done in writeBlob. 1065 if (!mAllowFds) return FDS_NOT_ALLOWED; 1066 status_t status = writeInt32(BLOB_ASHMEM_IMMUTABLE); 1067 if (status) return status; 1068 return writeDupFileDescriptor(fd); 1069} 1070 1071status_t Parcel::write(const FlattenableHelperInterface& val) 1072{ 1073 status_t err; 1074 1075 // size if needed 1076 const size_t len = val.getFlattenedSize(); 1077 const size_t fd_count = val.getFdCount(); 1078 1079 if ((len > INT32_MAX) || (fd_count > INT32_MAX)) { 1080 // don't accept size_t values which may have come from an 1081 // inadvertent conversion from a negative int. 1082 return BAD_VALUE; 1083 } 1084 1085 err = this->writeInt32(len); 1086 if (err) return err; 1087 1088 err = this->writeInt32(fd_count); 1089 if (err) return err; 1090 1091 // payload 1092 void* const buf = this->writeInplace(pad_size(len)); 1093 if (buf == NULL) 1094 return BAD_VALUE; 1095 1096 int* fds = NULL; 1097 if (fd_count) { 1098 fds = new int[fd_count]; 1099 } 1100 1101 err = val.flatten(buf, len, fds, fd_count); 1102 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) { 1103 err = this->writeDupFileDescriptor( fds[i] ); 1104 } 1105 1106 if (fd_count) { 1107 delete [] fds; 1108 } 1109 1110 return err; 1111} 1112 1113status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData) 1114{ 1115 const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity; 1116 const bool enoughObjects = mObjectsSize < mObjectsCapacity; 1117 if (enoughData && enoughObjects) { 1118restart_write: 1119 *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val; 1120 1121 // remember if it's a file descriptor 1122 if (val.type == BINDER_TYPE_FD) { 1123 if (!mAllowFds) { 1124 // fail before modifying our object index 1125 return FDS_NOT_ALLOWED; 1126 } 1127 mHasFds = mFdsKnown = true; 1128 } 1129 1130 // Need to write meta-data? 1131 if (nullMetaData || val.binder != 0) { 1132 mObjects[mObjectsSize] = mDataPos; 1133 acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize); 1134 mObjectsSize++; 1135 } 1136 1137 return finishWrite(sizeof(flat_binder_object)); 1138 } 1139 1140 if (!enoughData) { 1141 const status_t err = growData(sizeof(val)); 1142 if (err != NO_ERROR) return err; 1143 } 1144 if (!enoughObjects) { 1145 size_t newSize = ((mObjectsSize+2)*3)/2; 1146 if (newSize < mObjectsSize) return NO_MEMORY; // overflow 1147 binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t)); 1148 if (objects == NULL) return NO_MEMORY; 1149 mObjects = objects; 1150 mObjectsCapacity = newSize; 1151 } 1152 1153 goto restart_write; 1154} 1155 1156status_t Parcel::writeNoException() 1157{ 1158 binder::Status status; 1159 return status.writeToParcel(this); 1160} 1161 1162void Parcel::remove(size_t /*start*/, size_t /*amt*/) 1163{ 1164 LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!"); 1165} 1166 1167status_t Parcel::read(void* outData, size_t len) const 1168{ 1169 if (len > INT32_MAX) { 1170 // don't accept size_t values which may have come from an 1171 // inadvertent conversion from a negative int. 1172 return BAD_VALUE; 1173 } 1174 1175 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize 1176 && len <= pad_size(len)) { 1177 memcpy(outData, mData+mDataPos, len); 1178 mDataPos += pad_size(len); 1179 ALOGV("read Setting data pos of %p to %zu", this, mDataPos); 1180 return NO_ERROR; 1181 } 1182 return NOT_ENOUGH_DATA; 1183} 1184 1185const void* Parcel::readInplace(size_t len) const 1186{ 1187 if (len > INT32_MAX) { 1188 // don't accept size_t values which may have come from an 1189 // inadvertent conversion from a negative int. 1190 return NULL; 1191 } 1192 1193 if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize 1194 && len <= pad_size(len)) { 1195 const void* data = mData+mDataPos; 1196 mDataPos += pad_size(len); 1197 ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos); 1198 return data; 1199 } 1200 return NULL; 1201} 1202 1203template<class T> 1204status_t Parcel::readAligned(T *pArg) const { 1205 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T)); 1206 1207 if ((mDataPos+sizeof(T)) <= mDataSize) { 1208 const void* data = mData+mDataPos; 1209 mDataPos += sizeof(T); 1210 *pArg = *reinterpret_cast<const T*>(data); 1211 return NO_ERROR; 1212 } else { 1213 return NOT_ENOUGH_DATA; 1214 } 1215} 1216 1217template<class T> 1218T Parcel::readAligned() const { 1219 T result; 1220 if (readAligned(&result) != NO_ERROR) { 1221 result = 0; 1222 } 1223 1224 return result; 1225} 1226 1227template<class T> 1228status_t Parcel::writeAligned(T val) { 1229 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T)); 1230 1231 if ((mDataPos+sizeof(val)) <= mDataCapacity) { 1232restart_write: 1233 *reinterpret_cast<T*>(mData+mDataPos) = val; 1234 return finishWrite(sizeof(val)); 1235 } 1236 1237 status_t err = growData(sizeof(val)); 1238 if (err == NO_ERROR) goto restart_write; 1239 return err; 1240} 1241 1242status_t Parcel::readByteVector(std::vector<int8_t>* val) const { 1243 val->clear(); 1244 1245 int32_t size; 1246 status_t status = readInt32(&size); 1247 1248 if (status != OK) { 1249 return status; 1250 } 1251 1252 if (size < 0) { 1253 status = UNEXPECTED_NULL; 1254 return status; 1255 } 1256 if (size_t(size) > dataAvail()) { 1257 status = BAD_VALUE; 1258 return status; 1259 } 1260 1261 const void* data = readInplace(size); 1262 if (!data) { 1263 status = BAD_VALUE; 1264 return status; 1265 } 1266 val->resize(size); 1267 memcpy(val->data(), data, size); 1268 1269 return status; 1270} 1271 1272status_t Parcel::readInt32Vector(std::vector<int32_t>* val) const { 1273 return readTypedVector(val, &Parcel::readInt32); 1274} 1275 1276status_t Parcel::readInt64Vector(std::vector<int64_t>* val) const { 1277 return readTypedVector(val, &Parcel::readInt64); 1278} 1279 1280status_t Parcel::readFloatVector(std::vector<float>* val) const { 1281 return readTypedVector(val, &Parcel::readFloat); 1282} 1283 1284status_t Parcel::readDoubleVector(std::vector<double>* val) const { 1285 return readTypedVector(val, &Parcel::readDouble); 1286} 1287 1288status_t Parcel::readBoolVector(std::vector<bool>* val) const { 1289 val->clear(); 1290 1291 int32_t size; 1292 status_t status = readInt32(&size); 1293 1294 if (status != OK) { 1295 return status; 1296 } 1297 1298 if (size < 0) { 1299 return UNEXPECTED_NULL; 1300 } 1301 1302 val->resize(size); 1303 1304 /* C++ bool handling means a vector of bools isn't necessarily addressable 1305 * (we might use individual bits) 1306 */ 1307 bool data; 1308 for (int32_t i = 0; i < size; ++i) { 1309 status = readBool(&data); 1310 (*val)[i] = data; 1311 1312 if (status != OK) { 1313 return status; 1314 } 1315 } 1316 1317 return OK; 1318} 1319 1320status_t Parcel::readCharVector(std::vector<char16_t>* val) const { 1321 return readTypedVector(val, &Parcel::readChar); 1322} 1323 1324status_t Parcel::readString16Vector(std::vector<String16>* val) const { 1325 return readTypedVector(val, &Parcel::readString16); 1326} 1327 1328 1329status_t Parcel::readInt32(int32_t *pArg) const 1330{ 1331 return readAligned(pArg); 1332} 1333 1334int32_t Parcel::readInt32() const 1335{ 1336 return readAligned<int32_t>(); 1337} 1338 1339status_t Parcel::readUint32(uint32_t *pArg) const 1340{ 1341 return readAligned(pArg); 1342} 1343 1344uint32_t Parcel::readUint32() const 1345{ 1346 return readAligned<uint32_t>(); 1347} 1348 1349status_t Parcel::readInt64(int64_t *pArg) const 1350{ 1351 return readAligned(pArg); 1352} 1353 1354 1355int64_t Parcel::readInt64() const 1356{ 1357 return readAligned<int64_t>(); 1358} 1359 1360status_t Parcel::readUint64(uint64_t *pArg) const 1361{ 1362 return readAligned(pArg); 1363} 1364 1365uint64_t Parcel::readUint64() const 1366{ 1367 return readAligned<uint64_t>(); 1368} 1369 1370status_t Parcel::readPointer(uintptr_t *pArg) const 1371{ 1372 status_t ret; 1373 binder_uintptr_t ptr; 1374 ret = readAligned(&ptr); 1375 if (!ret) 1376 *pArg = ptr; 1377 return ret; 1378} 1379 1380uintptr_t Parcel::readPointer() const 1381{ 1382 return readAligned<binder_uintptr_t>(); 1383} 1384 1385 1386status_t Parcel::readFloat(float *pArg) const 1387{ 1388 return readAligned(pArg); 1389} 1390 1391 1392float Parcel::readFloat() const 1393{ 1394 return readAligned<float>(); 1395} 1396 1397#if defined(__mips__) && defined(__mips_hard_float) 1398 1399status_t Parcel::readDouble(double *pArg) const 1400{ 1401 union { 1402 double d; 1403 unsigned long long ll; 1404 } u; 1405 u.d = 0; 1406 status_t status; 1407 status = readAligned(&u.ll); 1408 *pArg = u.d; 1409 return status; 1410} 1411 1412double Parcel::readDouble() const 1413{ 1414 union { 1415 double d; 1416 unsigned long long ll; 1417 } u; 1418 u.ll = readAligned<unsigned long long>(); 1419 return u.d; 1420} 1421 1422#else 1423 1424status_t Parcel::readDouble(double *pArg) const 1425{ 1426 return readAligned(pArg); 1427} 1428 1429double Parcel::readDouble() const 1430{ 1431 return readAligned<double>(); 1432} 1433 1434#endif 1435 1436status_t Parcel::readIntPtr(intptr_t *pArg) const 1437{ 1438 return readAligned(pArg); 1439} 1440 1441 1442intptr_t Parcel::readIntPtr() const 1443{ 1444 return readAligned<intptr_t>(); 1445} 1446 1447status_t Parcel::readBool(bool *pArg) const 1448{ 1449 int32_t tmp; 1450 status_t ret = readInt32(&tmp); 1451 *pArg = (tmp != 0); 1452 return ret; 1453} 1454 1455bool Parcel::readBool() const 1456{ 1457 return readInt32() != 0; 1458} 1459 1460status_t Parcel::readChar(char16_t *pArg) const 1461{ 1462 int32_t tmp; 1463 status_t ret = readInt32(&tmp); 1464 *pArg = char16_t(tmp); 1465 return ret; 1466} 1467 1468char16_t Parcel::readChar() const 1469{ 1470 return char16_t(readInt32()); 1471} 1472 1473status_t Parcel::readByte(int8_t *pArg) const 1474{ 1475 int32_t tmp; 1476 status_t ret = readInt32(&tmp); 1477 *pArg = int8_t(tmp); 1478 return ret; 1479} 1480 1481int8_t Parcel::readByte() const 1482{ 1483 return int8_t(readInt32()); 1484} 1485 1486const char* Parcel::readCString() const 1487{ 1488 const size_t avail = mDataSize-mDataPos; 1489 if (avail > 0) { 1490 const char* str = reinterpret_cast<const char*>(mData+mDataPos); 1491 // is the string's trailing NUL within the parcel's valid bounds? 1492 const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail)); 1493 if (eos) { 1494 const size_t len = eos - str; 1495 mDataPos += pad_size(len+1); 1496 ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos); 1497 return str; 1498 } 1499 } 1500 return NULL; 1501} 1502 1503String8 Parcel::readString8() const 1504{ 1505 int32_t size = readInt32(); 1506 // watch for potential int overflow adding 1 for trailing NUL 1507 if (size > 0 && size < INT32_MAX) { 1508 const char* str = (const char*)readInplace(size+1); 1509 if (str) return String8(str, size); 1510 } 1511 return String8(); 1512} 1513 1514String16 Parcel::readString16() const 1515{ 1516 size_t len; 1517 const char16_t* str = readString16Inplace(&len); 1518 if (str) return String16(str, len); 1519 ALOGE("Reading a NULL string not supported here."); 1520 return String16(); 1521} 1522 1523status_t Parcel::readString16(String16* pArg) const 1524{ 1525 size_t len; 1526 const char16_t* str = readString16Inplace(&len); 1527 if (str) { 1528 pArg->setTo(str, len); 1529 return 0; 1530 } else { 1531 *pArg = String16(); 1532 return UNEXPECTED_NULL; 1533 } 1534} 1535 1536const char16_t* Parcel::readString16Inplace(size_t* outLen) const 1537{ 1538 int32_t size = readInt32(); 1539 // watch for potential int overflow from size+1 1540 if (size >= 0 && size < INT32_MAX) { 1541 *outLen = size; 1542 const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t)); 1543 if (str != NULL) { 1544 return str; 1545 } 1546 } 1547 *outLen = 0; 1548 return NULL; 1549} 1550 1551status_t Parcel::readStrongBinder(sp<IBinder>* val) const 1552{ 1553 return unflatten_binder(ProcessState::self(), *this, val); 1554} 1555 1556sp<IBinder> Parcel::readStrongBinder() const 1557{ 1558 sp<IBinder> val; 1559 readStrongBinder(&val); 1560 return val; 1561} 1562 1563wp<IBinder> Parcel::readWeakBinder() const 1564{ 1565 wp<IBinder> val; 1566 unflatten_binder(ProcessState::self(), *this, &val); 1567 return val; 1568} 1569 1570int32_t Parcel::readExceptionCode() const 1571{ 1572 binder::Status status; 1573 status.readFromParcel(*this); 1574 return status.exceptionCode(); 1575} 1576 1577native_handle* Parcel::readNativeHandle() const 1578{ 1579 int numFds, numInts; 1580 status_t err; 1581 err = readInt32(&numFds); 1582 if (err != NO_ERROR) return 0; 1583 err = readInt32(&numInts); 1584 if (err != NO_ERROR) return 0; 1585 1586 native_handle* h = native_handle_create(numFds, numInts); 1587 if (!h) { 1588 return 0; 1589 } 1590 1591 for (int i=0 ; err==NO_ERROR && i<numFds ; i++) { 1592 h->data[i] = dup(readFileDescriptor()); 1593 if (h->data[i] < 0) err = BAD_VALUE; 1594 } 1595 err = read(h->data + numFds, sizeof(int)*numInts); 1596 if (err != NO_ERROR) { 1597 native_handle_close(h); 1598 native_handle_delete(h); 1599 h = 0; 1600 } 1601 return h; 1602} 1603 1604 1605int Parcel::readFileDescriptor() const 1606{ 1607 const flat_binder_object* flat = readObject(true); 1608 if (flat) { 1609 switch (flat->type) { 1610 case BINDER_TYPE_FD: 1611 //ALOGI("Returning file descriptor %ld from parcel %p", flat->handle, this); 1612 return flat->handle; 1613 } 1614 } 1615 return BAD_TYPE; 1616} 1617 1618status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const 1619{ 1620 int32_t blobType; 1621 status_t status = readInt32(&blobType); 1622 if (status) return status; 1623 1624 if (blobType == BLOB_INPLACE) { 1625 ALOGV("readBlob: read in place"); 1626 const void* ptr = readInplace(len); 1627 if (!ptr) return BAD_VALUE; 1628 1629 outBlob->init(-1, const_cast<void*>(ptr), len, false); 1630 return NO_ERROR; 1631 } 1632 1633 ALOGV("readBlob: read from ashmem"); 1634 bool isMutable = (blobType == BLOB_ASHMEM_MUTABLE); 1635 int fd = readFileDescriptor(); 1636 if (fd == int(BAD_TYPE)) return BAD_VALUE; 1637 1638 void* ptr = ::mmap(NULL, len, isMutable ? PROT_READ | PROT_WRITE : PROT_READ, 1639 MAP_SHARED, fd, 0); 1640 if (ptr == MAP_FAILED) return NO_MEMORY; 1641 1642 outBlob->init(fd, ptr, len, isMutable); 1643 return NO_ERROR; 1644} 1645 1646status_t Parcel::read(FlattenableHelperInterface& val) const 1647{ 1648 // size 1649 const size_t len = this->readInt32(); 1650 const size_t fd_count = this->readInt32(); 1651 1652 if (len > INT32_MAX) { 1653 // don't accept size_t values which may have come from an 1654 // inadvertent conversion from a negative int. 1655 return BAD_VALUE; 1656 } 1657 1658 // payload 1659 void const* const buf = this->readInplace(pad_size(len)); 1660 if (buf == NULL) 1661 return BAD_VALUE; 1662 1663 int* fds = NULL; 1664 if (fd_count) { 1665 fds = new int[fd_count]; 1666 } 1667 1668 status_t err = NO_ERROR; 1669 for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) { 1670 fds[i] = dup(this->readFileDescriptor()); 1671 if (fds[i] < 0) { 1672 err = BAD_VALUE; 1673 ALOGE("dup() failed in Parcel::read, i is %zu, fds[i] is %d, fd_count is %zu, error: %s", 1674 i, fds[i], fd_count, strerror(errno)); 1675 } 1676 } 1677 1678 if (err == NO_ERROR) { 1679 err = val.unflatten(buf, len, fds, fd_count); 1680 } 1681 1682 if (fd_count) { 1683 delete [] fds; 1684 } 1685 1686 return err; 1687} 1688const flat_binder_object* Parcel::readObject(bool nullMetaData) const 1689{ 1690 const size_t DPOS = mDataPos; 1691 if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) { 1692 const flat_binder_object* obj 1693 = reinterpret_cast<const flat_binder_object*>(mData+DPOS); 1694 mDataPos = DPOS + sizeof(flat_binder_object); 1695 if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) { 1696 // When transferring a NULL object, we don't write it into 1697 // the object list, so we don't want to check for it when 1698 // reading. 1699 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos); 1700 return obj; 1701 } 1702 1703 // Ensure that this object is valid... 1704 binder_size_t* const OBJS = mObjects; 1705 const size_t N = mObjectsSize; 1706 size_t opos = mNextObjectHint; 1707 1708 if (N > 0) { 1709 ALOGV("Parcel %p looking for obj at %zu, hint=%zu", 1710 this, DPOS, opos); 1711 1712 // Start at the current hint position, looking for an object at 1713 // the current data position. 1714 if (opos < N) { 1715 while (opos < (N-1) && OBJS[opos] < DPOS) { 1716 opos++; 1717 } 1718 } else { 1719 opos = N-1; 1720 } 1721 if (OBJS[opos] == DPOS) { 1722 // Found it! 1723 ALOGV("Parcel %p found obj %zu at index %zu with forward search", 1724 this, DPOS, opos); 1725 mNextObjectHint = opos+1; 1726 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos); 1727 return obj; 1728 } 1729 1730 // Look backwards for it... 1731 while (opos > 0 && OBJS[opos] > DPOS) { 1732 opos--; 1733 } 1734 if (OBJS[opos] == DPOS) { 1735 // Found it! 1736 ALOGV("Parcel %p found obj %zu at index %zu with backward search", 1737 this, DPOS, opos); 1738 mNextObjectHint = opos+1; 1739 ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos); 1740 return obj; 1741 } 1742 } 1743 ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object list", 1744 this, DPOS); 1745 } 1746 return NULL; 1747} 1748 1749void Parcel::closeFileDescriptors() 1750{ 1751 size_t i = mObjectsSize; 1752 if (i > 0) { 1753 //ALOGI("Closing file descriptors for %zu objects...", i); 1754 } 1755 while (i > 0) { 1756 i--; 1757 const flat_binder_object* flat 1758 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]); 1759 if (flat->type == BINDER_TYPE_FD) { 1760 //ALOGI("Closing fd: %ld", flat->handle); 1761 close(flat->handle); 1762 } 1763 } 1764} 1765 1766uintptr_t Parcel::ipcData() const 1767{ 1768 return reinterpret_cast<uintptr_t>(mData); 1769} 1770 1771size_t Parcel::ipcDataSize() const 1772{ 1773 return (mDataSize > mDataPos ? mDataSize : mDataPos); 1774} 1775 1776uintptr_t Parcel::ipcObjects() const 1777{ 1778 return reinterpret_cast<uintptr_t>(mObjects); 1779} 1780 1781size_t Parcel::ipcObjectsCount() const 1782{ 1783 return mObjectsSize; 1784} 1785 1786void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize, 1787 const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie) 1788{ 1789 binder_size_t minOffset = 0; 1790 freeDataNoInit(); 1791 mError = NO_ERROR; 1792 mData = const_cast<uint8_t*>(data); 1793 mDataSize = mDataCapacity = dataSize; 1794 //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)", this, mDataSize, getpid()); 1795 mDataPos = 0; 1796 ALOGV("setDataReference Setting data pos of %p to %zu", this, mDataPos); 1797 mObjects = const_cast<binder_size_t*>(objects); 1798 mObjectsSize = mObjectsCapacity = objectsCount; 1799 mNextObjectHint = 0; 1800 mOwner = relFunc; 1801 mOwnerCookie = relCookie; 1802 for (size_t i = 0; i < mObjectsSize; i++) { 1803 binder_size_t offset = mObjects[i]; 1804 if (offset < minOffset) { 1805 ALOGE("%s: bad object offset %" PRIu64 " < %" PRIu64 "\n", 1806 __func__, (uint64_t)offset, (uint64_t)minOffset); 1807 mObjectsSize = 0; 1808 break; 1809 } 1810 minOffset = offset + sizeof(flat_binder_object); 1811 } 1812 scanForFds(); 1813} 1814 1815void Parcel::print(TextOutput& to, uint32_t /*flags*/) const 1816{ 1817 to << "Parcel("; 1818 1819 if (errorCheck() != NO_ERROR) { 1820 const status_t err = errorCheck(); 1821 to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\""; 1822 } else if (dataSize() > 0) { 1823 const uint8_t* DATA = data(); 1824 to << indent << HexDump(DATA, dataSize()) << dedent; 1825 const binder_size_t* OBJS = objects(); 1826 const size_t N = objectsCount(); 1827 for (size_t i=0; i<N; i++) { 1828 const flat_binder_object* flat 1829 = reinterpret_cast<const flat_binder_object*>(DATA+OBJS[i]); 1830 to << endl << "Object #" << i << " @ " << (void*)OBJS[i] << ": " 1831 << TypeCode(flat->type & 0x7f7f7f00) 1832 << " = " << flat->binder; 1833 } 1834 } else { 1835 to << "NULL"; 1836 } 1837 1838 to << ")"; 1839} 1840 1841void Parcel::releaseObjects() 1842{ 1843 const sp<ProcessState> proc(ProcessState::self()); 1844 size_t i = mObjectsSize; 1845 uint8_t* const data = mData; 1846 binder_size_t* const objects = mObjects; 1847 while (i > 0) { 1848 i--; 1849 const flat_binder_object* flat 1850 = reinterpret_cast<flat_binder_object*>(data+objects[i]); 1851 release_object(proc, *flat, this, &mOpenAshmemSize); 1852 } 1853} 1854 1855void Parcel::acquireObjects() 1856{ 1857 const sp<ProcessState> proc(ProcessState::self()); 1858 size_t i = mObjectsSize; 1859 uint8_t* const data = mData; 1860 binder_size_t* const objects = mObjects; 1861 while (i > 0) { 1862 i--; 1863 const flat_binder_object* flat 1864 = reinterpret_cast<flat_binder_object*>(data+objects[i]); 1865 acquire_object(proc, *flat, this, &mOpenAshmemSize); 1866 } 1867} 1868 1869void Parcel::freeData() 1870{ 1871 freeDataNoInit(); 1872 initState(); 1873} 1874 1875void Parcel::freeDataNoInit() 1876{ 1877 if (mOwner) { 1878 LOG_ALLOC("Parcel %p: freeing other owner data", this); 1879 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid()); 1880 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie); 1881 } else { 1882 LOG_ALLOC("Parcel %p: freeing allocated data", this); 1883 releaseObjects(); 1884 if (mData) { 1885 LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity); 1886 pthread_mutex_lock(&gParcelGlobalAllocSizeLock); 1887 if (mDataCapacity <= gParcelGlobalAllocSize) { 1888 gParcelGlobalAllocSize = gParcelGlobalAllocSize - mDataCapacity; 1889 } else { 1890 gParcelGlobalAllocSize = 0; 1891 } 1892 if (gParcelGlobalAllocCount > 0) { 1893 gParcelGlobalAllocCount--; 1894 } 1895 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); 1896 free(mData); 1897 } 1898 if (mObjects) free(mObjects); 1899 } 1900} 1901 1902status_t Parcel::growData(size_t len) 1903{ 1904 if (len > INT32_MAX) { 1905 // don't accept size_t values which may have come from an 1906 // inadvertent conversion from a negative int. 1907 return BAD_VALUE; 1908 } 1909 1910 size_t newSize = ((mDataSize+len)*3)/2; 1911 return (newSize <= mDataSize) 1912 ? (status_t) NO_MEMORY 1913 : continueWrite(newSize); 1914} 1915 1916status_t Parcel::restartWrite(size_t desired) 1917{ 1918 if (desired > INT32_MAX) { 1919 // don't accept size_t values which may have come from an 1920 // inadvertent conversion from a negative int. 1921 return BAD_VALUE; 1922 } 1923 1924 if (mOwner) { 1925 freeData(); 1926 return continueWrite(desired); 1927 } 1928 1929 uint8_t* data = (uint8_t*)realloc(mData, desired); 1930 if (!data && desired > mDataCapacity) { 1931 mError = NO_MEMORY; 1932 return NO_MEMORY; 1933 } 1934 1935 releaseObjects(); 1936 1937 if (data) { 1938 LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired); 1939 pthread_mutex_lock(&gParcelGlobalAllocSizeLock); 1940 gParcelGlobalAllocSize += desired; 1941 gParcelGlobalAllocSize -= mDataCapacity; 1942 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); 1943 mData = data; 1944 mDataCapacity = desired; 1945 } 1946 1947 mDataSize = mDataPos = 0; 1948 ALOGV("restartWrite Setting data size of %p to %zu", this, mDataSize); 1949 ALOGV("restartWrite Setting data pos of %p to %zu", this, mDataPos); 1950 1951 free(mObjects); 1952 mObjects = NULL; 1953 mObjectsSize = mObjectsCapacity = 0; 1954 mNextObjectHint = 0; 1955 mHasFds = false; 1956 mFdsKnown = true; 1957 mAllowFds = true; 1958 1959 return NO_ERROR; 1960} 1961 1962status_t Parcel::continueWrite(size_t desired) 1963{ 1964 if (desired > INT32_MAX) { 1965 // don't accept size_t values which may have come from an 1966 // inadvertent conversion from a negative int. 1967 return BAD_VALUE; 1968 } 1969 1970 // If shrinking, first adjust for any objects that appear 1971 // after the new data size. 1972 size_t objectsSize = mObjectsSize; 1973 if (desired < mDataSize) { 1974 if (desired == 0) { 1975 objectsSize = 0; 1976 } else { 1977 while (objectsSize > 0) { 1978 if (mObjects[objectsSize-1] < desired) 1979 break; 1980 objectsSize--; 1981 } 1982 } 1983 } 1984 1985 if (mOwner) { 1986 // If the size is going to zero, just release the owner's data. 1987 if (desired == 0) { 1988 freeData(); 1989 return NO_ERROR; 1990 } 1991 1992 // If there is a different owner, we need to take 1993 // posession. 1994 uint8_t* data = (uint8_t*)malloc(desired); 1995 if (!data) { 1996 mError = NO_MEMORY; 1997 return NO_MEMORY; 1998 } 1999 binder_size_t* objects = NULL; 2000 2001 if (objectsSize) { 2002 objects = (binder_size_t*)calloc(objectsSize, sizeof(binder_size_t)); 2003 if (!objects) { 2004 free(data); 2005 2006 mError = NO_MEMORY; 2007 return NO_MEMORY; 2008 } 2009 2010 // Little hack to only acquire references on objects 2011 // we will be keeping. 2012 size_t oldObjectsSize = mObjectsSize; 2013 mObjectsSize = objectsSize; 2014 acquireObjects(); 2015 mObjectsSize = oldObjectsSize; 2016 } 2017 2018 if (mData) { 2019 memcpy(data, mData, mDataSize < desired ? mDataSize : desired); 2020 } 2021 if (objects && mObjects) { 2022 memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t)); 2023 } 2024 //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid()); 2025 mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie); 2026 mOwner = NULL; 2027 2028 LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired); 2029 pthread_mutex_lock(&gParcelGlobalAllocSizeLock); 2030 gParcelGlobalAllocSize += desired; 2031 gParcelGlobalAllocCount++; 2032 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); 2033 2034 mData = data; 2035 mObjects = objects; 2036 mDataSize = (mDataSize < desired) ? mDataSize : desired; 2037 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize); 2038 mDataCapacity = desired; 2039 mObjectsSize = mObjectsCapacity = objectsSize; 2040 mNextObjectHint = 0; 2041 2042 } else if (mData) { 2043 if (objectsSize < mObjectsSize) { 2044 // Need to release refs on any objects we are dropping. 2045 const sp<ProcessState> proc(ProcessState::self()); 2046 for (size_t i=objectsSize; i<mObjectsSize; i++) { 2047 const flat_binder_object* flat 2048 = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]); 2049 if (flat->type == BINDER_TYPE_FD) { 2050 // will need to rescan because we may have lopped off the only FDs 2051 mFdsKnown = false; 2052 } 2053 release_object(proc, *flat, this, &mOpenAshmemSize); 2054 } 2055 binder_size_t* objects = 2056 (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t)); 2057 if (objects) { 2058 mObjects = objects; 2059 } 2060 mObjectsSize = objectsSize; 2061 mNextObjectHint = 0; 2062 } 2063 2064 // We own the data, so we can just do a realloc(). 2065 if (desired > mDataCapacity) { 2066 uint8_t* data = (uint8_t*)realloc(mData, desired); 2067 if (data) { 2068 LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity, 2069 desired); 2070 pthread_mutex_lock(&gParcelGlobalAllocSizeLock); 2071 gParcelGlobalAllocSize += desired; 2072 gParcelGlobalAllocSize -= mDataCapacity; 2073 gParcelGlobalAllocCount++; 2074 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); 2075 mData = data; 2076 mDataCapacity = desired; 2077 } else if (desired > mDataCapacity) { 2078 mError = NO_MEMORY; 2079 return NO_MEMORY; 2080 } 2081 } else { 2082 if (mDataSize > desired) { 2083 mDataSize = desired; 2084 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize); 2085 } 2086 if (mDataPos > desired) { 2087 mDataPos = desired; 2088 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos); 2089 } 2090 } 2091 2092 } else { 2093 // This is the first data. Easy! 2094 uint8_t* data = (uint8_t*)malloc(desired); 2095 if (!data) { 2096 mError = NO_MEMORY; 2097 return NO_MEMORY; 2098 } 2099 2100 if(!(mDataCapacity == 0 && mObjects == NULL 2101 && mObjectsCapacity == 0)) { 2102 ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired); 2103 } 2104 2105 LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired); 2106 pthread_mutex_lock(&gParcelGlobalAllocSizeLock); 2107 gParcelGlobalAllocSize += desired; 2108 gParcelGlobalAllocCount++; 2109 pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); 2110 2111 mData = data; 2112 mDataSize = mDataPos = 0; 2113 ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize); 2114 ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos); 2115 mDataCapacity = desired; 2116 } 2117 2118 return NO_ERROR; 2119} 2120 2121void Parcel::initState() 2122{ 2123 LOG_ALLOC("Parcel %p: initState", this); 2124 mError = NO_ERROR; 2125 mData = 0; 2126 mDataSize = 0; 2127 mDataCapacity = 0; 2128 mDataPos = 0; 2129 ALOGV("initState Setting data size of %p to %zu", this, mDataSize); 2130 ALOGV("initState Setting data pos of %p to %zu", this, mDataPos); 2131 mObjects = NULL; 2132 mObjectsSize = 0; 2133 mObjectsCapacity = 0; 2134 mNextObjectHint = 0; 2135 mHasFds = false; 2136 mFdsKnown = true; 2137 mAllowFds = true; 2138 mOwner = NULL; 2139 mOpenAshmemSize = 0; 2140} 2141 2142void Parcel::scanForFds() const 2143{ 2144 bool hasFds = false; 2145 for (size_t i=0; i<mObjectsSize; i++) { 2146 const flat_binder_object* flat 2147 = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]); 2148 if (flat->type == BINDER_TYPE_FD) { 2149 hasFds = true; 2150 break; 2151 } 2152 } 2153 mHasFds = hasFds; 2154 mFdsKnown = true; 2155} 2156 2157size_t Parcel::getBlobAshmemSize() const 2158{ 2159 // This used to return the size of all blobs that were written to ashmem, now we're returning 2160 // the ashmem currently referenced by this Parcel, which should be equivalent. 2161 // TODO: Remove method once ABI can be changed. 2162 return mOpenAshmemSize; 2163} 2164 2165size_t Parcel::getOpenAshmemSize() const 2166{ 2167 return mOpenAshmemSize; 2168} 2169 2170// --- Parcel::Blob --- 2171 2172Parcel::Blob::Blob() : 2173 mFd(-1), mData(NULL), mSize(0), mMutable(false) { 2174} 2175 2176Parcel::Blob::~Blob() { 2177 release(); 2178} 2179 2180void Parcel::Blob::release() { 2181 if (mFd != -1 && mData) { 2182 ::munmap(mData, mSize); 2183 } 2184 clear(); 2185} 2186 2187void Parcel::Blob::init(int fd, void* data, size_t size, bool isMutable) { 2188 mFd = fd; 2189 mData = data; 2190 mSize = size; 2191 mMutable = isMutable; 2192} 2193 2194void Parcel::Blob::clear() { 2195 mFd = -1; 2196 mData = NULL; 2197 mSize = 0; 2198 mMutable = false; 2199} 2200 2201}; // namespace android 2202