diff options
author | Martijn Coenen <maco@google.com> | 2017-02-03 17:40:50 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-02-10 10:00:01 -0500 |
commit | 4bfac80af3a63f2971b889b28999c830929e9256 (patch) | |
tree | b661bb80fcc985f72b1887401270119af87cc8eb | |
parent | a056af42032e56f6ee8e07cd22f1ea2b2e07f51b (diff) |
binder: Add extra size to allocator
The binder_buffer allocator currently only allocates
space for the data and offsets buffers of a Parcel.
This change allows for requesting an additional chunk
of data in the buffer, which can for example be used
to hold additional meta-data about the transaction
(eg a security context).
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Martijn Coenen <maco@google.com>
Cc: Arve Hjønnevåg <arve@android.com>
Cc: Amit Pundir <amit.pundir@linaro.org>
Cc: Serban Constantinescu <serban.constantinescu@arm.com>
Cc: Dmitry Shmidt <dimitrysh@google.com>
Cc: Rom Lemarchand <romlem@google.com>
Cc: Android Kernel Team <kernel-team@android.com>
Signed-off-by: Martijn Coenen <maco@google.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/android/binder.c | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 1a6969cdae7f..25aa452d2738 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c | |||
@@ -302,6 +302,7 @@ struct binder_buffer { | |||
302 | struct binder_node *target_node; | 302 | struct binder_node *target_node; |
303 | size_t data_size; | 303 | size_t data_size; |
304 | size_t offsets_size; | 304 | size_t offsets_size; |
305 | size_t extra_buffers_size; | ||
305 | uint8_t data[0]; | 306 | uint8_t data[0]; |
306 | }; | 307 | }; |
307 | 308 | ||
@@ -669,7 +670,9 @@ err_no_vma: | |||
669 | 670 | ||
670 | static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, | 671 | static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, |
671 | size_t data_size, | 672 | size_t data_size, |
672 | size_t offsets_size, int is_async) | 673 | size_t offsets_size, |
674 | size_t extra_buffers_size, | ||
675 | int is_async) | ||
673 | { | 676 | { |
674 | struct rb_node *n = proc->free_buffers.rb_node; | 677 | struct rb_node *n = proc->free_buffers.rb_node; |
675 | struct binder_buffer *buffer; | 678 | struct binder_buffer *buffer; |
@@ -677,7 +680,7 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, | |||
677 | struct rb_node *best_fit = NULL; | 680 | struct rb_node *best_fit = NULL; |
678 | void *has_page_addr; | 681 | void *has_page_addr; |
679 | void *end_page_addr; | 682 | void *end_page_addr; |
680 | size_t size; | 683 | size_t size, data_offsets_size; |
681 | 684 | ||
682 | if (proc->vma == NULL) { | 685 | if (proc->vma == NULL) { |
683 | pr_err("%d: binder_alloc_buf, no vma\n", | 686 | pr_err("%d: binder_alloc_buf, no vma\n", |
@@ -685,15 +688,20 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, | |||
685 | return NULL; | 688 | return NULL; |
686 | } | 689 | } |
687 | 690 | ||
688 | size = ALIGN(data_size, sizeof(void *)) + | 691 | data_offsets_size = ALIGN(data_size, sizeof(void *)) + |
689 | ALIGN(offsets_size, sizeof(void *)); | 692 | ALIGN(offsets_size, sizeof(void *)); |
690 | 693 | ||
691 | if (size < data_size || size < offsets_size) { | 694 | if (data_offsets_size < data_size || data_offsets_size < offsets_size) { |
692 | binder_user_error("%d: got transaction with invalid size %zd-%zd\n", | 695 | binder_user_error("%d: got transaction with invalid size %zd-%zd\n", |
693 | proc->pid, data_size, offsets_size); | 696 | proc->pid, data_size, offsets_size); |
694 | return NULL; | 697 | return NULL; |
695 | } | 698 | } |
696 | 699 | size = data_offsets_size + ALIGN(extra_buffers_size, sizeof(void *)); | |
700 | if (size < data_offsets_size || size < extra_buffers_size) { | ||
701 | binder_user_error("%d: got transaction with invalid extra_buffers_size %zd\n", | ||
702 | proc->pid, extra_buffers_size); | ||
703 | return NULL; | ||
704 | } | ||
697 | if (is_async && | 705 | if (is_async && |
698 | proc->free_async_space < size + sizeof(struct binder_buffer)) { | 706 | proc->free_async_space < size + sizeof(struct binder_buffer)) { |
699 | binder_debug(BINDER_DEBUG_BUFFER_ALLOC, | 707 | binder_debug(BINDER_DEBUG_BUFFER_ALLOC, |
@@ -762,6 +770,7 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, | |||
762 | proc->pid, size, buffer); | 770 | proc->pid, size, buffer); |
763 | buffer->data_size = data_size; | 771 | buffer->data_size = data_size; |
764 | buffer->offsets_size = offsets_size; | 772 | buffer->offsets_size = offsets_size; |
773 | buffer->extra_buffers_size = extra_buffers_size; | ||
765 | buffer->async_transaction = is_async; | 774 | buffer->async_transaction = is_async; |
766 | if (is_async) { | 775 | if (is_async) { |
767 | proc->free_async_space -= size + sizeof(struct binder_buffer); | 776 | proc->free_async_space -= size + sizeof(struct binder_buffer); |
@@ -836,7 +845,8 @@ static void binder_free_buf(struct binder_proc *proc, | |||
836 | buffer_size = binder_buffer_size(proc, buffer); | 845 | buffer_size = binder_buffer_size(proc, buffer); |
837 | 846 | ||
838 | size = ALIGN(buffer->data_size, sizeof(void *)) + | 847 | size = ALIGN(buffer->data_size, sizeof(void *)) + |
839 | ALIGN(buffer->offsets_size, sizeof(void *)); | 848 | ALIGN(buffer->offsets_size, sizeof(void *)) + |
849 | ALIGN(buffer->extra_buffers_size, sizeof(void *)); | ||
840 | 850 | ||
841 | binder_debug(BINDER_DEBUG_BUFFER_ALLOC, | 851 | binder_debug(BINDER_DEBUG_BUFFER_ALLOC, |
842 | "%d: binder_free_buf %p size %zd buffer_size %zd\n", | 852 | "%d: binder_free_buf %p size %zd buffer_size %zd\n", |
@@ -1553,7 +1563,8 @@ err_fd_not_accepted: | |||
1553 | 1563 | ||
1554 | static void binder_transaction(struct binder_proc *proc, | 1564 | static void binder_transaction(struct binder_proc *proc, |
1555 | struct binder_thread *thread, | 1565 | struct binder_thread *thread, |
1556 | struct binder_transaction_data *tr, int reply) | 1566 | struct binder_transaction_data *tr, int reply, |
1567 | binder_size_t extra_buffers_size) | ||
1557 | { | 1568 | { |
1558 | int ret; | 1569 | int ret; |
1559 | struct binder_transaction *t; | 1570 | struct binder_transaction *t; |
@@ -1697,20 +1708,22 @@ static void binder_transaction(struct binder_proc *proc, | |||
1697 | 1708 | ||
1698 | if (reply) | 1709 | if (reply) |
1699 | binder_debug(BINDER_DEBUG_TRANSACTION, | 1710 | binder_debug(BINDER_DEBUG_TRANSACTION, |
1700 | "%d:%d BC_REPLY %d -> %d:%d, data %016llx-%016llx size %lld-%lld\n", | 1711 | "%d:%d BC_REPLY %d -> %d:%d, data %016llx-%016llx size %lld-%lld-%lld\n", |
1701 | proc->pid, thread->pid, t->debug_id, | 1712 | proc->pid, thread->pid, t->debug_id, |
1702 | target_proc->pid, target_thread->pid, | 1713 | target_proc->pid, target_thread->pid, |
1703 | (u64)tr->data.ptr.buffer, | 1714 | (u64)tr->data.ptr.buffer, |
1704 | (u64)tr->data.ptr.offsets, | 1715 | (u64)tr->data.ptr.offsets, |
1705 | (u64)tr->data_size, (u64)tr->offsets_size); | 1716 | (u64)tr->data_size, (u64)tr->offsets_size, |
1717 | (u64)extra_buffers_size); | ||
1706 | else | 1718 | else |
1707 | binder_debug(BINDER_DEBUG_TRANSACTION, | 1719 | binder_debug(BINDER_DEBUG_TRANSACTION, |
1708 | "%d:%d BC_TRANSACTION %d -> %d - node %d, data %016llx-%016llx size %lld-%lld\n", | 1720 | "%d:%d BC_TRANSACTION %d -> %d - node %d, data %016llx-%016llx size %lld-%lld-%lld\n", |
1709 | proc->pid, thread->pid, t->debug_id, | 1721 | proc->pid, thread->pid, t->debug_id, |
1710 | target_proc->pid, target_node->debug_id, | 1722 | target_proc->pid, target_node->debug_id, |
1711 | (u64)tr->data.ptr.buffer, | 1723 | (u64)tr->data.ptr.buffer, |
1712 | (u64)tr->data.ptr.offsets, | 1724 | (u64)tr->data.ptr.offsets, |
1713 | (u64)tr->data_size, (u64)tr->offsets_size); | 1725 | (u64)tr->data_size, (u64)tr->offsets_size, |
1726 | (u64)extra_buffers_size); | ||
1714 | 1727 | ||
1715 | if (!reply && !(tr->flags & TF_ONE_WAY)) | 1728 | if (!reply && !(tr->flags & TF_ONE_WAY)) |
1716 | t->from = thread; | 1729 | t->from = thread; |
@@ -1726,7 +1739,8 @@ static void binder_transaction(struct binder_proc *proc, | |||
1726 | trace_binder_transaction(reply, t, target_node); | 1739 | trace_binder_transaction(reply, t, target_node); |
1727 | 1740 | ||
1728 | t->buffer = binder_alloc_buf(target_proc, tr->data_size, | 1741 | t->buffer = binder_alloc_buf(target_proc, tr->data_size, |
1729 | tr->offsets_size, !reply && (t->flags & TF_ONE_WAY)); | 1742 | tr->offsets_size, extra_buffers_size, |
1743 | !reply && (t->flags & TF_ONE_WAY)); | ||
1730 | if (t->buffer == NULL) { | 1744 | if (t->buffer == NULL) { |
1731 | return_error = BR_FAILED_REPLY; | 1745 | return_error = BR_FAILED_REPLY; |
1732 | goto err_binder_alloc_buf_failed; | 1746 | goto err_binder_alloc_buf_failed; |
@@ -2076,7 +2090,8 @@ static int binder_thread_write(struct binder_proc *proc, | |||
2076 | if (copy_from_user(&tr, ptr, sizeof(tr))) | 2090 | if (copy_from_user(&tr, ptr, sizeof(tr))) |
2077 | return -EFAULT; | 2091 | return -EFAULT; |
2078 | ptr += sizeof(tr); | 2092 | ptr += sizeof(tr); |
2079 | binder_transaction(proc, thread, &tr, cmd == BC_REPLY); | 2093 | binder_transaction(proc, thread, &tr, |
2094 | cmd == BC_REPLY, 0); | ||
2080 | break; | 2095 | break; |
2081 | } | 2096 | } |
2082 | 2097 | ||