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

glibc 2.41 will break fastbin examples #200

Open
ngn13 opened this issue Dec 23, 2024 · 1 comment
Open

glibc 2.41 will break fastbin examples #200

ngn13 opened this issue Dec 23, 2024 · 1 comment

Comments

@ngn13
Copy link

ngn13 commented Dec 23, 2024

ik the repo is following the ubuntu's glibc releases, however i just wanted to give a heads-up

this patch adds tcache support to calloc, so it's no longer possible to use calloc to get into fastbin, author also explains this:

Also fix tst-safe-linking failure after enabling tcache. In previous,
calloc() is used as a way to by-pass tcache in memory allocation and
trigger safe-linking check in fastbins path. With tcache enabled, it
needs extra workarounds to bypass tcache.

so the fastbin examples that use the following technique to get into the fastbin will no longer work:

	fprintf(stderr,"Fill up tcache first.\n");

	void *ptrs[7];

	for (int i=0; i<7; i++) {
		ptrs[i] = malloc(8);
	}
	for (int i=0; i<7; i++) {
		free(ptrs[i]);
	}
        
        ...
	
        int *a = calloc(1,8);
	int *b = calloc(1,8);
	int *c = calloc(1,8);

as a, b and c will be allocated from the tcache

ofc it's still possible to get into fastbin, for example i tried fixing fastbin_dup.c:

int main() {
  setbuf(stdout, NULL);

  printf("This file demonstrates a simple double-free attack with fastbins.\n");

  printf("Allocate buffers to fill up tcache.\n");
  void *ptrs[7];

  for (int i = 0; i < 7; i++) {
    ptrs[i] = malloc(8);
  }

  printf("Allocating 3 buffers.\n");
  int *a = malloc(8);
  int *b = malloc(8);
  int *c = malloc(8);

  printf("Fill up tcache first.\n");
  for (int i = 0; i < 7; i++) {
    free(ptrs[i]);
  }

  printf("1st malloc(8): %p\n", a);
  printf("2nd malloc(8): %p\n", b);
  printf("3rd malloc(8): %p\n", c);

  printf("Freeing the first one...\n");
  free(a);

  printf("If we free %p again, things will crash because %p is at the top of the free list.\n", a, a);
  // free(a);

  printf("So, instead, we'll free %p.\n", b);
  free(b);

  printf("Now, we can free %p again, since it's not the head of the free list.\n", a);
  free(a);

  printf("In order to use the free list for allocation, we'll need to empty the tcache.\n");
  for (int i = 0; i < 7; i++) {
    ptrs[i] = malloc(8);
  }

  printf("Now the free list has [ %p, %p, %p ]. If we malloc 3 times, we'll get %p twice!\n", a, b, a, a);
  a = malloc(8);
  b = malloc(8);
  c = malloc(8);
  printf("1st malloc(8): %p\n", a);
  printf("2nd malloc(8): %p\n", b);
  printf("3rd malloc(8): %p\n", c);
}

but from an exploitation standpoint it's significantly less viable now

@Kyle-Kyle
Copy link
Contributor

It is good to know that the examples will break in the next release. Thank you so much for that.
I'll leave the issue open. So when the next ubuntu release is out, I'll be able to fix the examples.

==
And yeah, it seems fastbin is less relevant in terms of exploitation now that we cannot directly access them. But they should still be in the repo for education purposes.

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

No branches or pull requests

2 participants