On Thu, Sep 26, 2024 at 4:36 PM Carlos Llamas <cmllamas@xxxxxxxxxx> wrote: > > Alice points out that binder_request_freeze_notification() should not > return EINVAL when the relevant node is dead [1]. The node can die at > any point even if the user input is valid. Instead, allow the request > to be allocated but skip the initial notification for dead nodes. This > avoids propagating unnecessary errors back to userspace. > > Fixes: d579b04a52a1 ("binder: frozen notification") > Cc: stable@xxxxxxxxxxxxxxx > Suggested-by: Alice Ryhl <aliceryhl@xxxxxxxxxx> > Link: https://lore.kernel.org/all/CAH5fLghapZJ4PbbkC8V5A6Zay-_sgTzwVpwqk6RWWUNKKyJC_Q@xxxxxxxxxxxxxx/ [1] > Signed-off-by: Carlos Llamas <cmllamas@xxxxxxxxxx> Acked-by: Todd Kjos <tkjos@xxxxxxxxxx> > --- > drivers/android/binder.c | 28 +++++++++++++--------------- > 1 file changed, 13 insertions(+), 15 deletions(-) > > diff --git a/drivers/android/binder.c b/drivers/android/binder.c > index 73dc6cbc1681..415fc9759249 100644 > --- a/drivers/android/binder.c > +++ b/drivers/android/binder.c > @@ -3856,7 +3856,6 @@ binder_request_freeze_notification(struct binder_proc *proc, > { > struct binder_ref_freeze *freeze; > struct binder_ref *ref; > - bool is_frozen; > > freeze = kzalloc(sizeof(*freeze), GFP_KERNEL); > if (!freeze) > @@ -3872,32 +3871,31 @@ binder_request_freeze_notification(struct binder_proc *proc, > } > > binder_node_lock(ref->node); > - > - if (ref->freeze || !ref->node->proc) { > - binder_user_error("%d:%d invalid BC_REQUEST_FREEZE_NOTIFICATION %s\n", > - proc->pid, thread->pid, > - ref->freeze ? "already set" : "dead node"); > + if (ref->freeze) { > + binder_user_error("%d:%d BC_REQUEST_FREEZE_NOTIFICATION already set\n", > + proc->pid, thread->pid); > binder_node_unlock(ref->node); > binder_proc_unlock(proc); > kfree(freeze); > return -EINVAL; > } > - binder_inner_proc_lock(ref->node->proc); > - is_frozen = ref->node->proc->is_frozen; > - binder_inner_proc_unlock(ref->node->proc); > > binder_stats_created(BINDER_STAT_FREEZE); > INIT_LIST_HEAD(&freeze->work.entry); > freeze->cookie = handle_cookie->cookie; > freeze->work.type = BINDER_WORK_FROZEN_BINDER; > - freeze->is_frozen = is_frozen; > - > ref->freeze = freeze; > > - binder_inner_proc_lock(proc); > - binder_enqueue_work_ilocked(&ref->freeze->work, &proc->todo); > - binder_wakeup_proc_ilocked(proc); > - binder_inner_proc_unlock(proc); > + if (ref->node->proc) { > + binder_inner_proc_lock(ref->node->proc); > + freeze->is_frozen = ref->node->proc->is_frozen; > + binder_inner_proc_unlock(ref->node->proc); > + > + binder_inner_proc_lock(proc); > + binder_enqueue_work_ilocked(&freeze->work, &proc->todo); > + binder_wakeup_proc_ilocked(proc); > + binder_inner_proc_unlock(proc); > + } > > binder_node_unlock(ref->node); > binder_proc_unlock(proc); > -- > 2.46.1.824.gd892dcdcdd-goog >