On Fri, Sep 27, 2024 at 12:19 AM Alice Ryhl <aliceryhl@xxxxxxxxxx> wrote: > > On Fri, Sep 27, 2024 at 1:37 AM 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> > > --- > > 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); > > This is not a problem with your change ... but, why exactly are we > scheduling the BINDER_WORK_FROZEN_BINDER right after creating it? For > death notications, we only schedule it immediately if the process is > dead. So shouldn't we only schedule it if the process is not frozen? > > And if the answer is that frozen notifications are always sent > immediately to notify about the current state, then we should also > send one for a dead process ... maybe. I guess a dead process is not > frozen? Yes this is to immediately notify about the current state (frozen or unfrozen). A dead process is in neither state so it feels more correct not to send either? > > > + } > > > > binder_node_unlock(ref->node); > > binder_proc_unlock(proc); > > -- > > 2.46.1.824.gd892dcdcdd-goog > >