Commit 4bfac80a authored by Martijn Coenen's avatar Martijn Coenen Committed by Greg Kroah-Hartman

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: default avatarMartijn Coenen <maco@google.com>
Signed-off-by: default avatarJohn Stultz <john.stultz@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a056af42
...@@ -302,6 +302,7 @@ struct binder_buffer { ...@@ -302,6 +302,7 @@ struct binder_buffer {
struct binder_node *target_node; struct binder_node *target_node;
size_t data_size; size_t data_size;
size_t offsets_size; size_t offsets_size;
size_t extra_buffers_size;
uint8_t data[0]; uint8_t data[0];
}; };
...@@ -669,7 +670,9 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, ...@@ -669,7 +670,9 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
size_t data_size, size_t data_size,
size_t offsets_size, int is_async) size_t offsets_size,
size_t extra_buffers_size,
int is_async)
{ {
struct rb_node *n = proc->free_buffers.rb_node; struct rb_node *n = proc->free_buffers.rb_node;
struct binder_buffer *buffer; struct binder_buffer *buffer;
...@@ -677,7 +680,7 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, ...@@ -677,7 +680,7 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
struct rb_node *best_fit = NULL; struct rb_node *best_fit = NULL;
void *has_page_addr; void *has_page_addr;
void *end_page_addr; void *end_page_addr;
size_t size; size_t size, data_offsets_size;
if (proc->vma == NULL) { if (proc->vma == NULL) {
pr_err("%d: binder_alloc_buf, no vma\n", 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,15 +688,20 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
return NULL; return NULL;
} }
size = ALIGN(data_size, sizeof(void *)) + data_offsets_size = ALIGN(data_size, sizeof(void *)) +
ALIGN(offsets_size, sizeof(void *)); ALIGN(offsets_size, sizeof(void *));
if (size < data_size || size < offsets_size) { if (data_offsets_size < data_size || data_offsets_size < offsets_size) {
binder_user_error("%d: got transaction with invalid size %zd-%zd\n", binder_user_error("%d: got transaction with invalid size %zd-%zd\n",
proc->pid, data_size, offsets_size); proc->pid, data_size, offsets_size);
return NULL; return NULL;
} }
size = data_offsets_size + ALIGN(extra_buffers_size, sizeof(void *));
if (size < data_offsets_size || size < extra_buffers_size) {
binder_user_error("%d: got transaction with invalid extra_buffers_size %zd\n",
proc->pid, extra_buffers_size);
return NULL;
}
if (is_async && if (is_async &&
proc->free_async_space < size + sizeof(struct binder_buffer)) { proc->free_async_space < size + sizeof(struct binder_buffer)) {
binder_debug(BINDER_DEBUG_BUFFER_ALLOC, binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
...@@ -762,6 +770,7 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, ...@@ -762,6 +770,7 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
proc->pid, size, buffer); proc->pid, size, buffer);
buffer->data_size = data_size; buffer->data_size = data_size;
buffer->offsets_size = offsets_size; buffer->offsets_size = offsets_size;
buffer->extra_buffers_size = extra_buffers_size;
buffer->async_transaction = is_async; buffer->async_transaction = is_async;
if (is_async) { if (is_async) {
proc->free_async_space -= size + sizeof(struct binder_buffer); proc->free_async_space -= size + sizeof(struct binder_buffer);
...@@ -836,7 +845,8 @@ static void binder_free_buf(struct binder_proc *proc, ...@@ -836,7 +845,8 @@ static void binder_free_buf(struct binder_proc *proc,
buffer_size = binder_buffer_size(proc, buffer); buffer_size = binder_buffer_size(proc, buffer);
size = ALIGN(buffer->data_size, sizeof(void *)) + size = ALIGN(buffer->data_size, sizeof(void *)) +
ALIGN(buffer->offsets_size, sizeof(void *)); ALIGN(buffer->offsets_size, sizeof(void *)) +
ALIGN(buffer->extra_buffers_size, sizeof(void *));
binder_debug(BINDER_DEBUG_BUFFER_ALLOC, binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
"%d: binder_free_buf %p size %zd buffer_size %zd\n", "%d: binder_free_buf %p size %zd buffer_size %zd\n",
...@@ -1553,7 +1563,8 @@ static int binder_translate_fd(int fd, ...@@ -1553,7 +1563,8 @@ static int binder_translate_fd(int fd,
static void binder_transaction(struct binder_proc *proc, static void binder_transaction(struct binder_proc *proc,
struct binder_thread *thread, struct binder_thread *thread,
struct binder_transaction_data *tr, int reply) struct binder_transaction_data *tr, int reply,
binder_size_t extra_buffers_size)
{ {
int ret; int ret;
struct binder_transaction *t; struct binder_transaction *t;
...@@ -1697,20 +1708,22 @@ static void binder_transaction(struct binder_proc *proc, ...@@ -1697,20 +1708,22 @@ static void binder_transaction(struct binder_proc *proc,
if (reply) if (reply)
binder_debug(BINDER_DEBUG_TRANSACTION, binder_debug(BINDER_DEBUG_TRANSACTION,
"%d:%d BC_REPLY %d -> %d:%d, data %016llx-%016llx size %lld-%lld\n", "%d:%d BC_REPLY %d -> %d:%d, data %016llx-%016llx size %lld-%lld-%lld\n",
proc->pid, thread->pid, t->debug_id, proc->pid, thread->pid, t->debug_id,
target_proc->pid, target_thread->pid, target_proc->pid, target_thread->pid,
(u64)tr->data.ptr.buffer, (u64)tr->data.ptr.buffer,
(u64)tr->data.ptr.offsets, (u64)tr->data.ptr.offsets,
(u64)tr->data_size, (u64)tr->offsets_size); (u64)tr->data_size, (u64)tr->offsets_size,
(u64)extra_buffers_size);
else else
binder_debug(BINDER_DEBUG_TRANSACTION, binder_debug(BINDER_DEBUG_TRANSACTION,
"%d:%d BC_TRANSACTION %d -> %d - node %d, data %016llx-%016llx size %lld-%lld\n", "%d:%d BC_TRANSACTION %d -> %d - node %d, data %016llx-%016llx size %lld-%lld-%lld\n",
proc->pid, thread->pid, t->debug_id, proc->pid, thread->pid, t->debug_id,
target_proc->pid, target_node->debug_id, target_proc->pid, target_node->debug_id,
(u64)tr->data.ptr.buffer, (u64)tr->data.ptr.buffer,
(u64)tr->data.ptr.offsets, (u64)tr->data.ptr.offsets,
(u64)tr->data_size, (u64)tr->offsets_size); (u64)tr->data_size, (u64)tr->offsets_size,
(u64)extra_buffers_size);
if (!reply && !(tr->flags & TF_ONE_WAY)) if (!reply && !(tr->flags & TF_ONE_WAY))
t->from = thread; t->from = thread;
...@@ -1726,7 +1739,8 @@ static void binder_transaction(struct binder_proc *proc, ...@@ -1726,7 +1739,8 @@ static void binder_transaction(struct binder_proc *proc,
trace_binder_transaction(reply, t, target_node); trace_binder_transaction(reply, t, target_node);
t->buffer = binder_alloc_buf(target_proc, tr->data_size, t->buffer = binder_alloc_buf(target_proc, tr->data_size,
tr->offsets_size, !reply && (t->flags & TF_ONE_WAY)); tr->offsets_size, extra_buffers_size,
!reply && (t->flags & TF_ONE_WAY));
if (t->buffer == NULL) { if (t->buffer == NULL) {
return_error = BR_FAILED_REPLY; return_error = BR_FAILED_REPLY;
goto err_binder_alloc_buf_failed; goto err_binder_alloc_buf_failed;
...@@ -2076,7 +2090,8 @@ static int binder_thread_write(struct binder_proc *proc, ...@@ -2076,7 +2090,8 @@ static int binder_thread_write(struct binder_proc *proc,
if (copy_from_user(&tr, ptr, sizeof(tr))) if (copy_from_user(&tr, ptr, sizeof(tr)))
return -EFAULT; return -EFAULT;
ptr += sizeof(tr); ptr += sizeof(tr);
binder_transaction(proc, thread, &tr, cmd == BC_REPLY); binder_transaction(proc, thread, &tr,
cmd == BC_REPLY, 0);
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment