Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/xlint/lint1 lint: fix memory corruption in statement...
details: https://anonhg.NetBSD.org/src/rev/667cbcb986fb
branches: trunk
changeset: 362040:667cbcb986fb
user: rillig <rillig%NetBSD.org@localhost>
date: Sat Feb 26 20:36:11 2022 +0000
description:
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.
diffstat:
tests/usr.bin/xlint/lint1/d_gcc_compound_statements2.c | 29 +++++++++++++--
tests/usr.bin/xlint/lint1/t_integration.sh | 25 +-------------
usr.bin/xlint/lint1/cgram.y | 10 +++--
usr.bin/xlint/lint1/externs1.h | 3 +-
usr.bin/xlint/lint1/tree.c | 33 ++++++++++++++---
5 files changed, 61 insertions(+), 39 deletions(-)
diffs (212 lines):
diff -r 1dcaa05ba3a6 -r 667cbcb986fb tests/usr.bin/xlint/lint1/d_gcc_compound_statements2.c
--- a/tests/usr.bin/xlint/lint1/d_gcc_compound_statements2.c Sat Feb 26 19:01:09 2022 +0000
+++ b/tests/usr.bin/xlint/lint1/d_gcc_compound_statements2.c Sat Feb 26 20:36:11 2022 +0000
@@ -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 @@
}
int
-compound_expression_with_only_stmt(void)
+statement_expr_with_only_stmt(void)
{
struct cpu_info ci = { 0 };
return ({
@@ -26,3 +31,19 @@
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;
+ });
+}
diff -r 1dcaa05ba3a6 -r 667cbcb986fb tests/usr.bin/xlint/lint1/t_integration.sh
--- a/tests/usr.bin/xlint/lint1/t_integration.sh Sat Feb 26 19:01:09 2022 +0000
+++ b/tests/usr.bin/xlint/lint1/t_integration.sh Sat Feb 26 20:36:11 2022 +0000
@@ -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 @@
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_add_test_case "$name"
done
-
- atf_add_test_case 'assertion_failures'
}
diff -r 1dcaa05ba3a6 -r 667cbcb986fb usr.bin/xlint/lint1/cgram.y
--- a/usr.bin/xlint/lint1/cgram.y Sat Feb 26 19:01:09 2022 +0000
+++ b/usr.bin/xlint/lint1/cgram.y Sat Feb 26 20:36:11 2022 +0000
@@ -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 @@
$$ = 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();
}
diff -r 1dcaa05ba3a6 -r 667cbcb986fb usr.bin/xlint/lint1/externs1.h
--- a/usr.bin/xlint/lint1/externs1.h Sat Feb 26 19:01:09 2022 +0000
+++ b/usr.bin/xlint/lint1/externs1.h Sat Feb 26 20:36:11 2022 +0000
@@ -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 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);
diff -r 1dcaa05ba3a6 -r 667cbcb986fb usr.bin/xlint/lint1/tree.c
--- a/usr.bin/xlint/lint1/tree.c Sat Feb 26 19:01:09 2022 +0000
+++ b/usr.bin/xlint/lint1/tree.c Sat Feb 26 20:36:11 2022 +0000
@@ -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 @@
}
}
+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 @@
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;
}
Home |
Main Index |
Thread Index |
Old Index