# HG changeset patch # User rtogni # Date 1174849239 0 # Node ID 4401909aac98cb0425c57984c8fcfb0e932d5473 # Parent 6279120e9465777db055e4223595c2b1ae509f65 Check buffer size in header dump functions diff -r 6279120e9465 -r 4401909aac98 stream/librtsp/rtsp_session.c --- a/stream/librtsp/rtsp_session.c Sun Mar 25 17:38:50 2007 +0000 +++ b/stream/librtsp/rtsp_session.c Sun Mar 25 19:00:39 2007 +0000 @@ -148,7 +148,17 @@ mp_msg(MSGT_OPEN, MSGL_V, "smil-over-realrtsp playlist, switching to raw rdt mode\n"); } else { rtsp_session->real_session->header_len = - rmff_dump_header (h, (char *) rtsp_session->real_session->header, 1024); + rmff_dump_header (h, (char *) rtsp_session->real_session->header, HEADER_SIZE); + + if (rtsp_session->real_session->header_len < 0) { + mp_msg (MSGT_OPEN, MSGL_ERR,"rtsp_session: error while dumping RMFF headers, session can not be established.\n"); + free_real_rtsp_session(rtsp_session->real_session); + rtsp_close(rtsp_session->s); + free (server); + free (mrl_line); + free(rtsp_session); + return NULL; + } rtsp_session->real_session->recv = xbuffer_copyin (rtsp_session->real_session->recv, 0, diff -r 6279120e9465 -r 4401909aac98 stream/realrtsp/rmff.c --- a/stream/realrtsp/rmff.c Sun Mar 25 17:38:50 2007 +0000 +++ b/stream/realrtsp/rmff.c Sun Mar 25 19:00:39 2007 +0000 @@ -70,19 +70,29 @@ * writes header data to a buffer */ -static void rmff_dump_fileheader(rmff_fileheader_t *fileheader, char *buffer) { +static int rmff_dump_fileheader(rmff_fileheader_t *fileheader, char *buffer, int bufsize) { + + if (!fileheader) return 0; - if (!fileheader) return; + if (bufsize < RMFF_FILEHEADER_SIZE) + return -1; + AV_WB32(buffer, fileheader->object_id); AV_WB32(buffer+4, fileheader->size); AV_WB16(buffer+8, fileheader->object_version); AV_WB32(buffer+10, fileheader->file_version); AV_WB32(buffer+14, fileheader->num_headers); + + return RMFF_FILEHEADER_SIZE; } -static void rmff_dump_prop(rmff_prop_t *prop, char *buffer) { +static int rmff_dump_prop(rmff_prop_t *prop, char *buffer, int bufsize) { + + if (!prop) return 0; - if (!prop) return; + if (bufsize < RMFF_PROPHEADER_SIZE) + return -1; + AV_WB32(buffer, prop->object_id); AV_WB32(buffer+4, prop->size); AV_WB16(buffer+8, prop->object_version); @@ -97,13 +107,20 @@ AV_WB32(buffer+42, prop->data_offset); AV_WB16(buffer+46, prop->num_streams); AV_WB16(buffer+48, prop->flags); + + return RMFF_PROPHEADER_SIZE; } -static void rmff_dump_mdpr(rmff_mdpr_t *mdpr, char *buffer) { +static int rmff_dump_mdpr(rmff_mdpr_t *mdpr, char *buffer, int bufsize) { int s1, s2, s3; - if (!mdpr) return; + if (!mdpr) return 0; + + if (!(bufsize > RMFF_MDPRHEADER_SIZE + mdpr->stream_name_size + mdpr->mime_type_size && + (unsigned)bufsize - RMFF_MDPRHEADER_SIZE - mdpr->stream_name_size - mdpr->mime_type_size > mdpr->type_specific_len)) + return -1; + AV_WB32(buffer, mdpr->object_id); AV_WB32(buffer+4, mdpr->size); AV_WB16(buffer+8, mdpr->object_version); @@ -127,13 +144,20 @@ AV_WB32(buffer+42+s1+s2, mdpr->type_specific_len); s3=mdpr->type_specific_len; memcpy(&buffer[46+s1+s2], mdpr->type_specific_data, s3); + + return RMFF_MDPRHEADER_SIZE + s1 + s2 + s3; } -static void rmff_dump_cont(rmff_cont_t *cont, char *buffer) { +static int rmff_dump_cont(rmff_cont_t *cont, char *buffer, int bufsize) { int p; - if (!cont) return; + if (!cont) return 0; + + if (bufsize < RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len + + cont->copyright_len + cont->comment_len) + return -1; + AV_WB32(buffer, cont->object_id); AV_WB32(buffer+4, cont->size); AV_WB16(buffer+8, cont->object_version); @@ -152,43 +176,65 @@ AV_WB16(buffer+p, cont->comment_len); memcpy(&buffer[p+2], cont->comment, cont->comment_len); + + return RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len + + cont->copyright_len + cont->comment_len; } -static void rmff_dump_dataheader(rmff_data_t *data, char *buffer) { +static int rmff_dump_dataheader(rmff_data_t *data, char *buffer, int bufsize) { + + if (!data) return 0; - if (!data) return; + if (bufsize < RMFF_DATAHEADER_SIZE) + return -1; + AV_WB32(buffer, data->object_id); AV_WB32(buffer+4, data->size); AV_WB16(buffer+8, data->object_version); AV_WB32(buffer+10, data->num_packets); AV_WB32(buffer+14, data->next_data_header); + + return RMFF_DATAHEADER_SIZE; } int rmff_dump_header(rmff_header_t *h, char *buffer, int max) { - int written=0; + int written=0, size; rmff_mdpr_t **stream=h->streams; - rmff_dump_fileheader(h->fileheader, &buffer[written]); - written+=h->fileheader->size; - rmff_dump_prop(h->prop, &buffer[written]); - written+=h->prop->size; - rmff_dump_cont(h->cont, &buffer[written]); - written+=h->cont->size; + if ((size=rmff_dump_fileheader(h->fileheader, &buffer[written], max)) < 0) + goto buftoosmall; + written+=size; + max -= size; + if ((size=rmff_dump_prop(h->prop, &buffer[written], max)) < 0) + goto buftoosmall; + written+=size; + max -= size; + if ((size=rmff_dump_cont(h->cont, &buffer[written], max)) < 0) + goto buftoosmall; + written+=size; + max -= size; if (stream) { while(*stream) { - rmff_dump_mdpr(*stream, &buffer[written]); - written+=(*stream)->size; + if ((size=rmff_dump_mdpr(*stream, &buffer[written], max)) < 0) + goto buftoosmall; + written+=size; + max -= size; stream++; } } - rmff_dump_dataheader(h->data, &buffer[written]); - written+=18; + if ((size=rmff_dump_dataheader(h->data, &buffer[written], max)) < 0) + goto buftoosmall; + written+=size; return written; + +buftoosmall: + mp_msg(MSGT_STREAM, MSGL_ERR, "rmff_dumpheader: buffer too small, aborting. Please report\n"); + return -1; } void rmff_dump_pheader(rmff_pheader_t *h, char *data) { diff -r 6279120e9465 -r 4401909aac98 stream/realrtsp/rmff.h --- a/stream/realrtsp/rmff.h Sun Mar 25 17:38:50 2007 +0000 +++ b/stream/realrtsp/rmff.h Sun Mar 25 19:00:39 2007 +0000 @@ -49,6 +49,12 @@ #define RMFF_HEADER_SIZE 0x12 +#define RMFF_FILEHEADER_SIZE 18 +#define RMFF_PROPHEADER_SIZE 50 +#define RMFF_MDPRHEADER_SIZE 46 +#define RMFF_CONTHEADER_SIZE 18 +#define RMFF_DATAHEADER_SIZE 18 + #define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \ (((long)(unsigned char)(ch3) ) | \ ( (long)(unsigned char)(ch2) << 8 ) | \