@@ -2244,14 +2244,22 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
2244
2244
off_end = (void * )off_start + buffer -> offsets_size ;
2245
2245
for (offp = off_start ; offp < off_end ; offp ++ ) {
2246
2246
struct binder_object_header * hdr ;
2247
- size_t object_size = binder_validate_object (buffer , * offp );
2248
-
2247
+ size_t object_size ;
2248
+ binder_size_t object_offset ;
2249
+ binder_size_t buffer_offset = (uintptr_t )offp -
2250
+ (uintptr_t )buffer -> data ;
2251
+
2252
+ binder_alloc_copy_from_buffer (& proc -> alloc , & object_offset ,
2253
+ buffer , buffer_offset ,
2254
+ sizeof (object_offset ));
2255
+ object_size = binder_validate_object (buffer , object_offset );
2249
2256
if (object_size == 0 ) {
2250
2257
pr_err ("transaction release %d bad object at offset %lld, size %zd\n" ,
2251
- debug_id , (u64 )* offp , buffer -> data_size );
2258
+ debug_id , (u64 )object_offset , buffer -> data_size );
2252
2259
continue ;
2253
2260
}
2254
- hdr = (struct binder_object_header * )(buffer -> data + * offp );
2261
+ hdr = (struct binder_object_header * )
2262
+ (buffer -> data + object_offset );
2255
2263
switch (hdr -> type ) {
2256
2264
case BINDER_TYPE_BINDER :
2257
2265
case BINDER_TYPE_WEAK_BINDER : {
@@ -2359,8 +2367,20 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
2359
2367
continue ;
2360
2368
}
2361
2369
fd_array = (u32 * )(parent_buffer + (uintptr_t )fda -> parent_offset );
2362
- for (fd_index = 0 ; fd_index < fda -> num_fds ; fd_index ++ )
2363
- binder_deferred_fd_close (fd_array [fd_index ]);
2370
+ for (fd_index = 0 ; fd_index < fda -> num_fds ;
2371
+ fd_index ++ ) {
2372
+ u32 fd ;
2373
+ binder_size_t offset =
2374
+ (uintptr_t )& fd_array [fd_index ] -
2375
+ (uintptr_t )buffer -> data ;
2376
+
2377
+ binder_alloc_copy_from_buffer (& proc -> alloc ,
2378
+ & fd ,
2379
+ buffer ,
2380
+ offset ,
2381
+ sizeof (fd ));
2382
+ binder_deferred_fd_close (fd );
2383
+ }
2364
2384
} break ;
2365
2385
default :
2366
2386
pr_err ("transaction release %d bad object type %x\n" ,
@@ -2496,7 +2516,7 @@ static int binder_translate_handle(struct flat_binder_object *fp,
2496
2516
return ret ;
2497
2517
}
2498
2518
2499
- static int binder_translate_fd (u32 * fdp ,
2519
+ static int binder_translate_fd (u32 fd , binder_size_t fd_offset ,
2500
2520
struct binder_transaction * t ,
2501
2521
struct binder_thread * thread ,
2502
2522
struct binder_transaction * in_reply_to )
@@ -2507,7 +2527,6 @@ static int binder_translate_fd(u32 *fdp,
2507
2527
struct file * file ;
2508
2528
int ret = 0 ;
2509
2529
bool target_allows_fd ;
2510
- int fd = * fdp ;
2511
2530
2512
2531
if (in_reply_to )
2513
2532
target_allows_fd = !!(in_reply_to -> flags & TF_ACCEPT_FDS );
@@ -2546,7 +2565,7 @@ static int binder_translate_fd(u32 *fdp,
2546
2565
goto err_alloc ;
2547
2566
}
2548
2567
fixup -> file = file ;
2549
- fixup -> offset = ( uintptr_t ) fdp - ( uintptr_t ) t -> buffer -> data ;
2568
+ fixup -> offset = fd_offset ;
2550
2569
trace_binder_transaction_fd_send (t , fd , fixup -> offset );
2551
2570
list_add_tail (& fixup -> fixup_entry , & t -> fd_fixups );
2552
2571
@@ -2598,8 +2617,17 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
2598
2617
return - EINVAL ;
2599
2618
}
2600
2619
for (fdi = 0 ; fdi < fda -> num_fds ; fdi ++ ) {
2601
- int ret = binder_translate_fd (& fd_array [fdi ], t , thread ,
2602
- in_reply_to );
2620
+ u32 fd ;
2621
+ int ret ;
2622
+ binder_size_t offset =
2623
+ (uintptr_t )& fd_array [fdi ] -
2624
+ (uintptr_t )t -> buffer -> data ;
2625
+
2626
+ binder_alloc_copy_from_buffer (& target_proc -> alloc ,
2627
+ & fd , t -> buffer ,
2628
+ offset , sizeof (fd ));
2629
+ ret = binder_translate_fd (fd , offset , t , thread ,
2630
+ in_reply_to );
2603
2631
if (ret < 0 )
2604
2632
return ret ;
2605
2633
}
@@ -3066,7 +3094,9 @@ static void binder_transaction(struct binder_proc *proc,
3066
3094
3067
3095
t -> security_ctx = (uintptr_t )kptr +
3068
3096
binder_alloc_get_user_buffer_offset (& target_proc -> alloc );
3069
- memcpy (kptr , secctx , secctx_sz );
3097
+ binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3098
+ t -> buffer , buf_offset ,
3099
+ secctx , secctx_sz );
3070
3100
security_release_secctx (secctx , secctx_sz );
3071
3101
secctx = NULL ;
3072
3102
}
@@ -3128,11 +3158,21 @@ static void binder_transaction(struct binder_proc *proc,
3128
3158
off_min = 0 ;
3129
3159
for (; offp < off_end ; offp ++ ) {
3130
3160
struct binder_object_header * hdr ;
3131
- size_t object_size = binder_validate_object (t -> buffer , * offp );
3132
-
3133
- if (object_size == 0 || * offp < off_min ) {
3161
+ size_t object_size ;
3162
+ binder_size_t object_offset ;
3163
+ binder_size_t buffer_offset =
3164
+ (uintptr_t )offp - (uintptr_t )t -> buffer -> data ;
3165
+
3166
+ binder_alloc_copy_from_buffer (& target_proc -> alloc ,
3167
+ & object_offset ,
3168
+ t -> buffer ,
3169
+ buffer_offset ,
3170
+ sizeof (object_offset ));
3171
+ object_size = binder_validate_object (t -> buffer , object_offset );
3172
+ if (object_size == 0 || object_offset < off_min ) {
3134
3173
binder_user_error ("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n" ,
3135
- proc -> pid , thread -> pid , (u64 )* offp ,
3174
+ proc -> pid , thread -> pid ,
3175
+ (u64 )object_offset ,
3136
3176
(u64 )off_min ,
3137
3177
(u64 )t -> buffer -> data_size );
3138
3178
return_error = BR_FAILED_REPLY ;
@@ -3141,8 +3181,9 @@ static void binder_transaction(struct binder_proc *proc,
3141
3181
goto err_bad_offset ;
3142
3182
}
3143
3183
3144
- hdr = (struct binder_object_header * )(t -> buffer -> data + * offp );
3145
- off_min = * offp + object_size ;
3184
+ hdr = (struct binder_object_header * )
3185
+ (t -> buffer -> data + object_offset );
3186
+ off_min = object_offset + object_size ;
3146
3187
switch (hdr -> type ) {
3147
3188
case BINDER_TYPE_BINDER :
3148
3189
case BINDER_TYPE_WEAK_BINDER : {
@@ -3173,8 +3214,10 @@ static void binder_transaction(struct binder_proc *proc,
3173
3214
3174
3215
case BINDER_TYPE_FD : {
3175
3216
struct binder_fd_object * fp = to_binder_fd_object (hdr );
3176
- int ret = binder_translate_fd (& fp -> fd , t , thread ,
3177
- in_reply_to );
3217
+ binder_size_t fd_offset = object_offset +
3218
+ (uintptr_t )& fp -> fd - (uintptr_t )fp ;
3219
+ int ret = binder_translate_fd (fp -> fd , fd_offset , t ,
3220
+ thread , in_reply_to );
3178
3221
3179
3222
if (ret < 0 ) {
3180
3223
return_error = BR_FAILED_REPLY ;
@@ -3967,6 +4010,7 @@ static int binder_wait_for_work(struct binder_thread *thread,
3967
4010
3968
4011
/**
3969
4012
* binder_apply_fd_fixups() - finish fd translation
4013
+ * @proc: binder_proc associated @t->buffer
3970
4014
* @t: binder transaction with list of fd fixups
3971
4015
*
3972
4016
* Now that we are in the context of the transaction target
@@ -3978,14 +4022,14 @@ static int binder_wait_for_work(struct binder_thread *thread,
3978
4022
* fput'ing files that have not been processed and ksys_close'ing
3979
4023
* any fds that have already been allocated.
3980
4024
*/
3981
- static int binder_apply_fd_fixups (struct binder_transaction * t )
4025
+ static int binder_apply_fd_fixups (struct binder_proc * proc ,
4026
+ struct binder_transaction * t )
3982
4027
{
3983
4028
struct binder_txn_fd_fixup * fixup , * tmp ;
3984
4029
int ret = 0 ;
3985
4030
3986
4031
list_for_each_entry (fixup , & t -> fd_fixups , fixup_entry ) {
3987
4032
int fd = get_unused_fd_flags (O_CLOEXEC );
3988
- u32 * fdp ;
3989
4033
3990
4034
if (fd < 0 ) {
3991
4035
binder_debug (BINDER_DEBUG_TRANSACTION ,
@@ -4000,33 +4044,20 @@ static int binder_apply_fd_fixups(struct binder_transaction *t)
4000
4044
trace_binder_transaction_fd_recv (t , fd , fixup -> offset );
4001
4045
fd_install (fd , fixup -> file );
4002
4046
fixup -> file = NULL ;
4003
- fdp = (u32 * )(t -> buffer -> data + fixup -> offset );
4004
- /*
4005
- * This store can cause problems for CPUs with a
4006
- * VIVT cache (eg ARMv5) since the cache cannot
4007
- * detect virtual aliases to the same physical cacheline.
4008
- * To support VIVT, this address and the user-space VA
4009
- * would both need to be flushed. Since this kernel
4010
- * VA is not constructed via page_to_virt(), we can't
4011
- * use flush_dcache_page() on it, so we'd have to use
4012
- * an internal function. If devices with VIVT ever
4013
- * need to run Android, we'll either need to go back
4014
- * to patching the translated fd from the sender side
4015
- * (using the non-standard kernel functions), or rework
4016
- * how the kernel uses the buffer to use page_to_virt()
4017
- * addresses instead of allocating in our own vm area.
4018
- *
4019
- * For now, we disable compilation if CONFIG_CPU_CACHE_VIVT.
4020
- */
4021
- * fdp = fd ;
4047
+ binder_alloc_copy_to_buffer (& proc -> alloc , t -> buffer ,
4048
+ fixup -> offset , & fd ,
4049
+ sizeof (u32 ));
4022
4050
}
4023
4051
list_for_each_entry_safe (fixup , tmp , & t -> fd_fixups , fixup_entry ) {
4024
4052
if (fixup -> file ) {
4025
4053
fput (fixup -> file );
4026
4054
} else if (ret ) {
4027
- u32 * fdp = ( u32 * )( t -> buffer -> data + fixup -> offset ) ;
4055
+ u32 fd ;
4028
4056
4029
- binder_deferred_fd_close (* fdp );
4057
+ binder_alloc_copy_from_buffer (& proc -> alloc , & fd ,
4058
+ t -> buffer , fixup -> offset ,
4059
+ sizeof (fd ));
4060
+ binder_deferred_fd_close (fd );
4030
4061
}
4031
4062
list_del (& fixup -> fixup_entry );
4032
4063
kfree (fixup );
@@ -4324,7 +4355,7 @@ static int binder_thread_read(struct binder_proc *proc,
4324
4355
trd -> sender_pid = 0 ;
4325
4356
}
4326
4357
4327
- ret = binder_apply_fd_fixups (t );
4358
+ ret = binder_apply_fd_fixups (proc , t );
4328
4359
if (ret ) {
4329
4360
struct binder_buffer * buffer = t -> buffer ;
4330
4361
bool oneway = !!(t -> flags & TF_ONE_WAY );
0 commit comments