redmine

Mooaar mprotect()-s

... ... @@ -19,13 +19,17 @@
#include <stdlib.h>
#include <string.h>
#ifdef CAPABILITIES_SUPPORT
# include <unistd.h>
# include <sys/mman.h>
#endif
#include "malloc.h"
#include "error.h"
void *xmalloc(size_t size) {
#ifdef _DEBUG
debug(20, "(%u)", size);
debug(20, "(%li)", size);
#endif
#ifdef PARANOID
size++; // Just in case
... ... @@ -33,8 +37,8 @@ void *xmalloc(size_t size) {
void *ret = malloc(size);
if(ret == NULL)
critical("xmalloc(%i): Cannot allocate memory.", size);
if (ret == NULL)
critical("(%li): Cannot allocate memory.", size);
#ifdef PARANOID
memset(ret, 0, size);
... ... @@ -44,7 +48,7 @@ void *xmalloc(size_t size) {
void *xcalloc(size_t nmemb, size_t size) {
#ifdef _DEBUG
debug(20, "(%u, %u)", nmemb, size);
debug(20, "(%li, %li)", nmemb, size);
#endif
#ifdef PARANOID
nmemb++; // Just in case
... ... @@ -53,8 +57,8 @@ void *xcalloc(size_t nmemb, size_t size) {
void *ret = calloc(nmemb, size);
if(ret == NULL)
critical("xcalloc(%i): Cannot allocate memory.", size);
if (ret == NULL)
critical("(%li): Cannot allocate memory.", size);
// memset(ret, 0, nmemb*size); // Just in case
return ret;
... ... @@ -62,7 +66,7 @@ void *xcalloc(size_t nmemb, size_t size) {
void *xrealloc(void *oldptr, size_t size) {
#ifdef _DEBUG
debug(20, "(%p, %u)", oldptr, size);
debug(20, "(%p, %li)", oldptr, size);
#endif
#ifdef PARANOID
size++; // Just in case
... ... @@ -70,8 +74,72 @@ void *xrealloc(void *oldptr, size_t size) {
void *ret = realloc(oldptr, size);
if(ret == NULL)
critical("xrealloc(%p, %i): Cannot reallocate memory.", oldptr, size);
if (ret == NULL)
critical("(%p, %li): Cannot reallocate memory.", oldptr, size);
return ret;
}
#ifdef CAPABILITIES_SUPPORT
void *malloc_align(size_t size) {
long pagesize = sysconf(_SC_PAGE_SIZE);
size_t total_size;
void *ret;
# ifdef _DEBUG
debug(20, "(%li)", size);
# endif
# ifdef PARANOID
size++; // Just in case
# endif
if (pagesize == -1)
critical("(%li): Got error from sysconf(_SC_PAGE_SIZE)");
total_size = size;
# ifdef PARANOID
total_size += pagesize-1;
total_size /= pagesize;
total_size *= pagesize;
# endif
if (posix_memalign(&ret, pagesize, total_size))
critical("(%li): Cannot allocate memory.", size);
# ifdef PARANOID
if (ret == NULL)
critical("(%li): ptr == NULL.", size);
# endif
// memset(ret, 0, nmemb*size); // Just in case
return ret;
}
void *calloc_align(size_t nmemb, size_t size) {
size_t total_size;
void *ret;
# ifdef _DEBUG
debug(20, "(%li, %li)", nmemb, size);
# endif
# ifdef PARANOID
nmemb++; // Just in case
size++; // Just in case
# endif
total_size = nmemb*size;
ret = malloc_align(total_size);
memset(ret, 0, total_size);
return ret;
}
char *strdup_protect(const char *src, int prot) {
size_t len = strlen(src);
char *dst = malloc_align(len);
strcpy(dst, src);
if (mprotect(dst, len, prot))
critical("(%p, 0x%o): Got error from mprotect(%p, %lu, 0x%o)", src, prot, dst, len, prot);
return dst;
}
#endif
... ...
... ... @@ -19,7 +19,12 @@
#include <sys/types.h>
void *xmalloc(size_t size);
void *xcalloc(size_t nmemb, size_t size);
void *xrealloc(void *oldptr, size_t size);
extern void *xmalloc(size_t size);
extern void *xcalloc(size_t nmemb, size_t size);
extern void *xrealloc(void *oldptr, size_t size);
#ifdef CAPABILITIES_SUPPORT
extern void *malloc_align(size_t size);
extern void *calloc_align(size_t nmemb, size_t size);
extern char *strdup_protect(const char *src, int prot);
#endif
... ...
... ... @@ -31,6 +31,7 @@
# include <fts.h> // fts_open()
# include <errno.h> // errno
# include <sys/capability.h> // capset()
# include "malloc.h" // strdup_protect();
#endif
#include <unistd.h> // execvp()
... ... @@ -501,11 +502,11 @@ int pa_setup(struct pa_options *opts, ctx_t *ctx_p, uid_t *exec_uid_p, gid_t *ex
if (argc_s < 1)
critical("Not enough arguments");
argv_d[0] = strdup(ctx_p->handlerfpath);
argv_d[0] = strdup_protect(ctx_p->handlerfpath, PROT_READ);
i = 0;
while (i < argc_s) {
argv_d[i+1] = strdup(argv_s[i]);
argv_d[i+1] = strdup_protect(argv_s[i], PROT_READ);
isex_d[i+1] = isex_s[i];
i++;
}
... ... @@ -519,17 +520,17 @@ int pa_setup(struct pa_options *opts, ctx_t *ctx_p, uid_t *exec_uid_p, gid_t *ex
*exec_uid_p = ctx_p->synchandler_uid;
*exec_gid_p = ctx_p->synchandler_gid;
opts->label = strdup(ctx_p->label);
opts->label = strdup_protect(ctx_p->label, PROT_READ);
if (ctx_p->exithookfile != NULL)
opts->exithookfile = strdup(ctx_p->exithookfile);
opts->exithookfile = strdup_protect(ctx_p->exithookfile, PROT_READ);
if (ctx_p->preexithookfile != NULL)
opts->preexithookfile = strdup(ctx_p->preexithookfile);
opts->preexithookfile = strdup_protect(ctx_p->preexithookfile, PROT_READ);
{
int i = 0;
while (i < ctx_p->permitted_hookfiles) {
opts->permitted_hookfile[i] = strdup(ctx_p->permitted_hookfile[i]);
opts->permitted_hookfile[i] = strdup_protect(ctx_p->permitted_hookfile[i], PROT_READ);
i++;
}
opts->permitted_hookfile[i] = NULL;
... ... @@ -538,6 +539,35 @@ int pa_setup(struct pa_options *opts, ctx_t *ctx_p, uid_t *exec_uid_p, gid_t *ex
return 0;
}
int pa_unsetup(struct pa_options *opts) {
free(opts->exithookfile);
free(opts->preexithookfile);
free(opts->label);
{
int a_i = 0;
do {
int i;
i = 0;
while (i < opts->args[a_i].c) {
free(opts->args[a_i].v[i]);
i++;
}
} while(++a_i < SHARGS_MAX);
}
{
int i = 0;
while (i < opts->permitted_hookfiles) {
free(opts->permitted_hookfile[i]);
i++;
}
}
return 0;
}
# ifdef HL_LOCKS
static int hl_count_wait [HLLOCK_MAX] = {0};
static int hl_count_signal[HLLOCK_MAX] = {0};
... ... @@ -636,9 +666,12 @@ void *privileged_handler(void *_ctx_p)
ctx_t *ctx_p = _ctx_p;
uid_t exec_uid = 65535;
gid_t exec_gid = 65535;
struct pa_options opts = {{{{0}}}};
struct pa_options *opts;
int use_args_check = 0;
opts = calloc_align(1, sizeof(*opts));
cap_drop(ctx_p, ctx_p->caps);
debug(2, "Syncing with the runner");
... ... @@ -685,7 +718,8 @@ void *privileged_handler(void *_ctx_p)
if (setup)
critical("Double privileged_handler setuping. It can be if somebody is trying to hack the clsync.");
pa_setup(&opts, cmd.arg, &exec_uid, &exec_gid);
pa_setup(opts, cmd.arg, &exec_uid, &exec_gid);
mprotect(opts, sizeof(*opts), PROT_READ);
use_args_check = ((ctx_t *)cmd.arg)->flags[CHECK_EXECVP_ARGS];
setup++;
break;
... ... @@ -728,7 +762,7 @@ void *privileged_handler(void *_ctx_p)
case PA_FORK_EXECVP: {
struct pa_fork_execvp_arg *arg_p = cmd.arg;
if (use_args_check)
privileged_execvp_check_arguments(&opts, arg_p->file, arg_p->argv);
privileged_execvp_check_arguments(opts, arg_p->file, arg_p->argv);
pid_t pid = fork();
switch (pid) {
case -1:
... ... @@ -769,6 +803,7 @@ void *privileged_handler(void *_ctx_p)
# endif
}
pa_unsetup(opts);
pthread_mutex_unlock(&pthread_mutex_privileged);
debug(2, "Finished");
return 0;
... ...