vss: Don't prefault header.
authorAndre Noll <maan@systemlinux.org>
Thu, 10 Nov 2011 09:14:21 +0000 (10:14 +0100)
committerAndre Noll <maan@systemlinux.org>
Fri, 11 Nov 2011 09:01:40 +0000 (10:01 +0100)
Commit 7bba6232 (vss: Mmap audio files using MAP_POPULATE.) introduced
read-ahead for chunks of the mmapped audio file. However, it missed
the fact that for ogg streams chunk 0 is created on the fly and stored
in a dynamically allocated buffer. Read-ahead on this buffer is likely
to access memory not owned by the process and might lead to a segfault.

Fix this bug by not performing read-ahead for chunk zero.

vss.c

diff --git a/vss.c b/vss.c
index e336a9e..db1beeb 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -1079,8 +1079,6 @@ static void vss_send(struct vss_task *vsst)
                        senders[i].send(mmd->current_chunk, mmd->chunks_sent,
                                buf, len, vsst->header_buf, vsst->header_len);
                }
-               mmd->chunks_sent++;
-               mmd->current_chunk++;
                /*
                 * Prefault next chunk(s)
                 *
@@ -1093,11 +1091,15 @@ static void vss_send(struct vss_task *vsst)
                 * eliminate the delays completely. Moreover, it is supported
                 * only on Linux. So we do our own read-ahead here.
                 */
-               buf += len;
-               for (i = 0; i < 5 && buf < vsst->map + mmd->size; i++) {
-                       __a_unused volatile char x = *buf;
-                       buf += 4096;
+               if (mmd->current_chunk > 0) { /* chunk 0 might be on the heap */
+                       buf += len;
+                       for (i = 0; i < 5 && buf < vsst->map + mmd->size; i++) {
+                               __a_unused volatile char x = *buf;
+                               buf += 4096;
+                       }
                }
+               mmd->chunks_sent++;
+               mmd->current_chunk++;
        }
 }