mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -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