diff --git a/0035-pstream-Don-t-split-non-SHM-memblocks.patch b/0035-pstream-Don-t-split-non-SHM-memblocks.patch new file mode 100644 index 0000000..abb95fd --- /dev/null +++ b/0035-pstream-Don-t-split-non-SHM-memblocks.patch @@ -0,0 +1,104 @@ +From 7b8e8cd3883e081a6e3f2d8ed307524801438e04 Mon Sep 17 00:00:00 2001 +From: David Henningsson +Date: Thu, 5 Mar 2015 14:55:51 +0100 +Subject: [PATCH 035/118] pstream: Don't split (non-SHM) memblocks + +In case SHM is full or disabled, audio data is sent through the +io/srbchannel. When this channel in turn gets full, memblocks +could previously be split up. This could lead to crashes in case +the split was on non-frame boundaries (in combination with full +memblock queues). + +BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=88452 +Signed-off-by: David Henningsson +--- + src/pulsecore/pstream.c | 61 ++++++++++++++++++++----------------------------- + 1 file changed, 25 insertions(+), 36 deletions(-) + +diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c +index b0ed5a7..877ff66 100644 +--- a/src/pulsecore/pstream.c ++++ b/src/pulsecore/pstream.c +@@ -682,6 +682,30 @@ fail: + return -1; + } + ++static void memblock_complete(pa_pstream *p, struct pstream_read *re) { ++ pa_memchunk chunk; ++ int64_t offset; ++ ++ if (!p->receive_memblock_callback) ++ return; ++ ++ chunk.memblock = re->memblock; ++ chunk.index = 0; ++ chunk.length = re->index - PA_PSTREAM_DESCRIPTOR_SIZE; ++ ++ offset = (int64_t) ( ++ (((uint64_t) ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI])) << 32) | ++ (((uint64_t) ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_LO])))); ++ ++ p->receive_memblock_callback( ++ p, ++ ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_CHANNEL]), ++ offset, ++ ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_FLAGS]) & PA_FLAG_SEEKMASK, ++ &chunk, ++ p->receive_memblock_callback_userdata); ++} ++ + static int do_read(pa_pstream *p, struct pstream_read *re) { + void *d; + size_t l; +@@ -831,47 +855,12 @@ static int do_read(pa_pstream *p, struct pstream_read *re) { + } + + } else if (re->index > PA_PSTREAM_DESCRIPTOR_SIZE) { +- /* Frame payload available */ +- +- if (re->memblock && p->receive_memblock_callback) { +- +- /* Is this memblock data? Than pass it to the user */ +- l = (re->index - (size_t) r) < PA_PSTREAM_DESCRIPTOR_SIZE ? (size_t) (re->index - PA_PSTREAM_DESCRIPTOR_SIZE) : (size_t) r; +- +- if (l > 0) { +- pa_memchunk chunk; +- +- chunk.memblock = re->memblock; +- chunk.index = re->index - PA_PSTREAM_DESCRIPTOR_SIZE - l; +- chunk.length = l; +- +- if (p->receive_memblock_callback) { +- int64_t offset; +- +- offset = (int64_t) ( +- (((uint64_t) ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI])) << 32) | +- (((uint64_t) ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_LO])))); +- +- p->receive_memblock_callback( +- p, +- ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_CHANNEL]), +- offset, +- ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_FLAGS]) & PA_FLAG_SEEKMASK, +- &chunk, +- p->receive_memblock_callback_userdata); +- } +- +- /* Drop seek info for following callbacks */ +- re->descriptor[PA_PSTREAM_DESCRIPTOR_FLAGS] = +- re->descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI] = +- re->descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_LO] = 0; +- } +- } + + /* Frame complete */ + if (re->index >= ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) + PA_PSTREAM_DESCRIPTOR_SIZE) { + + if (re->memblock) { ++ memblock_complete(p, re); + + /* This was a memblock frame. We can unref the memblock now */ + pa_memblock_unref(re->memblock); +-- +2.4.3 + diff --git a/0037-pstream-Remove-unnecessary-if-condition.patch b/0037-pstream-Remove-unnecessary-if-condition.patch new file mode 100644 index 0000000..fababc4 --- /dev/null +++ b/0037-pstream-Remove-unnecessary-if-condition.patch @@ -0,0 +1,139 @@ +From a13b6f001d0ef00f540ddf02f54915cda76109bd Mon Sep 17 00:00:00 2001 +From: David Henningsson +Date: Thu, 5 Mar 2015 14:55:53 +0100 +Subject: [PATCH 037/118] pstream: Remove unnecessary if condition + +Without split packets, the if condition can now be removed. + +Signed-off-by: David Henningsson +--- + src/pulsecore/pstream.c | 97 ++++++++++++++++++++++++------------------------- + 1 file changed, 47 insertions(+), 50 deletions(-) + +diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c +index 877ff66..8c14fbb 100644 +--- a/src/pulsecore/pstream.c ++++ b/src/pulsecore/pstream.c +@@ -854,72 +854,69 @@ static int do_read(pa_pstream *p, struct pstream_read *re) { + } + } + +- } else if (re->index > PA_PSTREAM_DESCRIPTOR_SIZE) { +- ++ } else if (re->index >= ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) + PA_PSTREAM_DESCRIPTOR_SIZE) { + /* Frame complete */ +- if (re->index >= ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) + PA_PSTREAM_DESCRIPTOR_SIZE) { + +- if (re->memblock) { +- memblock_complete(p, re); ++ if (re->memblock) { ++ memblock_complete(p, re); + +- /* This was a memblock frame. We can unref the memblock now */ +- pa_memblock_unref(re->memblock); ++ /* This was a memblock frame. We can unref the memblock now */ ++ pa_memblock_unref(re->memblock); + +- } else if (re->packet) { ++ } else if (re->packet) { + +- if (p->receive_packet_callback) ++ if (p->receive_packet_callback) + #ifdef HAVE_CREDS +- p->receive_packet_callback(p, re->packet, &p->read_ancil_data, p->receive_packet_callback_userdata); ++ p->receive_packet_callback(p, re->packet, &p->read_ancil_data, p->receive_packet_callback_userdata); + #else +- p->receive_packet_callback(p, re->packet, NULL, p->receive_packet_callback_userdata); ++ p->receive_packet_callback(p, re->packet, NULL, p->receive_packet_callback_userdata); + #endif + +- pa_packet_unref(re->packet); +- } else { +- pa_memblock *b; +- uint32_t flags = ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_FLAGS]); +- pa_assert((flags & PA_FLAG_SHMMASK) == PA_FLAG_SHMDATA); +- +- pa_assert(p->import); ++ pa_packet_unref(re->packet); ++ } else { ++ pa_memblock *b; ++ uint32_t flags = ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_FLAGS]); ++ pa_assert((flags & PA_FLAG_SHMMASK) == PA_FLAG_SHMDATA); + +- if (!(b = pa_memimport_get(p->import, +- ntohl(re->shm_info[PA_PSTREAM_SHM_BLOCKID]), +- ntohl(re->shm_info[PA_PSTREAM_SHM_SHMID]), +- ntohl(re->shm_info[PA_PSTREAM_SHM_INDEX]), +- ntohl(re->shm_info[PA_PSTREAM_SHM_LENGTH]), +- !!(flags & PA_FLAG_SHMWRITABLE)))) { ++ pa_assert(p->import); + +- if (pa_log_ratelimit(PA_LOG_DEBUG)) +- pa_log_debug("Failed to import memory block."); +- } ++ if (!(b = pa_memimport_get(p->import, ++ ntohl(re->shm_info[PA_PSTREAM_SHM_BLOCKID]), ++ ntohl(re->shm_info[PA_PSTREAM_SHM_SHMID]), ++ ntohl(re->shm_info[PA_PSTREAM_SHM_INDEX]), ++ ntohl(re->shm_info[PA_PSTREAM_SHM_LENGTH]), ++ !!(flags & PA_FLAG_SHMWRITABLE)))) { + +- if (p->receive_memblock_callback) { +- int64_t offset; +- pa_memchunk chunk; +- +- chunk.memblock = b; +- chunk.index = 0; +- chunk.length = b ? pa_memblock_get_length(b) : ntohl(re->shm_info[PA_PSTREAM_SHM_LENGTH]); +- +- offset = (int64_t) ( +- (((uint64_t) ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI])) << 32) | +- (((uint64_t) ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_LO])))); +- +- p->receive_memblock_callback( +- p, +- ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_CHANNEL]), +- offset, +- ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_FLAGS]) & PA_FLAG_SEEKMASK, +- &chunk, +- p->receive_memblock_callback_userdata); +- } ++ if (pa_log_ratelimit(PA_LOG_DEBUG)) ++ pa_log_debug("Failed to import memory block."); ++ } + +- if (b) +- pa_memblock_unref(b); ++ if (p->receive_memblock_callback) { ++ int64_t offset; ++ pa_memchunk chunk; ++ ++ chunk.memblock = b; ++ chunk.index = 0; ++ chunk.length = b ? pa_memblock_get_length(b) : ntohl(re->shm_info[PA_PSTREAM_SHM_LENGTH]); ++ ++ offset = (int64_t) ( ++ (((uint64_t) ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI])) << 32) | ++ (((uint64_t) ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_LO])))); ++ ++ p->receive_memblock_callback( ++ p, ++ ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_CHANNEL]), ++ offset, ++ ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_FLAGS]) & PA_FLAG_SEEKMASK, ++ &chunk, ++ p->receive_memblock_callback_userdata); + } + +- goto frame_done; ++ if (b) ++ pa_memblock_unref(b); + } ++ ++ goto frame_done; + } + + return 0; +-- +2.4.3 + diff --git a/pulseaudio.spec b/pulseaudio.spec index 182fb21..f781289 100644 --- a/pulseaudio.spec +++ b/pulseaudio.spec @@ -19,7 +19,7 @@ Name: pulseaudio Summary: Improved Linux Sound Server Version: %{pa_major}%{?pa_minor:.%{pa_minor}} -Release: 3%{?snap:.%{snap}git%{shortcommit}}%{?dist} +Release: 4%{?snap:.%{snap}git%{shortcommit}}%{?dist} License: LGPLv2+ URL: http://www.freedesktop.org/wiki/Software/PulseAudio %if 0%{?gitrel} @@ -35,6 +35,8 @@ Source2: http://freedesktop.org/software/pulseaudio/releases/pulseaudio-% Source5: default.pa-for-gdm ## upstream patches +Patch35: 0035-pstream-Don-t-split-non-SHM-memblocks.patch +Patch37: 0037-pstream-Remove-unnecessary-if-condition.patch ## upstreamable patches @@ -221,6 +223,9 @@ This package contains GDM integration hooks for the PulseAudio sound server. %prep %setup -q -T -b0 -n %{name}-%{version}%{?gitrel:-%{gitrel}-g%{shortcommit}} +%patch35 -p1 -b .0035 +%patch37 -p1 -b .0037 + sed -i.no_consolekit -e \ 's/^load-module module-console-kit/#load-module module-console-kit/' \ src/daemon/default.pa.in @@ -562,6 +567,9 @@ exit 0 %changelog +* Thu Jun 11 2015 Rex Dieter - 6.0-4 +- pulseaudio 6.0 breaks 5.1 network sound configuration (#1230957) + * Sat May 02 2015 Kalev Lember - 6.0-3 - Rebuilt for GCC 5 C++11 ABI change