Skip to content
Open
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
4 changes: 1 addition & 3 deletions src/GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ OBJDUMP ?= $(CROSS_COMPILE)objdump

CPPFLAGS += -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -I. -I$(VPATH)
CFLAGS += -Wall -Wextra -O2
LDFLAGS += -ltalloc -Wl,-z,noexecstack
LDFLAGS += -lleveldb -ltalloc -Wl,-z,noexecstack

OBJECTS += \
cli/cli.o \
Expand Down Expand Up @@ -66,8 +66,6 @@ OBJECTS += \
extension/fake_id0/utimensat.o \
extension/fake_id0/access.o \
extension/fake_id0/exec.o \
extension/fake_id0/link.o \
extension/fake_id0/symlink.o \
extension/fake_id0/mk.o \
extension/fake_id0/stat.o \
extension/fake_id0/helper_functions.o \
Expand Down
18 changes: 2 additions & 16 deletions src/extension/fake_id0/access.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,25 @@
#include "extension/fake_id0/helper_functions.h"

/** Handles the access and faccessat syscalls. Checks permissions according to
* a meta file if it exists. See access(2) for returned errors.
* the meta info if it exists. See access(2) for returned errors.
*/
int handle_access_enter_end(Tracee *tracee, Reg path_sysarg,
Reg mode_sysarg, Reg dirfd_sysarg, Config *config)
{
int status, mode, perms, mask;
char path[PATH_MAX];
char rel_path[PATH_MAX];
char meta_path[PATH_MAX];

status = read_sysarg_path(tracee, path, path_sysarg, CURRENT);
if(status < 0)
return status;
if(status == 1)
return 0;

status = get_fd_path(tracee, rel_path, dirfd_sysarg, CURRENT);
if(status < 0)
return status;

status = check_dir_perms(tracee, 'r', path, rel_path, config);
if(status < 0)
return status;

// Only care about calls checking permissions.
mode = peek_reg(tracee, ORIGINAL, mode_sysarg);
if(mode & F_OK)
return 0;

status = get_meta_path(path, meta_path);
if(status < 0)
return status;

mask = 0;
if((mode & R_OK) == R_OK)
mask += 4;
Expand All @@ -47,7 +33,7 @@ int handle_access_enter_end(Tracee *tracee, Reg path_sysarg,
if((mode & X_OK) == X_OK)
mask += 1;

perms = get_permissions(meta_path, config, 1);
perms = get_permissions(path, config, 1);
if((perms & mask) != mask)
return -EACCES;

Expand Down
22 changes: 4 additions & 18 deletions src/extension/fake_id0/chmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

#include "extension/fake_id0/helper_functions.h"

/** Handles chmod, fchmod, and fchmodat syscalls. Changes meta files to the new
* permissions if the meta file exists. See chmod(2) for returned permission
/** Handles chmod, fchmod, and fchmodat syscalls. Changes meta info to the new
* permissions if the meta info exists. See chmod(2) for returned permission
* errors.
*/
int handle_chmod_enter_end(Tracee *tracee, Reg path_sysarg, Reg mode_sysarg,
Expand All @@ -18,8 +18,6 @@ int handle_chmod_enter_end(Tracee *tracee, Reg path_sysarg, Reg mode_sysarg,
uid_t owner;
gid_t group;
char path[PATH_MAX];
char rel_path[PATH_MAX];
char meta_path[PATH_MAX];

// When path_sysarg is set to IGNORE, the call being handled is fchmod.
if(path_sysarg == IGNORE_SYSARG)
Expand All @@ -34,23 +32,11 @@ int handle_chmod_enter_end(Tracee *tracee, Reg path_sysarg, Reg mode_sysarg,
return 0;
}

status = get_meta_path(path, meta_path);
if(path_exists(meta_path) < 0)
return 0;

status = get_fd_path(tracee, rel_path, dirfd_sysarg, CURRENT);
if(status < 0)
return status;

status = check_dir_perms(tracee, 'r', path, rel_path, config);
if(status < 0)
return status;

read_meta_file(meta_path, &read_mode, &owner, &group, config);
read_meta_info(path, &read_mode, &owner, &group, config);
if(config->euid != owner && config->euid != 0)
return -EPERM;

call_mode = peek_reg(tracee, ORIGINAL, mode_sysarg);
set_sysnum(tracee, PR_getuid);
return write_meta_file(meta_path, call_mode, owner, group, 0, config);
return write_meta_info(path, call_mode, owner, group, 0, config);
}
29 changes: 6 additions & 23 deletions src/extension/fake_id0/chown.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ int handle_chown_enter_end(Tracee *tracee, Config *config, Reg uid_sysarg, Reg g
#endif /* ifndef USERLAND */

#ifdef USERLAND
/** Handles chown, lchown, fchown, and fchownat syscalls. Changes the meta file
* to reflect arguments sent to the syscall if the meta file exists. See
/** Handles chown, lchown, fchown, and fchownat syscalls. Changes the meta info
* to reflect arguments sent to the syscall if the meta info exists. See
* chown(2) for returned permission errors.
*/
int handle_chown_enter_end(Tracee *tracee, Reg path_sysarg, Reg owner_sysarg,
Expand All @@ -38,8 +38,6 @@ int handle_chown_enter_end(Tracee *tracee, Reg path_sysarg, Reg owner_sysarg,
uid_t owner, read_owner;
gid_t group, read_group;
char path[PATH_MAX];
char rel_path[PATH_MAX];
char meta_path[PATH_MAX];

if(path_sysarg == IGNORE_SYSARG)
status = get_fd_path(tracee, path, fd_sysarg, CURRENT);
Expand All @@ -53,38 +51,23 @@ int handle_chown_enter_end(Tracee *tracee, Reg path_sysarg, Reg owner_sysarg,
return 0;
}

status = get_meta_path(path, meta_path);
if(status < 0)
return status;

if(path_exists(meta_path) != 0)
return 0;

status = get_fd_path(tracee, rel_path, dirfd_sysarg, CURRENT);
if(status < 0)
return status;

status = check_dir_perms(tracee, 'r', path, rel_path, config);
if(status < 0)
return status;

read_meta_file(meta_path, &mode, &read_owner, &read_group, config);
read_meta_info(path, &mode, &read_owner, &read_group, config);
owner = peek_reg(tracee, ORIGINAL, owner_sysarg);
/** When chown is called without an owner specified, eg
* chown :1000 'file', the owner argument to the system call is implicitly
* set to -1. To avoid this, the owner argument is replaced with the owner
* according to the meta file if it exists, or the current euid.
* according to the meta info if it exists, or the current euid.
*/
if((int) owner == -1)
owner = read_owner;
group = peek_reg(tracee, ORIGINAL, group_sysarg);
if(config->euid == 0)
write_meta_file(meta_path, mode, owner, group, 0, config);
write_meta_info(path, mode, owner, group, 0, config);

//TODO Handle chown properly: owner can only change the group of
// a file to another group they belong to.
else if(config->euid == read_owner) {
write_meta_file(meta_path, mode, read_owner, group, 0, config);
write_meta_info(path, mode, read_owner, group, 0, config);
poke_reg(tracee, owner_sysarg, read_owner);
}

Expand Down
20 changes: 3 additions & 17 deletions src/extension/fake_id0/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@

#include "extension/fake_id0/helper_functions.h"

/** Handles execve system calls. Checks permissions in a meta file if it exists
/** Handles execve system calls. Checks permissions from the meta info if it exists
* and returns errors matching those in execve(2).
*/
int handle_exec_enter_end(Tracee *tracee, Reg filename_sysarg, Config *config)
{
int status, perms;
char path[PATH_MAX];
char meta_path[PATH_MAX];
uid_t uid;
gid_t gid;
mode_t mode;
Expand All @@ -24,26 +23,13 @@ int handle_exec_enter_end(Tracee *tracee, Reg filename_sysarg, Config *config)
if(status == 1)
return 0;

status = get_meta_path(path, meta_path);
if(status < 0)
return status;

/* If metafile doesn't exist, get out, but don't error. */
if(path_exists(meta_path) != 0)
return 0;

/* Check perms relative to / since there is no dirfd argument to execve */
status = check_dir_perms(tracee, 'r', meta_path, "/", config);
if(status < 0)
return status;

/* Check whether the file has execute permission. */
perms = get_permissions(meta_path, config, 0);
perms = get_permissions(path, config, 0);
if((perms & 1) != 1)
return -EACCES;

/* If the setuid or setgid bits are on, change config accordingly. */
read_meta_file(meta_path, &mode, &uid, &gid, config);
read_meta_info(path, &mode, &uid, &gid, config);
if ((mode & S_ISUID) != 0) {
config->ruid = 0;
config->euid = 0;
Expand Down
Loading