Skip to content

Commit

Permalink
wrapp sce scripts when tmp partition is noexec
Browse files Browse the repository at this point in the history
  • Loading branch information
DominiqueDevinci committed Nov 6, 2019
1 parent 149785d commit 7f23880
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 15 deletions.
39 changes: 24 additions & 15 deletions src/SCE/sce_engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ xccdf_test_result_type_t sce_engine_eval_rule(struct xccdf_policy *policy, const
{
struct sce_parameters* parameters = (struct sce_parameters*)usr;
const char* xccdf_directory = parameters->xccdf_directory;
bool use_sce_wrapper = false; // use osca-run-sce-script ?

char* tmp_href = oscap_sprintf("%s/%s", xccdf_directory, href);

Expand All @@ -381,27 +382,26 @@ xccdf_test_result_type_t sce_engine_eval_rule(struct xccdf_policy *policy, const

if (access(tmp_href, F_OK | X_OK))
{
// again, only to provide helpful error message
oscap_seterr(OSCAP_EFAMILY_SCE, "SCE has found script file '%s' at '%s' "
"but it isn't executable!", href, tmp_href);
free(tmp_href);
return XCCDF_RESULT_ERROR;
// use the sce wrapper if it's not possible to acquire +x rights
use_sce_wrapper = true;
dI("%s isn't executable, oscap-run-sce-script will be use.", tmp_href);
}

// all the result codes are shifted by 100, because otherwise syntax errors in scripts
// or even their nonexistence would cause XCCDF_RESULT_PASS to be the result

char* argvp[1 + 1] = {
char* argvp[3] = {
tmp_href,
tmp_href,
NULL
};

dI("arvp[0] = %s", argvp[0]);
// bound values in KEY=VALUE form, ready to be passed as environment variables
char ** env_values = malloc(10 * sizeof(char * ));
size_t env_value_count = 10;
const size_t index_of_first_env_value_not_compiled_in = 10;

env_values[0] = "PATH=/bin:/sbin:/usr/bin:/usr/sbin";
env_values[0] = "PATH=/bin:/sbin:/usr/bin:/usr/local/bin:/usr/sbin";

env_values[1] = "XCCDF_RESULT_PASS=101";
env_values[2] = "XCCDF_RESULT_FAIL=102";
Expand Down Expand Up @@ -491,7 +491,7 @@ xccdf_test_result_type_t sce_engine_eval_rule(struct xccdf_policy *policy, const
env_values[env_value_count] = env_operator_entry;
env_value_count++;
}

dI("debug0 ..");
env_values = realloc(env_values, (env_value_count + 1) * sizeof(char*));
env_values[env_value_count] = NULL;

Expand All @@ -508,27 +508,30 @@ xccdf_test_result_type_t sce_engine_eval_rule(struct xccdf_policy *policy, const
// FIXME: We definitely want to impose security restrictions in the forked child process in the future.
// This would prevent scripts from writing to files or deleting them.

dI("debug1 ..");

int fork_result = fork();
if (fork_result >= 0)
{
// fork successful

if (fork_result == 0)
{
dI("debug2 ..");
// we won't read from the pipes, so close the reading fd
close(stdout_pipefd[0]);
close(stderr_pipefd[0]);

dI("debug2.1 ..");
// forward stdout and stderr to our custom opened pipes
dup2(stdout_pipefd[1], fileno(stdout));
dup2(stderr_pipefd[1], fileno(stderr));

//dup2(stdout_pipefd[1], fileno(stdout));
//dup2(stderr_pipefd[1], fileno(stderr));
dI("debug2.2 ..");
// we duplicated the file descriptors twice, we can close the original
// ones now, stdout and stderr will be closed properly after the execved
// script/executable finishes
close(stdout_pipefd[1]);
close(stderr_pipefd[1]);

dI("debug3 ..");
// before we execute the script, lets make sure we get SIGTERM when
// oscap is killed, crashes or otherwise terminates
#ifdef PR_SET_PDEATHSIG
Expand All @@ -539,7 +542,13 @@ xccdf_test_result_type_t sce_engine_eval_rule(struct xccdf_policy *policy, const
#endif

// we are the child process
execve(tmp_href, argvp, env_values);
dI("argvp[0<] = %s", argvp[0]);
dI("env<(0 %s", env_values[0]);

if(use_sce_wrapper)
execvp("oscap-run-sce-script", argvp, env_values);
else
execve(tmp_href, argvp, env_values);

free_env_values(env_values, index_of_first_env_value_not_compiled_in, env_value_count);

Expand Down
4 changes: 4 additions & 0 deletions utils/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
install(PROGRAMS "oscap-run-sce-script"
DESTINATION ${CMAKE_INSTALL_BINDIR}
)

if(ENABLE_OSCAP_UTIL)
file(GLOB UTILS_SOURCES "*.c")
if(HAVE_GETOPT_H)
Expand Down
24 changes: 24 additions & 0 deletions utils/oscap-run-sce-script
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash
#
# Authors:
# Dominique Blaze <[email protected]>
#
# use by oscap for evaluate a SCE file when +x rights are missing

if [ ! -z $1 ] && [ -f $1 ]
then
# file exists. first check if shebang is here

firstline=$(head -n1 $1)
if [ ${firstline:0:2} = "#!" ]
then # it's a shebang
cmd=${firstline:2} # remove the begin (#!)
cmd=${cmd##*( )} # trim whitespaces
eval $cmd $1 > /dev/stdout
else # no shebang, trying bash by default ...
/usr/bin/env bash $1 > /dev/stdout
fi

else
echo "Script file not found: $1" > /dev/stderr
fi

0 comments on commit 7f23880

Please sign in to comment.