summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-09-08 15:13:11 +0200
committerwm4 <wm4@nowhere>2014-09-08 15:13:11 +0200
commit4ef531f8155762882a7ea72a4b569e922d055f2f (patch)
tree727b599a93eda534bb4dfa9d36f6ca4b026755f1
parent3b5f28bd0f52209f0aeabe4b4a4a0fc60c710e0f (diff)
downloadmpv-4ef531f8155762882a7ea72a4b569e922d055f2f.tar.bz2
mpv-4ef531f8155762882a7ea72a4b569e922d055f2f.tar.xz
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.
-rw-r--r--input/cmd_parse.c18
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;
}