diff --git a/binder/binder.c b/binder/binder.c index c0f6f12..70baa74 100644 --- a/binder/binder.c +++ b/binder/binder.c @@ -2869,8 +2869,13 @@ static void binder_transaction(struct binder_proc *proc, binder_size_t last_fixup_min_off = 0; struct binder_context *context = proc->context; int t_debug_id = atomic_inc_return(&binder_last_id); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) + struct lsmblob blob = {0}; + struct lsmcontext cp = {0}; +#else char *secctx = NULL; u32 secctx_sz = 0; +#endif e = binder_transaction_log_add(&binder_transaction_log); e->debug_id = t_debug_id; @@ -3125,22 +3130,35 @@ static void binder_transaction(struct binder_proc *proc, t->priority = task_nice(current); if (target_node && target_node->txn_security_ctx) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) u32 secid; +#endif size_t added_size; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) + security_task_getsecid_obj(proc->tsk, &blob); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) security_task_getsecid_obj(proc->tsk, &secid); #else security_task_getsecid(proc->tsk, &secid); #endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) + ret = security_secid_to_secctx(&blob, &cp, 0); +#else ret = security_secid_to_secctx(secid, &secctx, &secctx_sz); +#endif if (ret) { return_error = BR_FAILED_REPLY; return_error_param = ret; return_error_line = __LINE__; goto err_get_secctx_failed; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) + added_size = ALIGN(cp.len, sizeof(u64)); +#else added_size = ALIGN(secctx_sz, sizeof(u64)); +#endif extra_buffers_size += added_size; if (extra_buffers_size < added_size) { /* integer overflow of extra_buffers_size */ @@ -3167,23 +3185,41 @@ static void binder_transaction(struct binder_proc *proc, t->buffer = NULL; goto err_binder_alloc_buf_failed; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) + if (cp.context) { +#else if (secctx) { +#endif int err; size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) + ALIGN(tr->offsets_size, sizeof(void *)) + ALIGN(extra_buffers_size, sizeof(void *)) - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) + ALIGN(cp.len, sizeof(u64)); +#else ALIGN(secctx_sz, sizeof(u64)); +#endif t->security_ctx = (uintptr_t)t->buffer->user_data + buf_offset; err = binder_alloc_copy_to_buffer(&target_proc->alloc, t->buffer, buf_offset, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) + cp.context, cp.len); +#else secctx, secctx_sz); +#endif if (err) { t->security_ctx = 0; WARN_ON(1); } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) + security_release_secctx(&cp); + cp.context = NULL; +#else security_release_secctx(secctx, secctx_sz); secctx = NULL; +#endif } t->buffer->debug_id = t->debug_id; t->buffer->transaction = t; @@ -3240,7 +3276,11 @@ static void binder_transaction(struct binder_proc *proc, off_end_offset = off_start_offset + tr->offsets_size; sg_buf_offset = ALIGN(off_end_offset, sizeof(void *)); sg_buf_end_offset = sg_buf_offset + extra_buffers_size - +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) + ALIGN(cp.len, sizeof(u64)); +#else ALIGN(secctx_sz, sizeof(u64)); +#endif off_min = 0; for (buffer_offset = off_start_offset; buffer_offset < off_end_offset; buffer_offset += sizeof(binder_size_t)) { @@ -3516,8 +3556,13 @@ err_copy_data_failed: binder_alloc_free_buf(&target_proc->alloc, t->buffer); err_binder_alloc_buf_failed: err_bad_extra_size: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) + if (cp.context) + security_release_secctx(&cp); +#else if (secctx) security_release_secctx(secctx, secctx_sz); +#endif err_get_secctx_failed: kfree(tcomplete); binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);