Bug 21556 - malloc_stats printing size_t fields as unsigned int
Summary: malloc_stats printing size_t fields as unsigned int
Status: UNCONFIRMED
Alias: None
Product: glibc
Classification: Unclassified
Component: malloc (show other bugs)
Version: unspecified
: P2 minor
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-06-08 07:17 UTC by Ashish Sangwan
Modified: 2023-11-13 17:39 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments
Patch making malloc_stats() output not overflow (1.75 KB, patch)
2018-12-22 19:49 UTC, Niklas Hambüchen
Details | Diff
Newer patch based on mallinfo2 (877 bytes, patch)
2021-10-29 16:57 UTC, Niklas Hambüchen
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ashish Sangwan 2017-06-08 07:17:54 UTC
#define MALLINFO_FIELD_TYPE size_t

The mallinfo struct has all its variable as size_t type, but while printing stats in __malloc_stats it is typecast to unsigned int which is printing incorrect values because of overflow.
Comment 1 Niklas Hambüchen 2018-12-22 19:40:17 UTC
> #define MALLINFO_FIELD_TYPE size_t

> The mallinfo struct has all its variable as size_t type

I am confused by this statement:

While malloc_stats() is certainly bugged by integer overflow (and that is in particular despite `man 3 mallinfo` recommending it as non-overflowing alternative), there doesn't seem to be a `MALLINFO_FIELD_TYPE` in glibc's source code or git history, and the mallinfo struct has `int` inside.
Comment 2 Niklas Hambüchen 2018-12-22 19:49:06 UTC
Created attachment 11486 [details]
Patch making malloc_stats() output not overflow

I also encountered this issue of malloc_stats() reporting completely wrong numbers for my system.

I have attached a patch that fixes the problem.

It does not modify the public interface of `mallinfo()`.

Instead, it adds a new `mallinfo64()` function and struct that does not use `int` internally, and makes `malloc_stats()` use that.

I have added the `struct mallinfo64` to malloc.h in the hope that `mallinfo64()`  will be exported in the future as well.
If this is not desired, let me know, and I'll move it somewhere more private.
Comment 3 Niklas Hambüchen 2018-12-22 19:58:16 UTC
Also for those that come across this bug and think they can use malloc_info() instead, a short summary:

All 3 of 3 malloc information functions in glibc are bugged:

* mallinfo() uses `int` in the API, so it overflows at 2 GB and that is documented in the man page
  * The man page recommends malloc_info() and malloc_stats() instead, but that isn't helpful, because they both return wrong information
* malloc_info() does not overflow but I found that it forgets to account for significant amounts of memory
  * https://sourceware.org/bugzilla/show_bug.cgi?id=24026
* malloc_stats() has this integer overflow bug, so it overflows at 2 GB
  * especially odd is that the mallinfo() man page recommends malloc_stats() as a better alternative, even though it is *implemented* by calling mallinfo()!

In conclusion, it seems that nobody has used any of the malloc information functions in anger for the last 10 years :/
Comment 4 crusaderky 2021-05-28 12:49:23 UTC
malloc_stats has been recently updated to use the new mallinfo2 as its backend, but it still casts everything as unsigned int.

The accumulators in_use_b and system_b for the total paragraphs are also unsigned ints.
Comment 5 Niklas Hambüchen 2021-10-29 16:57:29 UTC
Created attachment 13746 [details]
Newer patch based on mallinfo2

I've updated the patch to the currentl glibc version, using the mallinfo2 struct, removing truncating casts.
Comment 6 Niklas Hambüchen 2021-10-29 17:12:11 UTC
I just submitted the new patch to libc-alpha@sourceware.org
Comment 7 Niklas Hambüchen 2023-11-13 17:39:22 UTC
(In reply to Niklas Hambüchen from comment #6)
> I just submitted the new patch to libc-alpha@sourceware.org

The thread: https://sourceware.org/pipermail/libc-alpha/2021-October/132474.html