Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion 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
7 changes: 1 addition & 6 deletions src/extension/fake_id0/access.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ int handle_access_enter_end(Tracee *tracee, Reg path_sysarg,
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)
Expand All @@ -35,10 +34,6 @@ int handle_access_enter_end(Tracee *tracee, Reg path_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 +42,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
9 changes: 2 additions & 7 deletions src/extension/fake_id0/chmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ int handle_chmod_enter_end(Tracee *tracee, Reg path_sysarg, Reg mode_sysarg,
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,10 +33,6 @@ 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;
Expand All @@ -46,11 +41,11 @@ int handle_chmod_enter_end(Tracee *tracee, Reg path_sysarg, Reg mode_sysarg,
if(status < 0)
return status;

read_meta_file(meta_path, &read_mode, &owner, &group, config);
read_meta_file(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_file(path, call_mode, owner, group, 0, config);
}
14 changes: 3 additions & 11 deletions src/extension/fake_id0/chown.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ int handle_chown_enter_end(Tracee *tracee, Reg path_sysarg, Reg owner_sysarg,
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,13 +52,6 @@ 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;
Expand All @@ -68,7 +60,7 @@ int handle_chown_enter_end(Tracee *tracee, Reg path_sysarg, Reg owner_sysarg,
if(status < 0)
return status;

read_meta_file(meta_path, &mode, &read_owner, &read_group, config);
read_meta_file(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
Expand All @@ -79,12 +71,12 @@ int handle_chown_enter_end(Tracee *tracee, Reg path_sysarg, Reg owner_sysarg,
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_file(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_file(path, mode, read_owner, group, 0, config);
poke_reg(tracee, owner_sysarg, read_owner);
}

Expand Down
15 changes: 3 additions & 12 deletions src/extension/fake_id0/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ 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,18 @@ 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);
status = check_dir_perms(tracee, 'r', 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_file(path, &mode, &uid, &gid, config);
if ((mode & S_ISUID) != 0) {
config->ruid = 0;
config->euid = 0;
Expand Down
11 changes: 11 additions & 0 deletions src/extension/fake_id0/fake_id0.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ static FilteredSysnum filtered_sysnums[] = {
FILTERED_SYSNUM_END,
};

bool meta_initialized;

/**
* Restore the @node->mode for the given @node->path.
*
Expand Down Expand Up @@ -1079,6 +1081,8 @@ int fake_id0_callback(Extension *extension, ExtensionEvent event, intptr_t data1
Config *config;
int uid, gid;

meta_initialized = false;

errno = 0;
uid = strtol(uid_string, NULL, 10);
if (errno != 0)
Expand Down Expand Up @@ -1206,6 +1210,13 @@ int fake_id0_callback(Extension *extension, ExtensionEvent event, intptr_t data1
Tracee *tracee = TRACEE(extension);
Config *config = talloc_get_type_abort(extension->config, Config);

#ifdef USERLAND
if (!meta_initialized) {
init_meta_hash(tracee);
meta_initialized = true;
}
#endif

return handle_sysenter_end(tracee, config);
}

Expand Down
Loading