[pulseaudio-discuss] [PATCH 1/3] pstream: Don't split (non-SHM) memblocks
David Henningsson
david.henningsson at canonical.com
Thu Mar 5 05:55:51 PST 2015
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 <david.henningsson at canonical.com>
---
src/pulsecore/pstream.c | 67 +++++++++++++++++++++++--------------------------
1 file changed, 31 insertions(+), 36 deletions(-)
diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c
index b0ed5a7..8c05a87 100644
--- a/src/pulsecore/pstream.c
+++ b/src/pulsecore/pstream.c
@@ -682,6 +682,36 @@ fail:
return -1;
}
+static void memblock_complete(pa_pstream *p, struct pstream_read *re) {
+ size_t l;
+ pa_memchunk chunk;
+ int64_t offset;
+
+ if (!p->receive_memblock_callback)
+ return;
+
+ /* Is this memblock data? Then pass it to the user */
+ l = re->index - PA_PSTREAM_DESCRIPTOR_SIZE;
+ if (l <= 0)
+ return;
+
+ chunk.memblock = re->memblock;
+ chunk.index = 0;
+ chunk.length = l;
+
+ 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 +861,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);
--
1.9.1
More information about the pulseaudio-discuss
mailing list