diff options
Diffstat (limited to 'libselinux/src/setexecfilecon.c')
-rw-r--r-- | libselinux/src/setexecfilecon.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/libselinux/src/setexecfilecon.c b/libselinux/src/setexecfilecon.c new file mode 100644 index 00000000..b3afa132 --- /dev/null +++ b/libselinux/src/setexecfilecon.c @@ -0,0 +1,71 @@ +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <selinux/flask.h> +#include "selinux_internal.h" +#include "context_internal.h" + +int setexecfilecon(const char *filename, const char *fallback_type) +{ + security_context_t mycon = NULL, fcon = NULL, newcon = NULL; + context_t con = NULL; + int rc = 0; + + if (is_selinux_enabled() < 1) + return 0; + + rc = getcon(&mycon); + if (rc < 0) + goto out; + + rc = getfilecon(filename, &fcon); + if (rc < 0) + goto out; + + rc = security_compute_create(mycon, fcon, SECCLASS_PROCESS, &newcon); + if (rc < 0) + goto out; + + if (!strcmp(mycon, newcon)) { + /* No default transition, use fallback_type for now. */ + rc = -1; + con = context_new(mycon); + if (!con) + goto out; + if (context_type_set(con, fallback_type)) + goto out; + freecon(newcon); + newcon = strdup(context_str(con)); + if (!newcon) + goto out; + rc = 0; + } + + rc = setexeccon(newcon); + if (rc < 0) + goto out; + out: + + if (rc < 0 && security_getenforce() == 0) + rc = 0; + + context_free(con); + freecon(newcon); + freecon(fcon); + freecon(mycon); + return rc < 0 ? rc : 0; +} + +#ifndef DISABLE_RPM +int rpm_execcon(unsigned int verified __attribute__ ((unused)), + const char *filename, char *const argv[], char *const envp[]) +{ + int rc; + + rc = setexecfilecon(filename, "rpm_script_t"); + if (rc < 0) + return rc; + + return execve(filename, argv, envp); +} +#endif |