aboutsummaryrefslogtreecommitdiffstats
path: root/libselinux/src/setexecfilecon.c
diff options
context:
space:
mode:
Diffstat (limited to 'libselinux/src/setexecfilecon.c')
-rw-r--r--libselinux/src/setexecfilecon.c71
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