From patchwork Sat Jan 3 20:04:40 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1227 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767470769; bh=bcb95kTs1DU6cIpt4CH8uVTbr2skP2hEY3/JqVIcRJA=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=kUW28uQ/mwoJwY9+eHPU+G3dLS1m7SkeOScdgfhQGwN6YLPenYb75feiit0uUppWL YtEkXqXsiUSSE855duBBBKDy1Ckrc7AGx6GHagbbltA7trUrmboOj1KvOT7QpO8xnS 4jm0Cp+kVK4Nd+w9RbWYx4Qj3dJVazqYc5mK/mf3Q09TfSeX+wH6CY4LSsltIB1sro MQrCaID6mpyRhQkG7YzhhS1jEiHZwDjhyqJU246/te3tvjX6ip58PBUHjeA0zxbAci Q5xoeqlr/BaNdE1oV/hse3tsfBjc4TJoJ5GZlv6MgJlllUkmmICkfT+7rG0HCJrNxR PMiyKDLAyAHzw== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id D4DE4690A1 for ; Sat, 3 Jan 2026 13:06:09 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id NldAH6jfqY8w for ; Sat, 3 Jan 2026 13:06:09 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767470769; bh=bcb95kTs1DU6cIpt4CH8uVTbr2skP2hEY3/JqVIcRJA=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=kUW28uQ/mwoJwY9+eHPU+G3dLS1m7SkeOScdgfhQGwN6YLPenYb75feiit0uUppWL YtEkXqXsiUSSE855duBBBKDy1Ckrc7AGx6GHagbbltA7trUrmboOj1KvOT7QpO8xnS 4jm0Cp+kVK4Nd+w9RbWYx4Qj3dJVazqYc5mK/mf3Q09TfSeX+wH6CY4LSsltIB1sro MQrCaID6mpyRhQkG7YzhhS1jEiHZwDjhyqJU246/te3tvjX6ip58PBUHjeA0zxbAci Q5xoeqlr/BaNdE1oV/hse3tsfBjc4TJoJ5GZlv6MgJlllUkmmICkfT+7rG0HCJrNxR PMiyKDLAyAHzw== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id C48E56908D for ; Sat, 3 Jan 2026 13:06:09 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767470768; bh=khX7MgNr8ooGgEI/Ixy7caBDTogIuf7TcHN+IBwgoqk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=usYLZcodCJ3xvy9ojrQbJgvi816lAiUYGdHx9seh5yfrvdl6L6vCtiVBkkfV+fzgK lkCe49MjleIxxIMvcVGLsJK0sVEsNw1yuHvFCk0VCxlMKvM68cBrbhlEY2mV8n/JUy g1pmft5WbcnYjmktYxa6q6ir26KCXfz3ppPQuu6/bcYpLk+tBKnYWVLHuFmDwtQnzg xejDXvnj9aW0h6EpsQqogu5Zt8adTuYgATkry19+sQ4ZFksEpBy11TuslXB65OxYRV 5Wd4Ea5oW7NTtXJLxrhAZgdsDabEGYl9T2+/eshlJD76AT1XsjLTBkmBj84e/JcmmL xX1VYCE2LeNPA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 264B668FCC; Sat, 3 Jan 2026 13:06:08 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id XwCwujNRPHUH; Sat, 3 Jan 2026 13:06:08 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1767470764; bh=K+bseODHmu4GRegnBG1qhsiYe7SXKyYK3jKkJqepRNk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JDmnnCoXM41W2VZoPKBqHo8dYBRXUakNzMAFU/vFMjom9q1MPiC4/Jqo6SVsN1Mqo o9BpHWY5iz6ciiAu9NnKIgIacu15LJTthJFz/CGr5SlogaBJIzU4HVTYHlXbrrKT6x 5DZU/JqBxI46IvNeWL1Jt49XifaLgM2QnZkUZFk2usKpVYQlgMRteZ7kiJ/paZ8JrZ unVnKLwuKJEQi9d2msc8YSVNe3vOpr0poNAhWbB8NQIWk5+x2fX2z7sI89QwHVt5xV Q3UQaf7oObd0T99Qn0K53MGsEyjig5ueyXjKipAPioFT6/LWGYoqYyONCJXa1zK8fB xFdp080tegTOw== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id B29286908D; Sat, 3 Jan 2026 13:06:03 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Sat, 3 Jan 2026 13:04:40 -0700 Message-ID: <20260103200510.3605009-10-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260103200510.3605009-1-sjg@u-boot.org> References: <20260103200510.3605009-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: IGTWWB7GZSD6D6GAVE4SPGDU7BZZ7QFZ X-Message-ID-Hash: IGTWWB7GZSD6D6GAVE4SPGDU7BZZ7QFZ X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Heinrich Schuchardt , Simon Glass , Claude X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH v2 09/29] sandbox: Add -M option to disable mcheck at runtime List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Add a command-line option (-M or --no_mcheck) to disable mcheck heap protection at runtime. When mcheck is disabled, the wrapper functions pass through directly to the underlying allocator without adding headers or checking for corruption. This is useful for debugging when mcheck interferes with test results, such as when memory-leak detection reports false positives due to accumulated allocations from other tests. Changes: - Add disable_mcheck flag to sandbox_state - Add mcheck_set_disabled() function to mcheck API - Modify dlmalloc wrappers to bypass mcheck when disabled - Add stub for when MCHECK_HEAP_PROTECTION is not enabled - Document the new option in sandbox.rst Co-developed-by: Claude Signed-off-by: Simon Glass --- (no changes since v1) arch/sandbox/cpu/start.c | 13 +++++++++++++ arch/sandbox/include/asm/state.h | 1 + common/dlmalloc.c | 33 +++++++++++++++++++++++++++++++- doc/arch/sandbox/sandbox.rst | 7 +++++++ include/mcheck.h | 11 +++++++++++ 5 files changed, 64 insertions(+), 1 deletion(-) diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 1a5ca97e15e..b9f48376d22 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -523,6 +524,15 @@ static int sandbox_cmdline_cb_noflat(struct sandbox_state *state, } SANDBOX_CMDLINE_OPT_SHORT(noflat, 'F', 0, "Don't run second set of DM tests"); +static int sandbox_cmdline_cb_no_mcheck(struct sandbox_state *state, + const char *arg) +{ + state->disable_mcheck = true; + + return 0; +} +SANDBOX_CMDLINE_OPT_SHORT(no_mcheck, 'M', 0, "Disable mcheck heap protection"); + static int sandbox_cmdline_cb_soft_fail(struct sandbox_state *state, const char *arg) { @@ -674,6 +684,9 @@ int sandbox_init(int argc, char *argv[], struct global_data *data) if (os_parse_args(state, argc, argv)) return 1; + if (state->disable_mcheck) + mcheck_set_disabled(true); + /* Remove old frame*.bmp files if video_frames_dir is set */ if (state->video_frames_dir) { char pattern[256]; diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index ff7493ec5d6..1b6eef4a9c3 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -178,6 +178,7 @@ struct sandbox_state { bool pager_bypass; /* Enable pager-bypass mode */ bool no_term_present; /* Assume no terminal present */ bool quiet_vidconsole; /* Don't use vidconsole for stdout */ + bool disable_mcheck; /* Disable mcheck heap protection */ int video_test; /* ms to wait before next assert */ const char *video_frames_dir; /* Directory to write video frames */ int video_frame_count; /* Number of frames written */ diff --git a/common/dlmalloc.c b/common/dlmalloc.c index 5069a95d9b3..78efdf5fd9a 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -5965,6 +5965,14 @@ static bool in_backtrace __section(".data"); */ static bool mcheck_skip_backtrace __section(".data"); +/* Runtime flag to disable mcheck - allows bypassing heap protection */ +static bool mcheck_disabled __section(".data"); + +void mcheck_set_disabled(bool disabled) +{ + mcheck_disabled = disabled; +} + void malloc_backtrace_skip(bool skip) { mcheck_skip_backtrace = skip; @@ -5993,6 +6001,9 @@ void *dlmalloc(size_t bytes) !(gd->flags & GD_FLG_FULL_MALLOC_INIT)) return malloc_simple(bytes); + if (mcheck_disabled) + return dlmalloc_impl(bytes CALLER_NULL); + mcheck_pedantic_prehook(); size_t fullsz = mcheck_alloc_prehook(bytes); void *p = dlmalloc_impl(fullsz CALLER_NULL); @@ -6009,12 +6020,15 @@ void dlfree(void *mem) dlfree_impl(mem); return; } + if (mcheck_disabled) { + dlfree_impl(mem); + return; + } dlfree_impl(mcheck_free_prehook(mem)); } void *dlrealloc(void *oldmem, size_t bytes) { - mcheck_pedantic_prehook(); #ifdef REALLOC_ZERO_BYTES_FREES if (bytes == 0) { if (oldmem) @@ -6026,6 +6040,10 @@ void *dlrealloc(void *oldmem, size_t bytes) if (oldmem == NULL) return dlmalloc(bytes); + if (mcheck_disabled) + return dlrealloc_impl(oldmem, bytes); + + mcheck_pedantic_prehook(); void *p = mcheck_reallocfree_prehook(oldmem); size_t newsz = mcheck_alloc_prehook(bytes); @@ -6041,6 +6059,9 @@ void *dlmemalign(size_t alignment, size_t bytes) !(gd->flags & GD_FLG_FULL_MALLOC_INIT)) return memalign_simple(alignment, bytes); + if (mcheck_disabled) + return dlmemalign_impl(alignment, bytes); + mcheck_pedantic_prehook(); size_t fullsz = mcheck_memalign_prehook(alignment, bytes); void *p = dlmemalign_impl(alignment, fullsz); @@ -6064,6 +6085,9 @@ void *dlcalloc(size_t n, size_t elem_size) return p; } + if (mcheck_disabled) + return dlcalloc_impl(n, elem_size); + mcheck_pedantic_prehook(); /* NB: no overflow check here */ size_t fullsz = mcheck_alloc_prehook(n * elem_size); @@ -6121,6 +6145,13 @@ void *dlcalloc(size_t n, size_t elem_size) } #endif /* MCHECK_HEAP_PROTECTION */ +#if !CONFIG_IS_ENABLED(MCHECK_HEAP_PROTECTION) +/* Stub when mcheck is not enabled */ +void mcheck_set_disabled(bool disabled) +{ +} +#endif + #endif /* !ONLY_MSPACES */ /* ----------------------------- user mspaces ---------------------------- */ diff --git a/doc/arch/sandbox/sandbox.rst b/doc/arch/sandbox/sandbox.rst index 90c3dfa837e..0962aeeb1a0 100644 --- a/doc/arch/sandbox/sandbox.rst +++ b/doc/arch/sandbox/sandbox.rst @@ -181,6 +181,13 @@ available options. Some of these are described below: all log statements at LOGL_DEBUG and below. The higher the number, the more info is shown. +-M, --no_mcheck + Disable mcheck heap protection at runtime. When enabled, the mcheck wrapper + functions pass through directly to the underlying allocator without adding + headers or checking for corruption. This is useful for debugging when mcheck + interferes with test results, such as when memory-leak detection reports false + positives due to accumulated allocations from other tests. + -m, --memory Sets the location of the file which holds sandbox's emulated RAM. This can be read and written across phases, so that sandbox behaves like a normal board. diff --git a/include/mcheck.h b/include/mcheck.h index b170acf6281..cd72edb6ae8 100644 --- a/include/mcheck.h +++ b/include/mcheck.h @@ -51,4 +51,15 @@ enum mcheck_status mprobe(void *__ptr); /* Called during RAM relocation to reset the heap registry */ void mcheck_on_ramrelocation(size_t offset); +/** + * mcheck_set_disabled() - Disable mcheck at runtime + * + * When disabled, mcheck wrapper functions pass through directly to the + * underlying allocator without adding headers or checking for corruption. + * This is useful for debugging when mcheck interferes with test results. + * + * @disabled: true to disable mcheck, false to enable + */ +void mcheck_set_disabled(bool disabled); + #endif