All of lore.kernel.org
 help / color / mirror / Atom feed
From: Todd Kjos <tkjos@google.com>
To: Martijn Coenen <maco@android.com>
Cc: "Greg KH" <gregkh@linuxfoundation.org>,
	"Christian Brauner" <christian@brauner.io>,
	"Arve Hjønnevåg" <arve@android.com>,
	"open list:ANDROID DRIVERS" <devel@driverdev.osuosl.org>,
	LKML <linux-kernel@vger.kernel.org>,
	"Martijn Coenen" <maco@google.com>,
	"Joel Fernandes" <joel@joelfernandes.org>,
	kernel-team@android.com, stable <stable@vger.kernel.org>
Subject: Re: [PATCH] binder: make sure fd closes complete
Date: Thu, 2 Sep 2021 08:35:35 -0700	[thread overview]
Message-ID: <CAHRSSExONtUFu0Mb8uJeVKcyDYb8=1PO7a=aQ=DUEpA5kAcTQA@mail.gmail.com> (raw)
In-Reply-To: <CAB0TPYFmUgPTONABLTJAdonK7fY7oqURKCpLp1-WqHLtyen7Zw@mail.gmail.com>

On Tue, Aug 31, 2021 at 12:24 AM Martijn Coenen <maco@android.com> wrote:
>
> On Mon, Aug 30, 2021 at 9:51 PM 'Todd Kjos' via kernel-team
> <kernel-team@android.com> wrote:
> >
> > During BC_FREE_BUFFER processing, the BINDER_TYPE_FDA object
> > cleanup may close 1 or more fds. The close operations are
> > completed using the task work mechanism -- which means the thread
> > needs to return to userspace or the file object may never be
> > dereferenced -- which can lead to hung processes.
> >
> > Force the binder thread back to userspace if an fd is closed during
> > BC_FREE_BUFFER handling.
> >
> > Signed-off-by: Todd Kjos <tkjos@google.com>
> Reviewed-by: Martijn Coenen <maco@android.com>

Please also add to stable releases 5.4 and later.

>
> > ---
> >  drivers/android/binder.c | 23 +++++++++++++++++------
> >  1 file changed, 17 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/android/binder.c b/drivers/android/binder.c
> > index bcec598b89f2..c2823f0d588f 100644
> > --- a/drivers/android/binder.c
> > +++ b/drivers/android/binder.c
> > @@ -1852,6 +1852,7 @@ static void binder_deferred_fd_close(int fd)
> >  }
> >
> >  static void binder_transaction_buffer_release(struct binder_proc *proc,
> > +                                             struct binder_thread *thread,
> >                                               struct binder_buffer *buffer,
> >                                               binder_size_t failed_at,
> >                                               bool is_failure)
> > @@ -2011,8 +2012,16 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
> >                                                 &proc->alloc, &fd, buffer,
> >                                                 offset, sizeof(fd));
> >                                 WARN_ON(err);
> > -                               if (!err)
> > +                               if (!err) {
> >                                         binder_deferred_fd_close(fd);
> > +                                       /*
> > +                                        * Need to make sure the thread goes
> > +                                        * back to userspace to complete the
> > +                                        * deferred close
> > +                                        */
> > +                                       if (thread)
> > +                                               thread->looper_need_return = true;
> > +                               }
> >                         }
> >                 } break;
> >                 default:
> > @@ -3105,7 +3114,7 @@ static void binder_transaction(struct binder_proc *proc,
> >  err_copy_data_failed:
> >         binder_free_txn_fixups(t);
> >         trace_binder_transaction_failed_buffer_release(t->buffer);
> > -       binder_transaction_buffer_release(target_proc, t->buffer,
> > +       binder_transaction_buffer_release(target_proc, NULL, t->buffer,
> >                                           buffer_offset, true);
> >         if (target_node)
> >                 binder_dec_node_tmpref(target_node);
> > @@ -3184,7 +3193,9 @@ static void binder_transaction(struct binder_proc *proc,
> >   * Cleanup buffer and free it.
> >   */
> >  static void
> > -binder_free_buf(struct binder_proc *proc, struct binder_buffer *buffer)
> > +binder_free_buf(struct binder_proc *proc,
> > +               struct binder_thread *thread,
> > +               struct binder_buffer *buffer)
> >  {
> >         binder_inner_proc_lock(proc);
> >         if (buffer->transaction) {
> > @@ -3212,7 +3223,7 @@ binder_free_buf(struct binder_proc *proc, struct binder_buffer *buffer)
> >                 binder_node_inner_unlock(buf_node);
> >         }
> >         trace_binder_transaction_buffer_release(buffer);
> > -       binder_transaction_buffer_release(proc, buffer, 0, false);
> > +       binder_transaction_buffer_release(proc, thread, buffer, 0, false);
> >         binder_alloc_free_buf(&proc->alloc, buffer);
> >  }
> >
> > @@ -3414,7 +3425,7 @@ static int binder_thread_write(struct binder_proc *proc,
> >                                      proc->pid, thread->pid, (u64)data_ptr,
> >                                      buffer->debug_id,
> >                                      buffer->transaction ? "active" : "finished");
> > -                       binder_free_buf(proc, buffer);
> > +                       binder_free_buf(proc, thread, buffer);
> >                         break;
> >                 }
> >
> > @@ -4107,7 +4118,7 @@ static int binder_thread_read(struct binder_proc *proc,
> >                         buffer->transaction = NULL;
> >                         binder_cleanup_transaction(t, "fd fixups failed",
> >                                                    BR_FAILED_REPLY);
> > -                       binder_free_buf(proc, buffer);
> > +                       binder_free_buf(proc, thread, buffer);
> >                         binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
> >                                      "%d:%d %stransaction %d fd fixups failed %d/%d, line %d\n",
> >                                      proc->pid, thread->pid,
> > --
> > 2.33.0.259.gc128427fd7-goog
> >
> >

  reply	other threads:[~2021-09-02 15:35 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-30 19:51 [PATCH] binder: make sure fd closes complete Todd Kjos
2021-08-31  7:24 ` Christian Brauner
2021-08-31  7:24 ` Martijn Coenen
2021-09-02 15:35   ` Todd Kjos [this message]
2021-09-02 16:11     ` Greg KH
2021-09-03  8:06     ` Dan Carpenter
2021-09-03 19:38       ` Todd Kjos
2021-09-14  7:01         ` Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAHRSSExONtUFu0Mb8uJeVKcyDYb8=1PO7a=aQ=DUEpA5kAcTQA@mail.gmail.com' \
    --to=tkjos@google.com \
    --cc=arve@android.com \
    --cc=christian@brauner.io \
    --cc=devel@driverdev.osuosl.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=joel@joelfernandes.org \
    --cc=kernel-team@android.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maco@android.com \
    --cc=maco@google.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.