qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Geoffrey McRae <geoff@hostfission.com>
To: Christian Schoenebeck <qemu_oss@crudebyte.com>
Cc: qemu-devel@nongnu.org, kraxel@redhat.com
Subject: Re: [PATCH v5 1/1] audio/jack: fix use after free segfault
Date: Thu, 20 Aug 2020 01:27:13 +1000	[thread overview]
Message-ID: <7fca183cc66cf07f6ba72eabea8a44cf@hostfission.com> (raw)
In-Reply-To: <5029913.bOW1W81TKx@silver>



On 2020-08-20 01:21, Christian Schoenebeck wrote:
> On Mittwoch, 19. August 2020 08:29:39 CEST Geoffrey McRae wrote:
>> This change registers a bottom handler to close the JACK client
>> connection when a server shutdown signal is recieved. Without this
>> libjack2 attempts to "clean up" old clients and causes a use after 
>> free
>> segfault.
>> 
>> Signed-off-by: Geoffrey McRae <geoff@hostfission.com>
>> ---
> 
> Looks much better now, but ...
> 
>>  audio/jackaudio.c | 29 ++++++++++++++++++++---------
>>  1 file changed, 20 insertions(+), 9 deletions(-)
>> 
>> diff --git a/audio/jackaudio.c b/audio/jackaudio.c
>> index 72ed7c4929..b0da5cd00b 100644
>> --- a/audio/jackaudio.c
>> +++ b/audio/jackaudio.c
>> @@ -25,6 +25,7 @@
>>  #include "qemu/osdep.h"
>>  #include "qemu/module.h"
>>  #include "qemu/atomic.h"
>> +#include "qemu/main-loop.h"
>>  #include "qemu-common.h"
>>  #include "audio.h"
>> 
>> @@ -63,6 +64,7 @@ typedef struct QJackClient {
>>      QJackState      state;
>>      jack_client_t  *client;
>>      jack_nframes_t  freq;
>> +    QEMUBH         *shutdown_bh;
>> 
>>      struct QJack   *j;
>>      int             nchannels;
>> @@ -306,21 +308,27 @@ static int qjack_xrun(void *arg)
>>      return 0;
>>  }
>> 
>> +static void qjack_shutdown_bh(void *opaque)
>> +{
>> +    QJackClient *c = (QJackClient *)opaque;
>> +    qjack_client_fini(c);
>> +}
>> +
>>  static void qjack_shutdown(void *arg)
>>  {
>>      QJackClient *c = (QJackClient *)arg;
>> -    c->state = QJACK_STATE_SHUTDOWN;
>> +    c->state       = QJACK_STATE_SHUTDOWN;
> 
> White space changes are not much embraced on high traffic projects BTW.

This change is unintentional and was missed in the rollback from the 
prior patch version.

> 
>> +    qemu_bh_schedule(c->shutdown_bh);
>>  }
>> 
>>  static void qjack_client_recover(QJackClient *c)
>>  {
>> -    if (c->state == QJACK_STATE_SHUTDOWN) {
>> -        qjack_client_fini(c);
>> +    if (c->state != QJACK_STATE_DISCONNECTED) {
>> +        return;
>>      }
>> 
>>      /* packets is used simply to throttle this */
>> -    if (c->state == QJACK_STATE_DISCONNECTED &&
>> -        c->packets % 100 == 0) {
>> +    if (c->packets % 100 == 0) {
>> 
>>          /* if enabled then attempt to recover */
>>          if (c->enabled) {
>> @@ -417,6 +425,10 @@ static int qjack_client_init(QJackClient *c)
>>          options |= JackServerName;
>>      }
>> 
>> +    if (!c->shutdown_bh) {
>> +        c->shutdown_bh = qemu_bh_new(qjack_shutdown_bh, c);
>> +    }
>> +
> 
> Where is qemu_bh_delete() ?

Whoops... I will correct this :)

> 
>>      c->client = jack_client_open(client_name, options, &status,
>>        c->opt->server_name);
>> 
>> @@ -489,8 +501,6 @@ static int qjack_init_out(HWVoiceOut *hw, struct
>> audsettings *as, QJackOut *jo  = (QJackOut *)hw;
>>      Audiodev *dev = (Audiodev *)drv_opaque;
>> 
>> -    qjack_client_fini(&jo->c);
>> -
>>      jo->c.out       = true;
>>      jo->c.enabled   = false;
>>      jo->c.nchannels = as->nchannels;
>> @@ -525,8 +535,6 @@ static int qjack_init_in(HWVoiceIn *hw, struct
>> audsettings *as, QJackIn  *ji  = (QJackIn *)hw;
>>      Audiodev *dev = (Audiodev *)drv_opaque;
>> 
>> -    qjack_client_fini(&ji->c);
>> -
>>      ji->c.out       = false;
>>      ji->c.enabled   = false;
>>      ji->c.nchannels = as->nchannels;
>> @@ -557,6 +565,8 @@ static int qjack_init_in(HWVoiceIn *hw, struct
>> audsettings *as,
>> 
>>  static void qjack_client_fini(QJackClient *c)
>>  {
>> +    qemu_bh_cancel(c->shutdown_bh);
>> +
> 
> Looks like a potential race. Quote from the API doc of 
> qemu_bh_cancel():
> 
> 	"While cancellation itself is also wait-free and thread-safe, it can 
> of
> 	course race with the loop that executes bottom halves unless you are
> 	holding the iothread mutex.  This makes it mostly useless if you are 
> not
> 	holding the mutex."
> 

Noted. How does one go about holding the iothread mutex?

>>      switch (c->state) {
>>      case QJACK_STATE_RUNNING:
>>          jack_deactivate(c->client);
>> @@ -564,6 +574,7 @@ static void qjack_client_fini(QJackClient *c)
>> 
>>      case QJACK_STATE_SHUTDOWN:
>>          jack_client_close(c->client);
>> +        c->client = NULL;
>>          /* fallthrough */
>> 
>>      case QJACK_STATE_DISCONNECTED:
> 
> Best regards,
> Christian Schoenebeck


  reply	other threads:[~2020-08-19 15:28 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-19  6:29 [PATCH v5 0/1] audio/jack: fix use after free segfault Geoffrey McRae
2020-08-19  6:29 ` [PATCH v5 1/1] " Geoffrey McRae
2020-08-19 15:21   ` Christian Schoenebeck
2020-08-19 15:27     ` Geoffrey McRae [this message]
2020-08-20  5:37     ` Gerd Hoffmann
2020-08-20 10:06       ` Christian Schoenebeck
2020-08-20 10:54         ` Paolo Bonzini
2020-08-20 12:00           ` Christian Schoenebeck
2020-08-21 13:13             ` Paolo Bonzini
2020-08-26 13:48               ` PTHREAD_MUTEX_ERRORCHECK and fork() Christian Schoenebeck
2020-08-21 11:12           ` recursive locks (in general) Christian Schoenebeck
2020-08-21 13:08             ` Paolo Bonzini
2020-08-21 15:25               ` Christian Schoenebeck
2020-08-21 11:28           ` [PATCH v5 1/1] audio/jack: fix use after free segfault Geoffrey McRae
2020-08-21 13:13             ` Paolo Bonzini

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=7fca183cc66cf07f6ba72eabea8a44cf@hostfission.com \
    --to=geoff@hostfission.com \
    --cc=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu_oss@crudebyte.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).