Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutexes and hypercalls for new process EUID and EGID. #6

Merged
merged 2 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 46 additions & 12 deletions fs/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ int suid_dumpable = 0;
static LIST_HEAD(formats);
static DEFINE_RWLOCK(binfmt_lock);

DEFINE_MUTEX(execve_mutex);

void __register_binfmt(struct linux_binfmt * fmt, int insert)
{
BUG_ON(!fmt);
Expand Down Expand Up @@ -1755,6 +1757,7 @@ static int do_execveat_common(int fd, struct filename *filename,
if ((retval = bprm->argc) < 0)
goto out;

mutex_lock(&execve_mutex); //prevents other kernel threads from issuing interleaved sequences of hypercalls
{
char __user **argv_ptr;
char *arg;
Expand All @@ -1766,28 +1769,59 @@ static int do_execveat_common(int fd, struct filename *filename,
#define MIN(x, y) ((x) < (y) ? (x) : (y))

argv_ptr = (char __user **) argv.ptr.native; // Not .compat but .native
for (i = 1; i < MIN(3, bprm->argc); ++i) { // Args 1 and 2
if (get_user(arg, &argv_ptr[i]) == 0) {
if (copy_from_user(arg_buf, arg, sizeof(arg_buf)) == 0) {
//printk(KERN_CRIT "Arg %d: %s\n", i, arg_buf);
igloo_hypercall(596+i, arg_buf);
}
}
}

if (bprm->argc < 1) igloo_hypercall(597, 0); // No arg1
if (bprm->argc < 2) igloo_hypercall(598, 0); // No arg2
for (i = 0; i < bprm->argc; ++i) {
if (get_user(arg, &argv_ptr[i]) == 0) {
if (copy_from_user(arg_buf, arg, sizeof(arg_buf)) == 0) {
//printk(KERN_CRIT "Arg %d: %s\n", i, arg_buf);
igloo_hypercall2(597, (uint32_t) arg_buf, i); //do a hypercall with each argv buffer and associated index
}
}
}

igloo_hypercall(598, bprm->argc);
}


bprm->envc = count(envp, MAX_ARG_STRINGS);
if ((retval = bprm->envc) < 0)
if ((retval = bprm->envc) < 0) {
printk(KERN_CRIT "EXITING BEFORE ENVP ENUMERATION\n");
mutex_unlock(&execve_mutex); //unlock the mutex in case of early exit
goto out;
}


{
char __user **envp_ptr;
char *arg;
char arg_buf[256];
int i;
#ifdef CONFIG_COMPAT
#error "Igloo hacks broke compat"
#endif
envp_ptr = (char __user **) envp.ptr.native; // Not .compat but .native
for (i = 0; i < bprm->envc; ++i) {
if (get_user(arg, &envp_ptr[i]) == 0) {
if (copy_from_user(arg_buf, arg, sizeof(arg_buf)) == 0) {
//printk(KERN_CRIT "Env %d: %s\n", i, arg_buf);
igloo_hypercall2(599, (uint32_t) arg_buf, i); //do a hypercall with each envp buffer and associated index
}
}
}
igloo_hypercall(600, bprm->envc);
}


retval = prepare_binprm(bprm);
if (retval < 0)
goto out;

//the creds are set in the call to prepare_binprm above
//printk(KERN_CRIT "EUID: %u, EGID: %u\n", bprm->cred->euid.val, bprm->cred->egid.val);
igloo_hypercall(601, bprm->cred->euid.val);
igloo_hypercall(602, bprm->cred->egid.val);

mutex_unlock(&execve_mutex);

retval = copy_strings_kernel(1, &bprm->filename, bprm);
if (retval < 0)
goto out;
Expand Down
4 changes: 2 additions & 2 deletions include/linux/hypercall.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#define HYPERCALL_H
#include "linux/types.h"

static inline void igloo_hypercall(uint32_t num, uint32_t arg1) {
static inline void igloo_hypercall(uint64_t num, uint64_t arg1) {
#ifdef CONFIG_MIPS
register unsigned long a0 asm("a0") = num;
register unsigned long a1 asm("a1") = arg1;
Expand Down Expand Up @@ -31,7 +31,7 @@ static inline void igloo_hypercall(uint32_t num, uint32_t arg1) {
#endif
}

static inline unsigned long igloo_hypercall2(unsigned long num, unsigned long arg1, unsigned long arg2) {
static inline unsigned long igloo_hypercall2(uint64_t num, uint64_t arg1, uint64_t arg2) {
#if defined(CONFIG_ARM)
register unsigned long r0 asm("r0") = num;
register unsigned long r1 asm("r1") = arg1;
Expand Down