ALT Linux kernel packages development
 help / color / mirror / Atom feed
From: lakostis@altlinux.org
To: devel-kernel@lists.altlinux.org
Subject: [d-kernel] [PATCH 1/4] binder: turn into module
Date: Fri, 23 Oct 2026 09:42:37 +0200
Message-ID: <20261023074559.941014-2-lakostis@altlinux.org> (raw)
In-Reply-To: <20261023074559.941014-1-lakostis@altlinux.org>

From: Christian Brauner <christian@brauner.io>

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 <christian.brauner@ubuntu.com>
[ saf: fix additional reference to init_ipc_ns from 5.0-rc6 ]
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
[ 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 <andrea.righi@canonical.com>
[ ppisati: export list_lru_add, list_lru_del, lock_vma_under_rcu]
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
[ tjaalton: selftests got converted to KUnit ]
[ tjaalton: 7.1: rename zap_page_range_simple to zap_vma_range]
Signed-off-by: Timo Aaltonen <timo.aaltonen@canonical.com>
Signed-off-by: Alexandre Frade <kernel@xanmod.org>
Signed-off-by: Konstantin A. Lepikhov <lakostis@altlinux.ru>
---
 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 <linux/kconfig.h>
 #include <linux/rbtree.h>
 #include <linux/list.h>
 #include <linux/mm.h>
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 <linux/fs.h>
+#include <linux/kconfig.h>
 #include <linux/list.h>
 #include <linux/miscdevice.h>
 #include <linux/mutex.h>
@@ -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



  reply	other threads:[~2026-10-23  7:42 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-23  7:42 [d-kernel] [7.3] " lakostis
2026-10-23  7:42 ` lakostis [this message]
2026-10-23  7:42 ` [d-kernel] [PATCH 2/4] binder: give binder_alloc its own debug mask file lakostis
2026-10-23  7:42 ` [d-kernel] [PATCH 3/4] wait: allow to use __wake_up_pollfree() from GPL modules lakostis
2026-10-23  7:42 ` [d-kernel] [PATCH 4/4] file: export file_close_fd() instead of close_fd_get_file() lakostis
2026-10-23  9:05 ` [d-kernel] [7.3] binder: turn into module Ivan A. Melnikov
2026-10-23 11:35   ` Konstantin Lepikhov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261023074559.941014-2-lakostis@altlinux.org \
    --to=lakostis@altlinux.org \
    --cc=devel-kernel@lists.altlinux.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

ALT Linux kernel packages development

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://lore.altlinux.org/devel-kernel/0 devel-kernel/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 devel-kernel devel-kernel/ http://lore.altlinux.org/devel-kernel \
		devel-kernel@altlinux.org devel-kernel@altlinux.ru devel-kernel@altlinux.com
	public-inbox-index devel-kernel

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://lore.altlinux.org/org.altlinux.lists.devel-kernel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git