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