vulnerable function:
parse_outputs from libavfilter/graphparser.c
static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs,
AVFilterInOut **open_inputs,
AVFilterInOut **open_outputs, void *log_ctx)
{
int ret, pad = 0;
while (**buf == '[') {
char *name = parse_link_name(buf, log_ctx);
AVFilterInOut *match;
AVFilterInOut *input = *curr_inputs;
if (!name)
return AVERROR(EINVAL);
if (!input) {
av_log(log_ctx, AV_LOG_ERROR,
"No output pad can be associated to link label '%s'.\n", name);
av_free(name);
return AVERROR(EINVAL);
}
*curr_inputs = (*curr_inputs)->next;
/* First check if the label is not in the open_inputs list */
match = extract_inout(name, open_inputs);
if (match) {
if ((ret = link_filter(input->filter_ctx, input->pad_idx,
match->filter_ctx, match->pad_idx, log_ctx)) < 0) {
av_free(name);
return ret;
}
av_freep(&match->name);
av_freep(&name);
av_freep(&match);
av_freep(&input);
} else {
/* Not in the list, so add the first input as an open_output */
input->name = name;
insert_inout(open_outputs, input);
}
*buf += strspn(*buf, WHITESPACES);
pad++;
}
return pad;
}
line 361:
match = extract_inout(name, open_inputs);
Extract a node from the linked list open_inputs
, the origin linked list changed here.
extract_inout from libavfilter/graphparser.c
static AVFilterInOut *extract_inout(const char *label, AVFilterInOut **links)
{
AVFilterInOut *ret;
// find the first node whose name is same as label.
while (*links && (!(*links)->name || strcmp((*links)->name, label)))
links = &((*links)->next);
ret = *links;
if (ret) { // off the chain
*links = ret->next;
ret->next = NULL;
}
return ret;
}
If the match
found, we enter here.
if (match) {
if ((ret = link_filter(input->filter_ctx, input->pad_idx,
match->filter_ctx, match->pad_idx, log_ctx)) < 0) {
av_free(name);
return ret;
}
av_freep(&match->name);
av_freep(&name);
av_freep(&match);
av_freep(&input);
}
If the link_filter call fails, the variable match
will never be freed!
So the memory leak happens here.
Compile the leak_poc.c
Run it and use htop or something else to monitor the memory consumption of the process. You will see the leak.