aboutsummaryrefslogtreecommitdiffhomepage
path: root/libao2
diff options
context:
space:
mode:
authorGravatar ranma <ranma@b3059339-0415-0410-9bf9-f77b7e298cf2>2005-06-17 02:22:34 +0000
committerGravatar ranma <ranma@b3059339-0415-0410-9bf9-f77b7e298cf2>2005-06-17 02:22:34 +0000
commita73a629c1b96e51bf2daa5254502e250b0327466 (patch)
treee9ba74aed83c1535ac586913a28345d95cc0b25a /libao2
parent4ea93f6ad85cbb0250f37dc9e46a62bf58add28a (diff)
Add missing range checks so we won't overflow the buffers, thanks to Erik Auerswald for noticing this problem
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@15742 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libao2')
-rw-r--r--libao2/ao_nas.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/libao2/ao_nas.c b/libao2/ao_nas.c
index f99573f915..f4c74dd7cb 100644
--- a/libao2/ao_nas.c
+++ b/libao2/ao_nas.c
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
+#include <limits.h>
#include <audio/audiolib.h>
#include "config.h"
@@ -102,7 +103,7 @@ static ao_info_t info =
{
"NAS audio output",
"nas",
- "Tobias Diedrich",
+ "Tobias Diedrich <ranma+mplayer@tdiedrich.de>",
""
};
@@ -117,10 +118,10 @@ struct ao_nas_data {
void *client_buffer;
void *server_buffer;
- int client_buffer_size;
- int client_buffer_used;
- int server_buffer_size;
- int server_buffer_used;
+ unsigned int client_buffer_size;
+ unsigned int client_buffer_used;
+ unsigned int server_buffer_size;
+ unsigned int server_buffer_used;
pthread_mutex_t buffer_mutex;
pthread_t event_thread;
@@ -153,19 +154,22 @@ static int nas_readBuffer(struct ao_nas_data *nas_data, int num)
pthread_mutex_unlock(&nas_data->buffer_mutex);
return 0;
}
- if (nas_data->client_buffer_used < num)
+ if (num > nas_data->client_buffer_used)
num = nas_data->client_buffer_used;
/*
* It is not appropriate to call AuWriteElement() here because the
* buffer is locked and delays writing to the network will cause
* other threads to block waiting for buffer_mutex. Instead the
- * data is copied to "server_buffer" and written it to the network
+ * data is copied to "server_buffer" and written to the network
* outside of the locked section of code.
*
* (Note: Rather than these two buffers, a single circular buffer
* could eliminate the memcpy/memmove steps.)
*/
+ /* make sure we don't overflow the buffer */
+ if (num > nas_data->server_buffer_size)
+ num = nas_data->server_buffer_size;
memcpy(nas_data->server_buffer, nas_data->client_buffer, num);
nas_data->client_buffer_used -= num;
@@ -183,17 +187,22 @@ static int nas_readBuffer(struct ao_nas_data *nas_data, int num)
return num;
}
-static void nas_writeBuffer(struct ao_nas_data *nas_data, void *data, int len)
+static int nas_writeBuffer(struct ao_nas_data *nas_data, void *data, int len)
{
pthread_mutex_lock(&nas_data->buffer_mutex);
mp_msg(MSGT_AO, MSGL_DBG2, "ao_nas: nas_writeBuffer(): len=%d client=%d/%d server=%d/%d\n",
len, nas_data->client_buffer_used, nas_data->client_buffer_size,
nas_data->server_buffer_used, nas_data->server_buffer_size);
+ /* make sure we don't overflow the buffer */
+ if (len > nas_data->client_buffer_size - nas_data->client_buffer_used)
+ len = nas_data->client_buffer_size - nas_data->client_buffer_used;
memcpy(nas_data->client_buffer + nas_data->client_buffer_used, data, len);
nas_data->client_buffer_used += len;
pthread_mutex_unlock(&nas_data->buffer_mutex);
+
+ return len;
}
static int nas_empty_event_queue(struct ao_nas_data *nas_data)
@@ -254,9 +263,13 @@ static AuBool nas_event_handler(AuServer *aud, AuEvent *ev, AuEventHandlerRec *h
event->num_bytes,
nas_data->expect_underrun);
+ if (event->num_bytes > INT_MAX) {
+ mp_msg(MSGT_AO, MSGL_ERR, "ao_nas: num_bytes > 2GB, server buggy?\n");
+ }
+
+ if (event->num_bytes > nas_data->server_buffer_used)
+ event->num_bytes = nas_data->server_buffer_used;
nas_data->server_buffer_used -= event->num_bytes;
- if (nas_data->server_buffer_used < 0)
- nas_data->server_buffer_used = 0;
switch (event->reason) {
case AuReasonWatermark:
@@ -569,7 +582,7 @@ static int play(void* data,int len,int flags)
ao_data.outburst;
pthread_mutex_unlock(&nas_data->buffer_mutex);
- nas_writeBuffer(nas_data, data, writelen);
+ writelen = nas_writeBuffer(nas_data, data, writelen);
if (nas_data->state != AuStateStart &&
maxbursts == playbursts) {