Module Name: src Committed By: rillig Date: Sat Jul 15 12:24:57 UTC 2023
Modified Files: src/distrib/sets/lists/tests: mi src/usr.bin/xlint/lint1: tree.c Added Files: src/tests/usr.bin/xlint/lint1: gcc_statement_expression.c Log Message: tests/lint: demonstrate use-after-free in GCC statement expression To generate a diff of this commit: cvs rdiff -u -r1.1276 -r1.1277 src/distrib/sets/lists/tests/mi cvs rdiff -u -r0 -r1.1 \ src/tests/usr.bin/xlint/lint1/gcc_statement_expression.c cvs rdiff -u -r1.566 -r1.567 src/usr.bin/xlint/lint1/tree.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/distrib/sets/lists/tests/mi diff -u src/distrib/sets/lists/tests/mi:1.1276 src/distrib/sets/lists/tests/mi:1.1277 --- src/distrib/sets/lists/tests/mi:1.1276 Wed Jul 12 18:13:39 2023 +++ src/distrib/sets/lists/tests/mi Sat Jul 15 12:24:57 2023 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.1276 2023/07/12 18:13:39 rillig Exp $ +# $NetBSD: mi,v 1.1277 2023/07/15 12:24:57 rillig Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -6681,6 +6681,7 @@ ./usr/tests/usr.bin/xlint/lint1/gcc_cast_union.exp tests-obsolete obsolete,atf ./usr/tests/usr.bin/xlint/lint1/gcc_init_compound_literal.c tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/xlint/lint1/gcc_init_compound_literal.exp tests-obsolete obsolete,atf +./usr/tests/usr.bin/xlint/lint1/gcc_statement_expression.c tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/xlint/lint1/gcc_stmt_asm.c tests-usr.bin-tests compattestfile,atf ./usr/tests/usr.bin/xlint/lint1/gcc_stmt_asm.exp tests-obsolete obsolete,atf ./usr/tests/usr.bin/xlint/lint1/gcc_typeof.c tests-usr.bin-tests compattestfile,atf Index: src/usr.bin/xlint/lint1/tree.c diff -u src/usr.bin/xlint/lint1/tree.c:1.566 src/usr.bin/xlint/lint1/tree.c:1.567 --- src/usr.bin/xlint/lint1/tree.c:1.566 Fri Jul 14 09:20:23 2023 +++ src/usr.bin/xlint/lint1/tree.c Sat Jul 15 12:24:57 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: tree.c,v 1.566 2023/07/14 09:20:23 rillig Exp $ */ +/* $NetBSD: tree.c,v 1.567 2023/07/15 12:24:57 rillig Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -37,7 +37,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: tree.c,v 1.566 2023/07/14 09:20:23 rillig Exp $"); +__RCSID("$NetBSD: tree.c,v 1.567 2023/07/15 12:24:57 rillig Exp $"); #endif #include <float.h> @@ -4794,6 +4794,8 @@ static stmt_expr *stmt_exprs; void begin_statement_expr(void) { + debug_enter(); + stmt_expr *se = xmalloc(sizeof(*se)); se->se_mem = expr_save_memory(); se->se_sym = NULL; @@ -4818,13 +4820,21 @@ do_statement_expr(tnode_t *tn) tnode_t * end_statement_expr(void) { + tnode_t *tn; + stmt_expr *se = stmt_exprs; - if (se->se_sym == NULL) - return NULL; /* after a syntax error */ - tnode_t *tn = build_name(se->se_sym, false); + if (se->se_sym == NULL) { + tn = NULL; /* after a syntax error */ + goto end; + } + + tn = build_name(se->se_sym, false); (void)expr_save_memory(); /* leak */ expr_restore_memory(se->se_mem); stmt_exprs = se->se_enclosing; free(se); + +end: + debug_leave(); return tn; } Added files: Index: src/tests/usr.bin/xlint/lint1/gcc_statement_expression.c diff -u /dev/null src/tests/usr.bin/xlint/lint1/gcc_statement_expression.c:1.1 --- /dev/null Sat Jul 15 12:24:57 2023 +++ src/tests/usr.bin/xlint/lint1/gcc_statement_expression.c Sat Jul 15 12:24:57 2023 @@ -0,0 +1,27 @@ +/* $NetBSD: gcc_statement_expression.c,v 1.1 2023/07/15 12:24:57 rillig Exp $ */ +# 3 "gcc_statement_expression.c" + +/* + * Tests for the GCC extension 'statement expressions', which allows a block of + * statements to occur as part of an expression. + */ + + +// Ensure that the inner types are accessible from outside the block. +// Depending on the memory management strategy, the inner types might be freed +// too early. +static inline int +use_inner_type_from_outside(void) +{ + int x = ({ + struct outer { + struct inner { + int member; + } inner; + } outer = { { 3 } }; + // TODO: Move the '.inner.member' out of the statement + // expression, without a use-after-free crash. + outer.inner.member; + }); + return x; +}