@@ -628,6 +628,26 @@ struct binder_transaction {
628628 spinlock_t lock ;
629629};
630630
631+ /**
632+ * struct binder_object - union of flat binder object types
633+ * @hdr: generic object header
634+ * @fbo: binder object (nodes and refs)
635+ * @fdo: file descriptor object
636+ * @bbo: binder buffer pointer
637+ * @fdao: file descriptor array
638+ *
639+ * Used for type-independent object copies
640+ */
641+ struct binder_object {
642+ union {
643+ struct binder_object_header hdr ;
644+ struct flat_binder_object fbo ;
645+ struct binder_fd_object fdo ;
646+ struct binder_buffer_object bbo ;
647+ struct binder_fd_array_object fdao ;
648+ };
649+ };
650+
631651/**
632652 * binder_proc_lock() - Acquire outer lock for given binder_proc
633653 * @proc: struct binder_proc to acquire
@@ -2017,26 +2037,33 @@ static void binder_cleanup_transaction(struct binder_transaction *t,
20172037}
20182038
20192039/**
2020- * binder_validate_object() - checks for a valid metadata object in a buffer.
2040+ * binder_get_object() - gets object and checks for valid metadata
2041+ * @proc: binder_proc owning the buffer
20212042 * @buffer: binder_buffer that we're parsing.
2022- * @offset: offset in the buffer at which to validate an object.
2043+ * @offset: offset in the @buffer at which to validate an object.
2044+ * @object: struct binder_object to read into
20232045 *
20242046 * Return: If there's a valid metadata object at @offset in @buffer, the
2025- * size of that object. Otherwise, it returns zero.
2047+ * size of that object. Otherwise, it returns zero. The object
2048+ * is read into the struct binder_object pointed to by @object.
20262049 */
2027- static size_t binder_validate_object (struct binder_buffer * buffer , u64 offset )
2050+ static size_t binder_get_object (struct binder_proc * proc ,
2051+ struct binder_buffer * buffer ,
2052+ unsigned long offset ,
2053+ struct binder_object * object )
20282054{
2029- /* Check if we can read a header first */
2055+ size_t read_size ;
20302056 struct binder_object_header * hdr ;
20312057 size_t object_size = 0 ;
20322058
2033- if (buffer -> data_size < sizeof (* hdr ) ||
2034- offset > buffer -> data_size - sizeof (* hdr ) ||
2035- !IS_ALIGNED (offset , sizeof (u32 )))
2059+ read_size = min_t (size_t , sizeof (* object ), buffer -> data_size - offset );
2060+ if (read_size < sizeof (* hdr ))
20362061 return 0 ;
2062+ binder_alloc_copy_from_buffer (& proc -> alloc , object , buffer ,
2063+ offset , read_size );
20372064
2038- /* Ok, now see if we can read a complete object. */
2039- hdr = ( struct binder_object_header * )( buffer -> data + offset ) ;
2065+ /* Ok, now see if we read a complete object. */
2066+ hdr = & object -> hdr ;
20402067 switch (hdr -> type ) {
20412068 case BINDER_TYPE_BINDER :
20422069 case BINDER_TYPE_WEAK_BINDER :
@@ -2245,21 +2272,22 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
22452272 for (offp = off_start ; offp < off_end ; offp ++ ) {
22462273 struct binder_object_header * hdr ;
22472274 size_t object_size ;
2275+ struct binder_object object ;
22482276 binder_size_t object_offset ;
22492277 binder_size_t buffer_offset = (uintptr_t )offp -
22502278 (uintptr_t )buffer -> data ;
22512279
22522280 binder_alloc_copy_from_buffer (& proc -> alloc , & object_offset ,
22532281 buffer , buffer_offset ,
22542282 sizeof (object_offset ));
2255- object_size = binder_validate_object (buffer , object_offset );
2283+ object_size = binder_get_object (proc , buffer ,
2284+ object_offset , & object );
22562285 if (object_size == 0 ) {
22572286 pr_err ("transaction release %d bad object at offset %lld, size %zd\n" ,
22582287 debug_id , (u64 )object_offset , buffer -> data_size );
22592288 continue ;
22602289 }
2261- hdr = (struct binder_object_header * )
2262- (buffer -> data + object_offset );
2290+ hdr = & object .hdr ;
22632291 switch (hdr -> type ) {
22642292 case BINDER_TYPE_BINDER :
22652293 case BINDER_TYPE_WEAK_BINDER : {
@@ -3159,6 +3187,7 @@ static void binder_transaction(struct binder_proc *proc,
31593187 for (; offp < off_end ; offp ++ ) {
31603188 struct binder_object_header * hdr ;
31613189 size_t object_size ;
3190+ struct binder_object object ;
31623191 binder_size_t object_offset ;
31633192 binder_size_t buffer_offset =
31643193 (uintptr_t )offp - (uintptr_t )t -> buffer -> data ;
@@ -3168,7 +3197,8 @@ static void binder_transaction(struct binder_proc *proc,
31683197 t -> buffer ,
31693198 buffer_offset ,
31703199 sizeof (object_offset ));
3171- object_size = binder_validate_object (t -> buffer , object_offset );
3200+ object_size = binder_get_object (target_proc , t -> buffer ,
3201+ object_offset , & object );
31723202 if (object_size == 0 || object_offset < off_min ) {
31733203 binder_user_error ("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n" ,
31743204 proc -> pid , thread -> pid ,
@@ -3181,8 +3211,7 @@ static void binder_transaction(struct binder_proc *proc,
31813211 goto err_bad_offset ;
31823212 }
31833213
3184- hdr = (struct binder_object_header * )
3185- (t -> buffer -> data + object_offset );
3214+ hdr = & object .hdr ;
31863215 off_min = object_offset + object_size ;
31873216 switch (hdr -> type ) {
31883217 case BINDER_TYPE_BINDER :
@@ -3197,6 +3226,9 @@ static void binder_transaction(struct binder_proc *proc,
31973226 return_error_line = __LINE__ ;
31983227 goto err_translate_failed ;
31993228 }
3229+ binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3230+ t -> buffer , object_offset ,
3231+ fp , sizeof (* fp ));
32003232 } break ;
32013233 case BINDER_TYPE_HANDLE :
32023234 case BINDER_TYPE_WEAK_HANDLE : {
@@ -3210,6 +3242,9 @@ static void binder_transaction(struct binder_proc *proc,
32103242 return_error_line = __LINE__ ;
32113243 goto err_translate_failed ;
32123244 }
3245+ binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3246+ t -> buffer , object_offset ,
3247+ fp , sizeof (* fp ));
32133248 } break ;
32143249
32153250 case BINDER_TYPE_FD : {
@@ -3226,6 +3261,9 @@ static void binder_transaction(struct binder_proc *proc,
32263261 goto err_translate_failed ;
32273262 }
32283263 fp -> pad_binder = 0 ;
3264+ binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3265+ t -> buffer , object_offset ,
3266+ fp , sizeof (* fp ));
32293267 } break ;
32303268 case BINDER_TYPE_FDA : {
32313269 struct binder_fd_array_object * fda =
@@ -3310,7 +3348,10 @@ static void binder_transaction(struct binder_proc *proc,
33103348 return_error_line = __LINE__ ;
33113349 goto err_translate_failed ;
33123350 }
3313- last_fixup_obj = bp ;
3351+ binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3352+ t -> buffer , object_offset ,
3353+ bp , sizeof (* bp ));
3354+ last_fixup_obj = t -> buffer -> data + object_offset ;
33143355 last_fixup_min_off = 0 ;
33153356 } break ;
33163357 default :
0 commit comments