mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-02 09:01:46 -05:00
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 <david.henningsson@canonical.com>
This commit is contained in:
parent
ebee1a6306
commit
7b8e8cd388
1 changed files with 25 additions and 36 deletions
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue