forked from libbpf/blazesym
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add test for process symbolization for binary using dedicated mount n…
…amespace This change adds a test that symbolizes an address in a process that uses a dedicated mount namespace. This is the first test that symbolizes an address in a "remote" process. As such it may end up being used as the scaffolding for additional tests that work on processes other than the test binary itself. Signed-off-by: Daniel Müller <[email protected]>
- Loading branch information
Showing
6 changed files
with
234 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
#define _GNU_SOURCE | ||
#include <dlfcn.h> | ||
#include <errno.h> | ||
#include <sched.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <sys/mount.h> | ||
#include <unistd.h> | ||
|
||
void rm_dir(char **path) { | ||
int rc; | ||
int err; | ||
|
||
rc = rmdir(*path); | ||
if (rc != 0) { | ||
err = errno; | ||
fprintf(stderr, "warning: failed to remove directory %s: %s (errno: %d)\n", | ||
*path, strerror(err), err); | ||
} | ||
} | ||
|
||
void unmount(char **path) { | ||
int rc; | ||
int err; | ||
|
||
rc = umount(*path); | ||
if (rc != 0) { | ||
err = errno; | ||
fprintf(stderr, "warning: failed to unmount %s: %s (errno: %d)\n", *path, | ||
strerror(err), err); | ||
} | ||
} | ||
|
||
void close_so(void **handle) { | ||
int rc; | ||
rc = dlclose(*handle); | ||
if (rc != 0) { | ||
fprintf(stderr, "warning: failed to dlclose: %s\n", dlerror()); | ||
} | ||
} | ||
|
||
void rm_file(const char **path) { | ||
int rc; | ||
int err; | ||
|
||
rc = unlink(*path); | ||
if (rc != 0) { | ||
err = errno; | ||
fprintf(stderr, "warning: failed to remove file %s: %s (errno: %d)\n", | ||
*path, strerror(err), err); | ||
} | ||
} | ||
|
||
int main(int argc, char **argv) { | ||
int rc; | ||
int err; | ||
|
||
if (argc != 2) { | ||
fprintf(stderr, "usage: %s <path-to-libtest.so>\n", | ||
argc > 0 ? argv[0] : "<program>"); | ||
return -1; | ||
} | ||
|
||
char const *libtest_src = argv[1]; | ||
/* Detach ourselves from the default mount namespace, effectively | ||
* creating a new one for this program. | ||
*/ | ||
rc = unshare(CLONE_NEWNS); | ||
if (rc != 0) { | ||
err = errno; | ||
fprintf(stderr, "unshare failed: %s (errno: %d)\n", strerror(err), err); | ||
return err; | ||
} | ||
|
||
/* Create a temporary directory (now already inside this mount | ||
* namespace) and mount a ramdisk in there. | ||
*/ | ||
char tmpl[] = "/tmp/mnt-ns.XXXXXX"; | ||
char *dir = mkdtemp(tmpl); | ||
|
||
if (dir == NULL) { | ||
err = errno; | ||
fprintf(stderr, "mkdtemp failed: %s (errno: %d)\n", strerror(err), err); | ||
return err; | ||
} | ||
char *_rm_dir __attribute__((cleanup(rm_dir))) = dir; | ||
|
||
rc = mount("tmpfs", dir, "tmpfs", 0, "size=16M"); | ||
if (rc != 0) { | ||
err = errno; | ||
fprintf(stderr, "mount failed: %s (errno: %d)\n", strerror(err), err); | ||
return err; | ||
} | ||
char *_umount __attribute__((cleanup(unmount))) = dir; | ||
|
||
char libtest_buf[256]; | ||
rc = snprintf(libtest_buf, sizeof(libtest_buf), "%s/libtest-so.so", dir); | ||
if (rc >= sizeof(libtest_buf)) { | ||
fprintf( | ||
stderr, | ||
"failed to construct destination path: insufficient buffer space\n"); | ||
return -1; | ||
} | ||
libtest_buf[rc] = 0; | ||
char const *libtest_dst = libtest_buf; | ||
|
||
char cmd_buf[256]; | ||
rc = snprintf(cmd_buf, sizeof(cmd_buf), "cp %s %s", libtest_src, libtest_dst); | ||
if (rc >= sizeof(cmd_buf)) { | ||
fprintf(stderr, | ||
"failed to construct cp command: insufficient buffer space\n"); | ||
return -1; | ||
} | ||
cmd_buf[rc] = 0; | ||
|
||
char const *cp_cmd = cmd_buf; | ||
/* Sorry, not gonna put up with copying a file in C using system | ||
* APIs... | ||
*/ | ||
rc = system(cp_cmd); | ||
if (rc != 0) { | ||
err = errno; | ||
fprintf(stderr, "failed to copy %s to %s: %d\n", libtest_src, libtest_dst, | ||
rc); | ||
return err; | ||
} | ||
const char *_rm __attribute__((cleanup(rm_file))) = libtest_dst; | ||
|
||
void *handle; | ||
handle = dlopen(libtest_dst, RTLD_NOW); | ||
if (handle == NULL) { | ||
fprintf(stderr, "failed to dlopen %s: %s\n", libtest_dst, dlerror()); | ||
return -1; | ||
} | ||
void *_dlclose __attribute__((cleanup(close_so))) = handle; | ||
|
||
void *sym; | ||
sym = dlsym(handle, "await_input"); | ||
if (sym == NULL) { | ||
fprintf(stderr, "failed to dlsym `await_input` function: %s\n", dlerror()); | ||
return -1; | ||
} | ||
|
||
int (*await_input)(void) = sym; | ||
return await_input(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,18 @@ | ||
#include <errno.h> | ||
#include <stdio.h> | ||
#include <time.h> | ||
|
||
int the_answer(void) { | ||
return 42; | ||
} | ||
|
||
int await_input(void) { | ||
struct timespec ts = {.tv_sec = 60}; | ||
|
||
fprintf(stdout, "%p\n", &await_input); | ||
fflush(stdout); | ||
|
||
int c; | ||
c = getc(stdin); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,5 +2,6 @@ | |
#define _TEST_SO_H | ||
|
||
int the_answer(void); | ||
int await_input(void); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters