@@ -628,6 +628,26 @@ struct binder_transaction {
628
628
spinlock_t lock ;
629
629
};
630
630
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
+
631
651
/**
632
652
* binder_proc_lock() - Acquire outer lock for given binder_proc
633
653
* @proc: struct binder_proc to acquire
@@ -2017,26 +2037,33 @@ static void binder_cleanup_transaction(struct binder_transaction *t,
2017
2037
}
2018
2038
2019
2039
/**
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
2021
2042
* @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
2023
2045
*
2024
2046
* 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.
2026
2049
*/
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 )
2028
2054
{
2029
- /* Check if we can read a header first */
2055
+ size_t read_size ;
2030
2056
struct binder_object_header * hdr ;
2031
2057
size_t object_size = 0 ;
2032
2058
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 ))
2036
2061
return 0 ;
2062
+ binder_alloc_copy_from_buffer (& proc -> alloc , object , buffer ,
2063
+ offset , read_size );
2037
2064
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 ;
2040
2067
switch (hdr -> type ) {
2041
2068
case BINDER_TYPE_BINDER :
2042
2069
case BINDER_TYPE_WEAK_BINDER :
@@ -2245,21 +2272,22 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
2245
2272
for (offp = off_start ; offp < off_end ; offp ++ ) {
2246
2273
struct binder_object_header * hdr ;
2247
2274
size_t object_size ;
2275
+ struct binder_object object ;
2248
2276
binder_size_t object_offset ;
2249
2277
binder_size_t buffer_offset = (uintptr_t )offp -
2250
2278
(uintptr_t )buffer -> data ;
2251
2279
2252
2280
binder_alloc_copy_from_buffer (& proc -> alloc , & object_offset ,
2253
2281
buffer , buffer_offset ,
2254
2282
sizeof (object_offset ));
2255
- object_size = binder_validate_object (buffer , object_offset );
2283
+ object_size = binder_get_object (proc , buffer ,
2284
+ object_offset , & object );
2256
2285
if (object_size == 0 ) {
2257
2286
pr_err ("transaction release %d bad object at offset %lld, size %zd\n" ,
2258
2287
debug_id , (u64 )object_offset , buffer -> data_size );
2259
2288
continue ;
2260
2289
}
2261
- hdr = (struct binder_object_header * )
2262
- (buffer -> data + object_offset );
2290
+ hdr = & object .hdr ;
2263
2291
switch (hdr -> type ) {
2264
2292
case BINDER_TYPE_BINDER :
2265
2293
case BINDER_TYPE_WEAK_BINDER : {
@@ -3159,6 +3187,7 @@ static void binder_transaction(struct binder_proc *proc,
3159
3187
for (; offp < off_end ; offp ++ ) {
3160
3188
struct binder_object_header * hdr ;
3161
3189
size_t object_size ;
3190
+ struct binder_object object ;
3162
3191
binder_size_t object_offset ;
3163
3192
binder_size_t buffer_offset =
3164
3193
(uintptr_t )offp - (uintptr_t )t -> buffer -> data ;
@@ -3168,7 +3197,8 @@ static void binder_transaction(struct binder_proc *proc,
3168
3197
t -> buffer ,
3169
3198
buffer_offset ,
3170
3199
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 );
3172
3202
if (object_size == 0 || object_offset < off_min ) {
3173
3203
binder_user_error ("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n" ,
3174
3204
proc -> pid , thread -> pid ,
@@ -3181,8 +3211,7 @@ static void binder_transaction(struct binder_proc *proc,
3181
3211
goto err_bad_offset ;
3182
3212
}
3183
3213
3184
- hdr = (struct binder_object_header * )
3185
- (t -> buffer -> data + object_offset );
3214
+ hdr = & object .hdr ;
3186
3215
off_min = object_offset + object_size ;
3187
3216
switch (hdr -> type ) {
3188
3217
case BINDER_TYPE_BINDER :
@@ -3197,6 +3226,9 @@ static void binder_transaction(struct binder_proc *proc,
3197
3226
return_error_line = __LINE__ ;
3198
3227
goto err_translate_failed ;
3199
3228
}
3229
+ binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3230
+ t -> buffer , object_offset ,
3231
+ fp , sizeof (* fp ));
3200
3232
} break ;
3201
3233
case BINDER_TYPE_HANDLE :
3202
3234
case BINDER_TYPE_WEAK_HANDLE : {
@@ -3210,6 +3242,9 @@ static void binder_transaction(struct binder_proc *proc,
3210
3242
return_error_line = __LINE__ ;
3211
3243
goto err_translate_failed ;
3212
3244
}
3245
+ binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3246
+ t -> buffer , object_offset ,
3247
+ fp , sizeof (* fp ));
3213
3248
} break ;
3214
3249
3215
3250
case BINDER_TYPE_FD : {
@@ -3226,6 +3261,9 @@ static void binder_transaction(struct binder_proc *proc,
3226
3261
goto err_translate_failed ;
3227
3262
}
3228
3263
fp -> pad_binder = 0 ;
3264
+ binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3265
+ t -> buffer , object_offset ,
3266
+ fp , sizeof (* fp ));
3229
3267
} break ;
3230
3268
case BINDER_TYPE_FDA : {
3231
3269
struct binder_fd_array_object * fda =
@@ -3310,7 +3348,10 @@ static void binder_transaction(struct binder_proc *proc,
3310
3348
return_error_line = __LINE__ ;
3311
3349
goto err_translate_failed ;
3312
3350
}
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 ;
3314
3355
last_fixup_min_off = 0 ;
3315
3356
} break ;
3316
3357
default :
0 commit comments