Browse code

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

Philip Gladstone authored on 2003/11/19 11:23:17
Showing 1 changed files
... ...
@@ -1253,7 +1253,7 @@ static int http_parse_request(HTTPContext *c)
1253 1253
         stream = stream->next;
1254 1254
     }
1255 1255
     if (stream == NULL) {
1256
-        sprintf(msg, "File '%s' not found", url);
1256
+        snprintf(msg, sizeof(msg), "File '%s' not found", url);
1257 1257
         goto send_error;
1258 1258
     }
1259 1259
 
... ...
@@ -1264,13 +1264,13 @@ static int http_parse_request(HTTPContext *c)
1264 1264
     if (stream->stream_type == STREAM_TYPE_REDIRECT) {
1265 1265
         c->http_error = 301;
1266 1266
         q = c->buffer;
1267
-        q += sprintf(q, "HTTP/1.0 301 Moved\r\n");
1268
-        q += sprintf(q, "Location: %s\r\n", stream->feed_filename);
1269
-        q += sprintf(q, "Content-type: text/html\r\n");
1270
-        q += sprintf(q, "\r\n");
1271
-        q += sprintf(q, "<html><head><title>Moved</title></head><body>\r\n");
1272
-        q += sprintf(q, "You should be <a href=\"%s\">redirected</a>.\r\n", stream->feed_filename);
1273
-        q += sprintf(q, "</body></html>\r\n");
1267
+        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 301 Moved\r\n");
1268
+        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Location: %s\r\n", stream->feed_filename);
1269
+        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: text/html\r\n");
1270
+        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
1271
+        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<html><head><title>Moved</title></head><body>\r\n");
1272
+        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "You should be <a href=\"%s\">redirected</a>.\r\n", stream->feed_filename);
1273
+        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "</body></html>\r\n");
1274 1274
 
1275 1275
         /* prepare output buffer */
1276 1276
         c->buffer_ptr = c->buffer;
... ...
@@ -1296,14 +1296,14 @@ static int http_parse_request(HTTPContext *c)
1296 1296
     if (post == 0 && max_bandwidth < current_bandwidth) {
1297 1297
         c->http_error = 200;
1298 1298
         q = c->buffer;
1299
-        q += sprintf(q, "HTTP/1.0 200 Server too busy\r\n");
1300
-        q += sprintf(q, "Content-type: text/html\r\n");
1301
-        q += sprintf(q, "\r\n");
1302
-        q += sprintf(q, "<html><head><title>Too busy</title></head><body>\r\n");
1303
-        q += sprintf(q, "The server is too busy to serve your request at this time.<p>\r\n");
1304
-        q += sprintf(q, "The bandwidth being served (including your stream) is %dkbit/sec, and this exceeds the limit of %dkbit/sec\r\n",
1299
+        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 Server too busy\r\n");
1300
+        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: text/html\r\n");
1301
+        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
1302
+        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<html><head><title>Too busy</title></head><body>\r\n");
1303
+        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");
1304
+        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",
1305 1305
             current_bandwidth, max_bandwidth);
1306
-        q += sprintf(q, "</body></html>\r\n");
1306
+        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "</body></html>\r\n");
1307 1307
 
1308 1308
         /* prepare output buffer */
1309 1309
         c->buffer_ptr = c->buffer;
... ...
@@ -1347,29 +1347,29 @@ static int http_parse_request(HTTPContext *c)
1347 1347
                     q = c->buffer;
1348 1348
                     switch(redir_type) {
1349 1349
                     case REDIR_ASX:
1350
-                        q += sprintf(q, "HTTP/1.0 200 ASX Follows\r\n");
1351
-                        q += sprintf(q, "Content-type: video/x-ms-asf\r\n");
1352
-                        q += sprintf(q, "\r\n");
1353
-                        q += sprintf(q, "<ASX Version=\"3\">\r\n");
1354
-                        q += sprintf(q, "<!-- Autogenerated by ffserver -->\r\n");
1355
-                        q += sprintf(q, "<ENTRY><REF HREF=\"http://%s/%s%s\"/></ENTRY>\r\n", 
1350
+                        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 ASX Follows\r\n");
1351
+                        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: video/x-ms-asf\r\n");
1352
+                        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
1353
+                        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<ASX Version=\"3\">\r\n");
1354
+                        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<!-- Autogenerated by ffserver -->\r\n");
1355
+                        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<ENTRY><REF HREF=\"http://%s/%s%s\"/></ENTRY>\r\n", 
1356 1356
                                 hostbuf, filename, info);
1357
-                        q += sprintf(q, "</ASX>\r\n");
1357
+                        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "</ASX>\r\n");
1358 1358
                         break;
1359 1359
                     case REDIR_RAM:
1360
-                        q += sprintf(q, "HTTP/1.0 200 RAM Follows\r\n");
1361
-                        q += sprintf(q, "Content-type: audio/x-pn-realaudio\r\n");
1362
-                        q += sprintf(q, "\r\n");
1363
-                        q += sprintf(q, "# Autogenerated by ffserver\r\n");
1364
-                        q += sprintf(q, "http://%s/%s%s\r\n", 
1360
+                        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 RAM Follows\r\n");
1361
+                        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: audio/x-pn-realaudio\r\n");
1362
+                        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
1363
+                        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "# Autogenerated by ffserver\r\n");
1364
+                        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "http://%s/%s%s\r\n", 
1365 1365
                                 hostbuf, filename, info);
1366 1366
                         break;
1367 1367
                     case REDIR_ASF:
1368
-                        q += sprintf(q, "HTTP/1.0 200 ASF Redirect follows\r\n");
1369
-                        q += sprintf(q, "Content-type: video/x-ms-asf\r\n");
1370
-                        q += sprintf(q, "\r\n");
1371
-                        q += sprintf(q, "[Reference]\r\n");
1372
-                        q += sprintf(q, "Ref1=http://%s/%s%s\r\n", 
1368
+                        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 ASF Redirect follows\r\n");
1369
+                        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: video/x-ms-asf\r\n");
1370
+                        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
1371
+                        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "[Reference]\r\n");
1372
+                        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Ref1=http://%s/%s%s\r\n", 
1373 1373
                                 hostbuf, filename, info);
1374 1374
                         break;
1375 1375
                     case REDIR_RTSP:
... ...
@@ -1380,11 +1380,11 @@ static int http_parse_request(HTTPContext *c)
1380 1380
                             p = strrchr(hostname, ':');
1381 1381
                             if (p)
1382 1382
                                 *p = '\0';
1383
-                            q += sprintf(q, "HTTP/1.0 200 RTSP Redirect follows\r\n");
1383
+                            q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 RTSP Redirect follows\r\n");
1384 1384
                             /* XXX: incorrect mime type ? */
1385
-                            q += sprintf(q, "Content-type: application/x-rtsp\r\n");
1386
-                            q += sprintf(q, "\r\n");
1387
-                            q += sprintf(q, "rtsp://%s:%d/%s\r\n", 
1385
+                            q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: application/x-rtsp\r\n");
1386
+                            q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
1387
+                            q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "rtsp://%s:%d/%s\r\n", 
1388 1388
                                          hostname, ntohs(my_rtsp_addr.sin_port), 
1389 1389
                                          filename);
1390 1390
                         }
... ...
@@ -1395,9 +1395,9 @@ static int http_parse_request(HTTPContext *c)
1395 1395
                             int sdp_data_size, len;
1396 1396
                             struct sockaddr_in my_addr;
1397 1397
 
1398
-                            q += sprintf(q, "HTTP/1.0 200 OK\r\n");
1399
-                            q += sprintf(q, "Content-type: application/sdp\r\n");
1400
-                            q += sprintf(q, "\r\n");
1398
+                            q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 OK\r\n");
1399
+                            q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: application/sdp\r\n");
1400
+                            q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
1401 1401
 
1402 1402
                             len = sizeof(my_addr);
1403 1403
                             getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
... ...
@@ -1428,7 +1428,7 @@ static int http_parse_request(HTTPContext *c)
1428 1428
             }
1429 1429
         }
1430 1430
 
1431
-        sprintf(msg, "ASX/RAM file not handled");
1431
+        snprintf(msg, sizeof(msg), "ASX/RAM file not handled");
1432 1432
         goto send_error;
1433 1433
     }
1434 1434
 
... ...
@@ -1493,12 +1493,12 @@ static int http_parse_request(HTTPContext *c)
1493 1493
                 }
1494 1494
             }
1495 1495
             
1496
-            sprintf(msg, "POST command not handled");
1496
+            snprintf(msg, sizeof(msg), "POST command not handled");
1497 1497
             c->stream = 0;
1498 1498
             goto send_error;
1499 1499
         }
1500 1500
         if (http_start_receive_data(c) < 0) {
1501
-            sprintf(msg, "could not open feed");
1501
+            snprintf(msg, sizeof(msg), "could not open feed");
1502 1502
             goto send_error;
1503 1503
         }
1504 1504
         c->http_error = 0;
... ...
@@ -1517,17 +1517,17 @@ static int http_parse_request(HTTPContext *c)
1517 1517
 
1518 1518
     /* open input stream */
1519 1519
     if (open_input_stream(c, info) < 0) {
1520
-        sprintf(msg, "Input stream corresponding to '%s' not found", url);
1520
+        snprintf(msg, sizeof(msg), "Input stream corresponding to '%s' not found", url);
1521 1521
         goto send_error;
1522 1522
     }
1523 1523
 
1524 1524
     /* prepare http header */
1525 1525
     q = c->buffer;
1526
-    q += sprintf(q, "HTTP/1.0 200 OK\r\n");
1526
+    q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 OK\r\n");
1527 1527
     mime_type = c->stream->fmt->mime_type;
1528 1528
     if (!mime_type)
1529 1529
         mime_type = "application/x-octet_stream";
1530
-    q += sprintf(q, "Pragma: no-cache\r\n");
1530
+    q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Pragma: no-cache\r\n");
1531 1531
 
1532 1532
     /* for asf, we need extra headers */
1533 1533
     if (!strcmp(c->stream->fmt->name,"asf_stream")) {
... ...
@@ -1535,10 +1535,10 @@ static int http_parse_request(HTTPContext *c)
1535 1535
 
1536 1536
         c->wmp_client_id = random() & 0x7fffffff;
1537 1537
 
1538
-        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);
1538
+        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);
1539 1539
     }
1540
-    q += sprintf(q, "Content-Type: %s\r\n", mime_type);
1541
-    q += sprintf(q, "\r\n");
1540
+    q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-Type: %s\r\n", mime_type);
1541
+    q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
1542 1542
     
1543 1543
     /* prepare output buffer */
1544 1544
     c->http_error = 0;
... ...
@@ -1549,13 +1549,13 @@ static int http_parse_request(HTTPContext *c)
1549 1549
  send_error:
1550 1550
     c->http_error = 404;
1551 1551
     q = c->buffer;
1552
-    q += sprintf(q, "HTTP/1.0 404 Not Found\r\n");
1553
-    q += sprintf(q, "Content-type: %s\r\n", "text/html");
1554
-    q += sprintf(q, "\r\n");
1555
-    q += sprintf(q, "<HTML>\n");
1556
-    q += sprintf(q, "<HEAD><TITLE>404 Not Found</TITLE></HEAD>\n");
1557
-    q += sprintf(q, "<BODY>%s</BODY>\n", msg);
1558
-    q += sprintf(q, "</HTML>\n");
1552
+    q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 404 Not Found\r\n");
1553
+    q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: %s\r\n", "text/html");
1554
+    q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
1555
+    q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<HTML>\n");
1556
+    q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<HEAD><TITLE>404 Not Found</TITLE></HEAD>\n");
1557
+    q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "<BODY>%s</BODY>\n", msg);
1558
+    q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "</HTML>\n");
1559 1559
 
1560 1560
     /* prepare output buffer */
1561 1561
     c->buffer_ptr = c->buffer;
... ...
@@ -1753,7 +1753,7 @@ static void compute_stats(HTTPContext *c)
1753 1753
                     break;
1754 1754
                 case CODEC_TYPE_VIDEO:
1755 1755
                     type = "video";
1756
-                    sprintf(parameters, "%dx%d, q=%d-%d, fps=%d", st->codec.width, st->codec.height,
1756
+                    snprintf(parameters, sizeof(parameters), "%dx%d, q=%d-%d, fps=%d", st->codec.width, st->codec.height,
1757 1757
                                 st->codec.qmin, st->codec.qmax, st->codec.frame_rate / st->codec.frame_rate_base);
1758 1758
                     break;
1759 1759
                 default:
... ...
@@ -2382,6 +2382,14 @@ static int http_receive_data(HTTPContext *c)
2382 2382
         }
2383 2383
     }
2384 2384
 
2385
+    if (c->buffer_ptr - c->buffer >= 2 && c->data_count > FFM_PACKET_SIZE) {
2386
+        if (c->buffer[0] != 'f' ||
2387
+            c->buffer[1] != 'm') {
2388
+            http_log("Feed stream has become desynchronized -- disconnecting\n");
2389
+            goto fail;
2390
+        }
2391
+    }
2392
+
2385 2393
     if (c->buffer_ptr >= c->buffer_end) {
2386 2394
         FFStream *feed = c->stream;
2387 2395
         /* a packet has been received : write it in the store, except
... ...
@@ -3210,6 +3218,7 @@ static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec)
3210 3210
     fst->priv_data = av_mallocz(sizeof(FeedData));
3211 3211
     memcpy(&fst->codec, codec, sizeof(AVCodecContext));
3212 3212
     fst->codec.coded_frame = &dummy_frame;
3213
+    fst->index = stream->nb_streams;
3213 3214
     stream->streams[stream->nb_streams++] = fst;
3214 3215
     return fst;
3215 3216
 }
... ...
@@ -3289,7 +3298,7 @@ static void extract_mpeg4_header(AVFormatContext *infile)
3289 3289
     if (!mpeg4_count)
3290 3290
         return;
3291 3291
 
3292
-    printf("MPEG4 without extra data: trying to find header\n");
3292
+    printf("MPEG4 without extra data: trying to find header in %s\n", infile->filename);
3293 3293
     while (mpeg4_count > 0) {
3294 3294
         if (av_read_packet(infile, &pkt) < 0)
3295 3295
             break;