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 libc/18292] Invalid pointer dereference in nsswitch.c:nss_new_service()


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

--- Comment #9 from Justin N. Ferguson <jf at ownco dot net> ---
Just as a follow-up; what a weird set of circumstances. There is definitely a
bug, but I'm not 100% who to blame it on.

In the allocator there is conflicting ways of handling the block size, in one:
request2size() on amd64 we treat the minimum structure size as 0x17, and in
another we treat it as 0x10.

When we enter _int_malloc(), we bitwise and the block size with
0xFFFFFFFFFFFFFFF0, which is apparently the proper alignment even though
~SIZE_BITS is 0xFFFFFFFFFFFFFFF8. This often results in a smaller than expected
block size that is variable between 3 and 8 bytes in length, but that is always
within the width of prev_size, which makes it mostly a non-issue from libc's
perspective.

Then when two chunks are split off from the top chunk, this can result in the
second block that is allocated to start inside of the end of the prior block--
which is as you say, the prev_size field and its overlayed-- I don't think you
all mean to overlay it however as evidenced by the fact that the amount of the
overlay is variable, and even if that is what's intended, then why on earth
would you ever return a pointer to an application wherein the tail end of one
points to the metadata of another, even if said variable is always (almost
always?) written to before its read from.

In the specific service_user or whatever structure in NSCD, these two
allocations happen in short succession so that the next pointer actually points
into the name field. This is generally not a problem, because prev_size will be
zero/NULL (or rather it will be *uninitialized* until the correct block is
deallocated-- which is in itself a problem if you consider buffer semantics of
libraries like openssl, which tend to believe user-data too much and
overallocate buffers to be safe, but then put a hard limit on the data to be
written so that you cannot overflow the buffer at a lower layer abstraction;
meaning the potential for an uninitialized pointer sized leak of address space
information cannot be discounted).

You all are going to mark this notation as 'INVALID' and say its expected
behavior and at some point in the future enough use-after-free bugs are going
to exploit it that we'll end up fixing it, and so this note is a message in a
bottle from the past to whomever later discerns this is useful. I, I'm probably
just going to patch chunksize() so that it is using the same size field as
everything else, incidentally, this opens up a bit in the size field which I
can use to mark the block as in use, which makes double free detection far far
easier; at least on amd64 anyway.

-- 
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]