comparison oggparsevorbis.c @ 5232:ee0eaff74dd3 libavformat

Fix possible buffer over-read in vorbis_comment, fix it double to be sure. First, make s signed, so that comparisons against end - p will not be made as unsigned, making the check incorrectly pass if p is beyond end. Also ensure that p will never be > end, so the code is correct also if buf is not padded.
author reimar
date Thu, 24 Sep 2009 15:37:09 +0000
parents a59767d33928
children f16b8dab057b
comparison
equal deleted inserted replaced
5231:d2e3bc991df4 5232:ee0eaff74dd3
48 int 48 int
49 vorbis_comment(AVFormatContext * as, uint8_t *buf, int size) 49 vorbis_comment(AVFormatContext * as, uint8_t *buf, int size)
50 { 50 {
51 const uint8_t *p = buf; 51 const uint8_t *p = buf;
52 const uint8_t *end = buf + size; 52 const uint8_t *end = buf + size;
53 unsigned s, n, j; 53 unsigned n, j;
54 int s;
54 55
55 if (size < 8) /* must have vendor_length and user_comment_list_length */ 56 if (size < 8) /* must have vendor_length and user_comment_list_length */
56 return -1; 57 return -1;
57 58
58 s = bytestream_get_le32(&p); 59 s = bytestream_get_le32(&p);
59 60
60 if (end - p < s) 61 if (end - p - 4 < s || s < 0)
61 return -1; 62 return -1;
62 63
63 p += s; 64 p += s;
64 65
65 n = bytestream_get_le32(&p); 66 n = bytestream_get_le32(&p);
66 67
67 while (p < end && n > 0) { 68 while (end - p >= 4 && n > 0) {
68 const char *t, *v; 69 const char *t, *v;
69 int tl, vl; 70 int tl, vl;
70 71
71 s = bytestream_get_le32(&p); 72 s = bytestream_get_le32(&p);
72 73
73 if (end - p < s) 74 if (end - p < s || s < 0)
74 break; 75 break;
75 76
76 t = p; 77 t = p;
77 p += s; 78 p += s;
78 n--; 79 n--;