@@ -2278,33 +2278,30 @@ static void binder_deferred_fd_close(int fd)
2278
2278
2279
2279
static void binder_transaction_buffer_release (struct binder_proc * proc ,
2280
2280
struct binder_buffer * buffer ,
2281
- binder_size_t * failed_at )
2281
+ binder_size_t failed_at ,
2282
+ bool is_failure )
2282
2283
{
2283
- binder_size_t * offp , * off_start , * off_end ;
2284
2284
int debug_id = buffer -> debug_id ;
2285
- binder_size_t off_start_offset ;
2285
+ binder_size_t off_start_offset , buffer_offset , off_end_offset ;
2286
2286
2287
2287
binder_debug (BINDER_DEBUG_TRANSACTION ,
2288
- "%d buffer release %d, size %zd-%zd, failed at %pK \n" ,
2288
+ "%d buffer release %d, size %zd-%zd, failed at %llx \n" ,
2289
2289
proc -> pid , buffer -> debug_id ,
2290
- buffer -> data_size , buffer -> offsets_size , failed_at );
2290
+ buffer -> data_size , buffer -> offsets_size ,
2291
+ (unsigned long long )failed_at );
2291
2292
2292
2293
if (buffer -> target_node )
2293
2294
binder_dec_node (buffer -> target_node , 1 , 0 );
2294
2295
2295
2296
off_start_offset = ALIGN (buffer -> data_size , sizeof (void * ));
2296
- off_start = (binder_size_t * )(buffer -> data + off_start_offset );
2297
- if (failed_at )
2298
- off_end = failed_at ;
2299
- else
2300
- off_end = (void * )off_start + buffer -> offsets_size ;
2301
- for (offp = off_start ; offp < off_end ; offp ++ ) {
2297
+ off_end_offset = is_failure ? failed_at :
2298
+ off_start_offset + buffer -> offsets_size ;
2299
+ for (buffer_offset = off_start_offset ; buffer_offset < off_end_offset ;
2300
+ buffer_offset += sizeof (binder_size_t )) {
2302
2301
struct binder_object_header * hdr ;
2303
2302
size_t object_size ;
2304
2303
struct binder_object object ;
2305
2304
binder_size_t object_offset ;
2306
- binder_size_t buffer_offset = (uintptr_t )offp -
2307
- (uintptr_t )buffer -> data ;
2308
2305
2309
2306
binder_alloc_copy_from_buffer (& proc -> alloc , & object_offset ,
2310
2307
buffer , buffer_offset ,
@@ -2380,9 +2377,10 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
2380
2377
struct binder_fd_array_object * fda ;
2381
2378
struct binder_buffer_object * parent ;
2382
2379
struct binder_object ptr_object ;
2383
- u32 * fd_array ;
2380
+ binder_size_t fda_offset ;
2384
2381
size_t fd_index ;
2385
2382
binder_size_t fd_buf_size ;
2383
+ binder_size_t num_valid ;
2386
2384
2387
2385
if (proc -> tsk != current -> group_leader ) {
2388
2386
/*
@@ -2393,12 +2391,14 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
2393
2391
continue ;
2394
2392
}
2395
2393
2394
+ num_valid = (buffer_offset - off_start_offset ) /
2395
+ sizeof (binder_size_t );
2396
2396
fda = to_binder_fd_array_object (hdr );
2397
2397
parent = binder_validate_ptr (proc , buffer , & ptr_object ,
2398
2398
fda -> parent ,
2399
2399
off_start_offset ,
2400
2400
NULL ,
2401
- offp - off_start );
2401
+ num_valid );
2402
2402
if (!parent ) {
2403
2403
pr_err ("transaction release %d bad parent offset\n" ,
2404
2404
debug_id );
@@ -2417,14 +2417,21 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
2417
2417
debug_id , (u64 )fda -> num_fds );
2418
2418
continue ;
2419
2419
}
2420
- fd_array = (u32 * )(uintptr_t )
2421
- (parent -> buffer + fda -> parent_offset );
2420
+ /*
2421
+ * the source data for binder_buffer_object is visible
2422
+ * to user-space and the @buffer element is the user
2423
+ * pointer to the buffer_object containing the fd_array.
2424
+ * Convert the address to an offset relative to
2425
+ * the base of the transaction buffer.
2426
+ */
2427
+ fda_offset =
2428
+ (parent -> buffer - (uintptr_t )buffer -> user_data ) +
2429
+ fda -> parent_offset ;
2422
2430
for (fd_index = 0 ; fd_index < fda -> num_fds ;
2423
2431
fd_index ++ ) {
2424
2432
u32 fd ;
2425
- binder_size_t offset =
2426
- (uintptr_t )& fd_array [fd_index ] -
2427
- (uintptr_t )buffer -> data ;
2433
+ binder_size_t offset = fda_offset +
2434
+ fd_index * sizeof (fd );
2428
2435
2429
2436
binder_alloc_copy_from_buffer (& proc -> alloc ,
2430
2437
& fd ,
@@ -2638,7 +2645,7 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
2638
2645
struct binder_transaction * in_reply_to )
2639
2646
{
2640
2647
binder_size_t fdi , fd_buf_size ;
2641
- u32 * fd_array ;
2648
+ binder_size_t fda_offset ;
2642
2649
struct binder_proc * proc = thread -> proc ;
2643
2650
struct binder_proc * target_proc = t -> to_proc ;
2644
2651
@@ -2655,18 +2662,24 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
2655
2662
proc -> pid , thread -> pid , (u64 )fda -> num_fds );
2656
2663
return - EINVAL ;
2657
2664
}
2658
- fd_array = (u32 * )(uintptr_t )(parent -> buffer + fda -> parent_offset );
2659
- if (!IS_ALIGNED ((unsigned long )fd_array , sizeof (u32 ))) {
2665
+ /*
2666
+ * the source data for binder_buffer_object is visible
2667
+ * to user-space and the @buffer element is the user
2668
+ * pointer to the buffer_object containing the fd_array.
2669
+ * Convert the address to an offset relative to
2670
+ * the base of the transaction buffer.
2671
+ */
2672
+ fda_offset = (parent -> buffer - (uintptr_t )t -> buffer -> user_data ) +
2673
+ fda -> parent_offset ;
2674
+ if (!IS_ALIGNED ((unsigned long )fda_offset , sizeof (u32 ))) {
2660
2675
binder_user_error ("%d:%d parent offset not aligned correctly.\n" ,
2661
2676
proc -> pid , thread -> pid );
2662
2677
return - EINVAL ;
2663
2678
}
2664
2679
for (fdi = 0 ; fdi < fda -> num_fds ; fdi ++ ) {
2665
2680
u32 fd ;
2666
2681
int ret ;
2667
- binder_size_t offset =
2668
- (uintptr_t )& fd_array [fdi ] -
2669
- (uintptr_t )t -> buffer -> data ;
2682
+ binder_size_t offset = fda_offset + fdi * sizeof (fd );
2670
2683
2671
2684
binder_alloc_copy_from_buffer (& target_proc -> alloc ,
2672
2685
& fd , t -> buffer ,
@@ -2724,7 +2737,7 @@ static int binder_fixup_parent(struct binder_transaction *t,
2724
2737
return - EINVAL ;
2725
2738
}
2726
2739
buffer_offset = bp -> parent_offset +
2727
- (uintptr_t )parent -> buffer - (uintptr_t )b -> data ;
2740
+ (uintptr_t )parent -> buffer - (uintptr_t )b -> user_data ;
2728
2741
binder_alloc_copy_to_buffer (& target_proc -> alloc , b , buffer_offset ,
2729
2742
& bp -> buffer , sizeof (bp -> buffer ));
2730
2743
@@ -2845,10 +2858,10 @@ static void binder_transaction(struct binder_proc *proc,
2845
2858
struct binder_transaction * t ;
2846
2859
struct binder_work * w ;
2847
2860
struct binder_work * tcomplete ;
2848
- binder_size_t * offp , * off_end , * off_start ;
2849
- binder_size_t off_start_offset ;
2861
+ binder_size_t buffer_offset = 0 ;
2862
+ binder_size_t off_start_offset , off_end_offset ;
2850
2863
binder_size_t off_min ;
2851
- u8 * sg_bufp , * sg_buf_end ;
2864
+ binder_size_t sg_buf_offset , sg_buf_end_offset ;
2852
2865
struct binder_proc * target_proc = NULL ;
2853
2866
struct binder_thread * target_thread = NULL ;
2854
2867
struct binder_node * target_node = NULL ;
@@ -3141,7 +3154,7 @@ static void binder_transaction(struct binder_proc *proc,
3141
3154
ALIGN (extra_buffers_size , sizeof (void * )) -
3142
3155
ALIGN (secctx_sz , sizeof (u64 ));
3143
3156
3144
- t -> security_ctx = (uintptr_t )t -> buffer -> data + buf_offset ;
3157
+ t -> security_ctx = (uintptr_t )t -> buffer -> user_data + buf_offset ;
3145
3158
binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3146
3159
t -> buffer , buf_offset ,
3147
3160
secctx , secctx_sz );
@@ -3152,9 +3165,6 @@ static void binder_transaction(struct binder_proc *proc,
3152
3165
t -> buffer -> transaction = t ;
3153
3166
t -> buffer -> target_node = target_node ;
3154
3167
trace_binder_transaction_alloc_buf (t -> buffer );
3155
- off_start_offset = ALIGN (tr -> data_size , sizeof (void * ));
3156
- off_start = (binder_size_t * )(t -> buffer -> data + off_start_offset );
3157
- offp = off_start ;
3158
3168
3159
3169
if (binder_alloc_copy_user_to_buffer (
3160
3170
& target_proc -> alloc ,
@@ -3200,17 +3210,18 @@ static void binder_transaction(struct binder_proc *proc,
3200
3210
return_error_line = __LINE__ ;
3201
3211
goto err_bad_offset ;
3202
3212
}
3203
- off_end = (void * )off_start + tr -> offsets_size ;
3204
- sg_bufp = (u8 * )(PTR_ALIGN (off_end , sizeof (void * )));
3205
- sg_buf_end = sg_bufp + extra_buffers_size ;
3213
+ off_start_offset = ALIGN (tr -> data_size , sizeof (void * ));
3214
+ buffer_offset = off_start_offset ;
3215
+ off_end_offset = off_start_offset + tr -> offsets_size ;
3216
+ sg_buf_offset = ALIGN (off_end_offset , sizeof (void * ));
3217
+ sg_buf_end_offset = sg_buf_offset + extra_buffers_size ;
3206
3218
off_min = 0 ;
3207
- for (; offp < off_end ; offp ++ ) {
3219
+ for (buffer_offset = off_start_offset ; buffer_offset < off_end_offset ;
3220
+ buffer_offset += sizeof (binder_size_t )) {
3208
3221
struct binder_object_header * hdr ;
3209
3222
size_t object_size ;
3210
3223
struct binder_object object ;
3211
3224
binder_size_t object_offset ;
3212
- binder_size_t buffer_offset =
3213
- (uintptr_t )offp - (uintptr_t )t -> buffer -> data ;
3214
3225
3215
3226
binder_alloc_copy_from_buffer (& target_proc -> alloc ,
3216
3227
& object_offset ,
@@ -3290,12 +3301,14 @@ static void binder_transaction(struct binder_proc *proc,
3290
3301
binder_size_t parent_offset ;
3291
3302
struct binder_fd_array_object * fda =
3292
3303
to_binder_fd_array_object (hdr );
3304
+ size_t num_valid = (buffer_offset - off_start_offset ) *
3305
+ sizeof (binder_size_t );
3293
3306
struct binder_buffer_object * parent =
3294
3307
binder_validate_ptr (target_proc , t -> buffer ,
3295
3308
& ptr_object , fda -> parent ,
3296
3309
off_start_offset ,
3297
3310
& parent_offset ,
3298
- offp - off_start );
3311
+ num_valid );
3299
3312
if (!parent ) {
3300
3313
binder_user_error ("%d:%d got transaction with invalid parent offset or type\n" ,
3301
3314
proc -> pid , thread -> pid );
@@ -3332,9 +3345,8 @@ static void binder_transaction(struct binder_proc *proc,
3332
3345
case BINDER_TYPE_PTR : {
3333
3346
struct binder_buffer_object * bp =
3334
3347
to_binder_buffer_object (hdr );
3335
- size_t buf_left = sg_buf_end - sg_bufp ;
3336
- binder_size_t sg_buf_offset = (uintptr_t )sg_bufp -
3337
- (uintptr_t )t -> buffer -> data ;
3348
+ size_t buf_left = sg_buf_end_offset - sg_buf_offset ;
3349
+ size_t num_valid ;
3338
3350
3339
3351
if (bp -> length > buf_left ) {
3340
3352
binder_user_error ("%d:%d got transaction with too large buffer\n" ,
@@ -3359,12 +3371,15 @@ static void binder_transaction(struct binder_proc *proc,
3359
3371
goto err_copy_data_failed ;
3360
3372
}
3361
3373
/* Fixup buffer pointer to target proc address space */
3362
- bp -> buffer = (uintptr_t )sg_bufp ;
3363
- sg_bufp += ALIGN (bp -> length , sizeof (u64 ));
3374
+ bp -> buffer = (uintptr_t )
3375
+ t -> buffer -> user_data + sg_buf_offset ;
3376
+ sg_buf_offset += ALIGN (bp -> length , sizeof (u64 ));
3364
3377
3378
+ num_valid = (buffer_offset - off_start_offset ) *
3379
+ sizeof (binder_size_t );
3365
3380
ret = binder_fixup_parent (t , thread , bp ,
3366
3381
off_start_offset ,
3367
- offp - off_start ,
3382
+ num_valid ,
3368
3383
last_fixup_obj_off ,
3369
3384
last_fixup_min_off );
3370
3385
if (ret < 0 ) {
@@ -3456,7 +3471,8 @@ static void binder_transaction(struct binder_proc *proc,
3456
3471
err_copy_data_failed :
3457
3472
binder_free_txn_fixups (t );
3458
3473
trace_binder_transaction_failed_buffer_release (t -> buffer );
3459
- binder_transaction_buffer_release (target_proc , t -> buffer , offp );
3474
+ binder_transaction_buffer_release (target_proc , t -> buffer ,
3475
+ buffer_offset , true);
3460
3476
if (target_node )
3461
3477
binder_dec_node_tmpref (target_node );
3462
3478
target_node = NULL ;
@@ -3557,7 +3573,7 @@ binder_free_buf(struct binder_proc *proc, struct binder_buffer *buffer)
3557
3573
binder_node_inner_unlock (buf_node );
3558
3574
}
3559
3575
trace_binder_transaction_buffer_release (buffer );
3560
- binder_transaction_buffer_release (proc , buffer , NULL );
3576
+ binder_transaction_buffer_release (proc , buffer , 0 , false );
3561
3577
binder_alloc_free_buf (& proc -> alloc , buffer );
3562
3578
}
3563
3579
@@ -4451,7 +4467,7 @@ static int binder_thread_read(struct binder_proc *proc,
4451
4467
}
4452
4468
trd -> data_size = t -> buffer -> data_size ;
4453
4469
trd -> offsets_size = t -> buffer -> offsets_size ;
4454
- trd -> data .ptr .buffer = (uintptr_t )t -> buffer -> data ;
4470
+ trd -> data .ptr .buffer = (uintptr_t )t -> buffer -> user_data ;
4455
4471
trd -> data .ptr .offsets = trd -> data .ptr .buffer +
4456
4472
ALIGN (t -> buffer -> data_size ,
4457
4473
sizeof (void * ));
@@ -5489,7 +5505,7 @@ static void print_binder_transaction_ilocked(struct seq_file *m,
5489
5505
seq_printf (m , " node %d" , buffer -> target_node -> debug_id );
5490
5506
seq_printf (m , " size %zd:%zd data %pK\n" ,
5491
5507
buffer -> data_size , buffer -> offsets_size ,
5492
- buffer -> data );
5508
+ buffer -> user_data );
5493
5509
}
5494
5510
5495
5511
static void print_binder_work_ilocked (struct seq_file * m ,
0 commit comments