@@ -2059,10 +2059,9 @@ static size_t binder_get_object(struct binder_proc *proc,
2059
2059
2060
2060
read_size = min_t (size_t , sizeof (* object ), buffer -> data_size - offset );
2061
2061
if (offset > buffer -> data_size || read_size < sizeof (* hdr ) ||
2062
- !IS_ALIGNED (offset , sizeof (u32 )))
2062
+ binder_alloc_copy_from_buffer (& proc -> alloc , object , buffer ,
2063
+ offset , read_size ))
2063
2064
return 0 ;
2064
- binder_alloc_copy_from_buffer (& proc -> alloc , object , buffer ,
2065
- offset , read_size );
2066
2065
2067
2066
/* Ok, now see if we read a complete object. */
2068
2067
hdr = & object -> hdr ;
@@ -2131,8 +2130,10 @@ static struct binder_buffer_object *binder_validate_ptr(
2131
2130
return NULL ;
2132
2131
2133
2132
buffer_offset = start_offset + sizeof (binder_size_t ) * index ;
2134
- binder_alloc_copy_from_buffer (& proc -> alloc , & object_offset ,
2135
- b , buffer_offset , sizeof (object_offset ));
2133
+ if (binder_alloc_copy_from_buffer (& proc -> alloc , & object_offset ,
2134
+ b , buffer_offset ,
2135
+ sizeof (object_offset )))
2136
+ return NULL ;
2136
2137
object_size = binder_get_object (proc , b , object_offset , object );
2137
2138
if (!object_size || object -> hdr .type != BINDER_TYPE_PTR )
2138
2139
return NULL ;
@@ -2212,10 +2213,12 @@ static bool binder_validate_fixup(struct binder_proc *proc,
2212
2213
return false;
2213
2214
last_min_offset = last_bbo -> parent_offset + sizeof (uintptr_t );
2214
2215
buffer_offset = objects_start_offset +
2215
- sizeof (binder_size_t ) * last_bbo -> parent ,
2216
- binder_alloc_copy_from_buffer (& proc -> alloc , & last_obj_offset ,
2217
- b , buffer_offset ,
2218
- sizeof (last_obj_offset ));
2216
+ sizeof (binder_size_t ) * last_bbo -> parent ;
2217
+ if (binder_alloc_copy_from_buffer (& proc -> alloc ,
2218
+ & last_obj_offset ,
2219
+ b , buffer_offset ,
2220
+ sizeof (last_obj_offset )))
2221
+ return false;
2219
2222
}
2220
2223
return (fixup_offset >= last_min_offset );
2221
2224
}
@@ -2301,15 +2304,15 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
2301
2304
for (buffer_offset = off_start_offset ; buffer_offset < off_end_offset ;
2302
2305
buffer_offset += sizeof (binder_size_t )) {
2303
2306
struct binder_object_header * hdr ;
2304
- size_t object_size ;
2307
+ size_t object_size = 0 ;
2305
2308
struct binder_object object ;
2306
2309
binder_size_t object_offset ;
2307
2310
2308
- binder_alloc_copy_from_buffer (& proc -> alloc , & object_offset ,
2309
- buffer , buffer_offset ,
2310
- sizeof (object_offset ));
2311
- object_size = binder_get_object (proc , buffer ,
2312
- object_offset , & object );
2311
+ if (! binder_alloc_copy_from_buffer (& proc -> alloc , & object_offset ,
2312
+ buffer , buffer_offset ,
2313
+ sizeof (object_offset )))
2314
+ object_size = binder_get_object (proc , buffer ,
2315
+ object_offset , & object );
2313
2316
if (object_size == 0 ) {
2314
2317
pr_err ("transaction release %d bad object at offset %lld, size %zd\n" ,
2315
2318
debug_id , (u64 )object_offset , buffer -> data_size );
@@ -2432,15 +2435,16 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
2432
2435
for (fd_index = 0 ; fd_index < fda -> num_fds ;
2433
2436
fd_index ++ ) {
2434
2437
u32 fd ;
2438
+ int err ;
2435
2439
binder_size_t offset = fda_offset +
2436
2440
fd_index * sizeof (fd );
2437
2441
2438
- binder_alloc_copy_from_buffer (& proc -> alloc ,
2439
- & fd ,
2440
- buffer ,
2441
- offset ,
2442
- sizeof ( fd ));
2443
- binder_deferred_fd_close (fd );
2442
+ err = binder_alloc_copy_from_buffer (
2443
+ & proc -> alloc , & fd , buffer ,
2444
+ offset , sizeof ( fd ));
2445
+ WARN_ON ( err );
2446
+ if (! err )
2447
+ binder_deferred_fd_close (fd );
2444
2448
}
2445
2449
} break ;
2446
2450
default :
@@ -2683,11 +2687,12 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda,
2683
2687
int ret ;
2684
2688
binder_size_t offset = fda_offset + fdi * sizeof (fd );
2685
2689
2686
- binder_alloc_copy_from_buffer (& target_proc -> alloc ,
2687
- & fd , t -> buffer ,
2688
- offset , sizeof (fd ));
2689
- ret = binder_translate_fd (fd , offset , t , thread ,
2690
- in_reply_to );
2690
+ ret = binder_alloc_copy_from_buffer (& target_proc -> alloc ,
2691
+ & fd , t -> buffer ,
2692
+ offset , sizeof (fd ));
2693
+ if (!ret )
2694
+ ret = binder_translate_fd (fd , offset , t , thread ,
2695
+ in_reply_to );
2691
2696
if (ret < 0 )
2692
2697
return ret ;
2693
2698
}
@@ -2740,8 +2745,12 @@ static int binder_fixup_parent(struct binder_transaction *t,
2740
2745
}
2741
2746
buffer_offset = bp -> parent_offset +
2742
2747
(uintptr_t )parent -> buffer - (uintptr_t )b -> user_data ;
2743
- binder_alloc_copy_to_buffer (& target_proc -> alloc , b , buffer_offset ,
2744
- & bp -> buffer , sizeof (bp -> buffer ));
2748
+ if (binder_alloc_copy_to_buffer (& target_proc -> alloc , b , buffer_offset ,
2749
+ & bp -> buffer , sizeof (bp -> buffer ))) {
2750
+ binder_user_error ("%d:%d got transaction with invalid parent offset\n" ,
2751
+ proc -> pid , thread -> pid );
2752
+ return - EINVAL ;
2753
+ }
2745
2754
2746
2755
return 0 ;
2747
2756
}
@@ -3160,15 +3169,20 @@ static void binder_transaction(struct binder_proc *proc,
3160
3169
goto err_binder_alloc_buf_failed ;
3161
3170
}
3162
3171
if (secctx ) {
3172
+ int err ;
3163
3173
size_t buf_offset = ALIGN (tr -> data_size , sizeof (void * )) +
3164
3174
ALIGN (tr -> offsets_size , sizeof (void * )) +
3165
3175
ALIGN (extra_buffers_size , sizeof (void * )) -
3166
3176
ALIGN (secctx_sz , sizeof (u64 ));
3167
3177
3168
3178
t -> security_ctx = (uintptr_t )t -> buffer -> user_data + buf_offset ;
3169
- binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3170
- t -> buffer , buf_offset ,
3171
- secctx , secctx_sz );
3179
+ err = binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3180
+ t -> buffer , buf_offset ,
3181
+ secctx , secctx_sz );
3182
+ if (err ) {
3183
+ t -> security_ctx = 0 ;
3184
+ WARN_ON (1 );
3185
+ }
3172
3186
security_release_secctx (secctx , secctx_sz );
3173
3187
secctx = NULL ;
3174
3188
}
@@ -3234,11 +3248,16 @@ static void binder_transaction(struct binder_proc *proc,
3234
3248
struct binder_object object ;
3235
3249
binder_size_t object_offset ;
3236
3250
3237
- binder_alloc_copy_from_buffer (& target_proc -> alloc ,
3238
- & object_offset ,
3239
- t -> buffer ,
3240
- buffer_offset ,
3241
- sizeof (object_offset ));
3251
+ if (binder_alloc_copy_from_buffer (& target_proc -> alloc ,
3252
+ & object_offset ,
3253
+ t -> buffer ,
3254
+ buffer_offset ,
3255
+ sizeof (object_offset ))) {
3256
+ return_error = BR_FAILED_REPLY ;
3257
+ return_error_param = - EINVAL ;
3258
+ return_error_line = __LINE__ ;
3259
+ goto err_bad_offset ;
3260
+ }
3242
3261
object_size = binder_get_object (target_proc , t -> buffer ,
3243
3262
object_offset , & object );
3244
3263
if (object_size == 0 || object_offset < off_min ) {
@@ -3262,31 +3281,34 @@ static void binder_transaction(struct binder_proc *proc,
3262
3281
3263
3282
fp = to_flat_binder_object (hdr );
3264
3283
ret = binder_translate_binder (fp , t , thread );
3265
- if (ret < 0 ) {
3284
+
3285
+ if (ret < 0 ||
3286
+ binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3287
+ t -> buffer ,
3288
+ object_offset ,
3289
+ fp , sizeof (* fp ))) {
3266
3290
return_error = BR_FAILED_REPLY ;
3267
3291
return_error_param = ret ;
3268
3292
return_error_line = __LINE__ ;
3269
3293
goto err_translate_failed ;
3270
3294
}
3271
- binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3272
- t -> buffer , object_offset ,
3273
- fp , sizeof (* fp ));
3274
3295
} break ;
3275
3296
case BINDER_TYPE_HANDLE :
3276
3297
case BINDER_TYPE_WEAK_HANDLE : {
3277
3298
struct flat_binder_object * fp ;
3278
3299
3279
3300
fp = to_flat_binder_object (hdr );
3280
3301
ret = binder_translate_handle (fp , t , thread );
3281
- if (ret < 0 ) {
3302
+ if (ret < 0 ||
3303
+ binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3304
+ t -> buffer ,
3305
+ object_offset ,
3306
+ fp , sizeof (* fp ))) {
3282
3307
return_error = BR_FAILED_REPLY ;
3283
3308
return_error_param = ret ;
3284
3309
return_error_line = __LINE__ ;
3285
3310
goto err_translate_failed ;
3286
3311
}
3287
- binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3288
- t -> buffer , object_offset ,
3289
- fp , sizeof (* fp ));
3290
3312
} break ;
3291
3313
3292
3314
case BINDER_TYPE_FD : {
@@ -3296,16 +3318,17 @@ static void binder_transaction(struct binder_proc *proc,
3296
3318
int ret = binder_translate_fd (fp -> fd , fd_offset , t ,
3297
3319
thread , in_reply_to );
3298
3320
3299
- if (ret < 0 ) {
3321
+ fp -> pad_binder = 0 ;
3322
+ if (ret < 0 ||
3323
+ binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3324
+ t -> buffer ,
3325
+ object_offset ,
3326
+ fp , sizeof (* fp ))) {
3300
3327
return_error = BR_FAILED_REPLY ;
3301
3328
return_error_param = ret ;
3302
3329
return_error_line = __LINE__ ;
3303
3330
goto err_translate_failed ;
3304
3331
}
3305
- fp -> pad_binder = 0 ;
3306
- binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3307
- t -> buffer , object_offset ,
3308
- fp , sizeof (* fp ));
3309
3332
} break ;
3310
3333
case BINDER_TYPE_FDA : {
3311
3334
struct binder_object ptr_object ;
@@ -3393,15 +3416,16 @@ static void binder_transaction(struct binder_proc *proc,
3393
3416
num_valid ,
3394
3417
last_fixup_obj_off ,
3395
3418
last_fixup_min_off );
3396
- if (ret < 0 ) {
3419
+ if (ret < 0 ||
3420
+ binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3421
+ t -> buffer ,
3422
+ object_offset ,
3423
+ bp , sizeof (* bp ))) {
3397
3424
return_error = BR_FAILED_REPLY ;
3398
3425
return_error_param = ret ;
3399
3426
return_error_line = __LINE__ ;
3400
3427
goto err_translate_failed ;
3401
3428
}
3402
- binder_alloc_copy_to_buffer (& target_proc -> alloc ,
3403
- t -> buffer , object_offset ,
3404
- bp , sizeof (* bp ));
3405
3429
last_fixup_obj_off = object_offset ;
3406
3430
last_fixup_min_off = 0 ;
3407
3431
} break ;
@@ -4140,20 +4164,27 @@ static int binder_apply_fd_fixups(struct binder_proc *proc,
4140
4164
trace_binder_transaction_fd_recv (t , fd , fixup -> offset );
4141
4165
fd_install (fd , fixup -> file );
4142
4166
fixup -> file = NULL ;
4143
- binder_alloc_copy_to_buffer (& proc -> alloc , t -> buffer ,
4144
- fixup -> offset , & fd ,
4145
- sizeof (u32 ));
4167
+ if (binder_alloc_copy_to_buffer (& proc -> alloc , t -> buffer ,
4168
+ fixup -> offset , & fd ,
4169
+ sizeof (u32 ))) {
4170
+ ret = - EINVAL ;
4171
+ break ;
4172
+ }
4146
4173
}
4147
4174
list_for_each_entry_safe (fixup , tmp , & t -> fd_fixups , fixup_entry ) {
4148
4175
if (fixup -> file ) {
4149
4176
fput (fixup -> file );
4150
4177
} else if (ret ) {
4151
4178
u32 fd ;
4152
-
4153
- binder_alloc_copy_from_buffer (& proc -> alloc , & fd ,
4154
- t -> buffer , fixup -> offset ,
4155
- sizeof (fd ));
4156
- binder_deferred_fd_close (fd );
4179
+ int err ;
4180
+
4181
+ err = binder_alloc_copy_from_buffer (& proc -> alloc , & fd ,
4182
+ t -> buffer ,
4183
+ fixup -> offset ,
4184
+ sizeof (fd ));
4185
+ WARN_ON (err );
4186
+ if (!err )
4187
+ binder_deferred_fd_close (fd );
4157
4188
}
4158
4189
list_del (& fixup -> fixup_entry );
4159
4190
kfree (fixup );
0 commit comments