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>
This commit is contained in:
parent
a056af4203
commit
4bfac80af3
|
@ -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 @@ err_no_vma:
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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 @@ err_fd_not_accepted:
|
||||||
|
|
||||||
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,
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue