From 7feb35bc16203c06362c31b95d0d2f291c0212d5 Mon Sep 17 00:00:00 2001 From: "Jiazi.Li" Date: Tue, 15 Nov 2022 20:03:51 +0800 Subject: binder: remove unneeded size check code In binder_ioctl function, the legitimacy check of cmd size has been done in switch-case code: switch (cmd) { case BINDER_WRITE_READ;//BINDER_WRITE_READ contains size info So unneeded do size check in binder_ioctl and binder_ioctl_write_read again. In the following version of Google GKI: Linux version 5.10.110-android12-9-00011-g2c814f559132-ab8969555 It seems that the compiler has made optimization and has not passed cmd parameters to binder_ioctl_write_read: : mov w8, #0x6201 // #25089 : movk w8, #0xc030, lsl #16 : cmp w20, w8 : b.ne 0xffffffda8aa97880 : mov x0, x23 //filp : mov x1, x27 //arg : mov x2, x22 //thread : bl 0xffffffda8aa9e6e4 : mov w26, w0 Signed-off-by: Jiazi.Li Acked-by: Carlos Llamas Link: https://lore.kernel.org/r/20221115120351.2769-1-jiazi.li@transsion.com Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'drivers/android') diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 880224ec6abb..48e5a3531282 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -5006,20 +5006,14 @@ static __poll_t binder_poll(struct file *filp, return 0; } -static int binder_ioctl_write_read(struct file *filp, - unsigned int cmd, unsigned long arg, +static int binder_ioctl_write_read(struct file *filp, unsigned long arg, struct binder_thread *thread) { int ret = 0; struct binder_proc *proc = filp->private_data; - unsigned int size = _IOC_SIZE(cmd); void __user *ubuf = (void __user *)arg; struct binder_write_read bwr; - if (size != sizeof(struct binder_write_read)) { - ret = -EINVAL; - goto out; - } if (copy_from_user(&bwr, ubuf, sizeof(bwr))) { ret = -EFAULT; goto out; @@ -5296,7 +5290,6 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) int ret; struct binder_proc *proc = filp->private_data; struct binder_thread *thread; - unsigned int size = _IOC_SIZE(cmd); void __user *ubuf = (void __user *)arg; /*pr_info("binder_ioctl: %d:%d %x %lx\n", @@ -5318,7 +5311,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) switch (cmd) { case BINDER_WRITE_READ: - ret = binder_ioctl_write_read(filp, cmd, arg, thread); + ret = binder_ioctl_write_read(filp, arg, thread); if (ret) goto err; break; @@ -5361,10 +5354,6 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) case BINDER_VERSION: { struct binder_version __user *ver = ubuf; - if (size != sizeof(struct binder_version)) { - ret = -EINVAL; - goto err; - } if (put_user(BINDER_CURRENT_PROTOCOL_VERSION, &ver->protocol_version)) { ret = -EINVAL; -- cgit v1.2.3 From 0567461a7a6ecb12692e3bbb97e86ff9d39a2837 Mon Sep 17 00:00:00 2001 From: Li Li Date: Wed, 23 Nov 2022 12:16:54 -0800 Subject: binder: return pending info for frozen async txns An async transaction to a frozen process will still be successfully put in the queue. But this pending async transaction won't be processed until the target process is unfrozen at an unspecified time in the future. Pass this important information back to the user space caller by returning BR_TRANSACTION_PENDING_FROZEN. Signed-off-by: Li Li Acked-by: Carlos Llamas Link: https://lore.kernel.org/r/20221123201654.589322-2-dualli@chromium.org Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder.c | 32 ++++++++++++++++++++++++++------ drivers/android/binder_internal.h | 3 ++- 2 files changed, 28 insertions(+), 7 deletions(-) (limited to 'drivers/android') diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 48e5a3531282..a73df6b6c127 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2728,7 +2728,10 @@ binder_find_outdated_transaction_ilocked(struct binder_transaction *t, * * Return: 0 if the transaction was successfully queued * BR_DEAD_REPLY if the target process or thread is dead - * BR_FROZEN_REPLY if the target process or thread is frozen + * BR_FROZEN_REPLY if the target process or thread is frozen and + * the sync transaction was rejected + * BR_TRANSACTION_PENDING_FROZEN if the target process is frozen + * and the async transaction was successfully queued */ static int binder_proc_transaction(struct binder_transaction *t, struct binder_proc *proc, @@ -2738,6 +2741,7 @@ static int binder_proc_transaction(struct binder_transaction *t, bool oneway = !!(t->flags & TF_ONE_WAY); bool pending_async = false; struct binder_transaction *t_outdated = NULL; + bool frozen = false; BUG_ON(!node); binder_node_lock(node); @@ -2751,15 +2755,16 @@ static int binder_proc_transaction(struct binder_transaction *t, binder_inner_proc_lock(proc); if (proc->is_frozen) { + frozen = true; proc->sync_recv |= !oneway; proc->async_recv |= oneway; } - if ((proc->is_frozen && !oneway) || proc->is_dead || + if ((frozen && !oneway) || proc->is_dead || (thread && thread->is_dead)) { binder_inner_proc_unlock(proc); binder_node_unlock(node); - return proc->is_frozen ? BR_FROZEN_REPLY : BR_DEAD_REPLY; + return frozen ? BR_FROZEN_REPLY : BR_DEAD_REPLY; } if (!thread && !pending_async) @@ -2770,7 +2775,7 @@ static int binder_proc_transaction(struct binder_transaction *t, } else if (!pending_async) { binder_enqueue_work_ilocked(&t->work, &proc->todo); } else { - if ((t->flags & TF_UPDATE_TXN) && proc->is_frozen) { + if ((t->flags & TF_UPDATE_TXN) && frozen) { t_outdated = binder_find_outdated_transaction_ilocked(t, &node->async_todo); if (t_outdated) { @@ -2807,6 +2812,9 @@ static int binder_proc_transaction(struct binder_transaction *t, binder_stats_deleted(BINDER_STAT_TRANSACTION); } + if (oneway && frozen) + return BR_TRANSACTION_PENDING_FROZEN; + return 0; } @@ -3607,9 +3615,17 @@ static void binder_transaction(struct binder_proc *proc, } else { BUG_ON(target_node == NULL); BUG_ON(t->buffer->async_transaction != 1); - binder_enqueue_thread_work(thread, tcomplete); return_error = binder_proc_transaction(t, target_proc, NULL); - if (return_error) + /* + * Let the caller know when async transaction reaches a frozen + * process and is put in a pending queue, waiting for the target + * process to be unfrozen. + */ + if (return_error == BR_TRANSACTION_PENDING_FROZEN) + tcomplete->type = BINDER_WORK_TRANSACTION_PENDING; + binder_enqueue_thread_work(thread, tcomplete); + if (return_error && + return_error != BR_TRANSACTION_PENDING_FROZEN) goto err_dead_proc_or_thread; } if (target_thread) @@ -4440,10 +4456,13 @@ retry: binder_stat_br(proc, thread, cmd); } break; case BINDER_WORK_TRANSACTION_COMPLETE: + case BINDER_WORK_TRANSACTION_PENDING: case BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT: { if (proc->oneway_spam_detection_enabled && w->type == BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT) cmd = BR_ONEWAY_SPAM_SUSPECT; + else if (w->type == BINDER_WORK_TRANSACTION_PENDING) + cmd = BR_TRANSACTION_PENDING_FROZEN; else cmd = BR_TRANSACTION_COMPLETE; binder_inner_proc_unlock(proc); @@ -6159,6 +6178,7 @@ static const char * const binder_return_strings[] = { "BR_FAILED_REPLY", "BR_FROZEN_REPLY", "BR_ONEWAY_SPAM_SUSPECT", + "BR_TRANSACTION_PENDING_FROZEN" }; static const char * const binder_command_strings[] = { diff --git a/drivers/android/binder_internal.h b/drivers/android/binder_internal.h index abe19d88c6ec..28ef5b3704b1 100644 --- a/drivers/android/binder_internal.h +++ b/drivers/android/binder_internal.h @@ -133,7 +133,7 @@ enum binder_stat_types { }; struct binder_stats { - atomic_t br[_IOC_NR(BR_ONEWAY_SPAM_SUSPECT) + 1]; + atomic_t br[_IOC_NR(BR_TRANSACTION_PENDING_FROZEN) + 1]; atomic_t bc[_IOC_NR(BC_REPLY_SG) + 1]; atomic_t obj_created[BINDER_STAT_COUNT]; atomic_t obj_deleted[BINDER_STAT_COUNT]; @@ -152,6 +152,7 @@ struct binder_work { enum binder_work_type { BINDER_WORK_TRANSACTION = 1, BINDER_WORK_TRANSACTION_COMPLETE, + BINDER_WORK_TRANSACTION_PENDING, BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT, BINDER_WORK_RETURN_ERROR, BINDER_WORK_NODE, -- cgit v1.2.3 From ad228a3468d17257a112f0d50e06ff0851667210 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 17 Jan 2023 10:37:45 -0800 Subject: android: fix W=1 kernel-doc warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean up kernel-doc notation, use correct function and parameter names. drivers/android/binderfs.c:236: warning: expecting prototype for binderfs_ctl_ioctl(). Prototype was for binder_ctl_ioctl() instead drivers/android/binder.c:386: warning: expecting prototype for binder_node_unlock(). Prototype was for binder_node_inner_unlock() instead drivers/android/binder.c:1206: warning: expecting prototype for binder_dec_ref(). Prototype was for binder_dec_ref_olocked() instead drivers/andrond/binder.c:284: warning: Excess function parameter 'proc' description in 'binder_proc_unlock' drivers/andrond/binder.c:387: warning: expecting prototype for binder_node_unlock(). Prototype was for binder_node_inner_unlock() instead Signed-off-by: Randy Dunlap Cc: Greg Kroah-Hartman Cc: Arve Hjønnevåg Cc: Todd Kjos Cc: Martijn Coenen Cc: Joel Fernandes Cc: Christian Brauner Cc: Carlos Llamas Cc: Suren Baghdasaryan Acked-by: Carlos Llamas Link: https://lore.kernel.org/r/20230117183745.20842-1-rdunlap@infradead.org Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder.c | 18 +++++++++--------- drivers/android/binderfs.c | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/android') diff --git a/drivers/android/binder.c b/drivers/android/binder.c index a73df6b6c127..ca3034afd1dc 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -277,11 +277,11 @@ _binder_proc_lock(struct binder_proc *proc, int line) /** * binder_proc_unlock() - Release spinlock for given binder_proc - * @proc: struct binder_proc to acquire + * @proc: struct binder_proc to acquire * * Release lock acquired via binder_proc_lock() */ -#define binder_proc_unlock(_proc) _binder_proc_unlock(_proc, __LINE__) +#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) @@ -378,7 +378,7 @@ _binder_node_inner_lock(struct binder_node *node, int line) } /** - * binder_node_unlock() - Release node and inner locks + * binder_node_inner_unlock() - Release node and inner locks * @node: struct binder_node to acquire * * Release lock acquired via binder_node_lock() @@ -1194,13 +1194,13 @@ static int binder_inc_ref_olocked(struct binder_ref *ref, int strong, } /** - * binder_dec_ref() - dec the ref for given handle + * binder_dec_ref_olocked() - dec the ref for given handle * @ref: ref to be decremented * @strong: if true, strong decrement, else weak * * Decrement the ref. * - * Return: true if ref is cleaned up and ready to be freed + * Return: %true if ref is cleaned up and ready to be freed. */ static bool binder_dec_ref_olocked(struct binder_ref *ref, int strong) { @@ -2821,8 +2821,8 @@ static int binder_proc_transaction(struct binder_transaction *t, /** * binder_get_node_refs_for_txn() - Get required refs on node for txn * @node: struct binder_node for which to get refs - * @proc: returns @node->proc if valid - * @error: if no @proc then returns BR_DEAD_REPLY + * @procp: returns @node->proc if valid + * @error: if no @procp then returns BR_DEAD_REPLY * * User-space normally keeps the node alive when creating a transaction * since it has a reference to the target. The local strong ref keeps it @@ -2836,8 +2836,8 @@ static int binder_proc_transaction(struct binder_transaction *t, * constructing the transaction, so we take that here as well. * * Return: The target_node with refs taken or NULL if no @node->proc is NULL. - * Also sets @proc if valid. If the @node->proc is NULL indicating that the - * target proc has died, @error is set to BR_DEAD_REPLY + * Also sets @procp if valid. If the @node->proc is NULL indicating that the + * target proc has died, @error is set to BR_DEAD_REPLY. */ static struct binder_node *binder_get_node_refs_for_txn( struct binder_node *node, diff --git a/drivers/android/binderfs.c b/drivers/android/binderfs.c index 09b2ce7e4c34..abb9c0980afb 100644 --- a/drivers/android/binderfs.c +++ b/drivers/android/binderfs.c @@ -222,14 +222,14 @@ err: } /** - * binderfs_ctl_ioctl - handle binder device node allocation requests + * binder_ctl_ioctl - handle binder device node allocation requests * * The request handler for the binder-control device. All requests operate on * the binderfs mount the binder-control device resides in: * - BINDER_CTL_ADD * Allocate a new binder device. * - * Return: 0 on success, negative errno on failure + * Return: %0 on success, negative errno on failure. */ static long binder_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -- cgit v1.2.3