diff mbox series

[v2] libtraceevent: Fix a double free in process_op()

Message ID 20240722161917.991077-1-namhyung@google.com (mailing list archive)
State Accepted
Commit c3dc22001ef35ed0392558bdceb79571466410a9
Headers show
Series [v2] libtraceevent: Fix a double free in process_op() | expand

Commit Message

Namhyung Kim July 22, 2024, 4:19 p.m. UTC
When process_cond() failed, it freed the token but didn't reset the
arg->op.op to NULL.  So it tried to free the arg->op.op again from
free_arg() from the caller and resulted in a double free.

And Steve found another location that needs an update.  Let's handle
the error in consolidate_op_arg() instead.

Signed-off-by: Namhyung Kim <namhyung@google.com>
---
 src/event-parse.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/src/event-parse.c b/src/event-parse.c
index 9f0522c..ba4a153 100644
--- a/src/event-parse.c
+++ b/src/event-parse.c
@@ -2197,21 +2197,24 @@  static int set_op_prio(struct tep_print_arg *arg)
 	return arg->op.prio;
 }
 
-static int consolidate_op_arg(struct tep_print_arg *arg)
+static int consolidate_op_arg(enum tep_event_type type, struct tep_print_arg *arg)
 {
 	unsigned long long val, left, right;
 	int ret = 0;
 
+	if (type == TEP_EVENT_ERROR)
+		return -1;
+
 	if (arg->type != TEP_PRINT_OP)
 		return 0;
 
 	if (arg->op.left)
-		ret = consolidate_op_arg(arg->op.left);
+		ret = consolidate_op_arg(type, arg->op.left);
 	if (ret < 0)
 		return ret;
 
 	if (arg->op.right)
-		ret = consolidate_op_arg(arg->op.right);
+		ret = consolidate_op_arg(type, arg->op.right);
 	if (ret < 0)
 		return ret;
 
@@ -2375,8 +2378,6 @@  process_op(struct tep_event *event, struct tep_print_arg *arg, char **tok)
 
 		/* it will set arg->op.right */
 		type = process_cond(event, arg, tok);
-		if (type == TEP_EVENT_ERROR)
-			free(token);
 
 	} else if (strcmp(token, ">>") == 0 ||
 		   strcmp(token, "<<") == 0 ||
@@ -2587,7 +2588,7 @@  static int alloc_and_process_delim(struct tep_event *event, char *next_token,
 	if (type == TEP_EVENT_OP) {
 		type = process_op(event, field, &token);
 
-		if (consolidate_op_arg(field) < 0)
+		if (consolidate_op_arg(type, field) < 0)
 			type = TEP_EVENT_ERROR;
 
 		if (type == TEP_EVENT_ERROR)
@@ -3818,7 +3819,7 @@  static int event_read_print_args(struct tep_event *event, struct tep_print_arg *
 			type = process_op(event, arg, &token);
 			free_token(token);
 
-			if (consolidate_op_arg(arg) < 0)
+			if (consolidate_op_arg(type, arg) < 0)
 				type = TEP_EVENT_ERROR;
 
 			if (type == TEP_EVENT_ERROR) {