1 /* 2 * Copyright (C) 2012 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 "android_os_Parcel.h" 21 #include "android_util_Binder.h" 22 23 #include <nativehelper/JNIPlatformHelp.h> 24 25 #include <fcntl.h> 26 #include <stdio.h> 27 #include <sys/stat.h> 28 #include <sys/types.h> 29 #include <unistd.h> 30 31 #include <binder/IInterface.h> 32 #include <binder/IPCThreadState.h> 33 #include <cutils/atomic.h> 34 #include <utils/Log.h> 35 #include <utils/SystemClock.h> 36 #include <utils/List.h> 37 #include <utils/KeyedVector.h> 38 #include <binder/Parcel.h> 39 #include <binder/ProcessState.h> 40 #include <binder/IServiceManager.h> 41 #include <utils/threads.h> 42 #include <utils/String8.h> 43 44 #include <nativehelper/ScopedUtfChars.h> 45 #include <nativehelper/ScopedLocalRef.h> 46 47 #include <android_runtime/AndroidRuntime.h> 48 49 #include "core_jni_helpers.h" 50 51 //#undef ALOGV 52 //#define ALOGV(...) fprintf(stderr, __VA_ARGS__) 53 54 #define DEBUG_DEATH 0 55 #if DEBUG_DEATH 56 #define LOGDEATH ALOGD 57 #else 58 #define LOGDEATH ALOGV 59 #endif 60 61 namespace android { 62 63 static struct parcel_offsets_t 64 { 65 jclass clazz; 66 jfieldID mNativePtr; 67 jmethodID obtain; 68 jmethodID recycle; 69 } gParcelOffsets; 70 71 Parcel* parcelForJavaObject(JNIEnv* env, jobject obj) 72 { 73 if (obj) { 74 Parcel* p = (Parcel*)env->GetLongField(obj, gParcelOffsets.mNativePtr); 75 if (p != NULL) { 76 return p; 77 } 78 jniThrowException(env, "java/lang/IllegalStateException", "Parcel has been finalized!"); 79 } 80 return NULL; 81 } 82 83 jobject createJavaParcelObject(JNIEnv* env) 84 { 85 return env->CallStaticObjectMethod(gParcelOffsets.clazz, gParcelOffsets.obtain); 86 } 87 88 void recycleJavaParcelObject(JNIEnv* env, jobject parcelObj) 89 { 90 env->CallVoidMethod(parcelObj, gParcelOffsets.recycle); 91 } 92 93 static void android_os_Parcel_markSensitive(jlong nativePtr) 94 { 95 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 96 if (parcel) { 97 parcel->markSensitive(); 98 } 99 } 100 101 static jint android_os_Parcel_dataSize(jlong nativePtr) 102 { 103 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 104 return parcel ? parcel->dataSize() : 0; 105 } 106 107 static jint android_os_Parcel_dataAvail(jlong nativePtr) 108 { 109 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 110 return parcel ? parcel->dataAvail() : 0; 111 } 112 113 static jint android_os_Parcel_dataPosition(jlong nativePtr) 114 { 115 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 116 return parcel ? parcel->dataPosition() : 0; 117 } 118 119 static jint android_os_Parcel_dataCapacity(jlong nativePtr) 120 { 121 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 122 return parcel ? parcel->dataCapacity() : 0; 123 } 124 125 static void android_os_Parcel_setDataSize(JNIEnv* env, jclass clazz, jlong nativePtr, jint size) 126 { 127 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 128 if (parcel != NULL) { 129 const status_t err = parcel->setDataSize(size); 130 if (err != NO_ERROR) { 131 signalExceptionForError(env, clazz, err); 132 } 133 } 134 } 135 136 static void android_os_Parcel_setDataPosition(jlong nativePtr, jint pos) 137 { 138 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 139 if (parcel != NULL) { 140 parcel->setDataPosition(pos); 141 } 142 } 143 144 static void android_os_Parcel_setDataCapacity(JNIEnv* env, jclass clazz, jlong nativePtr, jint size) 145 { 146 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 147 if (parcel != NULL) { 148 const status_t err = parcel->setDataCapacity(size); 149 if (err != NO_ERROR) { 150 signalExceptionForError(env, clazz, err); 151 } 152 } 153 } 154 155 static jboolean android_os_Parcel_pushAllowFds(jlong nativePtr, jboolean allowFds) 156 { 157 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 158 jboolean ret = JNI_TRUE; 159 if (parcel != NULL) { 160 ret = (jboolean)parcel->pushAllowFds(allowFds); 161 } 162 return ret; 163 } 164 165 static void android_os_Parcel_restoreAllowFds(jlong nativePtr, jboolean lastValue) 166 { 167 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 168 if (parcel != NULL) { 169 parcel->restoreAllowFds((bool)lastValue); 170 } 171 } 172 173 static void android_os_Parcel_writeByteArray(JNIEnv* env, jclass clazz, jlong nativePtr, 174 jobject data, jint offset, jint length) 175 { 176 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 177 if (parcel == NULL) { 178 return; 179 } 180 181 const status_t err = parcel->writeInt32(length); 182 if (err != NO_ERROR) { 183 signalExceptionForError(env, clazz, err); 184 return; 185 } 186 187 void* dest = parcel->writeInplace(length); 188 if (dest == NULL) { 189 signalExceptionForError(env, clazz, NO_MEMORY); 190 return; 191 } 192 193 jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0); 194 if (ar) { 195 memcpy(dest, ar + offset, length); 196 env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0); 197 } 198 } 199 200 static void android_os_Parcel_writeBlob(JNIEnv* env, jclass clazz, jlong nativePtr, jobject data, 201 jint offset, jint length) { 202 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 203 if (parcel == NULL) { 204 return; 205 } 206 207 if (data == NULL) { 208 const status_t err = parcel->writeInt32(-1); 209 if (err != NO_ERROR) { 210 signalExceptionForError(env, clazz, err); 211 } 212 return; 213 } 214 215 const status_t err = parcel->writeInt32(length); 216 if (err != NO_ERROR) { 217 signalExceptionForError(env, clazz, err); 218 return; 219 } 220 221 android::Parcel::WritableBlob blob; 222 android::status_t err2 = parcel->writeBlob(length, false, &blob); 223 if (err2 != NO_ERROR) { 224 signalExceptionForError(env, clazz, err2); 225 return; 226 } 227 228 jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)data, 0); 229 if (ar == NULL) { 230 memset(blob.data(), 0, length); 231 } else { 232 memcpy(blob.data(), ar + offset, length); 233 env->ReleasePrimitiveArrayCritical((jarray)data, ar, 0); 234 } 235 236 blob.release(); 237 } 238 239 static int android_os_Parcel_writeInt(jlong nativePtr, jint val) { 240 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 241 return (parcel != NULL) ? parcel->writeInt32(val) : OK; 242 } 243 244 static int android_os_Parcel_writeLong(jlong nativePtr, jlong val) { 245 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 246 return (parcel != NULL) ? parcel->writeInt64(val) : OK; 247 } 248 249 static int android_os_Parcel_writeFloat(jlong nativePtr, jfloat val) { 250 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 251 return (parcel != NULL) ? parcel->writeFloat(val) : OK; 252 } 253 254 static int android_os_Parcel_writeDouble(jlong nativePtr, jdouble val) { 255 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 256 return (parcel != NULL) ? parcel->writeDouble(val) : OK; 257 } 258 259 static void android_os_Parcel_nativeSignalExceptionForError(JNIEnv* env, jclass clazz, jint err) { 260 signalExceptionForError(env, clazz, err); 261 } 262 263 static void android_os_Parcel_writeString8(JNIEnv *env, jclass clazz, jlong nativePtr, 264 jstring val) { 265 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 266 if (parcel != nullptr) { 267 status_t err = NO_ERROR; 268 if (val) { 269 // NOTE: Keep this logic in sync with Parcel.cpp 270 const size_t len = env->GetStringLength(val); 271 const size_t allocLen = env->GetStringUTFLength(val); 272 err = parcel->writeInt32(allocLen); 273 char *data = reinterpret_cast<char*>(parcel->writeInplace(allocLen + sizeof(char))); 274 if (data != nullptr) { 275 env->GetStringUTFRegion(val, 0, len, data); 276 *(data + allocLen) = 0; 277 } else { 278 err = NO_MEMORY; 279 } 280 } else { 281 err = parcel->writeString8(nullptr, 0); 282 } 283 if (err != NO_ERROR) { 284 signalExceptionForError(env, clazz, err); 285 } 286 } 287 } 288 289 static void android_os_Parcel_writeString16(JNIEnv *env, jclass clazz, jlong nativePtr, 290 jstring val) { 291 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 292 if (parcel != nullptr) { 293 status_t err = NO_ERROR; 294 if (val) { 295 // NOTE: Keep this logic in sync with Parcel.cpp 296 const size_t len = env->GetStringLength(val); 297 const size_t allocLen = len * sizeof(char16_t); 298 err = parcel->writeInt32(len); 299 char *data = reinterpret_cast<char*>(parcel->writeInplace(allocLen + sizeof(char16_t))); 300 if (data != nullptr) { 301 env->GetStringRegion(val, 0, len, reinterpret_cast<jchar*>(data)); 302 *reinterpret_cast<char16_t*>(data + allocLen) = 0; 303 } else { 304 err = NO_MEMORY; 305 } 306 } else { 307 err = parcel->writeString16(nullptr, 0); 308 } 309 if (err != NO_ERROR) { 310 signalExceptionForError(env, clazz, err); 311 } 312 } 313 } 314 315 static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object) 316 { 317 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 318 if (parcel != NULL) { 319 const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object)); 320 if (err != NO_ERROR) { 321 signalExceptionForError(env, clazz, err); 322 } 323 } 324 } 325 326 static void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object) 327 { 328 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 329 if (parcel != NULL) { 330 const status_t err = 331 parcel->writeDupFileDescriptor(jniGetFDFromFileDescriptor(env, object)); 332 if (err != NO_ERROR) { 333 signalExceptionForError(env, clazz, err); 334 } 335 } 336 } 337 338 static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jclass clazz, jlong nativePtr) 339 { 340 jbyteArray ret = NULL; 341 342 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 343 if (parcel != NULL) { 344 int32_t len = parcel->readInt32(); 345 346 // Validate the stored length against the true data size 347 if (len >= 0 && len <= (int32_t)parcel->dataAvail()) { 348 ret = env->NewByteArray(len); 349 350 if (ret != NULL) { 351 jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0); 352 if (a2) { 353 const void* data = parcel->readInplace(len); 354 if (data) { 355 memcpy(a2, data, len); 356 } 357 env->ReleasePrimitiveArrayCritical(ret, a2, 0); 358 if (!data) { 359 ret = NULL; 360 } 361 } 362 } 363 } 364 } 365 366 return ret; 367 } 368 369 static jboolean android_os_Parcel_readByteArray(JNIEnv* env, jclass clazz, jlong nativePtr, 370 jobject dest, jint destLen) 371 { 372 jboolean ret = JNI_FALSE; 373 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 374 if (parcel == NULL) { 375 return ret; 376 } 377 378 int32_t len = parcel->readInt32(); 379 if (len >= 0 && len <= (int32_t)parcel->dataAvail() && len == destLen) { 380 jbyte* ar = (jbyte*)env->GetPrimitiveArrayCritical((jarray)dest, 0); 381 if (ar) { 382 const void* data = parcel->readInplace(len); 383 if (data) { 384 memcpy(ar, data, len); 385 ret = JNI_TRUE; 386 } else { 387 ret = JNI_FALSE; 388 } 389 390 env->ReleasePrimitiveArrayCritical((jarray)dest, ar, 0); 391 } 392 } 393 return ret; 394 } 395 396 static jbyteArray android_os_Parcel_readBlob(JNIEnv* env, jclass clazz, jlong nativePtr) 397 { 398 jbyteArray ret = NULL; 399 400 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 401 if (parcel != NULL) { 402 int32_t len = parcel->readInt32(); 403 if (len >= 0) { 404 android::Parcel::ReadableBlob blob; 405 android::status_t err = parcel->readBlob(len, &blob); 406 if (err != NO_ERROR) { 407 signalExceptionForError(env, clazz, err); 408 return NULL; 409 } 410 411 ret = env->NewByteArray(len); 412 if (ret != NULL) { 413 jbyte* a2 = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0); 414 if (a2) { 415 memcpy(a2, blob.data(), len); 416 env->ReleasePrimitiveArrayCritical(ret, a2, 0); 417 } 418 } 419 blob.release(); 420 } 421 } 422 423 return ret; 424 } 425 426 static jint android_os_Parcel_readInt(jlong nativePtr) 427 { 428 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 429 if (parcel != NULL) { 430 return parcel->readInt32(); 431 } 432 return 0; 433 } 434 435 static jlong android_os_Parcel_readLong(jlong nativePtr) 436 { 437 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 438 if (parcel != NULL) { 439 return parcel->readInt64(); 440 } 441 return 0; 442 } 443 444 static jfloat android_os_Parcel_readFloat(jlong nativePtr) 445 { 446 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 447 if (parcel != NULL) { 448 return parcel->readFloat(); 449 } 450 return 0; 451 } 452 453 static jdouble android_os_Parcel_readDouble(jlong nativePtr) 454 { 455 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 456 if (parcel != NULL) { 457 return parcel->readDouble(); 458 } 459 return 0; 460 } 461 462 static jstring android_os_Parcel_readString8(JNIEnv* env, jclass clazz, jlong nativePtr) 463 { 464 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 465 if (parcel != NULL) { 466 size_t len; 467 const char* str = parcel->readString8Inplace(&len); 468 if (str) { 469 return env->NewStringUTF(str); 470 } 471 return NULL; 472 } 473 return NULL; 474 } 475 476 static jstring android_os_Parcel_readString16(JNIEnv* env, jclass clazz, jlong nativePtr) 477 { 478 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 479 if (parcel != NULL) { 480 size_t len; 481 const char16_t* str = parcel->readString16Inplace(&len); 482 if (str) { 483 return env->NewString(reinterpret_cast<const jchar*>(str), len); 484 } 485 return NULL; 486 } 487 return NULL; 488 } 489 490 static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr) 491 { 492 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 493 if (parcel != NULL) { 494 return javaObjectForIBinder(env, parcel->readStrongBinder()); 495 } 496 return NULL; 497 } 498 499 static jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jclass clazz, jlong nativePtr) 500 { 501 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 502 if (parcel != NULL) { 503 int fd = parcel->readFileDescriptor(); 504 if (fd < 0) return NULL; 505 fd = fcntl(fd, F_DUPFD_CLOEXEC, 0); 506 if (fd < 0) return NULL; 507 jobject jifd = jniCreateFileDescriptor(env, fd); 508 if (jifd == NULL) { 509 close(fd); 510 } 511 return jifd; 512 } 513 return NULL; 514 } 515 516 static jlong android_os_Parcel_create(JNIEnv* env, jclass clazz) 517 { 518 Parcel* parcel = new Parcel(); 519 return reinterpret_cast<jlong>(parcel); 520 } 521 522 static void android_os_Parcel_freeBuffer(JNIEnv* env, jclass clazz, jlong nativePtr) 523 { 524 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 525 if (parcel != NULL) { 526 parcel->freeData(); 527 } 528 } 529 530 static void android_os_Parcel_destroy(JNIEnv* env, jclass clazz, jlong nativePtr) 531 { 532 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 533 delete parcel; 534 } 535 536 static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jlong nativePtr) 537 { 538 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 539 if (parcel == NULL) { 540 return NULL; 541 } 542 543 // do not marshall if there are binder objects in the parcel 544 if (parcel->objectsCount()) 545 { 546 jniThrowException(env, "java/lang/RuntimeException", "Tried to marshall a Parcel that contained Binder objects."); 547 return NULL; 548 } 549 550 jbyteArray ret = env->NewByteArray(parcel->dataSize()); 551 552 if (ret != NULL) 553 { 554 jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(ret, 0); 555 if (array != NULL) 556 { 557 memcpy(array, parcel->data(), parcel->dataSize()); 558 env->ReleasePrimitiveArrayCritical(ret, array, 0); 559 } 560 } 561 562 return ret; 563 } 564 565 static void android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jlong nativePtr, 566 jbyteArray data, jint offset, jint length) 567 { 568 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 569 if (parcel == NULL || length < 0) { 570 return; 571 } 572 573 jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0); 574 if (array) 575 { 576 parcel->setDataSize(length); 577 parcel->setDataPosition(0); 578 579 void* raw = parcel->writeInplace(length); 580 memcpy(raw, (array + offset), length); 581 582 env->ReleasePrimitiveArrayCritical(data, array, 0); 583 } 584 } 585 586 static jint android_os_Parcel_compareData(JNIEnv* env, jclass clazz, jlong thisNativePtr, 587 jlong otherNativePtr) 588 { 589 Parcel* thisParcel = reinterpret_cast<Parcel*>(thisNativePtr); 590 if (thisParcel == NULL) { 591 return 0; 592 } 593 Parcel* otherParcel = reinterpret_cast<Parcel*>(otherNativePtr); 594 if (otherParcel == NULL) { 595 return thisParcel->getOpenAshmemSize(); 596 } 597 598 return thisParcel->compareData(*otherParcel); 599 } 600 601 static void android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jlong thisNativePtr, 602 jlong otherNativePtr, jint offset, jint length) 603 { 604 Parcel* thisParcel = reinterpret_cast<Parcel*>(thisNativePtr); 605 if (thisParcel == NULL) { 606 return; 607 } 608 Parcel* otherParcel = reinterpret_cast<Parcel*>(otherNativePtr); 609 if (otherParcel == NULL) { 610 return; 611 } 612 613 status_t err = thisParcel->appendFrom(otherParcel, offset, length); 614 if (err != NO_ERROR) { 615 signalExceptionForError(env, clazz, err); 616 } 617 return; 618 } 619 620 static jboolean android_os_Parcel_hasFileDescriptors(jlong nativePtr) 621 { 622 jboolean ret = JNI_FALSE; 623 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 624 if (parcel != NULL) { 625 if (parcel->hasFileDescriptors()) { 626 ret = JNI_TRUE; 627 } 628 } 629 return ret; 630 } 631 632 // String tries to allocate itself on the stack, within a known size, but will 633 // make a heap allocation if not. 634 template <size_t StackReserve> 635 class StackString { 636 public: 637 StackString(JNIEnv* env, jstring str) : mEnv(env), mJStr(str) { 638 LOG_ALWAYS_FATAL_IF(str == nullptr); 639 mSize = env->GetStringLength(str); 640 if (mSize > StackReserve) { 641 mStr = new jchar[mSize]; 642 } else { 643 mStr = &mBuffer[0]; 644 } 645 mEnv->GetStringRegion(str, 0, mSize, mStr); 646 } 647 ~StackString() { 648 if (mStr != &mBuffer[0]) { 649 delete[] mStr; 650 } 651 } 652 const jchar* str() { return mStr; } 653 jsize size() { return mSize; } 654 655 private: 656 JNIEnv* mEnv; 657 jstring mJStr; 658 659 jchar mBuffer[StackReserve]; 660 // pointer to &mBuffer[0] if string fits in mBuffer, otherwise owned 661 jchar* mStr; 662 jsize mSize; 663 }; 664 665 // This size is chosen to be longer than most interface descriptors. 666 // Ones longer than this will be allocated on the heap. 667 typedef StackString<64> InterfaceDescriptorString; 668 669 static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jlong nativePtr, 670 jstring name) 671 { 672 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 673 if (parcel != nullptr) { 674 InterfaceDescriptorString descriptor(env, name); 675 parcel->writeInterfaceToken(reinterpret_cast<const char16_t*>(descriptor.str()), 676 descriptor.size()); 677 } 678 } 679 680 static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jlong nativePtr, jstring name) 681 { 682 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 683 if (parcel != nullptr) { 684 InterfaceDescriptorString descriptor(env, name); 685 IPCThreadState* threadState = IPCThreadState::self(); 686 const int32_t oldPolicy = threadState->getStrictModePolicy(); 687 const bool isValid = 688 parcel->enforceInterface(reinterpret_cast<const char16_t*>(descriptor.str()), 689 descriptor.size(), threadState); 690 if (isValid) { 691 const int32_t newPolicy = threadState->getStrictModePolicy(); 692 if (oldPolicy != newPolicy) { 693 // Need to keep the Java-level thread-local strict 694 // mode policy in sync for the libcore 695 // enforcements, which involves an upcall back 696 // into Java. (We can't modify the 697 // Parcel.enforceInterface signature, as it's 698 // pseudo-public, and used via AIDL 699 // auto-generation...) 700 set_dalvik_blockguard_policy(env, newPolicy); 701 } 702 return; // everything was correct -> return silently 703 } 704 } 705 706 // all error conditions wind up here 707 jniThrowException(env, "java/lang/SecurityException", 708 "Binder invocation to an incorrect interface"); 709 } 710 711 static jlong android_os_Parcel_getGlobalAllocSize(JNIEnv* env, jclass clazz) 712 { 713 return Parcel::getGlobalAllocSize(); 714 } 715 716 static jlong android_os_Parcel_getGlobalAllocCount(JNIEnv* env, jclass clazz) 717 { 718 return Parcel::getGlobalAllocCount(); 719 } 720 721 static jlong android_os_Parcel_getBlobAshmemSize(jlong nativePtr) 722 { 723 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 724 if (parcel != NULL) { 725 return parcel->getBlobAshmemSize(); 726 } 727 return 0; 728 } 729 730 static jint android_os_Parcel_readCallingWorkSourceUid(jlong nativePtr) 731 { 732 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 733 if (parcel != NULL) { 734 return parcel->readCallingWorkSourceUid(); 735 } 736 return IPCThreadState::kUnsetWorkSource; 737 } 738 739 static jboolean android_os_Parcel_replaceCallingWorkSourceUid(jlong nativePtr, jint uid) 740 { 741 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); 742 if (parcel != NULL) { 743 return parcel->replaceCallingWorkSourceUid(uid); 744 } 745 return false; 746 } 747 748 // ---------------------------------------------------------------------------- 749 750 static const JNINativeMethod gParcelMethods[] = { 751 // @CriticalNative 752 {"nativeMarkSensitive", "(J)V", (void*)android_os_Parcel_markSensitive}, 753 // @CriticalNative 754 {"nativeDataSize", "(J)I", (void*)android_os_Parcel_dataSize}, 755 // @CriticalNative 756 {"nativeDataAvail", "(J)I", (void*)android_os_Parcel_dataAvail}, 757 // @CriticalNative 758 {"nativeDataPosition", "(J)I", (void*)android_os_Parcel_dataPosition}, 759 // @CriticalNative 760 {"nativeDataCapacity", "(J)I", (void*)android_os_Parcel_dataCapacity}, 761 // @FastNative 762 {"nativeSetDataSize", "(JI)V", (void*)android_os_Parcel_setDataSize}, 763 // @CriticalNative 764 {"nativeSetDataPosition", "(JI)V", (void*)android_os_Parcel_setDataPosition}, 765 // @FastNative 766 {"nativeSetDataCapacity", "(JI)V", (void*)android_os_Parcel_setDataCapacity}, 767 768 // @CriticalNative 769 {"nativePushAllowFds", "(JZ)Z", (void*)android_os_Parcel_pushAllowFds}, 770 // @CriticalNative 771 {"nativeRestoreAllowFds", "(JZ)V", (void*)android_os_Parcel_restoreAllowFds}, 772 773 {"nativeWriteByteArray", "(J[BII)V", (void*)android_os_Parcel_writeByteArray}, 774 {"nativeWriteBlob", "(J[BII)V", (void*)android_os_Parcel_writeBlob}, 775 // @CriticalNative 776 {"nativeWriteInt", "(JI)I", (void*)android_os_Parcel_writeInt}, 777 // @CriticalNative 778 {"nativeWriteLong", "(JJ)I", (void*)android_os_Parcel_writeLong}, 779 // @CriticalNative 780 {"nativeWriteFloat", "(JF)I", (void*)android_os_Parcel_writeFloat}, 781 // @CriticalNative 782 {"nativeWriteDouble", "(JD)I", (void*)android_os_Parcel_writeDouble}, 783 {"nativeSignalExceptionForError", "(I)V", (void*)android_os_Parcel_nativeSignalExceptionForError}, 784 // @FastNative 785 {"nativeWriteString8", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeString8}, 786 // @FastNative 787 {"nativeWriteString16", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeString16}, 788 // @FastNative 789 {"nativeWriteStrongBinder", "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder}, 790 // @FastNative 791 {"nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor}, 792 793 {"nativeCreateByteArray", "(J)[B", (void*)android_os_Parcel_createByteArray}, 794 {"nativeReadByteArray", "(J[BI)Z", (void*)android_os_Parcel_readByteArray}, 795 {"nativeReadBlob", "(J)[B", (void*)android_os_Parcel_readBlob}, 796 // @CriticalNative 797 {"nativeReadInt", "(J)I", (void*)android_os_Parcel_readInt}, 798 // @CriticalNative 799 {"nativeReadLong", "(J)J", (void*)android_os_Parcel_readLong}, 800 // @CriticalNative 801 {"nativeReadFloat", "(J)F", (void*)android_os_Parcel_readFloat}, 802 // @CriticalNative 803 {"nativeReadDouble", "(J)D", (void*)android_os_Parcel_readDouble}, 804 // @FastNative 805 {"nativeReadString8", "(J)Ljava/lang/String;", (void*)android_os_Parcel_readString8}, 806 // @FastNative 807 {"nativeReadString16", "(J)Ljava/lang/String;", (void*)android_os_Parcel_readString16}, 808 // @FastNative 809 {"nativeReadStrongBinder", "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder}, 810 // @FastNative 811 {"nativeReadFileDescriptor", "(J)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor}, 812 813 {"nativeCreate", "()J", (void*)android_os_Parcel_create}, 814 {"nativeFreeBuffer", "(J)V", (void*)android_os_Parcel_freeBuffer}, 815 {"nativeDestroy", "(J)V", (void*)android_os_Parcel_destroy}, 816 817 {"nativeMarshall", "(J)[B", (void*)android_os_Parcel_marshall}, 818 {"nativeUnmarshall", "(J[BII)V", (void*)android_os_Parcel_unmarshall}, 819 {"nativeCompareData", "(JJ)I", (void*)android_os_Parcel_compareData}, 820 {"nativeAppendFrom", "(JJII)V", (void*)android_os_Parcel_appendFrom}, 821 // @CriticalNative 822 {"nativeHasFileDescriptors", "(J)Z", (void*)android_os_Parcel_hasFileDescriptors}, 823 {"nativeWriteInterfaceToken", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken}, 824 {"nativeEnforceInterface", "(JLjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface}, 825 826 {"getGlobalAllocSize", "()J", (void*)android_os_Parcel_getGlobalAllocSize}, 827 {"getGlobalAllocCount", "()J", (void*)android_os_Parcel_getGlobalAllocCount}, 828 829 // @CriticalNative 830 {"nativeGetBlobAshmemSize", "(J)J", (void*)android_os_Parcel_getBlobAshmemSize}, 831 832 // @CriticalNative 833 {"nativeReadCallingWorkSourceUid", "(J)I", (void*)android_os_Parcel_readCallingWorkSourceUid}, 834 // @CriticalNative 835 {"nativeReplaceCallingWorkSourceUid", "(JI)Z", (void*)android_os_Parcel_replaceCallingWorkSourceUid}, 836 }; 837 838 const char* const kParcelPathName = "android/os/Parcel"; 839 840 int register_android_os_Parcel(JNIEnv* env) 841 { 842 jclass clazz = FindClassOrDie(env, kParcelPathName); 843 844 gParcelOffsets.clazz = MakeGlobalRefOrDie(env, clazz); 845 gParcelOffsets.mNativePtr = GetFieldIDOrDie(env, clazz, "mNativePtr", "J"); 846 gParcelOffsets.obtain = GetStaticMethodIDOrDie(env, clazz, "obtain", "()Landroid/os/Parcel;"); 847 gParcelOffsets.recycle = GetMethodIDOrDie(env, clazz, "recycle", "()V"); 848 849 return RegisterMethodsOrDie(env, kParcelPathName, gParcelMethods, NELEM(gParcelMethods)); 850 } 851 852 }; 853