diff options
author | wm4 <wm4@nowhere> | 2014-09-08 15:13:11 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-09-08 15:13:11 +0200 |
commit | 4ef531f8155762882a7ea72a4b569e922d055f2f (patch) | |
tree | 727b599a93eda534bb4dfa9d36f6ca4b026755f1 /input | |
parent | 3b5f28bd0f52209f0aeabe4b4a4a0fc60c710e0f (diff) |
input: fix use after free with legacy commands
To handle legacy commands, string replacement is used; the modified
string is returned by parse_cmd_str(), but it also frees all temporary
memory, which includes the replaced string.
Closes #1075.
Diffstat (limited to 'input')
-rw-r--r-- | input/cmd_parse.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/input/cmd_parse.c b/input/cmd_parse.c index 05cd066dbf..fd45094105 100644 --- a/input/cmd_parse.c +++ b/input/cmd_parse.c @@ -242,27 +242,28 @@ error: return NULL; } -static struct mp_cmd *parse_cmd_str(struct mp_log *log, bstr *str, const char *loc) +static struct mp_cmd *parse_cmd_str(struct mp_log *log, void *tmp, + bstr *str, const char *loc) { struct parse_ctx ctx = { .log = log, .loc = loc, - .tmp = talloc_new(NULL), + .tmp = tmp, .str = *str, .start = *str, }; struct mp_cmd *res = parse_cmd(&ctx, MP_ON_OSD_AUTO | MP_EXPAND_PROPERTIES); - talloc_free(ctx.tmp); *str = ctx.str; return res; } mp_cmd_t *mp_input_parse_cmd_(struct mp_log *log, bstr str, const char *loc) { + void *tmp = talloc_new(NULL); bstr original = str; - struct mp_cmd *cmd = parse_cmd_str(log, &str, loc); + struct mp_cmd *cmd = parse_cmd_str(log, tmp, &str, loc); if (!cmd) - return NULL; + goto done; // Handle "multi" commands struct mp_cmd **p_prev = NULL; @@ -287,16 +288,19 @@ mp_cmd_t *mp_input_parse_cmd_(struct mp_log *log, bstr str, const char *loc) p_prev = &cmd->queue_next; cmd = list; } - struct mp_cmd *sub = parse_cmd_str(log, &str, loc); + struct mp_cmd *sub = parse_cmd_str(log, tmp, &str, loc); if (!sub) { talloc_free(cmd); - return NULL; + cmd = NULL; + goto done; } talloc_steal(cmd, sub); *p_prev = sub; p_prev = &sub->queue_next; } +done: + talloc_free(tmp); return cmd; } |