mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
Changed a bunch of calls to sprintf to snprintf to protect against buffer
overflows. Fix streaming from non-streaming ffm files. It turned out that you always got 'index & id do not match' errors. Add some more error detection on getting FFM feeds Originally committed as revision 2523 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
bf63eb4bba
commit
d445a7e9cc
123
ffserver.c
123
ffserver.c
@ -1253,7 +1253,7 @@ static int http_parse_request(HTTPContext *c)
|
|||||||
stream = stream->next;
|
stream = stream->next;
|
||||||
}
|
}
|
||||||
if (stream == NULL) {
|
if (stream == NULL) {
|
||||||
sprintf(msg, "File '%s' not found", url);
|
snprintf(msg, sizeof(msg), "File '%s' not found", url);
|
||||||
goto send_error;
|
goto send_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1264,13 +1264,13 @@ static int http_parse_request(HTTPContext *c)
|
|||||||
if (stream->stream_type == STREAM_TYPE_REDIRECT) {
|
if (stream->stream_type == STREAM_TYPE_REDIRECT) {
|
||||||
c->http_error = 301;
|
c->http_error = 301;
|
||||||
q = c->buffer;
|
q = c->buffer;
|
||||||
q += sprintf(q, "HTTP/1.0 301 Moved\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 301 Moved\r\n");
|
||||||
q += sprintf(q, "Location: %s\r\n", stream->feed_filename);
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Location: %s\r\n", stream->feed_filename);
|
||||||
q += sprintf(q, "Content-type: text/html\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: text/html\r\n");
|
||||||
q += sprintf(q, "\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
|
||||||
q += sprintf(q, "<html><head><title>Moved</title></head><body>\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<html><head><title>Moved</title></head><body>\r\n");
|
||||||
q += sprintf(q, "You should be <a href=\"%s\">redirected</a>.\r\n", stream->feed_filename);
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "You should be <a href=\"%s\">redirected</a>.\r\n", stream->feed_filename);
|
||||||
q += sprintf(q, "</body></html>\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "</body></html>\r\n");
|
||||||
|
|
||||||
/* prepare output buffer */
|
/* prepare output buffer */
|
||||||
c->buffer_ptr = c->buffer;
|
c->buffer_ptr = c->buffer;
|
||||||
@ -1296,14 +1296,14 @@ static int http_parse_request(HTTPContext *c)
|
|||||||
if (post == 0 && max_bandwidth < current_bandwidth) {
|
if (post == 0 && max_bandwidth < current_bandwidth) {
|
||||||
c->http_error = 200;
|
c->http_error = 200;
|
||||||
q = c->buffer;
|
q = c->buffer;
|
||||||
q += sprintf(q, "HTTP/1.0 200 Server too busy\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 Server too busy\r\n");
|
||||||
q += sprintf(q, "Content-type: text/html\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: text/html\r\n");
|
||||||
q += sprintf(q, "\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
|
||||||
q += sprintf(q, "<html><head><title>Too busy</title></head><body>\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<html><head><title>Too busy</title></head><body>\r\n");
|
||||||
q += sprintf(q, "The server is too busy to serve your request at this time.<p>\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "The server is too busy to serve your request at this time.<p>\r\n");
|
||||||
q += sprintf(q, "The bandwidth being served (including your stream) is %dkbit/sec, and this exceeds the limit of %dkbit/sec\r\n",
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "The bandwidth being served (including your stream) is %dkbit/sec, and this exceeds the limit of %dkbit/sec\r\n",
|
||||||
current_bandwidth, max_bandwidth);
|
current_bandwidth, max_bandwidth);
|
||||||
q += sprintf(q, "</body></html>\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "</body></html>\r\n");
|
||||||
|
|
||||||
/* prepare output buffer */
|
/* prepare output buffer */
|
||||||
c->buffer_ptr = c->buffer;
|
c->buffer_ptr = c->buffer;
|
||||||
@ -1347,29 +1347,29 @@ static int http_parse_request(HTTPContext *c)
|
|||||||
q = c->buffer;
|
q = c->buffer;
|
||||||
switch(redir_type) {
|
switch(redir_type) {
|
||||||
case REDIR_ASX:
|
case REDIR_ASX:
|
||||||
q += sprintf(q, "HTTP/1.0 200 ASX Follows\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 ASX Follows\r\n");
|
||||||
q += sprintf(q, "Content-type: video/x-ms-asf\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: video/x-ms-asf\r\n");
|
||||||
q += sprintf(q, "\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
|
||||||
q += sprintf(q, "<ASX Version=\"3\">\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<ASX Version=\"3\">\r\n");
|
||||||
q += sprintf(q, "<!-- Autogenerated by ffserver -->\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<!-- Autogenerated by ffserver -->\r\n");
|
||||||
q += sprintf(q, "<ENTRY><REF HREF=\"http://%s/%s%s\"/></ENTRY>\r\n",
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<ENTRY><REF HREF=\"http://%s/%s%s\"/></ENTRY>\r\n",
|
||||||
hostbuf, filename, info);
|
hostbuf, filename, info);
|
||||||
q += sprintf(q, "</ASX>\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "</ASX>\r\n");
|
||||||
break;
|
break;
|
||||||
case REDIR_RAM:
|
case REDIR_RAM:
|
||||||
q += sprintf(q, "HTTP/1.0 200 RAM Follows\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 RAM Follows\r\n");
|
||||||
q += sprintf(q, "Content-type: audio/x-pn-realaudio\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: audio/x-pn-realaudio\r\n");
|
||||||
q += sprintf(q, "\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
|
||||||
q += sprintf(q, "# Autogenerated by ffserver\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "# Autogenerated by ffserver\r\n");
|
||||||
q += sprintf(q, "http://%s/%s%s\r\n",
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "http://%s/%s%s\r\n",
|
||||||
hostbuf, filename, info);
|
hostbuf, filename, info);
|
||||||
break;
|
break;
|
||||||
case REDIR_ASF:
|
case REDIR_ASF:
|
||||||
q += sprintf(q, "HTTP/1.0 200 ASF Redirect follows\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 ASF Redirect follows\r\n");
|
||||||
q += sprintf(q, "Content-type: video/x-ms-asf\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: video/x-ms-asf\r\n");
|
||||||
q += sprintf(q, "\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
|
||||||
q += sprintf(q, "[Reference]\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "[Reference]\r\n");
|
||||||
q += sprintf(q, "Ref1=http://%s/%s%s\r\n",
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Ref1=http://%s/%s%s\r\n",
|
||||||
hostbuf, filename, info);
|
hostbuf, filename, info);
|
||||||
break;
|
break;
|
||||||
case REDIR_RTSP:
|
case REDIR_RTSP:
|
||||||
@ -1380,11 +1380,11 @@ static int http_parse_request(HTTPContext *c)
|
|||||||
p = strrchr(hostname, ':');
|
p = strrchr(hostname, ':');
|
||||||
if (p)
|
if (p)
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
q += sprintf(q, "HTTP/1.0 200 RTSP Redirect follows\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 RTSP Redirect follows\r\n");
|
||||||
/* XXX: incorrect mime type ? */
|
/* XXX: incorrect mime type ? */
|
||||||
q += sprintf(q, "Content-type: application/x-rtsp\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: application/x-rtsp\r\n");
|
||||||
q += sprintf(q, "\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
|
||||||
q += sprintf(q, "rtsp://%s:%d/%s\r\n",
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "rtsp://%s:%d/%s\r\n",
|
||||||
hostname, ntohs(my_rtsp_addr.sin_port),
|
hostname, ntohs(my_rtsp_addr.sin_port),
|
||||||
filename);
|
filename);
|
||||||
}
|
}
|
||||||
@ -1395,9 +1395,9 @@ static int http_parse_request(HTTPContext *c)
|
|||||||
int sdp_data_size, len;
|
int sdp_data_size, len;
|
||||||
struct sockaddr_in my_addr;
|
struct sockaddr_in my_addr;
|
||||||
|
|
||||||
q += sprintf(q, "HTTP/1.0 200 OK\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 OK\r\n");
|
||||||
q += sprintf(q, "Content-type: application/sdp\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: application/sdp\r\n");
|
||||||
q += sprintf(q, "\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
|
||||||
|
|
||||||
len = sizeof(my_addr);
|
len = sizeof(my_addr);
|
||||||
getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
|
getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
|
||||||
@ -1428,7 +1428,7 @@ static int http_parse_request(HTTPContext *c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(msg, "ASX/RAM file not handled");
|
snprintf(msg, sizeof(msg), "ASX/RAM file not handled");
|
||||||
goto send_error;
|
goto send_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1493,12 +1493,12 @@ static int http_parse_request(HTTPContext *c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(msg, "POST command not handled");
|
snprintf(msg, sizeof(msg), "POST command not handled");
|
||||||
c->stream = 0;
|
c->stream = 0;
|
||||||
goto send_error;
|
goto send_error;
|
||||||
}
|
}
|
||||||
if (http_start_receive_data(c) < 0) {
|
if (http_start_receive_data(c) < 0) {
|
||||||
sprintf(msg, "could not open feed");
|
snprintf(msg, sizeof(msg), "could not open feed");
|
||||||
goto send_error;
|
goto send_error;
|
||||||
}
|
}
|
||||||
c->http_error = 0;
|
c->http_error = 0;
|
||||||
@ -1517,17 +1517,17 @@ static int http_parse_request(HTTPContext *c)
|
|||||||
|
|
||||||
/* open input stream */
|
/* open input stream */
|
||||||
if (open_input_stream(c, info) < 0) {
|
if (open_input_stream(c, info) < 0) {
|
||||||
sprintf(msg, "Input stream corresponding to '%s' not found", url);
|
snprintf(msg, sizeof(msg), "Input stream corresponding to '%s' not found", url);
|
||||||
goto send_error;
|
goto send_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prepare http header */
|
/* prepare http header */
|
||||||
q = c->buffer;
|
q = c->buffer;
|
||||||
q += sprintf(q, "HTTP/1.0 200 OK\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 OK\r\n");
|
||||||
mime_type = c->stream->fmt->mime_type;
|
mime_type = c->stream->fmt->mime_type;
|
||||||
if (!mime_type)
|
if (!mime_type)
|
||||||
mime_type = "application/x-octet_stream";
|
mime_type = "application/x-octet_stream";
|
||||||
q += sprintf(q, "Pragma: no-cache\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Pragma: no-cache\r\n");
|
||||||
|
|
||||||
/* for asf, we need extra headers */
|
/* for asf, we need extra headers */
|
||||||
if (!strcmp(c->stream->fmt->name,"asf_stream")) {
|
if (!strcmp(c->stream->fmt->name,"asf_stream")) {
|
||||||
@ -1535,10 +1535,10 @@ static int http_parse_request(HTTPContext *c)
|
|||||||
|
|
||||||
c->wmp_client_id = random() & 0x7fffffff;
|
c->wmp_client_id = random() & 0x7fffffff;
|
||||||
|
|
||||||
q += sprintf(q, "Server: Cougar 4.1.0.3923\r\nCache-Control: no-cache\r\nPragma: client-id=%d\r\nPragma: features=\"broadcast\"\r\n", c->wmp_client_id);
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Server: Cougar 4.1.0.3923\r\nCache-Control: no-cache\r\nPragma: client-id=%d\r\nPragma: features=\"broadcast\"\r\n", c->wmp_client_id);
|
||||||
}
|
}
|
||||||
q += sprintf(q, "Content-Type: %s\r\n", mime_type);
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-Type: %s\r\n", mime_type);
|
||||||
q += sprintf(q, "\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
|
||||||
|
|
||||||
/* prepare output buffer */
|
/* prepare output buffer */
|
||||||
c->http_error = 0;
|
c->http_error = 0;
|
||||||
@ -1549,13 +1549,13 @@ static int http_parse_request(HTTPContext *c)
|
|||||||
send_error:
|
send_error:
|
||||||
c->http_error = 404;
|
c->http_error = 404;
|
||||||
q = c->buffer;
|
q = c->buffer;
|
||||||
q += sprintf(q, "HTTP/1.0 404 Not Found\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 404 Not Found\r\n");
|
||||||
q += sprintf(q, "Content-type: %s\r\n", "text/html");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: %s\r\n", "text/html");
|
||||||
q += sprintf(q, "\r\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
|
||||||
q += sprintf(q, "<HTML>\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<HTML>\n");
|
||||||
q += sprintf(q, "<HEAD><TITLE>404 Not Found</TITLE></HEAD>\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<HEAD><TITLE>404 Not Found</TITLE></HEAD>\n");
|
||||||
q += sprintf(q, "<BODY>%s</BODY>\n", msg);
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<BODY>%s</BODY>\n", msg);
|
||||||
q += sprintf(q, "</HTML>\n");
|
q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "</HTML>\n");
|
||||||
|
|
||||||
/* prepare output buffer */
|
/* prepare output buffer */
|
||||||
c->buffer_ptr = c->buffer;
|
c->buffer_ptr = c->buffer;
|
||||||
@ -1753,7 +1753,7 @@ static void compute_stats(HTTPContext *c)
|
|||||||
break;
|
break;
|
||||||
case CODEC_TYPE_VIDEO:
|
case CODEC_TYPE_VIDEO:
|
||||||
type = "video";
|
type = "video";
|
||||||
sprintf(parameters, "%dx%d, q=%d-%d, fps=%d", st->codec.width, st->codec.height,
|
snprintf(parameters, sizeof(parameters), "%dx%d, q=%d-%d, fps=%d", st->codec.width, st->codec.height,
|
||||||
st->codec.qmin, st->codec.qmax, st->codec.frame_rate / st->codec.frame_rate_base);
|
st->codec.qmin, st->codec.qmax, st->codec.frame_rate / st->codec.frame_rate_base);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -2382,6 +2382,14 @@ static int http_receive_data(HTTPContext *c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c->buffer_ptr - c->buffer >= 2 && c->data_count > FFM_PACKET_SIZE) {
|
||||||
|
if (c->buffer[0] != 'f' ||
|
||||||
|
c->buffer[1] != 'm') {
|
||||||
|
http_log("Feed stream has become desynchronized -- disconnecting\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (c->buffer_ptr >= c->buffer_end) {
|
if (c->buffer_ptr >= c->buffer_end) {
|
||||||
FFStream *feed = c->stream;
|
FFStream *feed = c->stream;
|
||||||
/* a packet has been received : write it in the store, except
|
/* a packet has been received : write it in the store, except
|
||||||
@ -3210,6 +3218,7 @@ static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec)
|
|||||||
fst->priv_data = av_mallocz(sizeof(FeedData));
|
fst->priv_data = av_mallocz(sizeof(FeedData));
|
||||||
memcpy(&fst->codec, codec, sizeof(AVCodecContext));
|
memcpy(&fst->codec, codec, sizeof(AVCodecContext));
|
||||||
fst->codec.coded_frame = &dummy_frame;
|
fst->codec.coded_frame = &dummy_frame;
|
||||||
|
fst->index = stream->nb_streams;
|
||||||
stream->streams[stream->nb_streams++] = fst;
|
stream->streams[stream->nb_streams++] = fst;
|
||||||
return fst;
|
return fst;
|
||||||
}
|
}
|
||||||
@ -3289,7 +3298,7 @@ static void extract_mpeg4_header(AVFormatContext *infile)
|
|||||||
if (!mpeg4_count)
|
if (!mpeg4_count)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
printf("MPEG4 without extra data: trying to find header\n");
|
printf("MPEG4 without extra data: trying to find header in %s\n", infile->filename);
|
||||||
while (mpeg4_count > 0) {
|
while (mpeg4_count > 0) {
|
||||||
if (av_read_packet(infile, &pkt) < 0)
|
if (av_read_packet(infile, &pkt) < 0)
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user