Skip to content

Instantly share code, notes, and snippets.

@mcopik
Created September 19, 2022 12:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mcopik/c6dc64e6b24aea9576d517ca00d1a9c0 to your computer and use it in GitHub Desktop.
Save mcopik/c6dc64e6b24aea9576d517ca00d1a9c0 to your computer and use it in GitHub Desktop.
Reproducing GDB hanging on reading a shared library from memory-mapped file
#!/bin/bash
gcc -fPIC -shared -g lib.c -o lib.so
gcc -DLOAD_FROM_FILE main.c -g -o from_file
gcc main.c -g -o from_memory
int foo(int x)
{
int var = 0;
return 0;
}
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#define _GNU_SOURCE
#include <unistd.h>
#include <dlfcn.h>
#include <sys/mman.h>
#include <sys/types.h>
int main(int argc, char ** argv)
{
const char* path = "lib.so";
// Receive code information
FILE* file = fopen(path, "rb");
assert(file);
fseek (file, 0 , SEEK_END);
size_t size = ftell(file);
rewind(file);
int fd = memfd_create("libfunction", 0);
assert(fd > 0);
int ret = ftruncate(fd, size) ;
assert(ret == 0);
void* memory_handle = mmap(NULL, size, PROT_WRITE, MAP_SHARED, fd, 0);
assert(memory_handle);
size_t bytes_read = fread(memory_handle, 1, size, file);
assert(bytes_read == size);
fclose(file);
msync(memory_handle, size, MS_SYNC);
char buf[32];
snprintf(buf, 32, "%s%d", "/proc/self/fd/", fd);
#if !defined(LOAD_FROM_FILE)
printf("Reading from %s\n", buf);
fflush(stdout);
void* library_handle = dlopen(buf, RTLD_NOW);
#else
void* library_handle = dlopen("./lib.so", RTLD_NOW);
#endif
assert(library_handle);
typedef int (*func_t)(int);
func_t func = dlsym(library_handle, "foo");
assert(func);
func(42);
dlclose(library_handle);
munmap(memory_handle, size);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment