From: Bart Van Assche <bvanassche@acm.org>
To: linux-sparse@vger.kernel.org
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
Bart Van Assche <bvanassche@acm.org>
Subject: [PATCH 21/73] compile-i386: Fix buffer bounds, unsigned '<=' codegen, and null checks
Date: Mon, 9 Nov 2026 12:32:07 -0800 [thread overview]
Message-ID: <20261109203259.362845-22-bvanassche@acm.org> (raw)
In-Reply-To: <20261109203259.362845-1-bvanassche@acm.org>
Harden x86 code generation in compile-i386.c:
- Enlarge fixed formatting buffers and replace strcpy()/sprintf() calls
with bounded snprintf() in stor_op_name(), emit_insn_atom(), and
emit_global_noinit().
- Guard against zero-length array division by zero in emit_initializer()
and use sym->bit_size / 8 directly in emit_array_noinit().
- Emit 'setbe' instead of 'setb' for SPECIAL_UNSIGNED_LTE in
emit_compare().
- Handle SYM_PTR scalar initializers and guard current_func and
stmt->goto_label before dereferencing them.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
compile-i386.c | 76 ++++++++++++++++++++++++++++----------------------
1 file changed, 43 insertions(+), 33 deletions(-)
diff --git a/compile-i386.c b/compile-i386.c
index 16b3893a4ef1..81f6a9a7eceb 100644
--- a/compile-i386.c
+++ b/compile-i386.c
@@ -434,30 +434,30 @@ static void stor_sym_init(struct symbol *sym)
static const char *stor_op_name(struct storage *s)
{
- static char name[32];
+ static char name[256];
switch (s->type) {
case STOR_PSEUDO:
- strcpy(name, pretty_offset((int) pseudo_offset(s)));
+ snprintf(name, sizeof(name), "%s", pretty_offset((int) pseudo_offset(s)));
break;
case STOR_ARG:
- strcpy(name, pretty_offset((int) arg_offset(s)));
+ snprintf(name, sizeof(name), "%s", pretty_offset((int) arg_offset(s)));
break;
case STOR_SYM:
- strcpy(name, show_ident(s->sym->ident));
+ snprintf(name, sizeof(name), "%s", show_ident(s->sym->ident));
break;
case STOR_REG:
- strcpy(name, s->reg->name);
+ snprintf(name, sizeof(name), "%s", s->reg->name);
break;
case STOR_VALUE:
- sprintf(name, "$%lld", s->value);
+ snprintf(name, sizeof(name), "$%lld", s->value);
break;
case STOR_LABEL:
- sprintf(name, "%s.L%d", s->flags & STOR_LABEL_VAL ? "$" : "",
+ snprintf(name, sizeof(name), "%s.L%d", s->flags & STOR_LABEL_VAL ? "$" : "",
s->label);
break;
case STOR_LABELSYM:
- sprintf(name, "%s.LS%p", s->flags & STOR_LABEL_VAL ? "$" : "",
+ snprintf(name, sizeof(name), "%s.LS%p", s->flags & STOR_LABEL_VAL ? "$" : "",
s->labelsym);
break;
}
@@ -707,27 +707,27 @@ static void emit_section(const char *s)
static void emit_insn_atom(struct function *f, struct atom *atom)
{
- char s[128];
- char comment[64];
+ char s[512];
+ char comment[128];
struct storage *op1 = atom->op1;
struct storage *op2 = atom->op2;
if (atom->comment[0])
- sprintf(comment, "\t\t# %s", atom->comment);
+ snprintf(comment, sizeof(comment), "\t\t# %s", atom->comment);
else
comment[0] = 0;
if (atom->op2) {
- char tmp[16];
- strcpy(tmp, stor_op_name(op1));
- sprintf(s, "\t%s\t%s, %s%s\n",
+ char tmp[256];
+ snprintf(tmp, sizeof(tmp), "%s", stor_op_name(op1));
+ snprintf(s, sizeof(s), "\t%s\t%s, %s%s\n",
atom->insn, tmp, stor_op_name(op2), comment);
} else if (atom->op1)
- sprintf(s, "\t%s\t%s%s%s\n",
+ snprintf(s, sizeof(s), "\t%s\t%s%s%s\n",
atom->insn, stor_op_name(op1),
comment[0] ? "\t" : "", comment);
else
- sprintf(s, "\t%s\t%s%s\n",
+ snprintf(s, sizeof(s), "\t%s\t%s%s\n",
atom->insn,
comment[0] ? "\t\t" : "", comment);
@@ -941,16 +941,16 @@ static void emit_scalar(struct expression *expr, unsigned int bit_size)
static void emit_global_noinit(const char *name, unsigned long modifiers,
unsigned long alignment, unsigned int byte_size)
{
- char s[64];
+ char s[256];
if (modifiers & MOD_STATIC) {
- sprintf(s, "\t.local\t%s\n", name);
+ snprintf(s, sizeof(s), "\t.local\t%s\n", name);
textbuf_push(&unit_post_text, s);
}
if (alignment)
- sprintf(s, "\t.comm\t%s,%d,%lu\n", name, byte_size, alignment);
+ snprintf(s, sizeof(s), "\t.comm\t%s,%d,%lu\n", name, byte_size, alignment);
else
- sprintf(s, "\t.comm\t%s,%d\n", name, byte_size);
+ snprintf(s, sizeof(s), "\t.comm\t%s,%d\n", name, byte_size);
textbuf_push(&unit_post_text, s);
}
@@ -966,9 +966,14 @@ static void emit_initializer(struct symbol *sym,
if (expr->type == EXPR_VALUE) {
struct symbol *base_type = sym->ctype.base_type;
+ long long nr;
assert(base_type != NULL);
- emit_scalar(expr, sym->bit_size / get_expression_value(base_type->array_size));
+ nr = get_expression_value(base_type->array_size);
+ if (nr > 0)
+ emit_scalar(expr, sym->bit_size / nr);
+ else if (base_type->ctype.base_type && base_type->ctype.base_type->bit_size > 0)
+ emit_scalar(expr, base_type->ctype.base_type->bit_size);
return;
}
if (expr->type != EXPR_INITIALIZER)
@@ -1129,7 +1134,7 @@ static void emit_array_noinit(struct symbol *sym)
{
emit_global_noinit(show_ident(sym->ident),
sym->ctype.modifiers, sym->ctype.alignment,
- get_expression_value(sym->array_size) * (sym->bit_size / 8));
+ sym->bit_size / 8);
stor_sym_init(sym);
}
@@ -1249,7 +1254,7 @@ static struct storage *emit_compare(struct expression *expr)
case SPECIAL_UNSIGNED_GT:
opname = "seta"; break;
case SPECIAL_UNSIGNED_LTE:
- opname = "setb"; break;
+ opname = "setbe"; break;
case SPECIAL_UNSIGNED_GTE:
opname = "setae"; break;
default:
@@ -1820,13 +1825,16 @@ static void x86_symbol(struct symbol *sym)
break;
case SYM_BASETYPE:
+ case SYM_PTR:
if (sym->initializer) {
- emit_object_pre(show_ident(sym->ident),
- sym->ctype.modifiers,
- sym->ctype.alignment,
- sym->bit_size / 8);
- emit_scalar(sym->initializer, sym->bit_size);
- stor_sym_init(sym);
+ if (sym->initializer->type == EXPR_VALUE) {
+ emit_object_pre(show_ident(sym->ident),
+ sym->ctype.modifiers,
+ sym->ctype.alignment,
+ sym->bit_size / 8);
+ emit_scalar(sym->initializer, sym->bit_size);
+ stor_sym_init(sym);
+ }
} else
emit_scalar_noinit(sym);
break;
@@ -1857,8 +1865,8 @@ static void x86_symbol(struct symbol *sym)
break;
}
- if (sym->initializer && (type->type != SYM_BASETYPE) &&
- (type->type != SYM_ARRAY)) {
+ if (current_func && sym->initializer && (type->type != SYM_BASETYPE) &&
+ (type->type != SYM_ARRAY) && (type->type != SYM_PTR)) {
printf(" = \n");
x86_expression(sym->initializer);
}
@@ -2039,12 +2047,14 @@ static struct storage *x86_statement(struct statement *stmt)
if (stmt->goto_expression) {
struct storage *val = x86_expression(stmt->goto_expression);
printf("\tgoto *v%d\n", val->pseudo);
- } else if (!strcmp("break", show_ident(stmt->goto_label->ident))) {
+ } else if (stmt->goto_label && stmt->goto_label->ident &&
+ !strcmp("break", show_ident(stmt->goto_label->ident))) {
struct storage *lbv = new_storage(STOR_LABEL);
lbv->label = loopstk_break();
lbv->flags = STOR_WANTS_FREE;
insn("jmp", lbv, NULL, "'break'; go to loop bottom");
- } else if (!strcmp("continue", show_ident(stmt->goto_label->ident))) {
+ } else if (stmt->goto_label && stmt->goto_label->ident &&
+ !strcmp("continue", show_ident(stmt->goto_label->ident))) {
struct storage *lbv = new_storage(STOR_LABEL);
lbv->label = loopstk_continue();
lbv->flags = STOR_WANTS_FREE;
next prev parent reply other threads:[~2026-11-09 20:33 UTC|newest]
Thread overview: 74+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 20:31 Bart Van Assche
2026-11-09 20:31 ` [PATCH 01/73] Makefile: Pass '--' to rm in clean target to handle dash-prefixed files Bart Van Assche
2026-11-09 20:31 ` [PATCH 02/73] sparse-llvm: Use LLVMCreateBuilderForModule() with LLVM 24 and later Bart Van Assche
2026-11-09 20:31 ` [PATCH 03/73] typeof_unqual: Strip qualifiers and address space from types and arrays Bart Van Assche
2026-11-09 20:31 ` [PATCH 04/73] bitfield: Pack consecutive _Bool bitfields into byte containers Bart Van Assche
2026-11-09 20:31 ` [PATCH 05/73] allocate: Harden slab allocation bounds, zeroing, and mmap checks Bart Van Assche
2026-11-09 20:31 ` [PATCH 06/73] tokenize: Support 4096-byte identifiers and fix escape bounds Bart Van Assche
2026-11-09 20:31 ` [PATCH 07/73] pre-process: Fix macro expansion and include directive handling Bart Van Assche
2026-11-09 20:31 ` [PATCH 08/73] options, lib: Harden warning buffers and command-line option parsing Bart Van Assche
2026-11-09 20:31 ` [PATCH 09/73] builtin: Fix atomic builtin type checking and object_size bounds Bart Van Assche
2026-11-09 20:31 ` [PATCH 10/73] parse, show-parse: Fix attribute propagation, enum overflow, and bounds Bart Van Assche
2026-11-09 20:31 ` [PATCH 11/73] target-openrisc: Set target_openrisc.mach to MACH_OPENRISC Bart Van Assche
2026-11-09 20:31 ` [PATCH 12/73] evaluate: Fix pointer arithmetic, incomplete types, and qualifiers Bart Van Assche
2026-11-09 20:31 ` [PATCH 13/73] expand: Fix static initializer folding and floating-point casts Bart Van Assche
2026-11-09 20:32 ` [PATCH 14/73] inline: Copy union cast types and VLA bounds when inlining Bart Van Assche
2026-11-09 20:32 ` [PATCH 15/73] linearize, flow: Fix asm operands, switch case bounds, and DSE Bart Van Assche
2026-11-09 20:32 ` [PATCH 16/73] memops, ssa: Walk parent insns in reverse and skip mixed-size SSA Bart Van Assche
2026-11-09 20:32 ` [PATCH 17/73] simplify: Prevent overflow on LLONG_MIN negation and fix simplifications Bart Van Assche
2026-11-09 20:32 ` [PATCH 18/73] sparse: Gate context failure warning on Wcontext and catch underflow Bart Van Assche
2026-11-09 20:32 ` [PATCH 19/73] ast-model: Return AST_N_COLUMNS and inspect child nodes lazily Bart Van Assche
2026-11-09 20:32 ` [PATCH 20/73] c2xml: Guard against recursive symbols and free xmlGetProp() string Bart Van Assche
2026-11-09 20:32 ` Bart Van Assche [this message]
2026-11-09 20:32 ` [PATCH 22/73] ctags: Fix line comparison order and handle SYM_RESTRICT and SYM_LABEL Bart Van Assche
2026-11-09 20:32 ` [PATCH 23/73] dissect: Unwrap array element type via base_type() Bart Van Assche
2026-11-09 20:32 ` [PATCH 24/73] example: Fix show_op() rotating buffer dimensions Bart Van Assche
2026-11-09 20:32 ` [PATCH 25/73] graph: Check PSEUDO_SYM before dereferencing insn->func->sym Bart Van Assche
2026-11-09 20:32 ` [PATCH 26/73] scheck: Fix slice() upper bit index calculation Bart Van Assche
2026-11-09 20:32 ` [PATCH 27/73] sparse-llvm: Support arbitrary struct member counts and fix operand types Bart Van Assche
2026-11-09 20:32 ` [PATCH 28/73] inline: Duplicate generic expressions instead of evaluating them Bart Van Assche
2026-11-09 20:32 ` [PATCH 29/73] lib: Avoid mutating fmt before va_start() in warning() Bart Van Assche
2026-11-09 20:32 ` [PATCH 30/73] cse, canon: Cast pointers to uintptr_t before relational comparison Bart Van Assche
2026-11-09 20:32 ` [PATCH 31/73] context: Add "conditional context increment" model Bart Van Assche
2026-11-09 20:32 ` [PATCH 32/73] expand: Simplify signed constants early Bart Van Assche
2026-11-09 20:32 ` [PATCH 33/73] bitwise: Allow all-bits-set as a restricted value Bart Van Assche
2026-11-09 20:32 ` [PATCH 34/73] bitwise: Allow restricted ordered compares with unrestricted values Bart Van Assche
2026-11-09 20:32 ` [PATCH 35/73] bitwise: Keep unrestricted values unrestricted after a cast Bart Van Assche
2026-11-09 20:32 ` [PATCH 36/73] bitwise: Don't remove MOD_SPECIFIER from 'bitwise' types Bart Van Assche
2026-11-09 20:32 ` [PATCH 37/73] bitwise: Allow both regular casts and forced casts for restricted values Bart Van Assche
2026-11-09 20:32 ` [PATCH 38/73] clang-format: Add .clang-format configuration file Bart Van Assche
2026-11-09 20:32 ` [PATCH 39/73] options: Add support for -std=c23, -std=c2x and -std=gnu23 Bart Van Assche
2026-11-09 20:32 ` [PATCH 40/73] preprocessor: Add support for #elifdef and #elifndef Bart Van Assche
2026-11-09 20:32 ` [PATCH 41/73] preprocessor: Add support for __has_include and __has_include_next Bart Van Assche
2026-11-09 20:32 ` [PATCH 42/73] c23: Add support for static_assert, alignas, alignof, thread_local Bart Van Assche
2026-11-09 20:32 ` [PATCH 43/73] c23: Add support for bool, true, and false keywords Bart Van Assche
2026-11-09 20:32 ` [PATCH 44/73] c23: Add support for nullptr and nullptr_t Bart Van Assche
2026-11-09 20:32 ` [PATCH 45/73] c23: Add support for digit separators in numeric literals Bart Van Assche
2026-11-09 20:32 ` [PATCH 46/73] c23: Support unnamed parameters in function definitions Bart Van Assche
2026-11-09 20:32 ` [PATCH 47/73] c23: Support variadic functions without named parameters Bart Van Assche
2026-11-09 20:32 ` [PATCH 48/73] c23: Support labels before declarations and at block ends Bart Van Assche
2026-11-09 20:32 ` [PATCH 49/73] c23: Support auto type inference Bart Van Assche
2026-11-09 20:32 ` [PATCH 50/73] c23: Support constexpr object specifier Bart Van Assche
2026-11-09 20:32 ` [PATCH 51/73] c23: Support enumerations with fixed underlying types Bart Van Assche
2026-11-09 20:32 ` [PATCH 52/73] c23: Support standard [[]] attribute syntax Bart Van Assche
2026-11-09 20:32 ` [PATCH 53/73] preprocessor: Add support for __has_c_attribute Bart Van Assche
2026-11-09 20:32 ` [PATCH 54/73] c23: Support empty initializer braces {} Bart Van Assche
2026-11-09 20:32 ` [PATCH 55/73] preprocessor: Add support for __has_embed Bart Van Assche
2026-11-09 20:32 ` [PATCH 56/73] preprocessor: Add support for #embed directive Bart Van Assche
2026-11-09 20:32 ` [PATCH 57/73] c23: Add support for u8 character constants and string literals Bart Van Assche
2026-11-09 20:32 ` [PATCH 58/73] preprocessor: Add support for __VA_OPT__ Bart Van Assche
2026-11-09 20:32 ` [PATCH 59/73] c23: Treat empty parameter list () as (void) and reject K&R functions Bart Van Assche
2026-11-09 20:32 ` [PATCH 60/73] c23: Support storage-class specifiers in compound literals Bart Van Assche
2026-11-09 20:32 ` [PATCH 61/73] c23: Add support for _BitInt(N) Bart Van Assche
2026-11-09 20:32 ` [PATCH 62/73] enum: Support machine mode attributes on enumeration types Bart Van Assche
2026-11-09 20:32 ` [PATCH 63/73] enum: Support __attribute__((packed)) " Bart Van Assche
2026-11-09 20:32 ` [PATCH 64/73] expand: Ignore top-level non-array address space in compare_types() Bart Van Assche
2026-11-09 20:32 ` [PATCH 65/73] builtin: Support __builtin_infer_alloc_token() as a size_t ICE Bart Van Assche
2026-11-09 20:32 ` [PATCH 66/73] builtin: Add support for Linux kernel compiler builtins Bart Van Assche
2026-11-09 20:32 ` [PATCH 67/73] builtin: Add support for __builtin_has_attribute() Bart Van Assche
2026-11-09 20:32 ` [PATCH 68/73] cleanup: Support __attribute__((cleanup(...))) in linearize and -Wcontext Bart Van Assche
2026-11-09 20:32 ` [PATCH 69/73] builtin: Do not evaluate __builtin_clz(0) and __builtin_ctz(0) Bart Van Assche
2026-11-09 20:32 ` [PATCH 70/73] pre-process: Support long token and string expansions dynamically Bart Van Assche
2026-11-09 20:32 ` [PATCH 71/73] x86: Undefine conflicting bitness macros when parsing -m flags Bart Van Assche
2026-11-09 20:32 ` [PATCH 72/73] evaluate: Accept conditional expressions with only one void side Bart Van Assche
2026-11-09 20:32 ` [PATCH 73/73] ci: Add Linux kernel GitHub Actions workflow and build script Bart Van Assche
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261109203259.362845-22-bvanassche@acm.org \
--to=bvanassche@acm.org \
--cc=linux-sparse@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox