[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v6 1/1] audio/jack: fix use after free segfault
From: |
Geoffrey McRae |
Subject: |
[PATCH v6 1/1] audio/jack: fix use after free segfault |
Date: |
Thu, 20 Aug 2020 10:25:15 +1000 |
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>
---
audio/jackaudio.c | 51 +++++++++++++++++++++++++++++++++--------------
ui/spice-input.c | 2 ++
2 files changed, 38 insertions(+), 15 deletions(-)
diff --git a/audio/jackaudio.c b/audio/jackaudio.c
index 72ed7c4929..3492c6b63b 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;
+ 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,7 @@ static int qjack_client_init(QJackClient *c)
options |= JackServerName;
}
+ c->shutdown_bh = qemu_bh_new(qjack_shutdown_bh, c);
c->client = jack_client_open(client_name, options, &status,
c->opt->server_name);
@@ -489,8 +498,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 +532,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;
@@ -563,29 +568,45 @@ static void qjack_client_fini(QJackClient *c)
/* fallthrough */
case QJACK_STATE_SHUTDOWN:
+ qemu_bh_delete(c->shutdown_bh);
+ c->shutdown_bh = NULL;
+
jack_client_close(c->client);
+ c->client = NULL;
+
+ qjack_buffer_free(&c->fifo);
+ g_free(c->port);
+
+ c->state = QJACK_STATE_DISCONNECTED;
/* fallthrough */
case QJACK_STATE_DISCONNECTED:
break;
}
-
- qjack_buffer_free(&c->fifo);
- g_free(c->port);
-
- c->state = QJACK_STATE_DISCONNECTED;
}
static void qjack_fini_out(HWVoiceOut *hw)
{
QJackOut *jo = (QJackOut *)hw;
- qjack_client_fini(&jo->c);
+
+ qemu_mutex_lock_iothread();
+ if (jo->c.state != QJACK_STATE_DISCONNECTED) {
+ qemu_bh_cancel(jo->c.shutdown_bh);
+ qjack_client_fini(&jo->c);
+ }
+ qemu_mutex_unlock_iothread();
}
static void qjack_fini_in(HWVoiceIn *hw)
{
QJackIn *ji = (QJackIn *)hw;
- qjack_client_fini(&ji->c);
+
+ qemu_mutex_lock_iothread();
+ if (ji->c.state != QJACK_STATE_DISCONNECTED) {
+ qemu_bh_cancel(ji->c.shutdown_bh);
+ qjack_client_fini(&ji->c);
+ }
+ qemu_mutex_unlock_iothread();
}
static void qjack_enable_out(HWVoiceOut *hw, bool enable)
diff --git a/ui/spice-input.c b/ui/spice-input.c
index cd4bb0043f..82c74fdf58 100644
--- a/ui/spice-input.c
+++ b/ui/spice-input.c
@@ -123,6 +123,8 @@ static void spice_update_buttons(QemuSpicePointer *pointer,
[INPUT_BUTTON_RIGHT] = 0x02,
[INPUT_BUTTON_WHEEL_UP] = 0x10,
[INPUT_BUTTON_WHEEL_DOWN] = 0x20,
+ [INPUT_BUTTON_SIDE] = 0x40,
+ [INPUT_BUTTON_EXTRA] = 0x80
};
if (wheel < 0) {
--
2.20.1