This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug malloc/24027] New: glibc: realloc() ncopies 32-bit integer overflow


https://sourceware.org/bugzilla/show_bug.cgi?id=24027

            Bug ID: 24027
           Summary: glibc: realloc() ncopies 32-bit integer overflow
           Product: glibc
           Version: 2.23
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: malloc
          Assignee: unassigned at sourceware dot org
          Reporter: mail at nh2 dot me
  Target Milestone: ---

I found an integer overflow bug in glibc (2002-current) realloc().
Quoting from the attachments (repro and patch):

    The overflow happens when a malloc(>= 32 GiB) is increased via realloc()
    (and M_MMAP_THRESHOLD is set very large or mmap() based allocation
    is disabled entirely by setting M_MMAP_MAX=0).

    Then only the first couple bytes of the buffer are copied,
    potentially leaving the majority of the returned buffer with
    unititialised memory instead of the original malloc()ed buffer's
    contents.
    This may turn into a security problem if you rely on realloc()
    preserving the contents you wrote into the buffer after malloc().

Due to the conditions (large allocation and disabling of mmap()) I expect that
only few people are affected by this right now, but it can happen to those with
large boxes that use glibc's tuning facilities.

secalert@redhat.com (who responded promptly, nice) agrees that the likelihood
of this being exploited currently is low and has consequently lifted the
embargo.

I have attached

* a reproduction (realloc-ncopies-overflow.c)
* a patch (malloc-Fix-realloc-integer-overflow.patch)

which contain more details.

The overflow happens at
 
https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=malloc/malloc.c;h=e247c77b7d4de26e0f2fbec16e352889bac3781b;hb=3c03baca37fdcb52c3881e653ca392bba7a99c2b#l4582
which is

    unsigned int ncopies = (size_t) copysize / 8;

To see the non-copying code path taken in the repro, you can insert a debug
print in this branch:
 
https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=malloc/malloc.c;h=e247c77b7d4de26e0f2fbec16e352889bac3781b;hb=3c03baca37fdcb52c3881e653ca392bba7a99c2b#l4589

This bug originates in tcmalloc2 from http://malloc.de, from which glibc's
current malloc implementation was taken, and tcmalloc2 also continues to have
this issue.
I expect that all malloc implementations in the wild that are based on
tcmalloc2 have this problem.

Have a nice day,
Niklas


PS:

Personally I'm a bit sad that ~20 years old code we all depend on has so
obvious bugs.

I found this issue after finding that all 3 glibc malloc memory use info
functions (malloc_stats(), mallinfo() and malloc_info()) are bugged and report
completely wrong numbers (bug 24026, bug 21556).

For malloc_stats() it was an integer overflow due to `unsigned int` being used
for counting bytes.
It is very well known among programmers for decades that `unsigned int` is not
the right type for buffer lengths.
At that point, I just searched for "unsigned int" in malloc.c to see if there
are any similar problems, and found this realloc() bug within a minute.

It seems nobody does in practice read the code of fundamental components
running on billions of devices.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]