[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#603052: qt4-x11: Potential buffer overrun in ALSA QAudioInput



Package: qt4-x11
Version: 4:4.6.3-4
Severity: important
Tags: patch upstream fixed-upstream
Forwarded: http://bugreports.qt.nokia.com/browse/QTBUG-14549

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

qint64 QAudioInputPrivate::read(char* data, qint64 len) in
qaudioinput_alsa_p.cpp ignores the len parameter, leading to a
potential buffer overflow in data.

Upstream bug:
http://bugreports.qt.nokia.com/browse/QTBUG-14549

Upstream commit:
http://qt.gitorious.org/+qt-developers/qt/staging/commit/e3f1268e63064a54215051cf91d5f6b8c8bd4f0f

Upstream raw patch:
http://qt.gitorious.org/+qt-developers/qt/staging/commit/e3f1268e63064a54215051cf91d5f6b8c8bd4f0f.patch


The patch is against 4.7.1 and doesn't apply cleanly against 4.6.3; I
tried to adapt it for 4.6.3 (attached), hope I got it right :)


Cheers,
gregor

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)

iQIcBAEBCAAGBQJM2tY9AAoJELs6aAGGSaoGwU4QAILIF+OF/3jsYlNC0/al4WzR
Z35VzBBprK2ghZZY2MMNhoaCgQW7J3ShdVVDZs/vI0p/QwEH9Rs0UNVzQ2MGGQIt
iZnfcliRtzNONnsm3z3ydHFxS2+zxW0FUYh4lj6SE3Ws9h/qGY9Qm+ME2+T3vRt9
vK6F/vDpnqBsCS+1G1ompjHdUIIadla2d4xl7/He0RAti1Ip80qYZ5V+788VPBU9
3Km8cFAqCa9NdQJaAUEKZi3U88VuxOyuvK7pcmxk1S+jNrws3D8MU/crKqz5lHO8
2B4mY4pdOejLeywhyjNjM5KPVJfQ0FHtsKasL/n3MCMd9teukonOHqRDEe9q7WjZ
JwiWfOaMV1uDNwHnzS/QVE0elxEEkx5fIe4AtHdOQh5BcBlppkoJtQAqy9URlU1p
HGB8gn42Ke8Ae1+YMoetphREt7zFQ0AZ1+nyK/4Ckhty0y3Nkoc3nOJcCfwW5USY
wfB23ur5tu1k3oxK/CxpH0UYnBcRcASDUgkjCb1lIH3k3Jehkef8xih3cdoQdN83
2C5gcRF685X4AojeX8vD3ZiCedAwFCA9bCckRFImBTVWfwMm1LUs1N9b3CPAOgew
lkCz2cLMbRUbMjN2pD/yQYf3alXyBhp7hLergK07HTitvpAX4Xb0bn5z8cgWun0a
zEs5qxkRReStwgZV0YSi
=Myzp
-----END PGP SIGNATURE-----
>From e3f1268e63064a54215051cf91d5f6b8c8bd4f0f Mon Sep 17 00:00:00 2001
From: Andrew den Exter <andrew.den-exter@nokia.com>
Date: Tue, 9 Nov 2010 16:30:32 +1000
Subject: [PATCH] Fix potential buffer overrun in ALSA QAudioInput implementation.

Don't write more than the supplied max buffer size to the output buffer.

Task-number: QTBUG-14549 QTBUG-8578
Reviewed-by: Derick Hawcroft
---
 src/multimedia/audio/qaudioinput_alsa_p.cpp |   21 ++++++++++++---------
 1 files changed, 12 insertions(+), 9 deletions(-)

--- a/src/multimedia/audio/qaudioinput_alsa_p.cpp
+++ b/src/multimedia/audio/qaudioinput_alsa_p.cpp
@@ -454,19 +454,18 @@
 
 qint64 QAudioInputPrivate::read(char* data, qint64 len)
 {
-    Q_UNUSED(len)
-
     // Read in some audio data and write it to QIODevice, pull mode
     if ( !handle )
         return 0;
 
-    bytesAvailable = bytesReady();
+    // bytesAvaiable is saved as a side effect of bytesReady().
+    int bytesToRead = bytesReady();
 
-    if (bytesAvailable < 0) {
+    if (bytesToRead < 0) {
         // bytesAvailable as negative is error code, try to recover from it.
-        xrun_recovery(bytesAvailable);
-        bytesAvailable = bytesReady();
-        if (bytesAvailable < 0) {
+        xrun_recovery(bytesToRead);
+        bytesToRead = bytesReady();
+        if (bytesToRead < 0) {
             // recovery failed must stop and set error.
             close();
             errorState = QAudio::IOError;
@@ -476,9 +475,11 @@
         }
     }
 
+    bytesToRead = qMin<qint64>(len, bytesToRead);
+    bytesToRead -= bytesToRead % period_size;
     int count=0, err = 0;
     while(count < 5) {
-        int chunks = bytesAvailable/period_size;
+        int chunks = bytesToRead/period_size;
         int frames = chunks*period_frames;
         if(frames > (int)buffer_frames)
             frames = buffer_frames;
@@ -526,6 +527,7 @@
                     emit stateChanged(deviceState);
                 }
             } else {
+                bytesAvailable -= err;
                 totalTimeValue += err;
                 resuming = false;
                 if (deviceState != QAudio::ActiveState) {
@@ -538,6 +540,7 @@
 
         } else {
             memcpy(data,audioBuffer,err);
+            bytesAvailable -= err;
             totalTimeValue += err;
             resuming = false;
             if (deviceState != QAudio::ActiveState) {
@@ -633,7 +636,7 @@
 {
     if(pullMode) {
         // reads some audio data and writes it to QIODevice
-        read(0,0);
+        read(0, buffer_size);
     } else {
         // emits readyRead() so user will call read() on QIODevice to get some audio data
         InputPrivate* a = qobject_cast<InputPrivate*>(audioSource);

Reply to: