From dcc70f58498fa0be8f455c8ffa73126d45bcd532 Mon Sep 17 00:00:00 2001 From: rtogni Date: Sun, 25 Mar 2007 19:00:39 +0000 Subject: Check buffer size in header dump functions git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@22821 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/librtsp/rtsp_session.c | 12 +++++- stream/realrtsp/rmff.c | 88 ++++++++++++++++++++++++++++++++----------- stream/realrtsp/rmff.h | 6 +++ 3 files changed, 84 insertions(+), 22 deletions(-) diff --git a/stream/librtsp/rtsp_session.c b/stream/librtsp/rtsp_session.c index cdc8d3d381..a3559212b2 100644 --- a/stream/librtsp/rtsp_session.c +++ b/stream/librtsp/rtsp_session.c @@ -148,7 +148,17 @@ rtsp_session_t *rtsp_session_start(int fd, char **mrl, char *path, char *host, 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 --git a/stream/realrtsp/rmff.c b/stream/realrtsp/rmff.c index c361303be4..5bfa086bb8 100644 --- a/stream/realrtsp/rmff.c +++ b/stream/realrtsp/rmff.c @@ -70,19 +70,29 @@ static void hexdump (const char *buf, int length) { * 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 (bufsize < RMFF_FILEHEADER_SIZE) + return -1; - if (!fileheader) return; 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 (bufsize < RMFF_PROPHEADER_SIZE) + return -1; - if (!prop) return; AV_WB32(buffer, prop->object_id); AV_WB32(buffer+4, prop->size); AV_WB16(buffer+8, prop->object_version); @@ -97,13 +107,20 @@ static void rmff_dump_prop(rmff_prop_t *prop, char *buffer) { 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 @@ static void rmff_dump_mdpr(rmff_mdpr_t *mdpr, char *buffer) { 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 @@ static void rmff_dump_cont(rmff_cont_t *cont, char *buffer) { 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 (bufsize < RMFF_DATAHEADER_SIZE) + return -1; - if (!data) return; 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 --git a/stream/realrtsp/rmff.h b/stream/realrtsp/rmff.h index 7ea75a04aa..3124645e32 100644 --- a/stream/realrtsp/rmff.h +++ b/stream/realrtsp/rmff.h @@ -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 ) | \ -- cgit v1.2.3