Commit Graph

112 Commits

Author SHA1 Message Date
Simon Glass
b4f6fdbcd2 sandbox: Add -M option to disable mcheck at runtime
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 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2026-01-03 12:39:14 -07:00
Simon Glass
b8b8a65133 mcheck: Skip mcheck overhead for pre-relocation allocations
When mcheck heap-protection is enabled, each allocation adds quite a
bit of overhead for headers and canaries. While this is needed for the
full allocator, it serves no purpose for pre-relocation allocations,
since:

1. Simple malloc is a bump allocator that cannot free memory
3. Mcheck's corruption-detection provides no benefit for non-freeable
   memory

Since the pre-relocation heap space is limited (typically <16KB), this
overhead can exhaust the heap, causing boot failures.

Fix this by bypassing mcheck hooks in dlmalloc(), dlfree(),
dlmemalign() and dlcalloc() when called before relocation, directly
calling the simple malloc functions instead.

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2026-01-01 14:27:30 -07:00
Simon Glass
9998ff5c87 malloc: Show caller info for freed chunks in malloc_dump
When CONFIG_MCHECK_HEAP_PROTECTION is enabled, show the original
caller info for freed chunks. This helps identify what code allocated
memory that is now free.

The mcheck header's canary and caller fields survive after free since
dlmalloc only overwrites the first 16 bytes (size, aln_skip) with its
free list pointers (fd, bk). We detect freed headers by looking for
the MAGICFREE canary pattern.

For small chunks or coalesced chunks where the header is not preserved,
the caller info is simply omitted.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-10 05:53:03 -07:00
Simon Glass
754a755e4a malloc: Record caller backtrace for each allocation
When CONFIG_MCHECK_HEAP_PROTECTION is enabled, use backtrace_str() to
capture the caller information for each malloc/calloc/realloc/memalign
call. This information is stored in the mcheck header and can be viewed
with 'malloc dump'.

Add a flag to disable the backtrace when the stack is corrupted, since
the backtrace code tries to walks the invalid stack frames and will
crash.

Note: A few allocations made during libbacktrace initialisation may
not have caller info since they occur during the first backtrace call.

Example output showing caller info:
    18a1d010   90  used  log_init:453 <-board_init_r:774
    18a1d0a0 6060  used  membuf_new:420 <-console_record
    18a3b840   90  used  of_alias_scan:911 <-board_init_

Fix up the backtrace test to avoid recursion.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-10 05:53:03 -07:00
Simon Glass
36118a9e18 malloc: Fix malloc_dump to find mcheck headers in memalign chunks
For memalign allocations, the mcheck header is placed at an offset from
the chunk start to maintain alignment. The current assumption is that
the header is always at the start of the chunk, but this is not true for
memalign allocations.

Add find_mcheck_hdr_in_chunk() which looks up the header in the mcheck
registry and validates:
- The header falls within the chunk's memory range
- The aln_skip field is consistent with the header position
- The canary is MAGICWORD (active), not MAGICFREE (freed)

This ensures malloc_dump correctly displays caller info for all
allocations including those made via memalign.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-10 05:53:03 -07:00
Simon Glass
ee8e9bf104 malloc: Add malloc dump command to walk the heap
Add a new 'malloc dump' command that walks the dlmalloc heap from start
to end, printing each chunk's address, size (in hex), and status
(used/free/top). This is useful for debugging memory allocation issues.

When CONFIG_MCHECK_HEAP_PROTECTION is enabled, the caller string is
also shown if available.

Example output:
    Heap dump: 18a1d000 - 1ea1f000
         Address        Size  Status
    ----------------------------------
        18a1d000          10  (chunk header)
        18a1d010          90  used
        18adfc30          60  <free>
        18adff90     5f3f030  top
        1ea1f000              end
    ----------------------------------
    Used: c2ef0 bytes in 931 chunks
    Free: 5f3f0c0 bytes in 2 chunks + top

Expand the console-record size to handle this command.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-10 05:53:03 -07:00
Simon Glass
e2ccfa9c23 malloc: Add a caller-info parameter to dlmalloc_impl()
When CONFIG_MALLOC_DEBUG is enabled, add an optional caller string
parameter to dlmalloc_impl(). This allows tracking where allocations
originate from when debugging memory issues.

The CALLER_PARAM, CALLER_ARG, and CALLER_NULL macros hide the parameter
when MALLOC_DEBUG is not enabled, keeping the non-debug code path clean.

When MALLOC_DEBUG is enabled (with or without MCHECK), the _impl
functions must be separate from the public API functions since they
have different signatures. Add simple pass-through wrappers for this
case.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-10 05:53:03 -07:00
Simon Glass
834e83ffc1 malloc: Support storing caller information
Add a field to store the caller for each allocation, using the backtrace
information. This can be useful when debugging heap corruption.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-10 05:53:03 -07:00
Simon Glass
87c2c087ea malloc: Update the valloc functions to use mcheck wrappers
Fix dlposix_memalign(), dlvalloc(), and dlpvalloc() to call dlmemalign()
instead of dlmemalign_impl() or internal_memalign() directly. This
ensures these functions go through the mcheck wrappers when
CONFIG_MCHECK_HEAP_PROTECTION is enabled.

Without this fix, internal_memalign is undefined when mcheck is enabled,
causing a build error.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-10 05:53:03 -07:00
Simon Glass
f96cb92d4c malloc: Fix internal calls and memalign for mcheck
With mcheck enabled, internal_malloc and internal_free go through mcheck
wrappers which expect user pointers (after mcheck header), not raw
allocator pointers. Also, dlmemalign_impl() needs a properly aligned base
pointer for mcheck to place its header correctly.

Use _impl functions directly for internal_malloc/internal_free. Call
internal_memalign() for alignments greater than MALLOC_ALIGNMENT.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-10 05:53:03 -07:00
Simon Glass
22c435d21b malloc: Move mcheck block after includes
Move the CONFIG_MCHECK_HEAP_PROTECTION block after the standard
includes so that size_t and string functions are available for
the inline MALLOC_ZERO and MALLOC_COPY functions.

Add the <string.h> and <linux/types.h> includes needed for mcheck.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-10 05:53:03 -07:00
Simon Glass
331063acd0 malloc: Add a Kconfig option for heap protection
Add CONFIG_MCHECK_HEAP_PROTECTION option to enable mcheck heap
protection. Convert all uses of MCHECK_HEAP_PROTECTION to use the
CONFIG_ -prefixed version to work with Kconfig.

Disable this option when tracing is enabled, since the mcheck hooks (mcheck_pedantic_prehook(), etc.) interfere with function tracing.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-10 05:53:03 -07:00
Simon Glass
d8b19014d7 malloc: Add call counters for malloc, free, realloc
Add counters to track the number of calls to malloc(), free(), and
realloc(). These are displayed by the 'malloc info' command and
accessible via malloc_get_info().

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-10 05:53:03 -07:00
Simon Glass
bd0f9a753c malloc: Enable stats if UNIT_TEST or MALLOC_DEBUG
When debugging or running unit tests it is helpful to have information
available from the malloc subsystem. Enable these features in those
cases.

Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-10 05:53:03 -07:00
Simon Glass
c3fb5f4018 malloc: Add a Kconfig option for debugging malloc()
Add a new CONFIG_MALLOC_DEBUG option to control malloc() debugging
features. This replaces the direct UNIT_TEST check and allows enabling
malloc debugging independently of whether UNIT_TEST is enabled.

The option defaults to y when UNIT_TEST is enabled, preserving existing
behaviour. Disable for RISC-V since it seems to have a size limitation.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-10 05:53:03 -07:00
Simon Glass
bd73f8182a malloc: Add malloc_get_info() to retrieve memory statistics
Add struct malloc_info and malloc_get_info() function to
programmatically access the memory-allocation stats that malloc_stats()
prints.

The struct contains the size of the malloc() poll and the number of
bytes in use.

Add a static inline stub to return an error when DEBUG is not defined.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-10 05:53:03 -07:00
Simon Glass
a91d1a5541 malloc: Fix unused internal_memalign warning with mcheck
When CONFIG_MCHECK_HEAP_PROTECTION is enabled, dlmemalign_impl() calls
dlmalloc_impl() directly since the mcheck wrapper handles alignment.
This leaves internal_memalign() unused, causing a compiler warning.

Guard internal_memalign() with a preprocessor check so it's only
compiled when needed (mcheck disabled or MSPACES enabled).

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-10 05:53:03 -07:00
Simon Glass
95f10a6302 malloc: Make mcheck respect REALLOC_ZERO_BYTES_FREES
The mcheck wrapper for realloc() unconditionally frees memory and
returns NULL when size is 0. This differs from dlmalloc's default
behaviour which returns a minimum-sized allocation unless
REALLOC_ZERO_BYTES_FREES is defined.

Make the mcheck wrapper respect the same REALLOC_ZERO_BYTES_FREES
setting for consistent behavior with or without mcheck enabled.

Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-10 05:53:03 -07:00
Simon Glass
4096d43361 doc: Add malloc documentation
Add doc/develop/malloc.rst documenting U-Boot's dynamic memory
allocation implementation:

- Overview of pre/post-relocation malloc phases
- dlmalloc 2.8.6 version and features
- Data structure sizes (~500 bytes vs 1032 bytes in 2.6.6)
- Configuration options for code-size optimization
- Debugging features (mcheck, valgrind, malloc testing)
- API reference

Also add an introductory comment to dlmalloc.c summarising the
U-Boot configuration.

Series-to: concept
Series-cc: heinrich
Cover-letter:
malloc: Import dlmalloc 2.8.6
This series imports dlmalloc 2.8.6 from Doug Lea, replacing the old
version 2.6.6 that U-Boot has been using since 2002.

The new version provides:
- Better memory efficiency with improved binning algorithms
- More robust overflow checking via MAX_REQUEST
- Somewhat cleaner codebase

All U-Boot-specific modifications from the historical commits have been
ported to the new implementation, including:
- Pre-relocation malloc via malloc_simple
- Valgrind annotations
- Malloc testing infrastructure
- mcheck heap protection support
- Sandbox USE_DL_PREFIX support

The approach here is to leave the upstream code unchanged, so much as
possible, clearly marking U-Boot-specific changes with an #ifdef

Unfortunately the code size is not great out-of-the-box, so the final
part of the series includes some options to remove in-place realloc(),
provide a simplified init, remove the tree stucture for large blocks
and a few other things.

With these adjustments the new version is about 1K less code on Thumb2
(firefly-rk3288).

The new free() algorithm is more sophisticated but also larger. If
needed we might be able to shrink by a few hundred bytes. Of course SPL
doesn't normally use free() so the benefit might be minimal.

Another point worth mentioning is that the pre-inited av_[] array has
been replaced replaced with a BSS _sm_ struct which reduces the image
size by about 1.5K. One patch adjusts some imx8mp boards to deal with
the larger BSS.

Some code-size stats:

  $ buildman -b mala imx8mp_venice firefly-rk3288 firefly-rk3399 -sS --step 0
  Summary of 2 commits for 3 boards (3 threads, 11 jobs per thread)
  01: backtrace: Strip the source tree prefix from filenames
     aarch64:  w+   imx8mp_venice firefly-rk3399
  40: doc: Add malloc documentation
     aarch64: (for 2/2 boards) all -3904.0 bss +864.0 data -2076.0
       spl/u-boot-spl:all -654.0 spl/u-boot-spl:bss +316.0
       spl/u-boot-spl:data -1034.0 spl/u-boot-spl:text +64.0 text -2692.0
     arm: (for 1/1 boards) all -1436.0 data -1040.0 text -396.0

For the new malloc.h I have avoided including string.h so have added
that to various places that need it.

The existing common/dlmalloc.src file is left alone.

In order to bring this in without losing functionality, I went through
the patches applied to the original implementation over time. Where
these commits were added, they are added as a cherry-pick, with the
original commit hash.

Here is a list of what was done with each U-Boot commit on top of the
new common/dlmalloc.c and include/malloc.h:

 1. 217c9dad82 2002-10-25 Initial revision
    - Ignored

 2. 5b1d713721 2002-11-03 Initial revision
    - Ignored

 3. 8bde7f776c 2003-06-27 * Code cleanup:
    - Ignored as we don't really want to change the style

 4. d87080b721 2006-03-31 GCC-4.x fixes: clean up global data pointer initialization for all boards.
    - Global data is not needed at this point

 5. 81673e9ae1 2008-05-13 Make sure common.h is the first include.
    - common.h has been removed

 6. f2302d4430 2008-08-06 Fix merge problems
    - no merge problems to fix with the new code

 7. 60a3f404ac 2009-06-13 malloc.h: protect it against multiple include
    - Already covered: new malloc.h has MALLOC_280_H include guards

 8. 5e93bd1c9a 2009-08-21 Consolidate arch-specific sbrk() implementations
    - Already covered: sbrk() and mem_malloc_init() in separate commit

 9. d4e8ada0f6 2009-08-21 Consolidate arch-specific mem_malloc_init() implementations
    - Already covered: mem_malloc_init() in separate commit

10. 521af04d85 2009-09-21 Conditionally perform common relocation fixups
    - Not needed: Manual relocation removed in 4babaa0c28

11. b4feeb4e8a 2009-11-24 i386: Fix malloc initialization
    - Already covered: mem_malloc_init() is common, no arch-specific guards

12. 2740544881 2010-01-15 malloc: return NULL if not initialized yet
    - Done: Add check in dlmalloc() to return NULL if not initialized

13. ae30b8c200 2010-04-06 malloc: sbrk() should return MORECORE_FAILURE instead of NULL on failure
    - Already covered: sbrk() returns MFAIL on failure

14. ea882baf9c 2010-06-20 New implementation for internal handling of environment variables.
    - Not needed: Just changes #if 0 to #ifdef DEBUG for old stats code

15. 1ba91ba233 2010-10-14 dlmalloc.c: Fix gcc alias warning
    - Not needed: New dlmalloc has no strict-aliasing warnings

16. 2e5167ccad 2010-10-28 Replace CONFIG_RELOC_FIXUP_WORKS by CONFIG_NEEDS_MANUAL_RELOC
    - Not needed: Manual relocation removed in 4babaa0c28

17. 6163f5b4c8 2010-11-15 malloc: Fix issue with calloc memory possibly being non-zero
    - Already covered: sbrk() clears memory on negative increment

18. 21726a7afc 2011-06-29 Add assert() for debug assertions
    - Not needed: New dlmalloc uses U-Boot's global assert()

19. ea95cb7331 2011-09-10 utx8245: fix build breakage due to assert()
    - Not needed: New dlmalloc has different debug check functions

20. 213adf6dff 2012-03-29 Malloc: Fix -Wundef warnings
    - Not needed: New malloc.h doesn't have these #if issues

21. 93691842e8 2012-09-04 Fix strict-aliasing warning in dlmalloc
    - Not needed: New dlmalloc has no malloc_bin_reloc()

22. 00d0d2ad4e 2012-06-03 malloc: remove extern declarations of malloc_bin_reloc() in board.c files
    - Not needed: New dlmalloc has no malloc_bin_reloc()

23. 199adb601f 2012-10-29 common/misc: sparse fixes
    - Not needed: New dlmalloc uses proper NULL

24. 7b395232da 2013-01-21 malloc: make malloc_bin_reloc static
    - Not needed: New dlmalloc has no malloc_bin_reloc()

25. 472d546054 2013-04-01 Consolidate bool type
    - Not needed: Just a comment change (True -> true)

26. d93041a4ca 2014-07-10 Remove form-feeds from dlmalloc.c
    - Not needed: New dlmalloc doesn't have form-feeds

27. d59476b644 2014-07-10 Add a simple malloc() implementation for pre-relocation
    - Done (updated): Redirect to malloc_simple before GD_FLG_FULL_MALLOC_INIT

28. 6d7601e744 2014-07-10 sandbox: Always enable malloc debug
    - Done (updated): Combined with #64, use 'DEBUG 1' for new dlmalloc

29. 854d2b9753 2014-10-29 dlmalloc: ensure gd is set for early alloc
    - Not needed: Reverted by #38

30. 868de51dde 2014-08-26 malloc: Output region when debugging
    - Already covered: debug() message in mem_malloc_init()

31. c9356be307 2014-11-10 dm: Split the simple malloc() implementation into its own file
    - Already covered: Redirect to malloc_simple.c via GD_FLG_FULL_MALLOC_INIT

32. 0aa8a4ad99 2015-03-04 dlmalloc: do memset in malloc init as new default config
    - Already covered: SYS_MALLOC_CLEAR_ON_INIT at line 6396

33. fb5cf7f16b 2015-02-27 Move initf_malloc() to a common place
    - Already covered: initf_malloc() at line 6357

34. 1eb0c03c21 2015-09-13 malloc_simple: Add Kconfig option for using only malloc_simple in the SPL
    - Not needed: Changes to Kconfig/malloc_simple.c, not dlmalloc.c

35. 4f144a4164 2016-01-25 malloc: work around some memalign fragmentation issues
    - Done (updated): Ported to internal_memalign() at line 4955

36. ee05fedc6c 2016-02-04 malloc: solve dead code issue in memalign()
    - Not needed: New dlmalloc 2.8.6 has rewritten internal_memalign()

37. 2f0bcd4de1 2016-03-05 malloc: use hidden visibility
    - Done (updated): Use DLMALLOC_EXPORT at line 546

38. deff6fb3a7 2016-03-05 malloc: remove !gd handling
    - Not needed: Reverts #29, we don't add gd check

39. 4eece2602b 2016-04-21 common/dlmalloc.c: Delete content that was moved to malloc.h
    - Not needed: New dlmalloc doesn't have #if 0 code

40. 034eda867f 2016-04-25 malloc: improve memalign fragmentation fix
    - Done (updated): Combined with #35 in memalign workaround port

41. 4e33316f65 2017-05-25 malloc: Turn on DEBUG when enabling unit tests
    - Already covered: Combined with #28, #63 at line 555

42. f1896c45cb 2017-07-24 spl: make SPL and normal u-boot stage use independent SYS_MALLOC_F_LEN
    - Already covered: Use CONFIG_IS_ENABLED and CONFIG_VAL at line 6410

43. a874cac3b4 2017-11-10 malloc: don't compare pointers to 0
    - Not needed: New dlmalloc uses proper NULL comparisons

44. ee038c58d5 2018-05-18 malloc: Use malloc simple before malloc is fully initialized in memalign()
    - Already covered: memalign_simple redirect at line 5367

45. 7cbd2d2e32 2018-11-18 malloc_simple: Add logging of allocations
    - Not needed: Changes to malloc_simple.c, not dlmalloc.c

46. 4c6be01c27 2019-03-27 malloc: Fix memalign not honoring alignment prior to full malloc init
    - Already covered: Uses memalign_simple at line 5367

47. bb71a2d9dc 2019-10-25 dlmalloc: calloc: fix zeroing early allocations
    - Done (updated): Port to dlcalloc() at line 4857

48. cfda60f99a 2020-02-03 sandbox: Use a prefix for all allocation functions
    - Done: USE_DL_PREFIX and reverse mappings in malloc.h

49. be621c11b9 2020-04-15 dlmalloc: remove unit test support in SPL
    - Already covered: CONFIG_IS_ENABLED(UNIT_TEST) at line 554

50. 9297e366d6 2020-04-29 malloc: dlmalloc: add an ability for the malloc to be re-init/init multiple times
    - Not needed: No boards use CONFIG_SYS_MALLOC_DEFAULT_TO_INIT

51. f7ae49fc4f 2020-05-10 common: Drop log.h from common header
    - Already covered: Includes log.h at line 559

52. 401d1c4f5d 2020-10-30 common: Drop asm/global_data.h from common header
    - Already covered: Includes asm/global_data.h at line 557

53. c6bf4f3898 2021-02-10 malloc: adjust memcpy() and memset() definitions.
    - Not needed: New malloc.h doesn't declare memset/memcpy

54. c197f6e279 2021-03-15 malloc: Export malloc_simple_info()
    - Not needed: Only changes malloc.h, not dlmalloc.c

55. 5ad9220bf7 2021-05-29 malloc: add SPDX license identifiers
    - Not needed: New dlmalloc has MIT-0 license from upstream

56. bdaeea1b68 2022-03-23 malloc: Annotate allocator for valgrind
    - Done (updated): Valgrind annotations in dlmalloc(), dlfree(), dlrealloc()

57. 62d638386c 2022-09-06 test: Support testing malloc() failures
    - Done: malloc_testing/malloc_max_allocs in dlmalloc()

58. f88d48cc74 2023-02-27 dlmalloc: Fix a warning with clang-15
    - Done: Add (void) to dlmalloc_stats() function definition

59. c9db9a2ef5 2023-08-25 dlmalloc: Add support for SPL_SYS_MALLOC_CLEAR_ON_INIT
    - Already covered: Uses CONFIG_IS_ENABLED() in mem_malloc_init() from #32

60. 6a595c2f67 2023-09-06 common: malloc: Remove unused NEEDS_MANUAL_RELOC code bits
    - Not needed: NEEDS_MANUAL_RELOC has been removed

61. ac897385bb 2023-10-02 Merge branch 'next'
    - Not needed: Merge commit, no dlmalloc changes

62. 3d6d507514 2023-09-26 spl: Use SYS_MALLOC_F instead of SYS_MALLOC_F_LEN
    - Already covered: Uses CONFIG_IS_ENABLED(SYS_MALLOC_F) throughout

63. 1786861415 2023-10-07 malloc: Enable assertions if UNIT_TEST is enabled
    - Done (updated): Combined with #28, use 'DEBUG 1' for new dlmalloc

64. c82ff48115 2024-03-31 mcheck: prepare +1 tier for mcheck-wrappers, in dl-*alloc commands
    - Done (updated): Added STATIC_IF_MCHECK and *_impl macros for dlmalloc 2.8.6

65. dfba071ddc 2024-03-31 mcheck: Use memset/memcpy instead of MALLOC_ZERO/MALLOC_COPY for mcheck.
    - Done: Undef and redefine MALLOC_ZERO/MALLOC_COPY when mcheck enabled

66. 151493a875 2024-03-31 mcheck: integrate mcheck into dlmalloc.c
    - Done: Added mcheck wrapper functions for dlmalloc, dlfree, dlrealloc, dlmemalign, dlcalloc

67. ae838768d7 2024-03-31 mcheck: support memalign
    - Done: Implemented dlmemalign wrapper with mcheck hooks

68. 18c1bfafe0 2024-03-31 mcheck: add pedantic mode support
    - Done: Added mcheck_pedantic_prehook() calls and mcheck_pedantic()/mcheck_check_all() API

69. a79fc7a79c 2024-04-27 common: Remove <common.h> and add needed includes
    - Not needed: common.h has been removed

70. d678a59d2d 2024-05-18 Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
    - Not needed: common.h has been removed

71. 03de305ec4 2024-05-20 Restore patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet"
    - Not needed: common.h has been removed

72. 910cef3d2f 2024-07-13 common: Remove duplicate newlines
    - Not needed: New dlmalloc has its own formatting from upstream

73. 6627fbba20 2024-07-23 include: Remove duplicate newlines
    - Not needed: New malloc.h has its own formatting from upstream

74. 04894f5ad5 2024-07-30 malloc: Support testing with realloc()
    - Done: Combined with #57, malloc_testing check in dlrealloc()

75. 8642b2178d 2024-08-02 dlmalloc: Fix integer overflow in request2size()
    - Not needed: New dlmalloc 2.8.6 uses MAX_REQUEST for robust overflow checks

76. 0a10b49206 2024-08-02 dlmalloc: Fix integer overflow in sbrk()
    - Already covered: sbrk() checks bounds before memset in U-Boot section

77. 9b9368b5c4 2024-08-02 dlmalloc: Make sure allocation size is within malloc area
    - Not needed: New dlmalloc 2.8.6 uses MAX_REQUEST for robust overflow checks

78. 41fecdc94e 2024-10-21 common: Tidy up how malloc() is inited
    - Already covered: mem_malloc_init() uses map_sysmem in U-Boot section

79. 22f87ef530 2025-08-17 malloc: Avoid defining calloc()
    - Done: Added SYS_MALLOC_SIMPLE section to malloc.h with calloc redirect
END

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-01 17:04:37 +00:00
Simon Glass
9c57da7282 malloc: Add SMALLCHUNKS_AS_FUNCS to convert macros to funcs
The insert_small_chunk() and unlink_first_small_chunk() macros are
inlined at multiple places in the code.

Provide an option to convert these to functions, so the compiler can try
to reduce code size.

Add braces to the insert_chunk macro.

This reduces code size imx8mp_venice SPL by about 208 bytes

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-01 17:00:23 +00:00
Simon Glass
3a6c517068 malloc: Add SIMPLE_MEMALIGN to simplify memalign for code size
Add a new SIMPLE_MEMALIGN to remove the fallback-retry logic from
memalign(), to reduce code sizein SPL.

The fallback mechanism attempts multiple allocation strategies:
1. Over-allocate to guarantee finding aligned space
2. If that fails, allocate exact size and check if aligned
3. If not aligned, free and retry with calculated extra space

While this fallback is useful in low-memory situations, SPL typically
has predictable memory usage and sufficient heap space for the initial
over-allocation to succeed. The fallback adds code complexity without
obvious practical benefit.

This reduces code size on imx8mp_venice (for example) SPL by 74 bytes.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-01 17:00:22 +00:00
Simon Glass
c87cac82e4 malloc: Add NO_TREE_BINS option to reduce code size
Add a new NO_TREE_BINS option to disable binary-tree bins for large
allocations (>= 256 bytes). While this is an invasive changes, it saves
about 1.25K of code size on arm64 (as well as 250 bytes of data). When
enabled, all large chunks use a simple doubly-linked list instead of
tree bins, trading O(log n) performance for smaller code size.

The tradeoff here is that large allocations use O(n) search instead of
O(log n) and fragmentation coud also become worse. So performance will
suffer when there are lots of large allocations and frees are done. This
is rare in SPL.

Implementation:
- Add a dedicated mchunkptr largebin field to malloc_state
- Replace treebins[NTREEBINS] array with a single linked-list pointer
- Implement simplified insert/unlink operations using largebin list
- Update allocation functions (tmalloc_small/large) for linear search
- Update heap checking functions (do_check_treebin, bin_find) to handle
  linked list traversal instead of tree traversal

It is enabled by CONFIG_SYS_MALLOC_SMALL, i.e. by default in SPL.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-01 16:59:59 +00:00
Simon Glass
319350496b malloc: Add NO_REALLOC_IN_PLACE option to reduce code size
Add a new NO_REALLOC_IN_PLACE option that disables in-place realloc
optimization. When enabled via CONFIG_SYS_MALLOC_SMALL, realloc() always
allocates new memory, copies data, and frees the old block instead of
trying to extend the existing allocation.

This saves about 500 bytes by eliminating try_realloc_chunk() and
mmap_resize() functions.

When unit tests are enabled, the extra realloc logic is included.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-01 16:57:15 +00:00
Simon Glass
d8c064ab34 malloc: Allow building dlmalloc with SPL_SYS_MALLOC_SIMPLE
When building boards that use CONFIG_SPL_SYS_MALLOC_SIMPLE (like
qemu-x86_64), we need to avoid a conflict between the stub free()
function defined by malloc and the real free() defined by dlmalloc.c

Fix this by define COMPILING_DLMALLOC in dlmalloc.c before including
malloc.h and adding a guard to the latter.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-01 16:57:15 +00:00
Simon Glass
1088f74ec6 malloc: Set up the malloc() state in mem_malloc_init()
Move the malloc state initialisation from lazy init in sys_alloc() to
explicit init in mem_malloc_init(). This allows is_initialized() to
always return true for U-Boot, eliminating runtime checks.

The initialisation sets up:
- least_addr, seg.base, seg.size, seg.sflags
- magic, release_checks, mflags
- bins (via init_bins)
- top chunk (via init_top)
- footprint tracking

Add a simplified sys_alloc() for small builds. Since the
heap is pre-allocated with fixed size, sys_alloc() only needs to extend
via sbrk() if space remains: no mmap, no multiple segments, no comple
merging. The helper functions mmap_alloc(), mmap_resize(),
prepend_alloc() and add_segment() are thus compiled out for non-sandbox
builds.

This is controlled by a new SIMPLE_SYSALLOC option, which is the
default. Sandbox retains full functionality for testing.

With this, the new dlmalloc is approximately at parity with the old one,
e.g. about 400 bytes less code on Thumb2 (firefly-rk3288).

There is a strange case here with a small number of boards which set up
the full malloc() when CONFIG_SYS_MALLOC_SIMPLE is enabled. This cannot
work.

With CONFIG_SPL_SYS_MALLOC_SIMPLE, all malloc()/free()/realloc() calls
are redirected to simple implementations via macros in thhe malloc.h
header. In this case, mem_malloc_init() doesn't need to init the dlmalloc
state structure (gm) since it will never be used.

Initing _gm_ pulls in the entire malloc_state BSS structure (~472
bytes) plus initialisation code (~128 bytes), adding ~600 bytes to SPL
on boards that use full malloc (K3 platforms with CONFIG_K3_LOAD_SYSFW).

Skip the _gm_ init when SYS_MALLOC_SIMPLE is enabled.

These boards call mem_malloc_init() even though it will have no effect:

   $ ./tools/qconfig.py -f CONFIG_K3_LOAD_SYSFW SPL_SYS_MALLOC_SIMPLE -l
   am62ax_evm_r5
   am62px_evm_r5
   am62x_beagleplay_r5
   am62x_evm_r5
   am62x_evm_r5_ethboot
   am62x_lpsk_r5
   am64x_evm_r5
   am68_sk_r5
   am69_sk_r5
   j721s2_evm_r5
   j722s_evm_r5
   j784s4_evm_r5
   phycore_am62x_r5
   phycore_am62x_r5_usbdfu
   phycore_am64x_r5
   verdin-am62_r5

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-01 16:57:15 +00:00
Simon Glass
e8eb87ea1b mcheck: add pedantic mode support
Add mcheck_pedantic_prehook() calls to dlmalloc, dlrealloc,
dlmemalign, and dlcalloc wrapper functions. Also add the
mcheck_pedantic() and mcheck_check_all() API functions.

The pedantic mode is runtime controlled, so the registry hooks
are called on every allocation operation.

Changes from original commit:
- Uses dl* function names instead of mALLOc style names

Signed-off-by: Eugene Uriev <eugeneuriev@gmail.com>
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
(cherry picked from commit 18c1bfafe0)
2025-12-01 16:57:15 +00:00
Simon Glass
e29c8176f4 mcheck: support memalign
Implement the dlmemalign wrapper function for mcheck heap protection.
Uses mcheck_memalign_prehook() and mcheck_memalign_posthook() to
properly handle aligned allocations.

Changes from original commit:
- Uses dlmemalign/dlmemalign_impl instead of mEMALIGn/mEMALIGn_impl

Signed-off-by: Eugene Uriev <eugeneuriev@gmail.com>
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
(cherry picked from commit ae838768d7)
2025-12-01 16:57:15 +00:00
Simon Glass
8bf36da37c mcheck: integrate mcheck into dlmalloc.c
Add mcheck wrapper functions for dlmalloc, dlfree, dlrealloc,
dlmemalign, and dlcalloc. When MCHECK_HEAP_PROTECTION is enabled,
these wrappers call the mcheck hooks around the internal *_impl
functions to provide heap corruption detection.

Also add the mcheck() and mprobe() API functions.

Changes from original commit:
- Adapted for dlmalloc 2.8.6 function names (dl* instead of mALLOc)
- Updated function signatures (void* instead of Void_t*)

Signed-off-by: Eugene Uriev <eugeneuriev@gmail.com>
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
(cherry picked from commit 151493a875)
2025-12-01 16:57:15 +00:00
Simon Glass
2bc5cc784a mcheck: Use memset/memcpy instead of MALLOC_ZERO/MALLOC_COPY for mcheck.
These fast helpers sometimes breach mem-chunk boundaries.
Thus they trigger mcheck alarm. Standard ones are accurate though.

When MCHECK_HEAP_PROTECTION is enabled, redefine MALLOC_ZERO and
MALLOC_COPY to use standard memset/memcpy instead of the optimized
versions that may access memory outside allocated chunks.

Signed-off-by: Eugene Uriev <eugeneuriev@gmail.com>
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
(cherry picked from commit dfba071ddc)
2025-12-01 16:57:15 +00:00
Simon Glass
2cb547df96 mcheck: prepare +1 tier for mcheck-wrappers, in dl-*alloc commands
Add STATIC_IF_MCHECK macro and rename the main allocation functions
to *_impl versions (dlmalloc_impl, dlfree_impl, dlrealloc_impl,
dlmemalign_impl, dlcalloc_impl) to prepare for mcheck wrappers.

When MCHECK_HEAP_PROTECTION is not defined, the *_impl macros map
directly to the original function names, so behavior is unchanged.

Changes from original commit:
- Adapted to new dlmalloc 2.8.6 function names (dl* vs mALLOc, etc.)
- Updated all internal calls to use *_impl versions

Signed-off-by: Eugene Uriev <eugeneuriev@gmail.com>
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
(cherry picked from commit c82ff48115)
2025-12-01 16:57:15 +00:00
Simon Glass
371eceab7d dlmalloc: Fix a warning with clang-15
Add (void) to dlmalloc_stats() function definition to match its
declaration and avoid the clang-15 warning about function declarations
without prototypes.

Signed-off-by: Tom Rini <trini@konsulko.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
(cherry picked from commit f88d48cc74)
2025-12-01 16:57:15 +00:00
Simon Glass
1289c7c524 test: Support testing malloc() failures
It is helpful to test that out-of-memory checks work correctly in code
that calls malloc().

Add a simple way to force failure after a given number of malloc() calls.

Also add support for realloc() testing (from commit 04894f5ad5).

Changes from original commits:
- Variable declarations moved to top of U-Boot section (before dlmalloc())
- Adapted to new dlmalloc function names (dlmalloc/dlrealloc vs mALLOc/rEALLOc)

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Sean Anderson <seanga2@gmail.com>
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
(cherry picked from commit 62d638386c)
(cherry picked from commit 04894f5ad5)
2025-12-01 16:57:15 +00:00
Simon Glass
a79d12a59f malloc: Annotate allocator for valgrind
Add valgrind annotations to track memory allocations:
- VALGRIND_MALLOCLIKE_BLOCK in dlmalloc() at the postaction label
- VALGRIND_FREELIKE_BLOCK in dlfree() for both pre-reloc and post-reloc paths
- VALGRIND_RESIZEINPLACE_BLOCK/VALGRIND_MAKE_MEM_DEFINED in dlrealloc()
  and dlrealloc_in_place() when resizing in place
- VALGRIND_MALLOCLIKE_BLOCK/VALGRIND_FREELIKE_BLOCK in dlrealloc() when
  allocating new memory

Changes from original commit:
- The new dlmalloc 2.8.6 uses a centralized "postaction" label pattern
  instead of multiple return points, allowing simpler annotation
- Annotations placed at strategic points covering all allocation paths
- dlrealloc_in_place() is a new function that needs annotations

Signed-off-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
(cherry picked from commit bdaeea1b68)
2025-12-01 16:57:15 +00:00
Simon Glass
bf6a7b4e28 dlmalloc: calloc: fix zeroing early allocations
When full malloc is enabled and SYS_MALLOC_F is also enabled, the
simple pre-reloc heap is used before relocation. The calloc_must_clear
macro relies on chunk metadata which does not exist for simple malloc
allocations.

Use memset directly to zero out memory from simple malloc.

Changes from original commit:
- Port to dlcalloc() in dlmalloc 2.8.6
- Update memset() second arg to be a char

Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
(cherry picked from bb71a2d9dc)
2025-12-01 16:57:15 +00:00
Simon Glass
8ae911811d malloc: use hidden visibility
When running sandbox, U-Boot's malloc symbols can be hooked into the
GOT before U-Boot code runs. This causes issues because the dynamic
linker may call malloc/free before gd is initialized.

Use hidden visibility for malloc symbols to prevent them from being
hooked into the GOT, so only code in the U-Boot binary itself calls
them; any other code calls the standard C library malloc().

Changes from original commit:
- Use DLMALLOC_EXPORT mechanism instead of #pragma in malloc.h

Cc: Rabin Vincent <rabin@rab.in>
Signed-off-by: Stephen Warren <swarren@wwwdotorg.org>
Reviewed-by: Tom Rini <trini@konsulko.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
(cherry picked from commit 2f0bcd4de1a5b990e58d12cd0c7f9d7e9248fec4)
2025-12-01 16:57:14 +00:00
Simon Glass
4228123d94 malloc: work around some memalign fragmentation issues
Use of memalign can trigger fragmentation issues where the over-sized
allocation needed to guarantee alignment fails, even though the exact
user-requested size would succeed and be properly aligned.

If the padded allocation fails, try allocating exactly the user's
requested size. If that happens to be aligned, return it. Otherwise,
try a third allocation with just enough extra space to achieve
alignment.

Changes from original commits:
- Port to dlmalloc 2.8.6 internal_memalign() instead of mEMALIGn()
- Use internal_malloc/internal_free instead of mALLOc/fREe

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
Acked-by: Lukasz Majewski <l.majewski@samsung.com>
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
(cherry picked from 4f144a4164)
2025-12-01 16:57:14 +00:00
Simon Glass
b928938cc0 malloc: Reduce code size with INSECURE and NO_MALLINFO
Enable INSECURE=1 to skip runtime heap validation checks (except for
sandbox), and NO_MALLINFO=1 to remove mallinfo support (except when unit
tests are enabled). These reduce code size significantly.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-01 16:57:14 +00:00
Simon Glass
fc22021182 malloc: Enable assertions if UNIT_TEST is enabled
dlmalloc has some sanity checks it performs on free() which can help
detect memory corruption. However, they are only enabled if DEBUG is
defined before including common.h. Define DEBUG earlier if UNIT_TEST is
enabled so that assertions are enabled in sandbox.

Changes from original commit(s):
- Combine commits 213adf6dff and 1786861415
- Use 'DEBUG 1' instead of 'DEBUG' since new dlmalloc uses '#if DEBUG'

Signed-off-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
(cherry picked from commit 6d7601e744)
(cherry picked from commit 1786861415)
2025-12-01 16:57:14 +00:00
Simon Glass
d62f9a5b90 Add a simple malloc() implementation for pre-relocation
If we are to have driver model before relocation we need to support some
way of calling memory allocation routines.

The standard malloc() is pretty complicated:

1. It uses some BSS memory for its state, and BSS is not available before
relocation

2. It supports algorithms for reducing memory fragmentation and improving
performace of free(). Before relocation we could happily just not support
free().

3. It includes about 4KB of code (Thumb 2) and 1KB of data. However since
this has been loaded anyway this is not really a problem.

The simplest way to support pre-relocation malloc() is to reserve an area
of memory and allocate it in increasing blocks as needed. This
implementation does this.

To enable it, you need to define the size of the malloc() pool as described
in the README. It will be located above the pre-relocation stack on
supported architectures.

Note that this implementation is only useful on machines which have some
memory available before dram_init() is called - this includes those that
do no DRAM init (like tegra) and those that do it in SPL (quite a few
boards). Enabling driver model preior to relocation for the rest of the
boards is left for a later exercise.

Changes from original commit:
- Squash in commit 'malloc: Redirect to malloc_simple before relocation'
- Modify dlmalloc/dlfree/dlrealloc/dlmemalign (new 2.8.6 names)
- Add #ifdef __UBOOT__ wrapper around the checks
- Redirect to malloc_simple()/memalign_simple() instead of embedding code
- Add declarations for malloc_simple() and memalign_simple() to malloc.h
- Move global_data.h include and DECLARE_GLOBAL_DATA_PTR to top
- Add proper documentation for the two new functions

Signed-off-by: Simon Glass <sjg@chromium.org>
Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
(cherry picked from commit d59476b644)
2025-12-01 16:57:04 +00:00
Simon Glass
2d2532e8ff malloc: return NULL if not initialized yet
When malloc() was called before it was properly initialized
(as would happen if when used before relocation to RAM) it returned
random, non-NULL values, which called all kinds of difficult to debug
subsequent errors.

Make sure to return NULL when initialization was not done yet.

Signed-off-by: Simon Glass <simon.glass@canonical.com>
(cherry picked from commit 2740544881)
2025-12-01 16:52:37 +00:00
Simon Glass
b64f2045f7 malloc: Fix assert warning
Include log.h early to prevent an assert() redefinition warning.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-01 16:52:37 +00:00
Simon Glass
b5ed4faf92 malloc: Add U-Boot configuration for dlmalloc 2.8.6
Add an #ifdef __UBOOT__ section to configure dlmalloc for U-Boot's
embedded environment:

- Disable mmap, set LACKS_* for unavailable headers
- Include string.h and errno.h
- Add ABORT definition using infinite loop
- Define DEBUG 0 to avoid assert redefinition issues
- Fix dlmalloc_footprint_limit() prototype (add void)
- Fix dlmalloc_usable_size() to use const void *
- Use MFAIL instead of MORECORE_FAILURE in sbrk()

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-01 16:52:37 +00:00
Simon Glass
1b2200b47b malloc: Add mem_malloc_init() and sbrk()
Add mem_malloc_init() to initialise the malloc heap and sbrk() for
heap extension. These are U-Boot-specific functions that manage the
memory pool used by dlmalloc.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-01 16:52:37 +00:00
Simon Glass
2ab06fd175 malloc: Import dlmalloc 2.8.6
Import the latest dlmalloc (2.8.6) from Doug Lea, preserving the current
version as dlmalloc_old.c/malloc_old.h for reference.

For now the current version is still active.

Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-01 16:52:35 +00:00
Simon Glass
2436d6ac54 malloc: Rename dlmalloc.c to dlmalloc_old.c
Rename this file so that we can start to bring in the new one.

Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-01 15:57:28 +00:00
Simon Glass
41fecdc94e common: Tidy up how malloc() is inited
The call to malloc() is a bit strange. The naming of the arguments
suggests that an address is passed, but in fact it is a pointer, at
least in the board_init_r() function and SPL equivalent.

Update it to work as described. Add a function comment as well.

Note that this does adjustment does not extend into the malloc()
implementation itself, apart from changing mem_malloc_init(), since
there are lots of casts and pointers and integers are used
interchangeably.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Tom Rini <trini@konsulko.com>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
2024-10-25 14:22:24 -06:00
Richard Weinberger
9b9368b5c4 dlmalloc: Make sure allocation size is within malloc area
Since U-Boot does not support memory overcommit we can
enforce that the allocation size is within the malloc area.
This is a simple and efficient hardening measure to mitigate
further integer overflows in dlmalloc.

Signed-off-by: Richard Weinberger <richard@nod.at>
Reviewed-by: Simon Glass <sjg@chromium.org>
2024-08-15 16:14:36 -06:00
Richard Weinberger
0a10b49206 dlmalloc: Fix integer overflow in sbrk()
Make sure that the new break is within mem_malloc_start
and mem_malloc_end before making progress.
ulong new = old + increment; can overflow for extremely large
increment values and memset() can get wrongly called.

Signed-off-by: Richard Weinberger <richard@nod.at>
Reviewed-by: Simon Glass <sjg@chromium.org>
2024-08-15 16:14:36 -06:00
Richard Weinberger
8642b2178d dlmalloc: Fix integer overflow in request2size()
req is of type size_t, casting it to long opens the door
for an integer overflow.
Values between LONG_MAX - (SIZE_SZ + MALLOC_ALIGN_MASK) - 1 and LONG_MAX
cause and overflow such that request2size() returns MINSIZE.

Fix by removing the cast.
The origin of the cast is unclear, it's in u-boot and ppcboot since ever
and predates the CVS history.
Doug Lea's original dlmalloc implementation also doesn't have it.

Signed-off-by: Richard Weinberger <richard@nod.at>
Reviewed-by: Simon Glass <sjg@chromium.org>
2024-08-15 16:14:36 -06:00
Simon Glass
04894f5ad5 malloc: Support testing with realloc()
At present in tests it is possible to cause an out-of-memory condition
with malloc() but not realloc(). Add support to realloc() too, so code
which uses that function can be tested.

Signed-off-by: Simon Glass <sjg@chromium.org>
2024-08-07 08:49:10 -06:00