From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on sa.local.altlinux.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.1 From: lakostis@altlinux.org To: devel-kernel@lists.altlinux.org Date: Fri, 23 Oct 2026 09:42:37 +0200 Message-ID: <20261023074559.941014-2-lakostis@altlinux.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20261023074559.941014-1-lakostis@altlinux.org> References: <20261023074559.941014-1-lakostis@altlinux.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [d-kernel] [PATCH 1/4] binder: turn into module X-BeenThere: devel-kernel@lists.altlinux.org X-Mailman-Version: 2.1.12 Precedence: list Reply-To: ALT Linux kernel packages development List-Id: ALT Linux kernel packages development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 Oct 2026 07:47:05 -0000 Archived-At: List-Archive: List-Post: From: Christian Brauner The Android binder driver needs to become a module for the sake of shipping Anbox. To do this we need to export the following functions since binder is currently still using them: - security_binder_set_context_mgr() - security_binder_transaction() - security_binder_transfer_binder() - security_binder_transfer_file() - can_nice() - __close_fd_get_file() - mmput_async() - task_work_add() - map_kernel_range_noflush() - get_vm_area() - zap_vma_range() - put_ipc_ns() - get_ipc_ns_exported() - show_init_ipc_ns() Signed-off-by: Christian Brauner [ saf: fix additional reference to init_ipc_ns from 5.0-rc6 ] Signed-off-by: Seth Forshee [ arighi: fix EXPORT_SYMBOL vs EXPORT_SYMBOL_GPL change from 6.0-rc5 ] [ arighi: zap_page_range() has been dropped, export zap_page_range_single() in 6.3 ] Signed-off-by: Andrea Righi [ ppisati: export list_lru_add, list_lru_del, lock_vma_under_rcu] Signed-off-by: Paolo Pisati [ tjaalton: selftests got converted to KUnit ] [ tjaalton: 7.1: rename zap_page_range_simple to zap_vma_range] Signed-off-by: Timo Aaltonen Signed-off-by: Alexandre Frade Signed-off-by: Konstantin A. Lepikhov --- drivers/android/Kconfig | 6 +++--- drivers/android/Makefile | 9 +++++---- drivers/android/binder.c | 15 ++++++++++++++- drivers/android/binder_alloc.h | 1 + drivers/android/binder_internal.h | 5 +++-- drivers/android/binderfs.c | 6 +++--- fs/file.c | 1 + include/linux/ipc_namespace.h | 3 +++ ipc/namespace.c | 17 +++++++++++++++++ kernel/sched/syscalls.c | 1 + kernel/task_work.c | 1 + mm/list_lru.c | 1 + mm/memory.c | 1 + mm/mmap_lock.c | 1 + mm/vmalloc.c | 1 + security/security.c | 4 ++++ 16 files changed, 60 insertions(+), 13 deletions(-) diff --git a/drivers/android/Kconfig b/drivers/android/Kconfig index 606a9d07f774..b5feebbead21 100644 --- a/drivers/android/Kconfig +++ b/drivers/android/Kconfig @@ -2,7 +2,7 @@ menu "Android" config ANDROID_BINDER_IPC - bool "Android Binder IPC Driver" + tristate "Android Binder IPC Driver" depends on MMU depends on NET default n @@ -28,8 +28,8 @@ config ANDROID_BINDER_IPC_RUST between said processes. config ANDROID_BINDERFS - bool "Android Binderfs filesystem" - depends on ANDROID_BINDER_IPC + tristate "Android Binderfs filesystem" + depends on (ANDROID_BINDER_IPC=y) || (ANDROID_BINDER_IPC=m && m) default n help Binderfs is a pseudo-filesystem for the Android Binder IPC driver diff --git a/drivers/android/Makefile b/drivers/android/Makefile index e0c650d3898e..81ac0681fa1b 100644 --- a/drivers/android/Makefile +++ b/drivers/android/Makefile @@ -1,7 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-only ccflags-y += -I$(src) # needed for trace events -obj-$(CONFIG_ANDROID_BINDERFS) += binderfs.o -obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o binder_alloc.o binder_netlink.o -obj-$(CONFIG_ANDROID_BINDER_ALLOC_KUNIT_TEST) += tests/ -obj-$(CONFIG_ANDROID_BINDER_IPC_RUST) += binder/ +binder_linux-y := binder.o binder_alloc.o binder_netlink.o +obj-$(CONFIG_ANDROID_BINDER_IPC) += binder_linux.o +binder_linux-$(CONFIG_ANDROID_BINDERFS) += binderfs.o +binder_linux-$(CONFIG_ANDROID_BINDER_ALLOC_KUNIT_TEST) += binder_alloc_selftest.o +binder_linux-$(CONFIG_ANDROID_BINDER_IPC_RUST) += binder/ diff --git a/drivers/android/binder.c b/drivers/android/binder.c index bc8bc9ee43a5..9422030f170b 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -7181,7 +7181,20 @@ static int __init binder_init(void) return ret; } -device_initcall(binder_init); +module_init(binder_init); +/* + * binder will have no exit function since binderfs instances can be mounted + * multiple times and also in user namespaces finding and destroying them all + * is not feasible without introducing insane locking. Just ignoring existing + * instances on module unload also wouldn't work since we would loose track of + * what major numer was dynamically allocated and also what minor numbers are + * already given out. So this would get us into all kinds of issues with device + * number reuse. So simply don't allow unloading unless we are forced to do so. + */ + +MODULE_AUTHOR("Google, Inc."); +MODULE_DESCRIPTION("Driver for Android binder device"); +MODULE_LICENSE("GPL v2"); #define CREATE_TRACE_POINTS #include "binder_trace.h" diff --git a/drivers/android/binder_alloc.h b/drivers/android/binder_alloc.h index d6f1f6f2d00e..7edae3eb50f5 100644 --- a/drivers/android/binder_alloc.h +++ b/drivers/android/binder_alloc.h @@ -6,6 +6,7 @@ #ifndef _LINUX_BINDER_ALLOC_H #define _LINUX_BINDER_ALLOC_H +#include #include #include #include diff --git a/drivers/android/binder_internal.h b/drivers/android/binder_internal.h index 342574bfd28a..a723f845bd6a 100644 --- a/drivers/android/binder_internal.h +++ b/drivers/android/binder_internal.h @@ -4,6 +4,7 @@ #define _LINUX_BINDER_INTERNAL_H #include +#include #include #include #include @@ -76,7 +77,7 @@ extern const struct file_operations binder_fops; extern char *binder_devices_param; -#ifdef CONFIG_ANDROID_BINDERFS +#if IS_ENABLED(CONFIG_ANDROID_BINDERFS) extern bool is_binderfs_device(const struct inode *inode); extern struct dentry *binderfs_create_file(struct dentry *dir, const char *name, const struct file_operations *fops, @@ -95,7 +96,7 @@ static inline struct dentry *binderfs_create_file(struct dentry *dir, } #endif -#ifdef CONFIG_ANDROID_BINDERFS +#if IS_ENABLED(CONFIG_ANDROID_BINDERFS) extern int __init init_binderfs(void); #else static inline int __init init_binderfs(void) diff --git a/drivers/android/binderfs.c b/drivers/android/binderfs.c index 1ca31b9a0583..748e96cddc59 100644 --- a/drivers/android/binderfs.c +++ b/drivers/android/binderfs.c @@ -123,7 +123,7 @@ static int binderfs_binder_device_create(struct inode *ref_inode, struct super_block *sb = ref_inode->i_sb; struct binderfs_info *info = sb->s_fs_info; #if defined(CONFIG_IPC_NS) - bool use_reserve = (info->ipc_ns == &init_ipc_ns); + bool use_reserve = (info->ipc_ns == show_init_ipc_ns()); #else bool use_reserve = true; #endif @@ -390,7 +390,7 @@ static int binderfs_binder_ctl_create(struct super_block *sb) struct dentry *root = sb->s_root; struct binderfs_info *info = sb->s_fs_info; #if defined(CONFIG_IPC_NS) - bool use_reserve = (info->ipc_ns == &init_ipc_ns); + bool use_reserve = (info->ipc_ns == show_init_ipc_ns()); #else bool use_reserve = true; #endif @@ -642,7 +642,7 @@ static int binderfs_fill_super(struct super_block *sb, struct fs_context *fc) return -ENOMEM; info = sb->s_fs_info; - info->ipc_ns = get_ipc_ns(current->nsproxy->ipc_ns); + info->ipc_ns = get_ipc_ns_exported(current->nsproxy->ipc_ns); info->root_gid = make_kgid(sb->s_user_ns, 0); if (!gid_valid(info->root_gid)) diff --git a/fs/file.c b/fs/file.c index 628ca07dc4b1..d18a19c2e6af 100644 --- a/fs/file.c +++ b/fs/file.c @@ -886,6 +886,7 @@ struct file *file_close_fd(unsigned int fd) return file; } +EXPORT_SYMBOL(close_fd_get_file); void do_close_on_exec(struct files_struct *files) { diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h index 12faca29bbb9..5bf174df249e 100644 --- a/include/linux/ipc_namespace.h +++ b/include/linux/ipc_namespace.h @@ -128,6 +128,9 @@ extern int mq_init_ns(struct ipc_namespace *ns); static inline int mq_init_ns(struct ipc_namespace *ns) { return 0; } #endif +extern struct ipc_namespace *get_ipc_ns_exported(struct ipc_namespace *ns); +extern struct ipc_namespace *show_init_ipc_ns(void); + #if defined(CONFIG_IPC_NS) static inline struct ipc_namespace *to_ipc_ns(struct ns_common *ns) { diff --git a/ipc/namespace.c b/ipc/namespace.c index 75aa7b469348..3559938a6ba0 100644 --- a/ipc/namespace.c +++ b/ipc/namespace.c @@ -210,6 +210,23 @@ void put_ipc_ns(struct ipc_namespace *ns) schedule_work(&free_ipc_work); } } +EXPORT_SYMBOL(put_ipc_ns); + +struct ipc_namespace *get_ipc_ns_exported(struct ipc_namespace *ns) +{ + return get_ipc_ns(ns); +} +EXPORT_SYMBOL(get_ipc_ns_exported); + +struct ipc_namespace *show_init_ipc_ns(void) +{ +#if defined(CONFIG_IPC_NS) + return &init_ipc_ns; +#else + return NULL; +#endif +} +EXPORT_SYMBOL(show_init_ipc_ns); static struct ns_common *ipcns_get(struct task_struct *task) { diff --git a/kernel/sched/syscalls.c b/kernel/sched/syscalls.c index b215b0ead9a6..a9fc5414292c 100644 --- a/kernel/sched/syscalls.c +++ b/kernel/sched/syscalls.c @@ -119,6 +119,7 @@ int can_nice(const struct task_struct *p, const int nice) { return is_nice_reduction(p, nice) || capable(CAP_SYS_NICE); } +EXPORT_SYMBOL(can_nice); #ifdef __ARCH_WANT_SYS_NICE diff --git a/kernel/task_work.c b/kernel/task_work.c index 0f7519f8e7c9..08eb29abaea6 100644 --- a/kernel/task_work.c +++ b/kernel/task_work.c @@ -102,6 +102,7 @@ int task_work_add(struct task_struct *task, struct callback_head *work, return 0; } +EXPORT_SYMBOL(task_work_add); /** * task_work_cancel_match - cancel a pending work added by task_work_add() diff --git a/mm/list_lru.c b/mm/list_lru.c index 36662d02ff96..b7ea86ae6d66 100644 --- a/mm/list_lru.c +++ b/mm/list_lru.c @@ -273,6 +273,7 @@ bool list_lru_del(struct list_lru *lru, struct list_head *item, int nid, list_lru_unlock(l); return ret; } +EXPORT_SYMBOL_GPL(list_lru_del); bool list_lru_del_obj(struct list_lru *lru, struct list_head *item) { diff --git a/mm/memory.c b/mm/memory.c index 8b0c2c735d3d..f07c56290222 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2378,6 +2378,7 @@ void zap_vma_range(struct vm_area_struct *vma, unsigned long address, zap_vma_range_batched(&tlb, vma, address, size, NULL); tlb_finish_mmu(&tlb); } +EXPORT_SYMBOL(zap_vma_range); /** * zap_special_vma_range - zap all page table entries in a special vma range diff --git a/mm/mmap_lock.c b/mm/mmap_lock.c index 898c2ef1e958..4f5e3badb8ea 100644 --- a/mm/mmap_lock.c +++ b/mm/mmap_lock.c @@ -340,6 +340,7 @@ struct vm_area_struct *lock_vma_under_rcu(struct mm_struct *mm, count_vm_vma_lock_event(VMA_LOCK_ABORT); return NULL; } +EXPORT_SYMBOL_GPL(lock_vma_under_rcu); static struct vm_area_struct *lock_next_vma_under_mmap_lock(struct mm_struct *mm, struct vma_iterator *vmi, diff --git a/mm/vmalloc.c b/mm/vmalloc.c index bea9f76ed7e7..4b51fbc83040 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -3292,6 +3292,7 @@ struct vm_struct *get_vm_area(unsigned long size, unsigned long flags) NUMA_NO_NODE, GFP_KERNEL, __builtin_return_address(0)); } +EXPORT_SYMBOL(get_vm_area); struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags, const void *caller) diff --git a/security/security.c b/security/security.c index 2ee276ab15c5..bad282ef9154 100644 --- a/security/security.c +++ b/security/security.c @@ -514,6 +514,7 @@ int security_binder_set_context_mgr(const struct cred *mgr) { return call_int_hook(binder_set_context_mgr, mgr); } +EXPORT_SYMBOL(security_binder_set_context_mgr); /** * security_binder_transaction() - Check if a binder transaction is allowed @@ -529,6 +530,7 @@ int security_binder_transaction(const struct cred *from, { return call_int_hook(binder_transaction, from, to); } +EXPORT_SYMBOL(security_binder_transaction); /** * security_binder_transfer_binder() - Check if a binder transfer is allowed @@ -544,6 +546,7 @@ int security_binder_transfer_binder(const struct cred *from, { return call_int_hook(binder_transfer_binder, from, to); } +EXPORT_SYMBOL(security_binder_transfer_binder); /** * security_binder_transfer_file() - Check if a binder file xfer is allowed @@ -560,6 +563,7 @@ int security_binder_transfer_file(const struct cred *from, { return call_int_hook(binder_transfer_file, from, to, file); } +EXPORT_SYMBOL(security_binder_transfer_file); /** * security_ptrace_access_check() - Check if tracing is allowed -- 2.50.1