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: