[FFmpeg-trac] #7084(avfilter:new): Memory leak in libavfilter/graphparser.c
FFmpeg
trac at avcodec.org
Tue Mar 13 12:51:53 EET 2018
#7084: Memory leak in libavfilter/graphparser.c
-------------------------------------+-------------------------------------
Reporter: Kira | Type: defect
Status: new | Priority: normal
Component: avfilter | Version:
Keywords: memory | unspecified
leak, parse_outputs | Blocked By:
Blocking: | Reproduced by developer: 0
Analyzed by developer: 0 |
-------------------------------------+-------------------------------------
parse_outputs from libavfilter/graphparser.c
{{{
#!div style="font-size: 80%"
{{{#!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
{{{
#!div style="font-size: 80%"
{{{#!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.
{{{
#!div style="font-size: 80%"
{{{#!C
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.
--
Ticket URL: <https://trac.ffmpeg.org/ticket/7084>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker
More information about the FFmpeg-trac
mailing list