Module Name: src Committed By: rillig Date: Sat Feb 26 20:36:11 UTC 2022
Modified Files: src/tests/usr.bin/xlint/lint1: d_gcc_compound_statements2.c t_integration.sh src/usr.bin/xlint/lint1: cgram.y externs1.h tree.c Log Message: lint: fix memory corruption in statement expressions (since 2021-12-17) The commit that introduced the assertion failure looks innocent, it only adds a few predefined functions for GCC mode. Nevertheless, before that commit, lint consistently complained about 'error: void type illegal in expression [109]', which doesn't make sense either. This fix also removes the creative use of the initialization stack to store the type of the statement expression. Having a separate stack for these statement expressions makes the code easier to understand. To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 \ src/tests/usr.bin/xlint/lint1/d_gcc_compound_statements2.c cvs rdiff -u -r1.74 -r1.75 src/tests/usr.bin/xlint/lint1/t_integration.sh cvs rdiff -u -r1.380 -r1.381 src/usr.bin/xlint/lint1/cgram.y cvs rdiff -u -r1.145 -r1.146 src/usr.bin/xlint/lint1/externs1.h cvs rdiff -u -r1.403 -r1.404 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/tests/usr.bin/xlint/lint1/d_gcc_compound_statements2.c diff -u src/tests/usr.bin/xlint/lint1/d_gcc_compound_statements2.c:1.4 src/tests/usr.bin/xlint/lint1/d_gcc_compound_statements2.c:1.5 --- src/tests/usr.bin/xlint/lint1/d_gcc_compound_statements2.c:1.4 Fri Sep 10 20:02:51 2021 +++ src/tests/usr.bin/xlint/lint1/d_gcc_compound_statements2.c Sat Feb 26 20:36:11 2022 @@ -1,13 +1,18 @@ -/* $NetBSD: d_gcc_compound_statements2.c,v 1.4 2021/09/10 20:02:51 rillig Exp $ */ +/* $NetBSD: d_gcc_compound_statements2.c,v 1.5 2022/02/26 20:36:11 rillig Exp $ */ # 3 "d_gcc_compound_statements2.c" -/* GCC compound statements with non-expressions */ +/* + * GCC statement expressions with non-expressions. + * + * https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html + */ + struct cpu_info { int bar; }; int -compound_expression_with_decl_and_stmt(void) +statement_expr_with_decl_and_stmt(void) { return ({ struct cpu_info *ci; @@ -17,7 +22,7 @@ compound_expression_with_decl_and_stmt(v } int -compound_expression_with_only_stmt(void) +statement_expr_with_only_stmt(void) { struct cpu_info ci = { 0 }; return ({ @@ -26,3 +31,19 @@ compound_expression_with_only_stmt(void) ci; }).bar; } + +/* + * Since main1.c 1.58 from 2021-12-17 and before tree.c 1.404 from + * 2022-02-26, lint ran into an assertion failure due to a use-after-free. + * When typeok checked the operand types of the '=', the left node and the + * right node overlapped by 16 out of their 40 bytes on x86_64. + */ +void +statement_expr_with_loop(unsigned u) +{ + u = ({ + do { + } while (0); + u; + }); +} Index: src/tests/usr.bin/xlint/lint1/t_integration.sh diff -u src/tests/usr.bin/xlint/lint1/t_integration.sh:1.74 src/tests/usr.bin/xlint/lint1/t_integration.sh:1.75 --- src/tests/usr.bin/xlint/lint1/t_integration.sh:1.74 Sat Feb 26 16:43:20 2022 +++ src/tests/usr.bin/xlint/lint1/t_integration.sh Sat Feb 26 20:36:11 2022 @@ -1,4 +1,4 @@ -# $NetBSD: t_integration.sh,v 1.74 2022/02/26 16:43:20 rillig Exp $ +# $NetBSD: t_integration.sh,v 1.75 2022/02/26 20:36:11 rillig Exp $ # # Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. # All rights reserved. @@ -145,27 +145,6 @@ check_lint1() fi } -atf_test_case 'assertion_failures' -assertion_failures_body() -{ - # seen in sys/external/bsd/drm2/include/linux/kref.h:73 - - cat <<'EOF' > input.c -# 2 "input.c" -void -fn(unsigned int u) -{ - u = ({ - do {} while (0); - u; - }); -} -EOF - - atf_check -s 'signal' -e 'match:lint: assertion ".*" failed' \ - "$lint1" -gS 'input.c' '/dev/null' -} - atf_init_test_cases() { local src name @@ -183,6 +162,4 @@ atf_init_test_cases() }" atf_add_test_case "$name" done - - atf_add_test_case 'assertion_failures' } Index: src/usr.bin/xlint/lint1/cgram.y diff -u src/usr.bin/xlint/lint1/cgram.y:1.380 src/usr.bin/xlint/lint1/cgram.y:1.381 --- src/usr.bin/xlint/lint1/cgram.y:1.380 Sat Feb 26 19:01:09 2022 +++ src/usr.bin/xlint/lint1/cgram.y Sat Feb 26 20:36:11 2022 @@ -1,5 +1,5 @@ %{ -/* $NetBSD: cgram.y,v 1.380 2022/02/26 19:01:09 rillig Exp $ */ +/* $NetBSD: cgram.y,v 1.381 2022/02/26 20:36:11 rillig Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -35,7 +35,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: cgram.y,v 1.380 2022/02/26 19:01:09 rillig Exp $"); +__RCSID("$NetBSD: cgram.y,v 1.381 2022/02/26 20:36:11 rillig Exp $"); #endif #include <limits.h> @@ -517,8 +517,10 @@ postfix_expression: $$ = build_name(*current_initsym(), false); end_initialization(); } - | T_LPAREN compound_statement_lbrace gcc_statement_expr_list { - do_statement_expr($3); + | T_LPAREN compound_statement_lbrace { + begin_statement_expr(); + } gcc_statement_expr_list { + do_statement_expr($4); } compound_statement_rbrace T_RPAREN { $$ = end_statement_expr(); } Index: src/usr.bin/xlint/lint1/externs1.h diff -u src/usr.bin/xlint/lint1/externs1.h:1.145 src/usr.bin/xlint/lint1/externs1.h:1.146 --- src/usr.bin/xlint/lint1/externs1.h:1.145 Sat Feb 26 19:01:09 2022 +++ src/usr.bin/xlint/lint1/externs1.h Sat Feb 26 20:36:11 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: externs1.h,v 1.145 2022/02/26 19:01:09 rillig Exp $ */ +/* $NetBSD: externs1.h,v 1.146 2022/02/26 20:36:11 rillig Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -262,6 +262,7 @@ extern bool constant_addr(const tnode_t extern strg_t *cat_strings(strg_t *, strg_t *); extern unsigned int type_size_in_bits(const type_t *); +void begin_statement_expr(void); void do_statement_expr(tnode_t *); tnode_t *end_statement_expr(void); Index: src/usr.bin/xlint/lint1/tree.c diff -u src/usr.bin/xlint/lint1/tree.c:1.403 src/usr.bin/xlint/lint1/tree.c:1.404 --- src/usr.bin/xlint/lint1/tree.c:1.403 Sat Feb 26 19:01:09 2022 +++ src/usr.bin/xlint/lint1/tree.c Sat Feb 26 20:36:11 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: tree.c,v 1.403 2022/02/26 19:01:09 rillig Exp $ */ +/* $NetBSD: tree.c,v 1.404 2022/02/26 20:36:11 rillig Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -37,7 +37,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: tree.c,v 1.403 2022/02/26 19:01:09 rillig Exp $"); +__RCSID("$NetBSD: tree.c,v 1.404 2022/02/26 20:36:11 rillig Exp $"); #endif #include <float.h> @@ -4539,13 +4539,30 @@ check_precedence_confusion(tnode_t *tn) } } +typedef struct stmt_expr { + struct memory_block *se_mem; + sym_t *se_sym; + struct stmt_expr *se_enclosing; +} stmt_expr; + +static stmt_expr *stmt_exprs; + +void +begin_statement_expr(void) +{ + stmt_expr *se = xmalloc(sizeof(*se)); + se->se_mem = expr_save_memory(); + se->se_sym = NULL; + se->se_enclosing = stmt_exprs; + stmt_exprs = se; +} + void do_statement_expr(tnode_t *tn) { block_level--; mem_block_level--; - /* Use the initialization code as temporary symbol storage. */ - begin_initialization(mktempsym(dup_type(tn->tn_type))); + stmt_exprs->se_sym = mktempsym(dup_type(tn->tn_type)); mem_block_level++; block_level++; /* ({ }) is a GCC extension */ @@ -4556,7 +4573,11 @@ do_statement_expr(tnode_t *tn) tnode_t * end_statement_expr(void) { - tnode_t *tn = build_name(*current_initsym(), false); - end_initialization(); + stmt_expr *se = stmt_exprs; + tnode_t *tn = build_name(se->se_sym, false); + expr_save_memory(); /* leak */ + expr_restore_memory(se->se_mem); + stmt_exprs = se->se_enclosing; + free(se); return tn; }