7186 lines · 202.4 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-only/* binder.c * * Android IPC Subsystem * * Copyright (C) 2007-2008 Google, Inc. */ /* * Locking overview * * There are 3 main spinlocks which must be acquired in the * order shown: * * 1) proc->outer_lock : protects binder_ref *    binder_proc_lock() and binder_proc_unlock() are *    used to acq/rel. * 2) node->lock : protects most fields of binder_node. *    binder_node_lock() and binder_node_unlock() are *    used to acq/rel * 3) proc->inner_lock : protects the thread and node lists *    (proc->threads, proc->waiting_threads, proc->nodes) *    and all todo lists associated with the binder_proc *    (proc->todo, thread->todo, proc->delivered_death and *    node->async_todo), as well as thread->transaction_stack *    binder_inner_proc_lock() and binder_inner_proc_unlock() *    are used to acq/rel * * Any lock under procA must never be nested under any lock at the same * level or below on procB. * * Functions that require a lock held on entry indicate which lock * in the suffix of the function name: * * foo_olocked() : requires node->outer_lock * foo_nlocked() : requires node->lock * foo_ilocked() : requires proc->inner_lock * foo_oilocked(): requires proc->outer_lock and proc->inner_lock * foo_nilocked(): requires node->lock and proc->inner_lock * ... */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/fdtable.h>#include <linux/file.h>#include <linux/freezer.h>#include <linux/fs.h>#include <linux/list.h>#include <linux/miscdevice.h>#include <linux/module.h>#include <linux/mutex.h>#include <linux/nsproxy.h>#include <linux/poll.h>#include <linux/debugfs.h>#include <linux/rbtree.h>#include <linux/sched/signal.h>#include <linux/sched/mm.h>#include <linux/seq_file.h>#include <linux/string.h>#include <linux/uaccess.h>#include <linux/pid_namespace.h>#include <linux/security.h>#include <linux/spinlock.h>#include <linux/ratelimit.h>#include <linux/syscalls.h>#include <linux/task_work.h>#include <linux/sizes.h>#include <linux/ktime.h> #include <kunit/visibility.h> #include <uapi/linux/android/binder.h> #include <linux/cacheflush.h> #include "binder_netlink.h"#include "binder_internal.h"#include "binder_trace.h" static HLIST_HEAD(binder_deferred_list);static DEFINE_MUTEX(binder_deferred_lock); static HLIST_HEAD(binder_devices);static DEFINE_SPINLOCK(binder_devices_lock); static HLIST_HEAD(binder_procs);static DEFINE_MUTEX(binder_procs_lock); static HLIST_HEAD(binder_dead_nodes);static DEFINE_SPINLOCK(binder_dead_nodes_lock); static struct dentry *binder_debugfs_dir_entry_root;static struct dentry *binder_debugfs_dir_entry_proc;static atomic_t binder_last_id; static int proc_show(struct seq_file *m, void *unused);DEFINE_SHOW_ATTRIBUTE(proc); #define FORBIDDEN_MMAP_FLAGS                (VM_WRITE) enum {	BINDER_DEBUG_USER_ERROR             = 1U << 0,	BINDER_DEBUG_FAILED_TRANSACTION     = 1U << 1,	BINDER_DEBUG_DEAD_TRANSACTION       = 1U << 2,	BINDER_DEBUG_OPEN_CLOSE             = 1U << 3,	BINDER_DEBUG_DEAD_BINDER            = 1U << 4,	BINDER_DEBUG_DEATH_NOTIFICATION     = 1U << 5,	BINDER_DEBUG_READ_WRITE             = 1U << 6,	BINDER_DEBUG_USER_REFS              = 1U << 7,	BINDER_DEBUG_THREADS                = 1U << 8,	BINDER_DEBUG_TRANSACTION            = 1U << 9,	BINDER_DEBUG_TRANSACTION_COMPLETE   = 1U << 10,	BINDER_DEBUG_FREE_BUFFER            = 1U << 11,	BINDER_DEBUG_INTERNAL_REFS          = 1U << 12,	BINDER_DEBUG_PRIORITY_CAP           = 1U << 13,	BINDER_DEBUG_SPINLOCKS              = 1U << 14,};static uint32_t binder_debug_mask = BINDER_DEBUG_USER_ERROR |	BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION;module_param_named(debug_mask, binder_debug_mask, uint, 0644); char *binder_devices_param = CONFIG_ANDROID_BINDER_DEVICES;module_param_named(devices, binder_devices_param, charp, 0444); static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait);static int binder_stop_on_user_error; static int binder_set_stop_on_user_error(const char *val,					 const struct kernel_param *kp){	int ret; 	ret = param_set_int(val, kp);	if (binder_stop_on_user_error < 2)		wake_up(&binder_user_error_wait);	return ret;}module_param_call(stop_on_user_error, binder_set_stop_on_user_error,	param_get_int, &binder_stop_on_user_error, 0644); static __printf(2, 3) void binder_debug(int mask, const char *format, ...){	struct va_format vaf;	va_list args; 	if (binder_debug_mask & mask) {		va_start(args, format);		vaf.va = &args;		vaf.fmt = format;		pr_info_ratelimited("%pV", &vaf);		va_end(args);	}} #define binder_txn_error(x...) \	binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, x) static __printf(1, 2) void binder_user_error(const char *format, ...){	struct va_format vaf;	va_list args; 	if (binder_debug_mask & BINDER_DEBUG_USER_ERROR) {		va_start(args, format);		vaf.va = &args;		vaf.fmt = format;		pr_info_ratelimited("%pV", &vaf);		va_end(args);	} 	if (binder_stop_on_user_error)		binder_stop_on_user_error = 2;} #define binder_set_extended_error(ee, _id, _command, _param) \	do { \		(ee)->id = _id; \		(ee)->command = _command; \		(ee)->param = _param; \	} while (0) #define to_flat_binder_object(hdr) \	container_of(hdr, struct flat_binder_object, hdr) #define to_binder_fd_object(hdr) container_of(hdr, struct binder_fd_object, hdr) #define to_binder_buffer_object(hdr) \	container_of(hdr, struct binder_buffer_object, hdr) #define to_binder_fd_array_object(hdr) \	container_of(hdr, struct binder_fd_array_object, hdr) static struct binder_stats binder_stats; static inline void binder_stats_deleted(enum binder_stat_types type){	atomic_inc(&binder_stats.obj_deleted[type]);} static inline void binder_stats_created(enum binder_stat_types type){	atomic_inc(&binder_stats.obj_created[type]);} struct binder_transaction_log_entry {	int debug_id;	int debug_id_done;	int call_type;	int from_proc;	int from_thread;	int target_handle;	int to_proc;	int to_thread;	int to_node;	int data_size;	int offsets_size;	int return_error_line;	uint32_t return_error;	uint32_t return_error_param;	char context_name[BINDERFS_MAX_NAME + 1];}; struct binder_transaction_log {	atomic_t cur;	bool full;	struct binder_transaction_log_entry entry[32];}; static struct binder_transaction_log binder_transaction_log;static struct binder_transaction_log binder_transaction_log_failed; static struct binder_transaction_log_entry *binder_transaction_log_add(	struct binder_transaction_log *log){	struct binder_transaction_log_entry *e;	unsigned int cur = atomic_inc_return(&log->cur); 	if (cur >= ARRAY_SIZE(log->entry))		log->full = true;	e = &log->entry[cur % ARRAY_SIZE(log->entry)];	WRITE_ONCE(e->debug_id_done, 0);	/*	 * write-barrier to synchronize access to e->debug_id_done.	 * We make sure the initialized 0 value is seen before	 * memset() other fields are zeroed by memset.	 */	smp_wmb();	memset(e, 0, sizeof(*e));	return e;} enum binder_deferred_state {	BINDER_DEFERRED_FLUSH        = 0x01,	BINDER_DEFERRED_RELEASE      = 0x02,}; enum {	BINDER_LOOPER_STATE_REGISTERED  = 0x01,	BINDER_LOOPER_STATE_ENTERED     = 0x02,	BINDER_LOOPER_STATE_EXITED      = 0x04,	BINDER_LOOPER_STATE_INVALID     = 0x08,	BINDER_LOOPER_STATE_WAITING     = 0x10,	BINDER_LOOPER_STATE_POLL        = 0x20,}; /** * binder_proc_lock() - Acquire outer lock for given binder_proc * @proc:         struct binder_proc to acquire * * Acquires proc->outer_lock. Used to protect binder_ref * structures associated with the given proc. */#define binder_proc_lock(proc) _binder_proc_lock(proc, __LINE__)static void_binder_proc_lock(struct binder_proc *proc, int line)	__acquires(&proc->outer_lock){	binder_debug(BINDER_DEBUG_SPINLOCKS,		     "%s: line=%d\n", __func__, line);	spin_lock(&proc->outer_lock);} /** * binder_proc_unlock() - Release outer lock for given binder_proc * @proc:                struct binder_proc to acquire * * Release lock acquired via binder_proc_lock() */#define binder_proc_unlock(proc) _binder_proc_unlock(proc, __LINE__)static void_binder_proc_unlock(struct binder_proc *proc, int line)	__releases(&proc->outer_lock){	binder_debug(BINDER_DEBUG_SPINLOCKS,		     "%s: line=%d\n", __func__, line);	spin_unlock(&proc->outer_lock);} /** * binder_inner_proc_lock() - Acquire inner lock for given binder_proc * @proc:         struct binder_proc to acquire * * Acquires proc->inner_lock. Used to protect todo lists */#define binder_inner_proc_lock(proc) _binder_inner_proc_lock(proc, __LINE__)static void_binder_inner_proc_lock(struct binder_proc *proc, int line)	__acquires(&proc->inner_lock){	binder_debug(BINDER_DEBUG_SPINLOCKS,		     "%s: line=%d\n", __func__, line);	spin_lock(&proc->inner_lock);} /** * binder_inner_proc_unlock() - Release inner lock for given binder_proc * @proc:         struct binder_proc to acquire * * Release lock acquired via binder_inner_proc_lock() */#define binder_inner_proc_unlock(proc) _binder_inner_proc_unlock(proc, __LINE__)static void_binder_inner_proc_unlock(struct binder_proc *proc, int line)	__releases(&proc->inner_lock){	binder_debug(BINDER_DEBUG_SPINLOCKS,		     "%s: line=%d\n", __func__, line);	spin_unlock(&proc->inner_lock);} /** * binder_node_lock() - Acquire spinlock for given binder_node * @node:         struct binder_node to acquire * * Acquires node->lock. Used to protect binder_node fields */#define binder_node_lock(node) _binder_node_lock(node, __LINE__)static void_binder_node_lock(struct binder_node *node, int line)	__acquires(&node->lock){	binder_debug(BINDER_DEBUG_SPINLOCKS,		     "%s: line=%d\n", __func__, line);	spin_lock(&node->lock);} /** * binder_node_unlock() - Release spinlock for given binder_proc * @node:         struct binder_node to acquire * * Release lock acquired via binder_node_lock() */#define binder_node_unlock(node) _binder_node_unlock(node, __LINE__)static void_binder_node_unlock(struct binder_node *node, int line)	__releases(&node->lock){	binder_debug(BINDER_DEBUG_SPINLOCKS,		     "%s: line=%d\n", __func__, line);	spin_unlock(&node->lock);} /** * binder_node_inner_lock() - Acquire node and inner locks * @node:         struct binder_node to acquire * * Acquires node->lock. If node->proc also acquires * proc->inner_lock. Used to protect binder_node fields */#define binder_node_inner_lock(node) _binder_node_inner_lock(node, __LINE__)static void_binder_node_inner_lock(struct binder_node *node, int line)	__acquires(&node->lock) __acquires(&node->proc->inner_lock){	binder_debug(BINDER_DEBUG_SPINLOCKS,		     "%s: line=%d\n", __func__, line);	spin_lock(&node->lock);	if (node->proc)		binder_inner_proc_lock(node->proc);	else		/* annotation for sparse */		__acquire(&node->proc->inner_lock);} /** * binder_node_inner_unlock() - Release node and inner locks * @node:         struct binder_node to acquire * * Release lock acquired via binder_node_lock() */#define binder_node_inner_unlock(node) _binder_node_inner_unlock(node, __LINE__)static void_binder_node_inner_unlock(struct binder_node *node, int line)	__releases(&node->lock) __releases(&node->proc->inner_lock){	struct binder_proc *proc = node->proc; 	binder_debug(BINDER_DEBUG_SPINLOCKS,		     "%s: line=%d\n", __func__, line);	if (proc)		binder_inner_proc_unlock(proc);	else		/* annotation for sparse */		__release(&node->proc->inner_lock);	spin_unlock(&node->lock);} static bool binder_worklist_empty_ilocked(struct list_head *list){	return list_empty(list);} /** * binder_worklist_empty() - Check if no items on the work list * @proc:       binder_proc associated with list * @list:	list to check * * Return: true if there are no items on list, else false */static bool binder_worklist_empty(struct binder_proc *proc,				  struct list_head *list){	bool ret; 	binder_inner_proc_lock(proc);	ret = binder_worklist_empty_ilocked(list);	binder_inner_proc_unlock(proc);	return ret;} /** * binder_enqueue_work_ilocked() - Add an item to the work list * @work:         struct binder_work to add to list * @target_list:  list to add work to * * Adds the work to the specified list. Asserts that work * is not already on a list. * * Requires the proc->inner_lock to be held. */static voidbinder_enqueue_work_ilocked(struct binder_work *work,			   struct list_head *target_list){	BUG_ON(target_list == NULL);	BUG_ON(work->entry.next && !list_empty(&work->entry));	list_add_tail(&work->entry, target_list);} /** * binder_enqueue_deferred_thread_work_ilocked() - Add deferred thread work * @thread:       thread to queue work to * @work:         struct binder_work to add to list * * Adds the work to the todo list of the thread. Doesn't set the process_todo * flag, which means that (if it wasn't already set) the thread will go to * sleep without handling this work when it calls read. * * Requires the proc->inner_lock to be held. */static voidbinder_enqueue_deferred_thread_work_ilocked(struct binder_thread *thread,					    struct binder_work *work){	WARN_ON(!list_empty(&thread->waiting_thread_node));	binder_enqueue_work_ilocked(work, &thread->todo);} /** * binder_enqueue_thread_work_ilocked() - Add an item to the thread work list * @thread:       thread to queue work to * @work:         struct binder_work to add to list * * Adds the work to the todo list of the thread, and enables processing * of the todo queue. * * Requires the proc->inner_lock to be held. */static voidbinder_enqueue_thread_work_ilocked(struct binder_thread *thread,				   struct binder_work *work){	WARN_ON(!list_empty(&thread->waiting_thread_node));	binder_enqueue_work_ilocked(work, &thread->todo); 	/* (e)poll-based threads require an explicit wakeup signal when	 * queuing their own work; they rely on these events to consume	 * messages without I/O block. Without it, threads risk waiting	 * indefinitely without handling the work.	 */	if (thread->looper & BINDER_LOOPER_STATE_POLL &&	    thread->pid == current->pid && !thread->process_todo)		wake_up_interruptible_sync(&thread->wait); 	thread->process_todo = true;} /** * binder_enqueue_thread_work() - Add an item to the thread work list

Lines 1–500 of 7186.