Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct have_fastchunks arena adjustment #704

Merged
merged 2 commits into from
Sep 8, 2021
Merged

Correct have_fastchunks arena adjustment #704

merged 2 commits into from
Sep 8, 2021

Conversation

CptGibbon
Copy link
Contributor

Correct have_fastchunks arena adjustment

Patches a check that (though uncommented) appears to have been introduced to compensate for the have_fastchunks flag being moved from an arena's flags into its own field in GLIBC 2.27. The code in question is used to parse arenas when the linked GLIBC build has no debug symbols available. The only thing I've changed is the version number, it should read >= 2.27 rather that 2.26. In its current state, if you try to debug a program linked to a GLIBC 2.26 build without debug symbols, the arena layout is misinterpreted and heap commands will hang or give incorrect information.

Only tested on x86_64 hardware.

@theguy147
Copy link
Collaborator

theguy147 commented Aug 24, 2021

Can you provide some test case that fails with the glibc version check for version >= 2.26?

I just created a testing setup with Fedora27 (that uses glibc version 2.26) and I have the exact opposite experience: Before applying your patch it works fine and afterwards it doesn't anymore.

My test setup was done with the current generic/fedora27 vagrant box (https://app.vagrantup.com/generic/boxes/fedora27):

[vagrant@fedora27 ~]$ uname -a
Linux fedora27.localdomain 4.18.19-100.fc27.x86_64 #1 SMP Wed Nov 14 22:04:34 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

This is without your patch:

image

This is with your patch:

image

Note that heap chunks doesn't return anything anymore and heap bins makes GEF freeze without returning to the prompt.

As a test binary I just used this very simple program, compiled it without debug symbols and set a breakpoint after the call to malloc:

// file: test.c
#include<stdlib.h>
#include<stdio.h>

int main() {
	int* ptr = malloc(0x100);
	printf("%p\n", ptr);
	return 0;
}

EDIT: As a sidenote, I think the glibc version check is needed as is because glibc introduced tcaches in 2.26 (and also messed with the MALLOC_ALIGNMENT constant for i386 architecture).

@CptGibbon
Copy link
Contributor Author

CptGibbon commented Aug 25, 2021

I tested against GLIBC versions 2.25, 2.26 & 2.27 with & without debug symbols. In my tests the versions with debug symbols performed correctly before the patch, but the 2.26 version without debug symbols failed. After the patch all versions with or without debug symbols perform correctly.
I'll see if I can replicate the Fedora issue, in the mean time I would note that you're testing with debug symbols which is not what this patch is targeting. In fact the code that I changed shouldn't even run in the presence of debug symbols, so that's strange. It may be a case of Fedora backporting some code into their libc build, I'll let you know what I find.

@theguy147
Copy link
Collaborator

theguy147 commented Aug 25, 2021

Oh, sorry, I misread. I thought you meant that the target executable should not have debug symbols. I will look into your scenario.
But yes, backporting would definitely mess with the hardcoded version checks.

@CptGibbon
Copy link
Contributor Author

I've tested against a Fedora 27 VM with its native GLIBC 2.26 and am still seeing my original results, it doesn't look like Red Hat backported any major arena changes to their 2.26 libc build.
Not to imply your tests are faulty 😅, but would you mind confirming you've used my patch and not changed the value manually? There are 3 of those version checks & they all look very similar, but only one of them needs changing.
It's just odd that GEF behaves differently with the patch on your setup because that code shouldn't fire if the libc debug symbols are present, which it appears they are on your system (normally you'd see a message along the lines of missing separate debug info for target...
If the patch is sound then I'm not sure what to do...

@theguy147
Copy link
Collaborator

theguy147 commented Aug 25, 2021

I did change the value manually (using the line number in your patch: L651). I'm still getting the same results every time! oO

When stripping the binary I also get your "missing separate debuginfos ..." but still without your patch it works and after it does not anymore.

In my screenshots I used the gef-remote command that tries to automatically load the debug symbols even if compiled without (so without -g flag for gcc) but since then I tried it locally and again: same results as in my first test...

EDIT: I agree that I appears that this code shouldn't change anything in my setup with debug symbols in glibc enabled at first glance...

EDIT2: Sorry, now I got completely confused! To clarify: the GLIBC version does not have debug symbols in my test setup. Even in my first reply it did not (the output containing the word debug in my screenshots is GDB trying to find them - but they were not there!). But it is not stripped if that is what you mean when saying "without debug symbols" ? Also the target executables I tried did not have debug symbols and now I even extended the setup to even strip them. Still same results.

EDIT3: I do get the "missing separate debuginfos ..." message every time I try to debug on the fedora27 machine locally. I just didn't see it sometimes because I didn't look for it specifically.

@theguy147
Copy link
Collaborator

OK, so after having discussed the issue with @CptGibbon some more on discord we found out that my fedora27 setup actually has the separate have_fastchunk flags in GLIBC 2.26 even though this was only introduced in GLIBC 2.27, so it appears to have been backported there.

@theguy147
Copy link
Collaborator

IMO this PR should be merged after adding the missing comment to respect vanilla GLIBC versions instead of every possible backport (which is just impossible). We could then add ways of respecting backports to https://github.com/hugsy/gef-extras with e.g. some kind of glibc database with offsets of important structs for GEF (per distro and glibc version) or something.

This check (though uncommented) appears to have been introduced to compensate for the have_fastchunks flag being moved from an arena's flags into its own field in GLIBC 2.27. The only thing that needs changing is the version number, it should be >= 2.27 rather that 2.26. In its current state, if you try to debug a program linked to a GLIBC 2.26 build without debug symbols, the arena layout is misinterpreted and heap commands will hang or give incorrect information.
@theguy147 theguy147 added this to the Release: next milestone Sep 7, 2021
@Grazfather Grazfather merged commit 620ca60 into hugsy:dev Sep 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants