Skip to content

Commit

Permalink
Support for char** -> Vec<CString> -> list[bytes] for ExecOp (#52)
Browse files Browse the repository at this point in the history
* Record args and env in ExecOp from libprobe

* Record argc and envc in ExecOp

* Update reading list

* Fix off-by-one length error (non-null-termination)

* add support for char** to Vec<CString> to list[bytes] to frontend

* oh the things we accidentally check into version control

* CI fixes

* fix README whitespace

* ✨ documentation ✨

---------

Co-authored-by: Samuel Grayson <[email protected]>
  • Loading branch information
Ex-32 and charmoniumQ authored Aug 20, 2024
1 parent 8739376 commit aa659eb
Show file tree
Hide file tree
Showing 13 changed files with 404 additions and 121 deletions.
139 changes: 98 additions & 41 deletions probe_src/libprobe/generated/libc_hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -1523,8 +1523,13 @@ char * mkdtemp(char *template)
int execv(const char *filename, char * const argv[])
{
maybe_init_thread();
putenv_probe_vars();
struct Op op = {exec_op_code, {.exec = {.path = create_path_lazy(0, filename, 0), .ferrno = 0}}, {0}, 0, 0};
size_t argc = -1;
char * const *copied_argv = arena_copy_argv(get_data_arena(), argv, &argc);
size_t envc = 0;
char * const *updated_env = update_env_with_probe_vars(environ, &envc);
char * const *copied_updated_env = arena_copy_argv(get_data_arena(), updated_env, &envc);
struct Op op = {exec_op_code, {.exec = {.path = create_path_lazy(0, filename, 0), .ferrno = 0, .argc = argc, .argv = copied_argv, .envc = envc, .env = copied_updated_env}}, {0}, 0, 0};
op.data.exec.argc = argc;
if (likely(prov_log_is_enabled()))
{
prov_log_try(op);
Expand All @@ -1534,8 +1539,9 @@ int execv(const char *filename, char * const argv[])
{
prov_log_save();
}
int ret = unwrapped_execv(filename, argv);
int ret = unwrapped_execvpe(filename, argv, updated_env);
int saved_errno = errno;
free((char **) updated_env);
if (likely(prov_log_is_enabled()))
{
assert(errno > 0);
Expand All @@ -1549,8 +1555,22 @@ int execv(const char *filename, char * const argv[])
int execl(const char *filename, const char *arg0, ...)
{
maybe_init_thread();
putenv_probe_vars();
struct Op op = {exec_op_code, {.exec = {.path = create_path_lazy(0, filename, 0), .ferrno = 0}}, {0}, 0, 0};
size_t argc = COUNT_NONNULL_VARARGS(arg0);
char **argv = malloc((argc + 1) * (sizeof(char *)));
va_list ap;
va_start(ap, arg0);
for (size_t i = 0; i < argc; ++i)
{
argv[i] = va_arg(ap, __type_charp);
}

va_end(ap);
argv[argc] = NULL;
char * const *copied_argv = arena_copy_argv(get_data_arena(), argv, &argc);
size_t envc = 0;
char * const *updated_env = update_env_with_probe_vars(environ, &envc);
char * const *copied_updated_env = arena_copy_argv(get_data_arena(), updated_env, &envc);
struct Op op = {exec_op_code, {.exec = {.path = create_path_lazy(0, filename, 0), .ferrno = 0, .argc = argc, .argv = copied_argv, .envc = envc, .env = copied_updated_env}}, {0}, 0, 0};
if (likely(prov_log_is_enabled()))
{
prov_log_try(op);
Expand All @@ -1560,9 +1580,10 @@ int execl(const char *filename, const char *arg0, ...)
{
prov_log_save();
}
size_t varargs_size = (sizeof(char *)) + ((COUNT_NONNULL_VARARGS(arg0) + 1) * (sizeof(char *)));
int ret = *((int *) __builtin_apply((void (*)()) unwrapped_execl, __builtin_apply_args(), varargs_size));
int ret = unwrapped_execvpe(filename, argv, updated_env);
int saved_errno = errno;
free((char **) updated_env);
free((char **) argv);
if (likely(prov_log_is_enabled()))
{
assert(errno > 0);
Expand All @@ -1576,8 +1597,12 @@ int execl(const char *filename, const char *arg0, ...)
int execve(const char *filename, char * const argv[], char * const env[])
{
maybe_init_thread();
env = update_env_with_probe_vars(env);
struct Op op = {exec_op_code, {.exec = {.path = create_path_lazy(0, filename, 0), .ferrno = 0}}, {0}, 0, 0};
size_t argc = 0;
char * const *copied_argv = arena_copy_argv(get_data_arena(), argv, &argc);
size_t envc = 0;
char * const *updated_env = update_env_with_probe_vars(env, &envc);
char * const *copied_updated_env = arena_copy_argv(get_data_arena(), updated_env, &envc);
struct Op op = {exec_op_code, {.exec = {.path = create_path_lazy(0, filename, 0), .ferrno = 0, .argc = argc, .argv = copied_argv, .envc = envc, .env = copied_updated_env}}, {0}, 0, 0};
if (likely(prov_log_is_enabled()))
{
prov_log_try(op);
Expand All @@ -1587,10 +1612,9 @@ int execve(const char *filename, char * const argv[], char * const env[])
{
prov_log_save();
}
DEBUG("in Execve");
int ret = unwrapped_execve(filename, argv, env);
int ret = unwrapped_execvpe(filename, argv, updated_env);
int saved_errno = errno;
free((char **) env);
free((char **) updated_env);
if (likely(prov_log_is_enabled()))
{
assert(errno > 0);
Expand All @@ -1604,8 +1628,12 @@ int execve(const char *filename, char * const argv[], char * const env[])
int fexecve(int fd, char * const argv[], char * const env[])
{
maybe_init_thread();
env = update_env_with_probe_vars(env);
struct Op op = {exec_op_code, {.exec = {.path = create_path_lazy(fd, "", AT_EMPTY_PATH), .ferrno = 0}}, {0}, 0, 0};
size_t argc = 0;
char * const *copied_argv = arena_copy_argv(get_data_arena(), argv, &argc);
size_t envc = 0;
char * const *updated_env = update_env_with_probe_vars(env, &envc);
char * const *copied_updated_env = arena_copy_argv(get_data_arena(), updated_env, &envc);
struct Op op = {exec_op_code, {.exec = {.path = create_path_lazy(fd, "", AT_EMPTY_PATH), .ferrno = 0, .argc = argc, .argv = copied_argv, .envc = envc, .env = copied_updated_env}}, {0}, 0, 0};
if (likely(prov_log_is_enabled()))
{
prov_log_try(op);
Expand All @@ -1615,9 +1643,9 @@ int fexecve(int fd, char * const argv[], char * const env[])
{
prov_log_save();
}
int ret = unwrapped_fexecve(fd, argv, env);
int ret = unwrapped_fexecve(fd, argv, updated_env);
int saved_errno = errno;
free((char **) env);
free((char **) updated_env);
if (likely(prov_log_is_enabled()))
{
assert(errno > 0);
Expand All @@ -1631,7 +1659,23 @@ int fexecve(int fd, char * const argv[], char * const env[])
int execle(const char *filename, const char *arg0, ...)
{
maybe_init_thread();
struct Op op = {exec_op_code, {.exec = {.path = create_path_lazy(0, filename, 0), .ferrno = 0}}, {0}, 0, 0};
size_t argc = COUNT_NONNULL_VARARGS(arg0) - 1;
char **argv = malloc((argc + 1) * (sizeof(char *)));
va_list ap;
va_start(ap, arg0);
for (size_t i = 0; i < argc; ++i)
{
argv[i] = va_arg(ap, __type_charp);
}

argv[argc] = NULL;
char * const *copied_argv = arena_copy_argv(get_data_arena(), argv, &argc);
char **env = va_arg(ap, __type_charpp);
va_end(ap);
size_t envc = 0;
char * const *updated_env = update_env_with_probe_vars(env, &envc);
char * const *copied_updated_env = arena_copy_argv(get_data_arena(), updated_env, &envc);
struct Op op = {exec_op_code, {.exec = {.path = create_path_lazy(0, filename, 0), .ferrno = 0, .argc = argc, .argv = copied_argv, .envc = envc, .env = copied_updated_env}}, {0}, 0, 0};
if (likely(prov_log_is_enabled()))
{
prov_log_try(op);
Expand All @@ -1642,21 +1686,10 @@ int execle(const char *filename, const char *arg0, ...)
prov_log_save();
}
ERROR("Not implemented; I need to figure out how to update the environment.");
size_t argc = COUNT_NONNULL_VARARGS(arg0);
char **arg_vec = malloc(argc * (sizeof(char *)));
va_list ap;
va_start(ap, arg0);
for (size_t i = 0; i < (argc - 1); ++i)
{
arg_vec[i] = va_arg(ap, __type_charp);
}

char **env = va_arg(ap, __type_charpp);
va_end(ap);
char * const *updated_env = update_env_with_probe_vars(env);
int ret = unwrapped_execve(filename, arg_vec, updated_env);
int ret = unwrapped_execvpe(filename, argv, updated_env);
int saved_errno = errno;
free((char **) updated_env);
free((char **) argv);
if (likely(prov_log_is_enabled()))
{
assert(errno > 0);
Expand All @@ -1670,10 +1703,14 @@ int execle(const char *filename, const char *arg0, ...)
int execvp(const char *filename, char * const argv[])
{
maybe_init_thread();
putenv_probe_vars();
char *bin_path = arena_calloc(get_data_arena(), PATH_MAX + 1, sizeof(char));
bool found = lookup_on_path(filename, bin_path);
struct Op op = {exec_op_code, {.exec = {.path = (found) ? (create_path_lazy(0, bin_path, 0)) : (null_path), .ferrno = 0}}, {0}, 0, 0};
size_t argc = 0;
char * const *copied_argv = arena_copy_argv(get_data_arena(), argv, &argc);
size_t envc = 0;
char * const *updated_env = update_env_with_probe_vars(environ, &envc);
char * const *copied_updated_env = arena_copy_argv(get_data_arena(), updated_env, &envc);
struct Op op = {exec_op_code, {.exec = {.path = (found) ? (create_path_lazy(0, bin_path, 0)) : (null_path), .ferrno = 0, .argc = argc, .argv = copied_argv, .envc = envc, .env = copied_updated_env}}, {0}, 0, 0};
if (likely(prov_log_is_enabled()))
{
prov_log_try(op);
Expand All @@ -1683,8 +1720,9 @@ int execvp(const char *filename, char * const argv[])
{
prov_log_save();
}
int ret = unwrapped_execvp(filename, argv);
int ret = unwrapped_execvpe(filename, argv, updated_env);
int saved_errno = errno;
free((char **) updated_env);
if (likely(prov_log_is_enabled()))
{
assert(errno > 0);
Expand All @@ -1698,10 +1736,24 @@ int execvp(const char *filename, char * const argv[])
int execlp(const char *filename, const char *arg0, ...)
{
maybe_init_thread();
putenv_probe_vars();
char *bin_path = arena_calloc(get_data_arena(), PATH_MAX + 1, sizeof(char));
bool found = lookup_on_path(filename, bin_path);
struct Op op = {exec_op_code, {.exec = {.path = (found) ? (create_path_lazy(0, bin_path, 0)) : (null_path), .ferrno = 0}}, {0}, 0, 0};
size_t argc = COUNT_NONNULL_VARARGS(arg0);
char **argv = malloc((argc + 1) * (sizeof(char *)));
va_list ap;
va_start(ap, arg0);
for (size_t i = 0; i < argc; ++i)
{
argv[i] = va_arg(ap, __type_charp);
}

argv[argc] = NULL;
va_end(ap);
char * const *copied_argv = arena_copy_argv(get_data_arena(), argv, &argc);
size_t envc = 0;
char * const *updated_env = update_env_with_probe_vars(environ, &envc);
char * const *copied_updated_env = arena_copy_argv(get_data_arena(), updated_env, &envc);
struct Op op = {exec_op_code, {.exec = {.path = (found) ? (create_path_lazy(0, bin_path, 0)) : (null_path), .ferrno = 0, .argc = argc, .argv = copied_argv, .envc = envc, .env = copied_updated_env}}, {0}, 0, 0};
if (likely(prov_log_is_enabled()))
{
prov_log_try(op);
Expand All @@ -1711,9 +1763,10 @@ int execlp(const char *filename, const char *arg0, ...)
{
prov_log_save();
}
size_t varargs_size = (sizeof(char *)) + ((COUNT_NONNULL_VARARGS(arg0) + 1) * (sizeof(char *)));
int ret = *((int *) __builtin_apply((void (*)()) unwrapped_execlp, __builtin_apply_args(), varargs_size));
int ret = unwrapped_execvpe(filename, argv, updated_env);
int saved_errno = errno;
free((char **) updated_env);
free((char **) argv);
if (likely(prov_log_is_enabled()))
{
assert(errno > 0);
Expand All @@ -1727,10 +1780,14 @@ int execlp(const char *filename, const char *arg0, ...)
int execvpe(const char *filename, char * const argv[], char * const envp[])
{
maybe_init_thread();
envp = update_env_with_probe_vars(envp);
char *bin_path = arena_calloc(get_data_arena(), PATH_MAX + 1, sizeof(char));
bool found = lookup_on_path(filename, bin_path);
struct Op op = {exec_op_code, {.exec = {.path = (found) ? (create_path_lazy(0, bin_path, 0)) : (null_path), .ferrno = 0}}, {0}, 0, 0};
size_t argc = 0;
char * const *copied_argv = arena_copy_argv(get_data_arena(), argv, &argc);
size_t envc = 0;
char * const *updated_env = update_env_with_probe_vars(envp, &envc);
char * const *copied_updated_env = arena_copy_argv(get_data_arena(), updated_env, &envc);
struct Op op = {exec_op_code, {.exec = {.path = (found) ? (create_path_lazy(0, bin_path, 0)) : (null_path), .ferrno = 0, .argc = argc, .argv = copied_argv, .envc = envc, .env = copied_updated_env}}, {0}, 0, 0};
if (likely(prov_log_is_enabled()))
{
prov_log_try(op);
Expand All @@ -1740,9 +1797,9 @@ int execvpe(const char *filename, char * const argv[], char * const envp[])
{
prov_log_save();
}
int ret = unwrapped_execvpe(filename, argv, envp);
int ret = unwrapped_execvpe(filename, argv, updated_env);
int saved_errno = errno;
free((char **) envp);
free((char **) updated_env);
if (likely(prov_log_is_enabled()))
{
assert(errno > 0);
Expand Down
Loading

0 comments on commit aa659eb

Please sign in to comment.