@@ -2244,14 +2244,22 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
22442244 off_end = (void * )off_start + buffer -> offsets_size ;
22452245 for (offp = off_start ; offp < off_end ; offp ++ ) {
22462246 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 );
22492256 if (object_size == 0 ) {
22502257 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 );
22522259 continue ;
22532260 }
2254- hdr = (struct binder_object_header * )(buffer -> data + * offp );
2261+ hdr = (struct binder_object_header * )
2262+ (buffer -> data + object_offset );
22552263 switch (hdr -> type ) {
22562264 case BINDER_TYPE_BINDER :
22572265 case BINDER_TYPE_WEAK_BINDER : {
@@ -2359,8 +2367,20 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
23592367 continue ;
23602368 }
23612369 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+ }
23642384 } break ;
23652385 default :
23662386 pr_err ("transaction release %d bad object type %x\n" ,
@@ -2496,7 +2516,7 @@ static int binder_translate_handle(struct flat_binder_object *fp,
24962516 return ret ;
24972517}
24982518
2499- static int binder_translate_fd (u32 * fdp ,
2519+ static int binder_translate_fd (u32 fd , binder_size_t fd_offset ,
25002520 struct binder_transaction * t ,
25012521 struct binder_thread * thread ,
25022522 struct binder_transaction * in_reply_to )
@@ -2507,7 +2527,6 @@ static int binder_translate_fd(u32 *fdp,
25072527 struct file * file ;
25082528 int ret = 0 ;
25092529 bool target_allows_fd ;
2510- int fd = * fdp ;
25112530
25122531 if (in_reply_to )
25132532 target_allows_fd = !!(in_reply_to -> flags & TF_ACCEPT_FDS );
@@ -2546,7 +2565,7 @@ static int binder_translate_fd(u32 *fdp,
25462565 goto err_alloc ;
25472566 }
25482567 fixup -> file = file ;
2549- fixup -> offset = ( uintptr_t ) fdp - ( uintptr_t ) t -> buffer -> data ;
2568+ fixup -> offset = fd_offset ;
25502569 trace_binder_transaction_fd_send (t , fd , fixup -> offset );
25512570 list_add_tail (& fixup -> fixup_entry , & t -> fd_fixups );
25522571
@@ -2598,8 +2617,17 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
25982617 return - EINVAL ;
25992618 }
26002619 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 );
26032631 if (ret < 0 )
26042632 return ret ;
26052633 }
@@ -3066,7 +3094,9 @@ static void binder_transaction(struct binder_proc *proc,
30663094
30673095 t -> security_ctx = (uintptr_t )kptr +
30683096 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 );
30703100 security_release_secctx (secctx , secctx_sz );
30713101 secctx = NULL ;
30723102 }
@@ -3128,11 +3158,21 @@ static void binder_transaction(struct binder_proc *proc,
31283158 off_min = 0 ;
31293159 for (; offp < off_end ; offp ++ ) {
31303160 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 ) {
31343173 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 ,
31363176 (u64 )off_min ,
31373177 (u64 )t -> buffer -> data_size );
31383178 return_error = BR_FAILED_REPLY ;
@@ -3141,8 +3181,9 @@ static void binder_transaction(struct binder_proc *proc,
31413181 goto err_bad_offset ;
31423182 }
31433183
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 ;
31463187 switch (hdr -> type ) {
31473188 case BINDER_TYPE_BINDER :
31483189 case BINDER_TYPE_WEAK_BINDER : {
@@ -3173,8 +3214,10 @@ static void binder_transaction(struct binder_proc *proc,
31733214
31743215 case BINDER_TYPE_FD : {
31753216 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 );
31783221
31793222 if (ret < 0 ) {
31803223 return_error = BR_FAILED_REPLY ;
@@ -3967,6 +4010,7 @@ static int binder_wait_for_work(struct binder_thread *thread,
39674010
39684011/**
39694012 * binder_apply_fd_fixups() - finish fd translation
4013+ * @proc: binder_proc associated @t->buffer
39704014 * @t: binder transaction with list of fd fixups
39714015 *
39724016 * 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,
39784022 * fput'ing files that have not been processed and ksys_close'ing
39794023 * any fds that have already been allocated.
39804024 */
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 )
39824027{
39834028 struct binder_txn_fd_fixup * fixup , * tmp ;
39844029 int ret = 0 ;
39854030
39864031 list_for_each_entry (fixup , & t -> fd_fixups , fixup_entry ) {
39874032 int fd = get_unused_fd_flags (O_CLOEXEC );
3988- u32 * fdp ;
39894033
39904034 if (fd < 0 ) {
39914035 binder_debug (BINDER_DEBUG_TRANSACTION ,
@@ -4000,33 +4044,20 @@ static int binder_apply_fd_fixups(struct binder_transaction *t)
40004044 trace_binder_transaction_fd_recv (t , fd , fixup -> offset );
40014045 fd_install (fd , fixup -> file );
40024046 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 ));
40224050 }
40234051 list_for_each_entry_safe (fixup , tmp , & t -> fd_fixups , fixup_entry ) {
40244052 if (fixup -> file ) {
40254053 fput (fixup -> file );
40264054 } else if (ret ) {
4027- u32 * fdp = ( u32 * )( t -> buffer -> data + fixup -> offset ) ;
4055+ u32 fd ;
40284056
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 );
40304061 }
40314062 list_del (& fixup -> fixup_entry );
40324063 kfree (fixup );
@@ -4324,7 +4355,7 @@ static int binder_thread_read(struct binder_proc *proc,
43244355 trd -> sender_pid = 0 ;
43254356 }
43264357
4327- ret = binder_apply_fd_fixups (t );
4358+ ret = binder_apply_fd_fixups (proc , t );
43284359 if (ret ) {
43294360 struct binder_buffer * buffer = t -> buffer ;
43304361 bool oneway = !!(t -> flags & TF_ONE_WAY );
0 commit comments