The following commit has been merged in the master branch:
commit 99529be532e9bb6c0d4fda1d803588c64b8fa47a
Author: Guillem Jover <[email protected]>
Date: Sat Nov 10 04:02:25 2012 +0100
dpkg: Execute maintainer scripts in a new SELinux execution context
Try to create a new execution context based on the current one and the
specific maintainer script filename. If it is the same as the current
one, use "dpkg_script_t" as a fallback.
The maintscript_set_exec_context() function is heavily based on the
libselinux rpm_execcon() function, which is licensed as Public Domain.
diff --git a/debian/changelog b/debian/changelog
index c99c0d6..f90109d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -56,6 +56,9 @@ dpkg (1.17.0) UNRELEASED; urgency=low
architectures on «dpkg-query --list».
* Rework SELinux code on unpack to reload the label database if it has
changed, for example while upgrading the SELinux policy package.
+ * Execute maintainer scripts in a new execution context, based on the
+ current one and the specific maintainer script filename, and if it's
+ not different to the current one, use "dpkg_script_t" as a fallback.
-- Guillem Jover <[email protected]> Fri, 03 Aug 2012 13:21:00 +0200
diff --git a/src/script.c b/src/script.c
index c03441b..94c4f0a 100644
--- a/src/script.c
+++ b/src/script.c
@@ -31,6 +31,12 @@
#include <unistd.h>
#include <stdlib.h>
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#include <selinux/flask.h>
+#include <selinux/context.h>
+#endif
+
#include <dpkg/i18n.h>
#include <dpkg/dpkg.h>
#include <dpkg/dpkg-db.h>
@@ -136,6 +142,66 @@ preexecscript(struct command *cmd)
return cmd->filename + instdirl;
}
+/**
+ * Set a new security execution context for the maintainer script.
+ *
+ * Try to create a new execution context based on the current one and the
+ * specific maintainer script filename. If it's the same as the current
+ * one, use the given fallback.
+ */
+static int
+maintscript_set_exec_context(struct command *cmd, const char *fallback)
+{
+ int rc = 0;
+#ifdef WITH_SELINUX
+ security_context_t curcon = NULL, newcon = NULL, filecon = NULL;
+ context_t tmpcon = NULL;
+
+ if (is_selinux_enabled() < 1)
+ return 0;
+
+ rc = getcon(&curcon);
+ if (rc < 0)
+ goto out;
+
+ rc = getfilecon(cmd->filename, &filecon);
+ if (rc < 0)
+ goto out;
+
+ rc = security_compute_create(curcon, filecon, SECCLASS_PROCESS,
&newcon);
+ if (rc < 0)
+ goto out;
+
+ if (strcmp(curcon, newcon) == 0) {
+ /* No default transition, use fallback for now. */
+ rc = -1;
+ tmpcon = context_new(curcon);
+ if (tmpcon == NULL)
+ goto out;
+ if (context_type_set(tmpcon, fallback))
+ goto out;
+ freecon(newcon);
+ newcon = strdup(context_str(tmpcon));
+ if (newcon == NULL)
+ goto out;
+ rc = 0;
+ }
+
+ rc = setexeccon(newcon);
+
+out:
+ if (rc < 0 && security_getenforce() == 0)
+ rc = 0;
+
+ context_free(tmpcon);
+ freecon(newcon);
+ freecon(curcon);
+ freecon(filecon);
+#endif
+
+ return rc < 0 ? rc : 0;
+}
+
static int
do_script(struct pkginfo *pkg, struct pkgbin *pkgbin,
struct command *cmd, struct stat *stab, int warn)
@@ -156,6 +222,11 @@ do_script(struct pkginfo *pkg, struct pkgbin *pkgbin,
ohshite(_("unable to setenv for maintainer script"));
cmd->filename = cmd->argv[0] = preexecscript(cmd);
+
+ if (maintscript_set_exec_context(cmd, "dpkg_script_t") < 0)
+ ohshite(_("cannot set security execution context for "
+ "maintainer script"));
+
command_exec(cmd);
}
subproc_signals_setup(cmd->name); /* This does a push_cleanup(). */
--
dpkg's main repository
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]