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