how2heap icon indicating copy to clipboard operation
how2heap copied to clipboard

glibc 2.41 will break fastbin examples

Open ngn13 opened this issue 2 months ago • 1 comments

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

ngn13 avatar Dec 23 '24 21:12 ngn13