1 /*
2 * Copyright (C) 2018 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 #include <android/binder_parcel.h>
18 #include <android/binder_parcel_platform.h>
19 #include <binder/Parcel.h>
20 #include <binder/ParcelFileDescriptor.h>
21 #include <binder/unique_fd.h>
22 #include <inttypes.h>
23 #include <utils/Unicode.h>
24
25 #include <limits>
26
27 #include "ibinder_internal.h"
28 #include "parcel_internal.h"
29 #include "status_internal.h"
30
31 using ::android::IBinder;
32 using ::android::Parcel;
33 using ::android::sp;
34 using ::android::status_t;
35 using ::android::binder::unique_fd;
36 using ::android::os::ParcelFileDescriptor;
37
38 template <typename T>
39 using ContiguousArrayAllocator = bool (*)(void* arrayData, int32_t length, T** outBuffer);
40
41 template <typename T>
42 using ArrayAllocator = bool (*)(void* arrayData, int32_t length);
43 template <typename T>
44 using ArrayGetter = T (*)(const void* arrayData, size_t index);
45 template <typename T>
46 using ArraySetter = void (*)(void* arrayData, size_t index, T value);
47
WriteAndValidateArraySize(AParcel * parcel,bool isNullArray,int32_t length)48 static binder_status_t WriteAndValidateArraySize(AParcel* parcel, bool isNullArray,
49 int32_t length) {
50 // only -1 can be used to represent a null array
51 if (length < -1) return STATUS_BAD_VALUE;
52
53 if (!isNullArray && length < 0) {
54 ALOGE("non-null array but length is %" PRIi32, length);
55 return STATUS_BAD_VALUE;
56 }
57 if (isNullArray && length > 0) {
58 ALOGE("null buffer cannot be for size %" PRIi32 " array.", length);
59 return STATUS_BAD_VALUE;
60 }
61
62 Parcel* rawParcel = parcel->get();
63
64 status_t status = rawParcel->writeInt32(length);
65 if (status != STATUS_OK) return PruneStatusT(status);
66
67 return STATUS_OK;
68 }
69
ReadAndValidateArraySize(const AParcel * parcel,int32_t * length)70 static binder_status_t ReadAndValidateArraySize(const AParcel* parcel, int32_t* length) {
71 if (status_t status = parcel->get()->readInt32(length); status != STATUS_OK) {
72 return PruneStatusT(status);
73 }
74
75 if (*length < -1) return STATUS_BAD_VALUE; // libbinder_ndk reserves these
76 if (*length <= 0) return STATUS_OK; // null
77 if (static_cast<size_t>(*length) > parcel->get()->dataAvail()) return STATUS_NO_MEMORY;
78
79 return STATUS_OK;
80 }
81
82 template <typename T>
WriteArray(AParcel * parcel,const T * array,int32_t length)83 binder_status_t WriteArray(AParcel* parcel, const T* array, int32_t length) {
84 binder_status_t status = WriteAndValidateArraySize(parcel, array == nullptr, length);
85 if (status != STATUS_OK) return status;
86 if (length <= 0) return STATUS_OK;
87
88 int32_t size = 0;
89 if (__builtin_smul_overflow(sizeof(T), length, &size)) return STATUS_NO_MEMORY;
90
91 void* const data = parcel->get()->writeInplace(size);
92 if (data == nullptr) return STATUS_NO_MEMORY;
93
94 memcpy(data, array, size);
95
96 return STATUS_OK;
97 }
98
99 // Each element in a char16_t array is converted to an int32_t (not packed).
100 template <>
WriteArray(AParcel * parcel,const char16_t * array,int32_t length)101 binder_status_t WriteArray<char16_t>(AParcel* parcel, const char16_t* array, int32_t length) {
102 binder_status_t status = WriteAndValidateArraySize(parcel, array == nullptr, length);
103 if (status != STATUS_OK) return status;
104 if (length <= 0) return STATUS_OK;
105
106 int32_t size = 0;
107 if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;
108
109 Parcel* rawParcel = parcel->get();
110
111 for (int32_t i = 0; i < length; i++) {
112 status = rawParcel->writeChar(array[i]);
113
114 if (status != STATUS_OK) return PruneStatusT(status);
115 }
116
117 return STATUS_OK;
118 }
119
120 template <typename T>
ReadArray(const AParcel * parcel,void * arrayData,ContiguousArrayAllocator<T> allocator)121 binder_status_t ReadArray(const AParcel* parcel, void* arrayData,
122 ContiguousArrayAllocator<T> allocator) {
123 const Parcel* rawParcel = parcel->get();
124
125 int32_t length;
126 if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
127 return status;
128 }
129
130 T* array;
131 if (!allocator(arrayData, length, &array)) {
132 if (length < 0) {
133 return STATUS_UNEXPECTED_NULL;
134 } else {
135 return STATUS_NO_MEMORY;
136 }
137 }
138
139 if (length <= 0) return STATUS_OK;
140 if (array == nullptr) return STATUS_NO_MEMORY;
141
142 int32_t size = 0;
143 if (__builtin_smul_overflow(sizeof(T), length, &size)) return STATUS_NO_MEMORY;
144
145 const void* data = rawParcel->readInplace(size);
146 if (data == nullptr) return STATUS_NO_MEMORY;
147
148 memcpy(array, data, size);
149
150 return STATUS_OK;
151 }
152
153 // Each element in a char16_t array is converted to an int32_t (not packed)
154 template <>
ReadArray(const AParcel * parcel,void * arrayData,ContiguousArrayAllocator<char16_t> allocator)155 binder_status_t ReadArray<char16_t>(const AParcel* parcel, void* arrayData,
156 ContiguousArrayAllocator<char16_t> allocator) {
157 const Parcel* rawParcel = parcel->get();
158
159 int32_t length;
160 if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
161 return status;
162 }
163
164 char16_t* array;
165 if (!allocator(arrayData, length, &array)) {
166 if (length < 0) {
167 return STATUS_UNEXPECTED_NULL;
168 } else {
169 return STATUS_NO_MEMORY;
170 }
171 }
172
173 if (length <= 0) return STATUS_OK;
174 if (array == nullptr) return STATUS_NO_MEMORY;
175
176 int32_t size = 0;
177 if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;
178
179 for (int32_t i = 0; i < length; i++) {
180 status_t status = rawParcel->readChar(array + i);
181
182 if (status != STATUS_OK) return PruneStatusT(status);
183 }
184
185 return STATUS_OK;
186 }
187
188 template <typename T>
WriteArray(AParcel * parcel,const void * arrayData,int32_t length,ArrayGetter<T> getter,status_t (Parcel::* write)(T))189 binder_status_t WriteArray(AParcel* parcel, const void* arrayData, int32_t length,
190 ArrayGetter<T> getter, status_t (Parcel::*write)(T)) {
191 // we have no clue if arrayData represents a null object or not, we can only infer from length
192 bool arrayIsNull = length < 0;
193 binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
194 if (status != STATUS_OK) return status;
195 if (length <= 0) return STATUS_OK;
196
197 Parcel* rawParcel = parcel->get();
198
199 for (int32_t i = 0; i < length; i++) {
200 status = (rawParcel->*write)(getter(arrayData, i));
201
202 if (status != STATUS_OK) return PruneStatusT(status);
203 }
204
205 return STATUS_OK;
206 }
207
208 template <typename T>
ReadArray(const AParcel * parcel,void * arrayData,ArrayAllocator<T> allocator,ArraySetter<T> setter,status_t (Parcel::* read)(T *)const)209 binder_status_t ReadArray(const AParcel* parcel, void* arrayData, ArrayAllocator<T> allocator,
210 ArraySetter<T> setter, status_t (Parcel::*read)(T*) const) {
211 const Parcel* rawParcel = parcel->get();
212
213 int32_t length;
214 if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
215 return status;
216 }
217
218 if (!allocator(arrayData, length)) {
219 if (length < 0) {
220 return STATUS_UNEXPECTED_NULL;
221 } else {
222 return STATUS_NO_MEMORY;
223 }
224 }
225
226 if (length <= 0) return STATUS_OK;
227
228 for (int32_t i = 0; i < length; i++) {
229 T readTarget;
230 status_t status = (rawParcel->*read)(&readTarget);
231 if (status != STATUS_OK) return PruneStatusT(status);
232
233 setter(arrayData, i, readTarget);
234 }
235
236 return STATUS_OK;
237 }
238
AParcel_delete(AParcel * parcel)239 void AParcel_delete(AParcel* parcel) {
240 delete parcel;
241 }
242
AParcel_setDataPosition(const AParcel * parcel,int32_t position)243 binder_status_t AParcel_setDataPosition(const AParcel* parcel, int32_t position) {
244 if (position < 0) {
245 return STATUS_BAD_VALUE;
246 }
247
248 parcel->get()->setDataPosition(position);
249 return STATUS_OK;
250 }
251
AParcel_getDataPosition(const AParcel * parcel)252 int32_t AParcel_getDataPosition(const AParcel* parcel) {
253 return parcel->get()->dataPosition();
254 }
255
AParcel_markSensitive(const AParcel * parcel)256 void AParcel_markSensitive(const AParcel* parcel) {
257 return parcel->get()->markSensitive();
258 }
259
AParcel_writeStrongBinder(AParcel * parcel,AIBinder * binder)260 binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder) {
261 sp<IBinder> writeBinder = binder != nullptr ? binder->getBinder() : nullptr;
262 return parcel->get()->writeStrongBinder(writeBinder);
263 }
AParcel_readStrongBinder(const AParcel * parcel,AIBinder ** binder)264 binder_status_t AParcel_readStrongBinder(const AParcel* parcel, AIBinder** binder) {
265 sp<IBinder> readBinder = nullptr;
266 status_t status = parcel->get()->readNullableStrongBinder(&readBinder);
267 if (status != STATUS_OK) {
268 return PruneStatusT(status);
269 }
270 sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(readBinder);
271 AIBinder_incStrong(ret.get());
272
273 if (ret.get() != nullptr && parcel->get()->isServiceFuzzing()) {
274 if (auto bp = ret->asABpBinder(); bp != nullptr) {
275 bp->setServiceFuzzing();
276 }
277 }
278
279 *binder = ret.get();
280 return PruneStatusT(status);
281 }
282
AParcel_writeParcelFileDescriptor(AParcel * parcel,int fd)283 binder_status_t AParcel_writeParcelFileDescriptor(AParcel* parcel, int fd) {
284 if (fd < 0) {
285 if (fd != -1) {
286 return STATUS_UNKNOWN_ERROR;
287 }
288 return PruneStatusT(parcel->get()->writeInt32(0)); // null
289 }
290 status_t status = parcel->get()->writeInt32(1); // not-null
291 if (status != STATUS_OK) return PruneStatusT(status);
292
293 status = parcel->get()->writeDupParcelFileDescriptor(fd);
294 return PruneStatusT(status);
295 }
296
AParcel_readParcelFileDescriptor(const AParcel * parcel,int * fd)297 binder_status_t AParcel_readParcelFileDescriptor(const AParcel* parcel, int* fd) {
298 std::optional<ParcelFileDescriptor> parcelFd;
299
300 status_t status = parcel->get()->readParcelable(&parcelFd);
301 if (status != STATUS_OK) return PruneStatusT(status);
302
303 if (parcelFd) {
304 *fd = parcelFd->release().release();
305 } else {
306 *fd = -1;
307 }
308
309 return STATUS_OK;
310 }
311
AParcel_writeStatusHeader(AParcel * parcel,const AStatus * status)312 binder_status_t AParcel_writeStatusHeader(AParcel* parcel, const AStatus* status) {
313 return PruneStatusT(status->get().writeToParcel(parcel->get()));
314 }
AParcel_readStatusHeader(const AParcel * parcel,AStatus ** status)315 binder_status_t AParcel_readStatusHeader(const AParcel* parcel, AStatus** status) {
316 ::android::binder::Status bstatus;
317 binder_status_t ret = PruneStatusT(bstatus.readFromParcel(*parcel->get()));
318 if (ret == STATUS_OK) {
319 *status = new AStatus(std::move(bstatus));
320 }
321 return PruneStatusT(ret);
322 }
323
AParcel_writeString(AParcel * parcel,const char * string,int32_t length)324 binder_status_t AParcel_writeString(AParcel* parcel, const char* string, int32_t length) {
325 if (string == nullptr) {
326 if (length != -1) {
327 ALOGW("null string must be used with length == -1.");
328 return STATUS_BAD_VALUE;
329 }
330
331 status_t err = parcel->get()->writeInt32(-1);
332 return PruneStatusT(err);
333 }
334
335 if (length < 0) {
336 ALOGW("Negative string length: %" PRIi32, length);
337 return STATUS_BAD_VALUE;
338 }
339
340 const uint8_t* str8 = (uint8_t*)string;
341 const ssize_t len16 = utf8_to_utf16_length(str8, length);
342
343 if (len16 < 0 || len16 >= std::numeric_limits<int32_t>::max()) {
344 ALOGW("Invalid string length: %zd", len16);
345 return STATUS_BAD_VALUE;
346 }
347
348 status_t err = parcel->get()->writeInt32(len16);
349 if (err) {
350 return PruneStatusT(err);
351 }
352
353 void* str16 = parcel->get()->writeInplace((len16 + 1) * sizeof(char16_t));
354 if (str16 == nullptr) {
355 return STATUS_NO_MEMORY;
356 }
357
358 utf8_to_utf16(str8, length, (char16_t*)str16, (size_t)len16 + 1);
359
360 return STATUS_OK;
361 }
362
AParcel_readString(const AParcel * parcel,void * stringData,AParcel_stringAllocator allocator)363 binder_status_t AParcel_readString(const AParcel* parcel, void* stringData,
364 AParcel_stringAllocator allocator) {
365 size_t len16;
366 const char16_t* str16 = parcel->get()->readString16Inplace(&len16);
367
368 if (str16 == nullptr) {
369 if (allocator(stringData, -1, nullptr)) {
370 return STATUS_OK;
371 }
372
373 return STATUS_UNEXPECTED_NULL;
374 }
375
376 ssize_t len8;
377
378 if (len16 == 0) {
379 len8 = 1;
380 } else {
381 len8 = utf16_to_utf8_length(str16, len16) + 1;
382 }
383
384 if (len8 <= 0 || len8 > std::numeric_limits<int32_t>::max()) {
385 ALOGW("Invalid string length: %zd", len8);
386 return STATUS_BAD_VALUE;
387 }
388
389 char* str8;
390 bool success = allocator(stringData, len8, &str8);
391
392 if (!success || str8 == nullptr) {
393 ALOGW("AParcel_stringAllocator failed to allocate.");
394 return STATUS_NO_MEMORY;
395 }
396
397 utf16_to_utf8(str16, len16, str8, len8);
398
399 return STATUS_OK;
400 }
401
AParcel_writeStringArray(AParcel * parcel,const void * arrayData,int32_t length,AParcel_stringArrayElementGetter getter)402 binder_status_t AParcel_writeStringArray(AParcel* parcel, const void* arrayData, int32_t length,
403 AParcel_stringArrayElementGetter getter) {
404 // we have no clue if arrayData represents a null object or not, we can only infer from length
405 bool arrayIsNull = length < 0;
406 binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
407 if (status != STATUS_OK) return status;
408 if (length <= 0) return STATUS_OK;
409
410 for (int32_t i = 0; i < length; i++) {
411 int32_t elementLength = 0;
412 const char* str = getter(arrayData, i, &elementLength);
413 if (str == nullptr && elementLength != -1) return STATUS_BAD_VALUE;
414
415 binder_status_t status = AParcel_writeString(parcel, str, elementLength);
416 if (status != STATUS_OK) return status;
417 }
418
419 return STATUS_OK;
420 }
421
422 // This implements AParcel_stringAllocator for a string using an array, index, and element
423 // allocator.
424 struct StringArrayElementAllocationAdapter {
425 void* arrayData; // stringData from the NDK
426 int32_t index; // index into the string array
427 AParcel_stringArrayElementAllocator elementAllocator;
428
AllocatorStringArrayElementAllocationAdapter429 static bool Allocator(void* stringData, int32_t length, char** buffer) {
430 StringArrayElementAllocationAdapter* adapter =
431 static_cast<StringArrayElementAllocationAdapter*>(stringData);
432 return adapter->elementAllocator(adapter->arrayData, adapter->index, length, buffer);
433 }
434 };
435
AParcel_readStringArray(const AParcel * parcel,void * arrayData,AParcel_stringArrayAllocator allocator,AParcel_stringArrayElementAllocator elementAllocator)436 binder_status_t AParcel_readStringArray(const AParcel* parcel, void* arrayData,
437 AParcel_stringArrayAllocator allocator,
438 AParcel_stringArrayElementAllocator elementAllocator) {
439 int32_t length;
440 if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
441 return status;
442 }
443
444 if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
445
446 if (length == -1) return STATUS_OK; // null string array
447
448 StringArrayElementAllocationAdapter adapter{
449 .arrayData = arrayData,
450 .index = 0,
451 .elementAllocator = elementAllocator,
452 };
453
454 for (; adapter.index < length; adapter.index++) {
455 binder_status_t status = AParcel_readString(parcel, static_cast<void*>(&adapter),
456 StringArrayElementAllocationAdapter::Allocator);
457
458 if (status != STATUS_OK) return status;
459 }
460
461 return STATUS_OK;
462 }
463
AParcel_writeParcelableArray(AParcel * parcel,const void * arrayData,int32_t length,AParcel_writeParcelableElement elementWriter)464 binder_status_t AParcel_writeParcelableArray(AParcel* parcel, const void* arrayData, int32_t length,
465 AParcel_writeParcelableElement elementWriter) {
466 // we have no clue if arrayData represents a null object or not, we can only infer from length
467 bool arrayIsNull = length < 0;
468 binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
469 if (status != STATUS_OK) return status;
470 if (length <= 0) return STATUS_OK;
471
472 for (int32_t i = 0; i < length; i++) {
473 binder_status_t status = elementWriter(parcel, arrayData, i);
474 if (status != STATUS_OK) return status;
475 }
476
477 return STATUS_OK;
478 }
479
AParcel_readParcelableArray(const AParcel * parcel,void * arrayData,AParcel_parcelableArrayAllocator allocator,AParcel_readParcelableElement elementReader)480 binder_status_t AParcel_readParcelableArray(const AParcel* parcel, void* arrayData,
481 AParcel_parcelableArrayAllocator allocator,
482 AParcel_readParcelableElement elementReader) {
483 int32_t length;
484 if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
485 return status;
486 }
487
488 if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
489
490 if (length == -1) return STATUS_OK; // null array
491
492 for (int32_t i = 0; i < length; i++) {
493 binder_status_t status = elementReader(parcel, arrayData, i);
494 if (status != STATUS_OK) return status;
495 }
496
497 return STATUS_OK;
498 }
499
500 // See gen_parcel_helper.py. These auto-generated read/write methods use the same types for
501 // libbinder and this library.
502 // @START
AParcel_writeInt32(AParcel * parcel,int32_t value)503 binder_status_t AParcel_writeInt32(AParcel* parcel, int32_t value) {
504 status_t status = parcel->get()->writeInt32(value);
505 return PruneStatusT(status);
506 }
507
AParcel_writeUint32(AParcel * parcel,uint32_t value)508 binder_status_t AParcel_writeUint32(AParcel* parcel, uint32_t value) {
509 status_t status = parcel->get()->writeUint32(value);
510 return PruneStatusT(status);
511 }
512
AParcel_writeInt64(AParcel * parcel,int64_t value)513 binder_status_t AParcel_writeInt64(AParcel* parcel, int64_t value) {
514 status_t status = parcel->get()->writeInt64(value);
515 return PruneStatusT(status);
516 }
517
AParcel_writeUint64(AParcel * parcel,uint64_t value)518 binder_status_t AParcel_writeUint64(AParcel* parcel, uint64_t value) {
519 status_t status = parcel->get()->writeUint64(value);
520 return PruneStatusT(status);
521 }
522
AParcel_writeFloat(AParcel * parcel,float value)523 binder_status_t AParcel_writeFloat(AParcel* parcel, float value) {
524 status_t status = parcel->get()->writeFloat(value);
525 return PruneStatusT(status);
526 }
527
AParcel_writeDouble(AParcel * parcel,double value)528 binder_status_t AParcel_writeDouble(AParcel* parcel, double value) {
529 status_t status = parcel->get()->writeDouble(value);
530 return PruneStatusT(status);
531 }
532
AParcel_writeBool(AParcel * parcel,bool value)533 binder_status_t AParcel_writeBool(AParcel* parcel, bool value) {
534 status_t status = parcel->get()->writeBool(value);
535 return PruneStatusT(status);
536 }
537
AParcel_writeChar(AParcel * parcel,char16_t value)538 binder_status_t AParcel_writeChar(AParcel* parcel, char16_t value) {
539 status_t status = parcel->get()->writeChar(value);
540 return PruneStatusT(status);
541 }
542
AParcel_writeByte(AParcel * parcel,int8_t value)543 binder_status_t AParcel_writeByte(AParcel* parcel, int8_t value) {
544 status_t status = parcel->get()->writeByte(value);
545 return PruneStatusT(status);
546 }
547
AParcel_readInt32(const AParcel * parcel,int32_t * value)548 binder_status_t AParcel_readInt32(const AParcel* parcel, int32_t* value) {
549 status_t status = parcel->get()->readInt32(value);
550 return PruneStatusT(status);
551 }
552
AParcel_readUint32(const AParcel * parcel,uint32_t * value)553 binder_status_t AParcel_readUint32(const AParcel* parcel, uint32_t* value) {
554 status_t status = parcel->get()->readUint32(value);
555 return PruneStatusT(status);
556 }
557
AParcel_readInt64(const AParcel * parcel,int64_t * value)558 binder_status_t AParcel_readInt64(const AParcel* parcel, int64_t* value) {
559 status_t status = parcel->get()->readInt64(value);
560 return PruneStatusT(status);
561 }
562
AParcel_readUint64(const AParcel * parcel,uint64_t * value)563 binder_status_t AParcel_readUint64(const AParcel* parcel, uint64_t* value) {
564 status_t status = parcel->get()->readUint64(value);
565 return PruneStatusT(status);
566 }
567
AParcel_readFloat(const AParcel * parcel,float * value)568 binder_status_t AParcel_readFloat(const AParcel* parcel, float* value) {
569 status_t status = parcel->get()->readFloat(value);
570 return PruneStatusT(status);
571 }
572
AParcel_readDouble(const AParcel * parcel,double * value)573 binder_status_t AParcel_readDouble(const AParcel* parcel, double* value) {
574 status_t status = parcel->get()->readDouble(value);
575 return PruneStatusT(status);
576 }
577
AParcel_readBool(const AParcel * parcel,bool * value)578 binder_status_t AParcel_readBool(const AParcel* parcel, bool* value) {
579 status_t status = parcel->get()->readBool(value);
580 return PruneStatusT(status);
581 }
582
AParcel_readChar(const AParcel * parcel,char16_t * value)583 binder_status_t AParcel_readChar(const AParcel* parcel, char16_t* value) {
584 status_t status = parcel->get()->readChar(value);
585 return PruneStatusT(status);
586 }
587
AParcel_readByte(const AParcel * parcel,int8_t * value)588 binder_status_t AParcel_readByte(const AParcel* parcel, int8_t* value) {
589 status_t status = parcel->get()->readByte(value);
590 return PruneStatusT(status);
591 }
592
AParcel_writeInt32Array(AParcel * parcel,const int32_t * arrayData,int32_t length)593 binder_status_t AParcel_writeInt32Array(AParcel* parcel, const int32_t* arrayData, int32_t length) {
594 return WriteArray<int32_t>(parcel, arrayData, length);
595 }
596
AParcel_writeUint32Array(AParcel * parcel,const uint32_t * arrayData,int32_t length)597 binder_status_t AParcel_writeUint32Array(AParcel* parcel, const uint32_t* arrayData,
598 int32_t length) {
599 return WriteArray<uint32_t>(parcel, arrayData, length);
600 }
601
AParcel_writeInt64Array(AParcel * parcel,const int64_t * arrayData,int32_t length)602 binder_status_t AParcel_writeInt64Array(AParcel* parcel, const int64_t* arrayData, int32_t length) {
603 return WriteArray<int64_t>(parcel, arrayData, length);
604 }
605
AParcel_writeUint64Array(AParcel * parcel,const uint64_t * arrayData,int32_t length)606 binder_status_t AParcel_writeUint64Array(AParcel* parcel, const uint64_t* arrayData,
607 int32_t length) {
608 return WriteArray<uint64_t>(parcel, arrayData, length);
609 }
610
AParcel_writeFloatArray(AParcel * parcel,const float * arrayData,int32_t length)611 binder_status_t AParcel_writeFloatArray(AParcel* parcel, const float* arrayData, int32_t length) {
612 return WriteArray<float>(parcel, arrayData, length);
613 }
614
AParcel_writeDoubleArray(AParcel * parcel,const double * arrayData,int32_t length)615 binder_status_t AParcel_writeDoubleArray(AParcel* parcel, const double* arrayData, int32_t length) {
616 return WriteArray<double>(parcel, arrayData, length);
617 }
618
AParcel_writeBoolArray(AParcel * parcel,const void * arrayData,int32_t length,AParcel_boolArrayGetter getter)619 binder_status_t AParcel_writeBoolArray(AParcel* parcel, const void* arrayData, int32_t length,
620 AParcel_boolArrayGetter getter) {
621 return WriteArray<bool>(parcel, arrayData, length, getter, &Parcel::writeBool);
622 }
623
AParcel_writeCharArray(AParcel * parcel,const char16_t * arrayData,int32_t length)624 binder_status_t AParcel_writeCharArray(AParcel* parcel, const char16_t* arrayData, int32_t length) {
625 return WriteArray<char16_t>(parcel, arrayData, length);
626 }
627
AParcel_writeByteArray(AParcel * parcel,const int8_t * arrayData,int32_t length)628 binder_status_t AParcel_writeByteArray(AParcel* parcel, const int8_t* arrayData, int32_t length) {
629 return WriteArray<int8_t>(parcel, arrayData, length);
630 }
631
AParcel_readInt32Array(const AParcel * parcel,void * arrayData,AParcel_int32ArrayAllocator allocator)632 binder_status_t AParcel_readInt32Array(const AParcel* parcel, void* arrayData,
633 AParcel_int32ArrayAllocator allocator) {
634 return ReadArray<int32_t>(parcel, arrayData, allocator);
635 }
636
AParcel_readUint32Array(const AParcel * parcel,void * arrayData,AParcel_uint32ArrayAllocator allocator)637 binder_status_t AParcel_readUint32Array(const AParcel* parcel, void* arrayData,
638 AParcel_uint32ArrayAllocator allocator) {
639 return ReadArray<uint32_t>(parcel, arrayData, allocator);
640 }
641
AParcel_readInt64Array(const AParcel * parcel,void * arrayData,AParcel_int64ArrayAllocator allocator)642 binder_status_t AParcel_readInt64Array(const AParcel* parcel, void* arrayData,
643 AParcel_int64ArrayAllocator allocator) {
644 return ReadArray<int64_t>(parcel, arrayData, allocator);
645 }
646
AParcel_readUint64Array(const AParcel * parcel,void * arrayData,AParcel_uint64ArrayAllocator allocator)647 binder_status_t AParcel_readUint64Array(const AParcel* parcel, void* arrayData,
648 AParcel_uint64ArrayAllocator allocator) {
649 return ReadArray<uint64_t>(parcel, arrayData, allocator);
650 }
651
AParcel_readFloatArray(const AParcel * parcel,void * arrayData,AParcel_floatArrayAllocator allocator)652 binder_status_t AParcel_readFloatArray(const AParcel* parcel, void* arrayData,
653 AParcel_floatArrayAllocator allocator) {
654 return ReadArray<float>(parcel, arrayData, allocator);
655 }
656
AParcel_readDoubleArray(const AParcel * parcel,void * arrayData,AParcel_doubleArrayAllocator allocator)657 binder_status_t AParcel_readDoubleArray(const AParcel* parcel, void* arrayData,
658 AParcel_doubleArrayAllocator allocator) {
659 return ReadArray<double>(parcel, arrayData, allocator);
660 }
661
AParcel_readBoolArray(const AParcel * parcel,void * arrayData,AParcel_boolArrayAllocator allocator,AParcel_boolArraySetter setter)662 binder_status_t AParcel_readBoolArray(const AParcel* parcel, void* arrayData,
663 AParcel_boolArrayAllocator allocator,
664 AParcel_boolArraySetter setter) {
665 return ReadArray<bool>(parcel, arrayData, allocator, setter, &Parcel::readBool);
666 }
667
AParcel_readCharArray(const AParcel * parcel,void * arrayData,AParcel_charArrayAllocator allocator)668 binder_status_t AParcel_readCharArray(const AParcel* parcel, void* arrayData,
669 AParcel_charArrayAllocator allocator) {
670 return ReadArray<char16_t>(parcel, arrayData, allocator);
671 }
672
AParcel_readByteArray(const AParcel * parcel,void * arrayData,AParcel_byteArrayAllocator allocator)673 binder_status_t AParcel_readByteArray(const AParcel* parcel, void* arrayData,
674 AParcel_byteArrayAllocator allocator) {
675 return ReadArray<int8_t>(parcel, arrayData, allocator);
676 }
677
AParcel_getAllowFds(const AParcel * parcel)678 bool AParcel_getAllowFds(const AParcel* parcel) {
679 return parcel->get()->allowFds();
680 }
681
AParcel_reset(AParcel * parcel)682 binder_status_t AParcel_reset(AParcel* parcel) {
683 parcel->get()->freeData();
684 return STATUS_OK;
685 }
686
AParcel_getDataSize(const AParcel * parcel)687 int32_t AParcel_getDataSize(const AParcel* parcel) {
688 return parcel->get()->dataSize();
689 }
690
AParcel_appendFrom(const AParcel * from,AParcel * to,int32_t start,int32_t size)691 binder_status_t AParcel_appendFrom(const AParcel* from, AParcel* to, int32_t start, int32_t size) {
692 status_t status = to->get()->appendFrom(from->get(), start, size);
693 return PruneStatusT(status);
694 }
695
AParcel_create()696 AParcel* AParcel_create() {
697 return new AParcel(nullptr);
698 }
699
AParcel_marshal(const AParcel * parcel,uint8_t * buffer,size_t start,size_t len)700 binder_status_t AParcel_marshal(const AParcel* parcel, uint8_t* buffer, size_t start, size_t len) {
701 if (parcel->get()->objectsCount()) {
702 return STATUS_INVALID_OPERATION;
703 }
704 // b/264739302 - getDataSize will return dataPos if it is greater than dataSize
705 // which will cause crashes in memcpy at later point. Instead compare with
706 // actual length of internal buffer
707 int32_t dataSize = parcel->get()->dataBufferSize();
708 if (len > static_cast<size_t>(dataSize) || start > static_cast<size_t>(dataSize) - len) {
709 return STATUS_BAD_VALUE;
710 }
711 const uint8_t* internalBuffer = parcel->get()->data();
712 if (internalBuffer == nullptr) {
713 return STATUS_UNEXPECTED_NULL;
714 }
715 memcpy(buffer, internalBuffer + start, len);
716 return STATUS_OK;
717 }
718
AParcel_unmarshal(AParcel * parcel,const uint8_t * buffer,size_t len)719 binder_status_t AParcel_unmarshal(AParcel* parcel, const uint8_t* buffer, size_t len) {
720 status_t status = parcel->get()->setDataSize(len);
721 if (status != ::android::OK) {
722 return PruneStatusT(status);
723 }
724 parcel->get()->setDataPosition(0);
725
726 void* raw = parcel->get()->writeInplace(len);
727 if (raw == nullptr) {
728 return STATUS_NO_MEMORY;
729 }
730 memcpy(raw, buffer, len);
731 return STATUS_OK;
732 }
733
734 // @END
735