--- libmms-0.2.orig/src/mms.c +++ libmms-0.2/src/mms.c @@ -144,7 +144,7 @@ int stream_types[ASF_MAX_NUM_STREAMS]; off_t start_packet_seq; /* for live streams != 0, need to keep it around */ int need_discont; /* whether we need to set start_packet_seq */ - int asf_packet_len; + uint32_t asf_packet_len; uint64_t file_len; char guid[37]; uint32_t bitrates[ASF_MAX_NUM_STREAMS]; @@ -477,7 +477,7 @@ } static void string_utf16(iconv_t url_conv, char *dest, char *src, int len) { - memset(dest, 0, 1000); + memset(dest, 0, 2 * len); if (url_conv == (iconv_t)-1) { int i; @@ -503,7 +503,7 @@ static void string_utf16(int unused, char *dest, char *src, int len) { int i; - memset (dest, 0, 1000); + memset (dest, 0, 2 * len); for (i = 0; i < len; i++) { dest[i * 2] = src[i]; @@ -539,13 +539,17 @@ goto error; header->packet_len = LE_32(this->buf + 8) + 4; + if (header->packet_len > BUF_SIZE - 12) { + header->packet_len = 0; + goto error; + } lprintf("mms command\n"); packet_type = MMS_PACKET_COMMAND; } else { header->packet_seq = LE_32(this->buf); header->packet_id_type = this->buf[4]; header->flags = this->buf[5]; - header->packet_len = LE_16(this->buf + 6) - 8; + header->packet_len = (LE_16(this->buf + 6) - 8) & 0xffff; if (header->packet_id_type == ASF_HEADER_PACKET_ID_TYPE) { lprintf("asf header\n"); packet_type = MMS_PACKET_ASF_HEADER; @@ -674,6 +678,11 @@ break; case MMS_PACKET_ASF_HEADER: case MMS_PACKET_ASF_PACKET: + if (header.packet_len + this->asf_header_len > ASF_HEADER_LEN) { + lprintf( "***LOG:*** -- " + "libmms: asf packet too large\n"); + return 0; + } len = io_read(io, this->s, this->asf_header + this->asf_header_len, header.packet_len); if (len != header.packet_len) { @@ -720,6 +729,12 @@ case GUID_ASF_FILE_PROPERTIES: this->asf_packet_len = LE_32(this->asf_header + i + 92 - 24); + if (this->asf_packet_len > BUF_SIZE) { + this->asf_packet_len = 0; + lprintf( "***LOG:*** -- " + "libmms: asf packet len too large\n"); + break; + } this->file_len = LE_64(this->asf_header + i + 40 - 24); lprintf ("file object, packet length = %d (%d)\n", this->asf_packet_len, LE_32(this->asf_header + i + 96 - 24)); @@ -1420,8 +1435,20 @@ /* explicit padding with 0 */ lprintf("padding: %d bytes\n", this->asf_packet_len - header.packet_len); - memset(this->buf + header.packet_len, 0, this->asf_packet_len - header.packet_len); - this->buf_size = this->asf_packet_len; + { + char *base = (char *)(this->buf); + char *start = base + header.packet_len; + char *end = start + this->asf_packet_len - header.packet_len; + if ((start > base) && (start < (base+BUF_SIZE-1)) && + (start < end) && (end < (base+BUF_SIZE-1))) { + memset(this->buf + header.packet_len, 0, this->asf_packet_len - header.packet_len); + } + if (this->asf_packet_len > BUF_SIZE) { + this->buf_size = BUF_SIZE; + } else { + this->buf_size = this->asf_packet_len; + } + } } break; } --- libmms-0.2.orig/src/mmsh.c +++ libmms-0.2/src/mmsh.c @@ -184,7 +184,7 @@ int num_stream_ids; int stream_ids[ASF_MAX_NUM_STREAMS]; int stream_types[ASF_MAX_NUM_STREAMS]; - int packet_length; + uint32_t packet_length; int64_t file_length; char guid[37]; uint32_t bitrates[ASF_MAX_NUM_STREAMS]; @@ -604,6 +604,10 @@ case GUID_ASF_FILE_PROPERTIES: this->packet_length = LE_32(this->asf_header + i + 92 - 24); + if (this->packet_length > CHUNK_SIZE) { + this->packet_length = 0; + break; + } this->file_length = LE_64(this->asf_header + i + 40 - 24); lprintf ("file object, packet length = %d (%d)\n", this->packet_length, LE_32(this->asf_header + i + 96 - 24)); @@ -1054,9 +1058,22 @@ this->chunk_length, this->packet_length); return 0; } - memset(this->buf + this->chunk_length, 0, - this->packet_length - this->chunk_length); - this->buf_size = this->packet_length; + + { + char *base = (char *)(this->buf); + char *start = base + this->chunk_length; + char *end = start + this->packet_length - this->chunk_length; + if ((start > base) && (start < (base+CHUNK_SIZE-1)) && + (start < end) && (end < (base+CHUNK_SIZE-1))) { + memset(start, 0, + this->packet_length - this->chunk_length); + } + if (this->packet_length > CHUNK_SIZE) { + this->buf_size = CHUNK_SIZE; + } else { + this->buf_size = this->packet_length; + } + } return 1; } else { lprintf ("mmsh: read error, %d != %d\n", len, this->chunk_length);