Commit ea47fdf5 authored by Michael Smith's avatar Michael Smith

Buffer overflows.

Requires a change to the format plugin interface - jack: if you want this
done differently, feel free to change it (or ask me to).

svn path=/trunk/httpp/; revision=3219
parent 235a2639
......@@ -24,7 +24,8 @@ typedef struct _format_plugin_tag
*/
int has_predata;
refbuf_t *(*get_buffer)(struct _format_plugin_tag *self, char *data, unsigned long len);
int (*get_buffer)(struct _format_plugin_tag *self, char *data, unsigned long
len, refbuf_t **buffer);
refbuf_queue_t *(*get_predata)(struct _format_plugin_tag *self);
void (*free_plugin)(struct _format_plugin_tag *self);
......
......@@ -16,6 +16,8 @@
#include "stats.h"
#include "format.h"
#define MAX_HEADER_PAGES 10
typedef struct _vstate_tag
{
ogg_sync_state oy;
......@@ -26,12 +28,12 @@ typedef struct _vstate_tag
ogg_page og;
unsigned long serialno;
int header;
refbuf_t *headbuf[10];
refbuf_t *headbuf[MAX_HEADER_PAGES];
int packets;
} vstate_t;
void format_vorbis_free_plugin(format_plugin_t *self);
refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned long len);
int format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned long len, refbuf_t **buffer);
refbuf_queue_t *format_vorbis_get_predata(format_plugin_t *self);
format_plugin_t *format_vorbis_get_plugin(void)
......@@ -68,7 +70,7 @@ void format_vorbis_free_plugin(format_plugin_t *self)
vorbis_comment_clear(&state->vc);
vorbis_info_clear(&state->vi);
for (i = 0; i < 10; i++) {
for (i = 0; i < MAX_HEADER_PAGES; i++) {
if (state->headbuf[i]) {
refbuf_release(state->headbuf[i]);
state->headbuf[i] = NULL;
......@@ -81,19 +83,19 @@ void format_vorbis_free_plugin(format_plugin_t *self)
free(self);
}
refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned long len)
int format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned long len, refbuf_t **buffer)
{
char *buffer;
refbuf_t *refbuf;
char *buf;
int i, result;
ogg_packet op;
char *tag;
refbuf_t *refbuf;
vstate_t *state = (vstate_t *)self->_state;
if (data) {
/* write the data to the buffer */
buffer = ogg_sync_buffer(&state->oy, len);
memcpy(buffer, data, len);
buf = ogg_sync_buffer(&state->oy, len);
memcpy(buf, data, len);
ogg_sync_wrote(&state->oy, len);
}
......@@ -109,7 +111,7 @@ refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned l
state->packets = 0;
/* release old headers, stream state, vorbis data */
for (i = 0; i < 10; i++) {
for (i = 0; i < MAX_HEADER_PAGES; i++) {
if (state->headbuf[i]) {
refbuf_release(state->headbuf[i]);
state->headbuf[i] = NULL;
......@@ -150,6 +152,10 @@ refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned l
/* cache header pages */
if (state->header > 0) {
if(state->header > MAX_HEADER_PAGES) {
refbuf_release(refbuf);
return -1;
}
refbuf_addref(refbuf);
state->headbuf[state->header - 1] = refbuf;
......@@ -174,7 +180,8 @@ refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned l
}
}
return refbuf;
*buffer = refbuf;
return 0;
}
refbuf_queue_t *format_vorbis_get_predata(format_plugin_t *self)
......@@ -184,7 +191,7 @@ refbuf_queue_t *format_vorbis_get_predata(format_plugin_t *self)
vstate_t *state = (vstate_t *)self->_state;
queue = NULL;
for (i = 0; i < 10; i++) {
for (i = 0; i < MAX_HEADER_PAGES; i++) {
if (state->headbuf[i]) {
refbuf_addref(state->headbuf[i]);
refbuf_queue_add(&queue, state->headbuf[i]);
......
......@@ -3,6 +3,8 @@
** http parsing engine
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
......@@ -15,6 +17,8 @@
#define strcasecmp stricmp
#endif
#define MAX_HEADERS 32
/* internal functions */
/* misc */
......@@ -48,7 +52,7 @@ void httpp_initialize(http_parser_t *parser, http_varlist_t *defaults)
int httpp_parse(http_parser_t *parser, char *http_data, unsigned long len)
{
char *data, *tmp;
char *line[32]; /* limited to 32 lines, should be more than enough */
char *line[MAX_HEADERS]; /* limited to 32 lines, should be more than enough */
int i, l, retlen;
int lines;
char *req_type = NULL;
......@@ -73,7 +77,7 @@ int httpp_parse(http_parser_t *parser, char *http_data, unsigned long len)
*/
lines = 0;
line[lines] = data;
for (i = 0; i < len; i++) {
for (i = 0; i < len && lines < MAX_HEADERS; i++) {
if (data[i] == '\r')
data[i] = '\0';
if (data[i] == '\n') {
......
......@@ -35,7 +35,7 @@ typedef struct log_tag
char *filename;
FILE *logfile;
char *buffer;
char *buffer;
} log_t;
log_t loglist[LOG_MAXLOGS];
......@@ -170,7 +170,9 @@ void log_write(int log_id, int priority, const char *cat, const char *fmt, ...)
va_list ap;
if (log_id < 0) return;
if (log_id > LOG_MAXLOGS) return; /* Bad log number */
if (loglist[log_id].level < priority) return;
if (priority > 4) return; /* Bad priority */
va_start(ap, fmt);
......
......@@ -147,7 +147,11 @@ void *source_main(void *arg)
stats_event(source->mount, "description", s);
while (global.running == ICE_RUNNING) {
refbuf = source->format->get_buffer(source->format, NULL, 0);
int ret = source->format->get_buffer(source->format, NULL, 0, &refbuf);
if(ret < 0) {
WARN0("Bad data from source");
break;
}
while (refbuf == NULL) {
bytes = 0;
while (bytes <= 0) {
......@@ -167,7 +171,11 @@ void *source_main(void *arg)
if (bytes == 0 || (bytes < 0 && !sock_recoverable(sock_error()))) break;
}
if (bytes <= 0) break;
refbuf = source->format->get_buffer(source->format, buffer, bytes);
ret = source->format->get_buffer(source->format, buffer, bytes, &refbuf);
if(ret < 0) {
WARN0("Bad data from source");
goto done;
}
}
if (bytes <= 0) {
......@@ -333,6 +341,8 @@ void *source_main(void *arg)
avl_tree_unlock(source->client_tree);
}
done:
printf("DEBUG: we're going down...\n");
/* we need to empty the client and pending trees */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment