aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartijn Coenen <maco@google.com>2017-02-03 17:40:50 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-02-10 10:00:01 -0500
commit4bfac80af3a63f2971b889b28999c830929e9256 (patch)
treeb661bb80fcc985f72b1887401270119af87cc8eb
parenta056af42032e56f6ee8e07cd22f1ea2b2e07f51b (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.c41
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
670static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, 671static 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
1554static void binder_transaction(struct binder_proc *proc, 1564static 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