Verified Commit 18a847c2 authored by A. Wilcox's avatar A. Wilcox

unistd: Interpose execv* functions for LOADER

Newer releases of Chromium directly execv /proc/self/exe, missing our
readlink(3) interposing.  We go ahead and interpose all three execv*
functions just to ensure wider compatibility.
parent 581bddc0
......@@ -8,9 +8,14 @@
© 2016-2019 Adélie Linux and contributors. NCSA open source licence.
1.0.0 (20??-??-??)
0.9.0 (2020-07-??)
==================
unistd
------
* Add execv/execve/execvp family of functions to catch exec of /proc/self/exe.
wchar
-----
......
......@@ -3,6 +3,10 @@
#include <limits.h> /* NGROUPS_MAX */
#include <stddef.h> /* NULL, size_t */
#include <unistd.h> /* confstr, getcwd, getgroups, ... */
#include <errno.h> /* ENOSYS, ENOMEM */
#include <stdlib.h> /* calloc */
#include <dlfcn.h> /* dlsym */
#include <string.h> /* strcmp */
#include "alias.h" /* alias */
......@@ -179,3 +183,53 @@ int group_member(gid_t gid)
return 0;
}
#ifndef LOADER
#error LOADER must be defined
#endif
static int (*real_execve)(const char *pathname, char *const argv[], char *const envp[]);
int execve(const char *pathname, char *const argv[], char *const envp[]) {
if(real_execve == NULL) {
real_execve = dlsym(RTLD_NEXT, "execve");
if(real_execve == NULL) {
errno = ENOSYS;
return -1;
}
}
if(!strcmp(pathname, "/proc/self/exe")) {
char **new_argv;
char target[PATH_MAX] = "";
int argc = 0, i = 0;
while(argv[i++] != 0) argc++;
i = readlink("/proc/self/exe", target, sizeof(target));
if(i < 0 || i == sizeof(target)) {
errno = ENOMEM;
return -1;
}
new_argv = calloc(argc + 6, sizeof(char *));
new_argv[0] = LOADER;
new_argv[1] = "--argv0";
new_argv[2] = argv[0];
new_argv[3] = "--preload";
new_argv[4] = "/lib/libgcompat.so.0";
new_argv[5] = target;
for(int j = 1, i = 6; j < argc; ++i, ++j) {
new_argv[i] = argv[j];
}
return execve(LINKER, new_argv, envp);
}
return real_execve(pathname, argv, envp);
}
extern char **environ;
int execv(const char *pathname, char *const argv[]) {
return execve(pathname, argv, environ);
}
int execvp(const char *file, char *const argv[]) {
return execv(file, argv);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment