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