Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory corruption in FLV wrapping if there is not enough allocated space for metadata #347

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 27 additions & 9 deletions src/flv.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ int flv_write_metadata (struct flv *flv, refbuf_t *scmeta, const char *mount)
{
char *value = stats_get_value (mount, "server_name");

flvmeta = flv_meta_allocate (200);
flvmeta = flv_meta_allocate (4000);
if (value)
flv_meta_append_string (flvmeta, "name", value);
free (value);
Expand Down Expand Up @@ -261,7 +261,7 @@ int flv_write_metadata (struct flv *flv, refbuf_t *scmeta, const char *mount)
flv_meta_append_bool (flvmeta, "hasMetadata", 1);
flv_meta_append_bool (flvmeta, "hasVideo", 0);
flv_meta_append_bool (flvmeta, "hasAudio", 1);
flv_meta_append_string (flvmeta, NULL, NULL);
flv_meta_append_end_marker (flvmeta);
flvm = (struct flvmeta *)flvmeta->data;
meta_copied = flvm->meta_pos - sizeof (*flvm);
if (meta_copied + 15 + flv->raw_offset > raw->len)
Expand Down Expand Up @@ -411,20 +411,29 @@ refbuf_t *flv_meta_allocate (size_t len)
}


void flv_meta_append_end_marker (refbuf_t *buffer)
{
struct flvmeta *flvm = (struct flvmeta *)buffer->data;
unsigned char *ptr = (unsigned char *)buffer->data + flvm->meta_pos;

if (3 + flvm->meta_pos > buffer->len) {
WARN0 ("not enough space for end-of-metadata marker");
return;
}

memcpy (ptr, "\000\000\011", 3);
flvm->meta_pos += 3;
}


static int flv_meta_increase (refbuf_t *buffer, int taglen, int valuelen)
{
struct flvmeta *flvm = (struct flvmeta *)buffer->data;
unsigned char *array_size_loc = (unsigned char *)buffer->data + sizeof (*flvm) + 16;

if (taglen + valuelen + 3 + flvm->meta_pos > buffer->len - 3)
taglen = 0; // force end of the metadata
if (taglen == 0)
{
DEBUG1 ("%d array elements", flvm->arraylen);
memcpy (buffer->data+flvm->meta_pos, "\000\000\011", 3);
flvm->meta_pos += 3;
return -1;
}

flvm->arraylen++;
flv_write_UI16 (array_size_loc, flvm->arraylen); // over 64k tags not handled
flvm->meta_pos += (2 + taglen + 1 + valuelen);
Expand All @@ -439,7 +448,10 @@ void flv_meta_append_bool (refbuf_t *buffer, const char *tag, int value)
unsigned char *ptr = (unsigned char *)buffer->data + flvm->meta_pos;

if (flv_meta_increase (buffer, taglen, 1) < 0)
{
WARN1 ("not enough space for %s", tag);
return;
}

flv_write_UI16 (ptr, taglen);
memcpy (ptr+2, tag, taglen);
Expand All @@ -457,7 +469,10 @@ void flv_meta_append_number (refbuf_t *buffer, const char *tag, double value)

if (tag) taglen = strlen (tag);
if (flv_meta_increase (buffer, taglen, 8) < 0)
{
WARN1 ("not enough space for %s", tag);
return;
}

flv_write_UI16 (ptr, taglen);
memcpy (ptr+2, tag, taglen);
Expand All @@ -479,7 +494,10 @@ void flv_meta_append_string (refbuf_t *buffer, const char *tag, const char *valu
if (value) valuelen = strlen (value);

if (flv_meta_increase (buffer, taglen, valuelen+2) < 0)
{
WARN1 ("not enough space for %s", tag);
return;
}

flv_write_UI16 (ptr, taglen);
memcpy (ptr+2, tag, taglen);
Expand Down
1 change: 1 addition & 0 deletions src/flv.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ refbuf_t *flv_meta_allocate (size_t len);
void flv_meta_append_string (refbuf_t *buffer, const char *tag, const char *value);
void flv_meta_append_number (refbuf_t *buffer, const char *tag, double value);
void flv_meta_append_bool (refbuf_t *buffer, const char *tag, int value);
void flv_meta_append_end_marker (refbuf_t *buffer);
2 changes: 1 addition & 1 deletion src/format_mp3.c
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ static void mp3_set_title (source_t *source)
DEBUG1 ("icy metadata as %.80s...", p->data+1);
yp_touch (source->mount, source->stats);

flv_meta_append_string (flvmeta, NULL, NULL);
flv_meta_append_end_marker (flvmeta);

if (ib_len > 0) ib_len--; // add nul char to help parsing
iceblock->len -= ib_len;
Expand Down