Skip to content

Commit 7a67a39

Browse files
Todd Kjosgregkh
authored andcommitted
binder: add function to copy binder object from buffer
When creating or tearing down a transaction, the binder driver examines objects in the buffer and takes appropriate action. To do this without needing to dereference pointers into the buffer, the local copies of the objects are needed. This patch introduces a function to validate and copy binder objects from the buffer to a local structure. Signed-off-by: Todd Kjos <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 8ced0c6 commit 7a67a39

File tree

1 file changed

+58
-17
lines changed

1 file changed

+58
-17
lines changed

drivers/android/binder.c

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,26 @@ struct binder_transaction {
628628
spinlock_t lock;
629629
};
630630

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+
631651
/**
632652
* binder_proc_lock() - Acquire outer lock for given binder_proc
633653
* @proc: struct binder_proc to acquire
@@ -2017,26 +2037,33 @@ static void binder_cleanup_transaction(struct binder_transaction *t,
20172037
}
20182038

20192039
/**
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
20212042
* @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
20232045
*
20242046
* 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.
20262049
*/
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)
20282054
{
2029-
/* Check if we can read a header first */
2055+
size_t read_size;
20302056
struct binder_object_header *hdr;
20312057
size_t object_size = 0;
20322058

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))
20362061
return 0;
2062+
binder_alloc_copy_from_buffer(&proc->alloc, object, buffer,
2063+
offset, read_size);
20372064

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;
20402067
switch (hdr->type) {
20412068
case BINDER_TYPE_BINDER:
20422069
case BINDER_TYPE_WEAK_BINDER:
@@ -2245,21 +2272,22 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
22452272
for (offp = off_start; offp < off_end; offp++) {
22462273
struct binder_object_header *hdr;
22472274
size_t object_size;
2275+
struct binder_object object;
22482276
binder_size_t object_offset;
22492277
binder_size_t buffer_offset = (uintptr_t)offp -
22502278
(uintptr_t)buffer->data;
22512279

22522280
binder_alloc_copy_from_buffer(&proc->alloc, &object_offset,
22532281
buffer, buffer_offset,
22542282
sizeof(object_offset));
2255-
object_size = binder_validate_object(buffer, object_offset);
2283+
object_size = binder_get_object(proc, buffer,
2284+
object_offset, &object);
22562285
if (object_size == 0) {
22572286
pr_err("transaction release %d bad object at offset %lld, size %zd\n",
22582287
debug_id, (u64)object_offset, buffer->data_size);
22592288
continue;
22602289
}
2261-
hdr = (struct binder_object_header *)
2262-
(buffer->data + object_offset);
2290+
hdr = &object.hdr;
22632291
switch (hdr->type) {
22642292
case BINDER_TYPE_BINDER:
22652293
case BINDER_TYPE_WEAK_BINDER: {
@@ -3159,6 +3187,7 @@ static void binder_transaction(struct binder_proc *proc,
31593187
for (; offp < off_end; offp++) {
31603188
struct binder_object_header *hdr;
31613189
size_t object_size;
3190+
struct binder_object object;
31623191
binder_size_t object_offset;
31633192
binder_size_t buffer_offset =
31643193
(uintptr_t)offp - (uintptr_t)t->buffer->data;
@@ -3168,7 +3197,8 @@ static void binder_transaction(struct binder_proc *proc,
31683197
t->buffer,
31693198
buffer_offset,
31703199
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);
31723202
if (object_size == 0 || object_offset < off_min) {
31733203
binder_user_error("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n",
31743204
proc->pid, thread->pid,
@@ -3181,8 +3211,7 @@ static void binder_transaction(struct binder_proc *proc,
31813211
goto err_bad_offset;
31823212
}
31833213

3184-
hdr = (struct binder_object_header *)
3185-
(t->buffer->data + object_offset);
3214+
hdr = &object.hdr;
31863215
off_min = object_offset + object_size;
31873216
switch (hdr->type) {
31883217
case BINDER_TYPE_BINDER:
@@ -3197,6 +3226,9 @@ static void binder_transaction(struct binder_proc *proc,
31973226
return_error_line = __LINE__;
31983227
goto err_translate_failed;
31993228
}
3229+
binder_alloc_copy_to_buffer(&target_proc->alloc,
3230+
t->buffer, object_offset,
3231+
fp, sizeof(*fp));
32003232
} break;
32013233
case BINDER_TYPE_HANDLE:
32023234
case BINDER_TYPE_WEAK_HANDLE: {
@@ -3210,6 +3242,9 @@ static void binder_transaction(struct binder_proc *proc,
32103242
return_error_line = __LINE__;
32113243
goto err_translate_failed;
32123244
}
3245+
binder_alloc_copy_to_buffer(&target_proc->alloc,
3246+
t->buffer, object_offset,
3247+
fp, sizeof(*fp));
32133248
} break;
32143249

32153250
case BINDER_TYPE_FD: {
@@ -3226,6 +3261,9 @@ static void binder_transaction(struct binder_proc *proc,
32263261
goto err_translate_failed;
32273262
}
32283263
fp->pad_binder = 0;
3264+
binder_alloc_copy_to_buffer(&target_proc->alloc,
3265+
t->buffer, object_offset,
3266+
fp, sizeof(*fp));
32293267
} break;
32303268
case BINDER_TYPE_FDA: {
32313269
struct binder_fd_array_object *fda =
@@ -3310,7 +3348,10 @@ static void binder_transaction(struct binder_proc *proc,
33103348
return_error_line = __LINE__;
33113349
goto err_translate_failed;
33123350
}
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;
33143355
last_fixup_min_off = 0;
33153356
} break;
33163357
default:

0 commit comments

Comments
 (0)