FROMGIT: binder: allow freeze notification for dead nodes
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@vger.kernel.org Suggested-by: Alice Ryhl <aliceryhl@google.com> Link: https://lore.kernel.org/all/CAH5fLghapZJ4PbbkC8V5A6Zay-_sgTzwVpwqk6RWWUNKKyJC_Q@mail.gmail.com/ [1] Signed-off-by: Carlos Llamas <cmllamas@google.com> Acked-by: Todd Kjos <tkjos@google.com> Link: https://lore.kernel.org/r/20240926233632.821189-7-cmllamas@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Bug: 366003708 (cherry picked from commit ca63c66935b978441055e3d87d30225267f99329 git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git char-misc-next) Change-Id: I03af1eedfeb194f5a775388cbb4e7487e4a5dfc0 Signed-off-by: Carlos Llamas <cmllamas@google.com>
This commit is contained in:
parent
9b5b1ffec3
commit
90e90ed13c
1 changed files with 13 additions and 15 deletions
|
@ -3950,7 +3950,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)
|
||||
|
@ -3966,31 +3965,30 @@ 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);
|
||||
|
||||
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;
|
||||
|
||||
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(&ref->freeze->work, &proc->todo);
|
||||
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);
|
||||
|
|
Loading…
Add table
Reference in a new issue