From 94b7c10aba2a0c79b88a2b37598adefd206f3e5b Mon Sep 17 00:00:00 2001 From: heppen Date: Mon, 26 Jun 2023 17:11:55 +0800 Subject: [PATCH] Adapt binder as a kernel module --- Makefile | 21 ++++++++--- binder.c | 26 +++++++++++-- binder_alloc.c | 2 +- external_symbols.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 131 insertions(+), 9 deletions(-) create mode 100644 external_symbols.c diff --git a/Makefile b/Makefile index c9d3d0c..5d07f84 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,17 @@ -# SPDX-License-Identifier: GPL-2.0-only -ccflags-y += -I$(src) # needed for trace events +CONFIG_MODULE_SIG=n +ccflags-y += -I$(src) -Wno-int-conversion -Wno-implicit-function-declaration -DCONFIG_ANDROID_BINDER_DEVICES=\"binder\" -obj-$(CONFIG_ANDROID_BINDERFS) += binderfs.o -obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o binder_alloc.o -obj-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o +# only support openEuler-22.03-LTS-SP2 kernel. +ifneq ($(KERNELRELEASE),) +obj-m := binder_linux.o +binder_linux-y := external_symbols.o binder.o binder_alloc.o +else +KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build + + +all: + $(MAKE) -C $(KERNEL_SRC) V=0 M=$$PWD + +clean: + $(MAKE) -C $(KERNEL_SRC) M=$$PWD clean +endif diff --git a/binder.c b/binder.c index b403c7f..35384d8 100644 --- a/binder.c +++ b/binder.c @@ -2039,8 +2039,8 @@ static size_t binder_get_object(struct binder_proc *proc, return 0; } else { if (binder_alloc_copy_from_buffer(&proc->alloc, object, buffer, - offset, read_size)) - return 0; + offset, read_size)) + return 0; } /* Ok, now see if we read a complete object. */ @@ -6531,7 +6531,27 @@ err_alloc_device_names_failed: return ret; } -device_initcall(binder_init); +static void __exit binder_exit(void) +{ + struct hlist_node *tmp; + struct binder_device *device; + + debugfs_remove_recursive(binder_debugfs_dir_entry_root); + + if (!IS_ENABLED(CONFIG_ANDROID_BINDERFS) && + strcmp(binder_devices_param, "") != 0) { + hlist_for_each_entry_safe (device, tmp, &binder_devices,hlist) { + misc_deregister(&device->miscdev); + hlist_del(&device->hlist); + kfree(device); + } + } + + pr_info("unloaded\n"); +} + +module_init(binder_init); +module_exit(binder_exit); #define CREATE_TRACE_POINTS #include "binder_trace.h" diff --git a/binder_alloc.c b/binder_alloc.c index a77ed66..1f5446c 100644 --- a/binder_alloc.c +++ b/binder_alloc.c @@ -38,7 +38,7 @@ enum { }; static uint32_t binder_alloc_debug_mask = BINDER_DEBUG_USER_ERROR; -module_param_named(debug_mask, binder_alloc_debug_mask, +module_param_named(alloc_debug_mask, binder_alloc_debug_mask, uint, 0644); #define binder_alloc_debug(mask, x...) \ diff --git a/external_symbols.c b/external_symbols.c new file mode 100644 index 0000000..4ee95e7 --- /dev/null +++ b/external_symbols.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +static struct kprobe kp = { + .symbol_name = "kallsyms_lookup_name" +}; +typedef unsigned long (*kallsyms_lookup_name_t)(const char *name); + +static kallsyms_lookup_name_t kallsyms_lookup_name_ptr = NULL; + +kallsyms_lookup_name_t static get_lookup(void) { + if (kallsyms_lookup_name_ptr == NULL) { + register_kprobe(&kp); + kallsyms_lookup_name_ptr = (kallsyms_lookup_name_t) kp.addr; + unregister_kprobe(&kp); + } + return kallsyms_lookup_name_ptr; +} + +static void (*zap_page_range_ptr)(struct vm_area_struct *, unsigned long, unsigned long) = NULL; +static int (*can_nice_ptr)(const struct task_struct *, const int) = NULL; +static int (*security_binder_set_context_mgr_ptr)(struct task_struct *mgr) = NULL; +static int (*security_binder_transaction_ptr)(struct task_struct *from, struct task_struct *to) = NULL; +static int (*security_binder_transfer_binder_ptr)(struct task_struct *from, struct task_struct *to) = NULL; +static int (*security_binder_transfer_file_ptr)(struct task_struct *from, struct task_struct *to, struct file *file) = NULL; +static int (*task_work_add_ptr)(struct task_struct *task, struct callback_head *twork, + enum task_work_notify_mode mode) = NULL; +static void (*__wake_up_pollfree_ptr)(wait_queue_head_t *wq_head) = NULL; + +static int (*close_fd_get_file_ptr)(unsigned int fd, struct file **res) = NULL; + +void zap_page_range(struct vm_area_struct *vma, unsigned long address, unsigned long size) +{ + zap_page_range_ptr = get_lookup()("zap_page_range"); + zap_page_range_ptr(vma, address, size); +} + +int can_nice(const struct task_struct *p, const int nice) +{ + can_nice_ptr = get_lookup()("can_nice"); + return can_nice_ptr(p, nice); +} + +int security_binder_set_context_mgr(struct task_struct *mgr) +{ + security_binder_set_context_mgr_ptr = get_lookup()("security_binder_set_context_mgr"); + return security_binder_set_context_mgr_ptr(mgr); +} + +int security_binder_transaction(struct task_struct *from, struct task_struct *to) +{ + security_binder_transaction_ptr = get_lookup()("security_binder_transaction"); + return security_binder_transaction_ptr(from, to); +} + +int security_binder_transfer_binder(struct task_struct *from, struct task_struct *to) +{ + security_binder_transfer_binder_ptr = get_lookup()("security_binder_transfer_binder"); + return security_binder_transfer_binder_ptr(from, to); +} + +int security_binder_transfer_file(struct task_struct *from, struct task_struct *to, struct file *file) +{ + security_binder_transfer_file_ptr = get_lookup()("security_binder_transfer_file"); + return security_binder_transfer_file_ptr(from, to, file); +} + +int task_work_add(struct task_struct *task, struct callback_head *twork, + enum task_work_notify_mode mode) +{ + task_work_add_ptr = get_lookup()("task_work_add"); + return task_work_add_ptr(task, twork, mode); +} + +int close_fd_get_file(unsigned int fd, struct file **res) +{ + close_fd_get_file_ptr = get_lookup()("close_fd_get_file"); + return close_fd_get_file_ptr(fd, res); +} + +void __wake_up_pollfree(wait_queue_head_t *wq_head) +{ + __wake_up_pollfree_ptr = get_lookup()("__wake_up_pollfree"); + return __wake_up_pollfree_ptr(wq_head); +} -- 2.33.0