On overrun in both capture and playback paths, the code logs an error
but proceeds to write the full unclamped size. This advances the write
index past read_index + RINGBUFFER_SIZE, causing filled to exceed the
buffer capacity on subsequent calls. Once in that state, avail goes
negative and the signed/unsigned comparison fails to clamp further
writes, leaving the ring buffer in a degenerate state.

Clamp to the remaining space so the write index stays within bounds.

Reported-by: Pavee Hui <[email protected]>
Fixes: c2d3d1c29415 ("audio/pwaudio.c: Add Pipewire audio backend for QEMU")
Signed-off-by: Marc-André Lureau <[email protected]>
---
 audio/pwaudio.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/audio/pwaudio.c b/audio/pwaudio.c
index af360e2ec5ed..1105e920f3c2 100644
--- a/audio/pwaudio.c
+++ b/audio/pwaudio.c
@@ -188,6 +188,7 @@ capture_on_process(void *data)
         if ((uint32_t) filled + n_bytes > RINGBUFFER_SIZE) {
             error_report("%p: overrun write:%u filled:%d + size:%u > max:%u",
             p, index, filled, n_bytes, RINGBUFFER_SIZE);
+            n_bytes = RINGBUFFER_SIZE - (uint32_t)filled;
         }
     }
     spa_ringbuffer_write_data(&v->ring,
@@ -318,6 +319,7 @@ qpw_write(HWVoiceOut *hw, void *data, size_t len)
         if ((uint32_t) filled + len > RINGBUFFER_SIZE) {
             error_report("%p: overrun write:%u filled:%d + size:%zu > max:%u",
             pw, index, filled, len, RINGBUFFER_SIZE);
+            len = RINGBUFFER_SIZE - (uint32_t)filled;
         }
     }
 

-- 
2.56.0.rc0.29.g47ce80527c56


Reply via email to