Your message dated Wed, 6 Sep 2017 03:04:01 +0200
with message-id <[email protected]>
and subject line Re: Bug#852539: dpkg: run maintainer scripts with SELinux user 
system_u
has caused the Debian Bug report #852539,
regarding dpkg: run maintainer scripts with SELinux user system_u
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)


-- 
852539: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=852539
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: dpkg
Version: 1.18.18
User: [email protected]
Usertags: selinux

Currently, dpkg runs its maintainer tasks in the SELinux type
dpkg_script_t without changing the SELinux user or role.
So when running root as sysadm_u:sysadm_r:sysadm_t, the tasks will be
run in unconfined_u:unconfined_r:dpkg_script_t.
The problem are the postinst scripts: They create files and run binaries.
Almost all the files created in this way do not have the correct file
context system_u:object_r:*, which can break a ubac enabled system.
e.g.:

Would relabel /usr/share/info/dir.old from staff_u:object_r:usr_t:s0
to system_u:object_r:usr_t:s0
Would relabel /usr/share/info/dir from staff_u:object_r:usr_t:s0 to
system_u:object_r:usr_t:s0
Would relabel /var/cache/man/pt/index.db from
unconfined_u:object_r:man_cache_t:s0 to
system_u:object_r:man_cache_t:s0

Also, for example, the exim4 post install script does some work
leading to run exim in system_mail_t, which is not allowed to run
under the roles sysadm_r/unconfined_r.

type=PROCTITLE msg=audit(01/24/17 15:51:28.963:2602) :
proctitle=/usr/sbin/exim4 -C /var/lib/exim4/config.autogenerated.tmp
-bV
type=SYSCALL msg=audit(01/24/17 15:51:28.963:2602) : arch=armeb
syscall=socket per=PER_LINUX_32BIT success=yes exit=4 a0=local
a1=SOCK_STREAM a2=ip a3=0x0 items=0 ppid=22511 pid=22748
auid=christian uid=root gid=root euid=root suid=root fsuid=root
egid=root sgid=root fsgid=root tty=pts1 ses=359 comm=exim4
exe=/usr/sbin/exim4 subj=staff_u:sysadm_r:system_mail_t:s0 key=(null)
type=SELINUX_ERR msg=audit(01/24/17 15:51:28.963:2602) :
op=security_compute_sid
invalid_context=staff_u:sysadm_r:system_mail_t:s0
scontext=staff_u:sysadm_r:system_mail_t:s0
tcontext=staff_u:sysadm_r:system_mail_t:s0 tclass=unix_stream_socket

This can cause issues when upgrading packages in enforced mode even as
unconfined user.

The following dpkg patch runs the maintainer tasks in the context
system_u:system_r:dpkg_script_t (may be altered inside the SELinux
policy):

Note: The patch does not touch the SELinux detection in the build
logic and the SELinux policy has to be updated beforehand.

From: root <root@debianSE>
Date: Mon, 9 Jan 2017 22:42:03 +0100
Subject: [PATCH] dpkg: fix maintainer SELinux context

---
src/script.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 85 insertions(+), 10 deletions(-)

diff --git a/src/script.c b/src/script.c
index 2f252ae..72b92cf 100644
--- a/src/script.c
+++ b/src/script.c
@@ -32,6 +32,7 @@
#include <stdlib.h>

#ifdef WITH_LIBSELINUX
+#include <ctype.h> // isspace
#include <selinux/selinux.h>
#endif

@@ -141,23 +142,97 @@ maintscript_pre_exec(struct command *cmd)
       return cmd->filename + instdirlen;
}

+#ifdef WITH_LIBSELINUX
+/*
+ * derived from get_init_context()
+ * 
https://github.com/SELinuxProject/selinux/blob/master/policycoreutils/run_init/run_init.c
+ *
+ * Get the CONTEXT associated with the context for the dpkg maint scripts.
+ *
+ * in:          nothing
+ * out:         The CONTEXT associated with the context.
+ * return:      0 on success, -1 on failure.
+ */
+static int
+get_dpkg_context(char **context)
+{
+       FILE *fp;
+       char buf[255], *bufp;
+       size_t buf_len;
+       char context_file[4096];
+       snprintf(context_file, sizeof(context_file) - 1, "%s/%s",
selinux_contexts_path(), "dpkg_context");
+       fp = fopen(context_file, "r");
+       if (!fp) {
+               ohshite(_("Could not open file %s\n"), context_file);
+               return -1;
+       }
+
+       while (1) {             /* loop until we find a non-empty line */
+
+               if (!fgets(buf, sizeof buf, fp)) {
+                       break;
+               }
+
+               buf_len = strlen(buf);
+               if (buf[buf_len - 1] == '\n') {
+                        buf[buf_len - 1] = 0;
+               }
+
+               bufp = buf;
+               while (*bufp && isspace(*bufp)) {
+                        bufp++;
+               }
+
+               if (*bufp) {
+                       *context = strdup(bufp);
+                       if (!(*context)) {
+                               goto out;
+                       }
+                       fclose(fp);
+                       return 0;
+               }
+       }
+      out:
+       fclose(fp);
+       ohshit(_("No context in file %s\n"), context_file);
+       return -1;
+}
+#endif
+
/**
 * 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)
+maintscript_set_exec_context(void)
{
+#ifdef WITH_LIBSELINUX
       int rc = 0;
+       char *dpkg_context = NULL;

-#ifdef WITH_LIBSELINUX
-       rc = setexecfilecon(cmd->filename, fallback);
-#endif
+       if (is_selinux_enabled() < 1) {
+               return 0;
+       }

-       return rc < 0 ? rc : 0;
+       if ((rc = get_dpkg_context(&dpkg_context)) < 0) {
+               ohshit(_("Can not get dpkg_context"));
+               goto out;
+       }
+
+       if ((rc = setexeccon(dpkg_context)) < 0) {
+               ohshite(_("Can not set exec content to %s"), dpkg_context);
+               goto out;;
+       }
+
+      out:
+       if (rc < 0 && security_getenforce() == 0) {
+               rc = 0;
+       }
+
+       free(dpkg_context);
+       return rc;
+#else
+       return 0;
+#endif
}

static int
@@ -190,7 +265,7 @@ maintscript_exec(struct pkginfo *pkg, struct pkgbin *pkgbin,

               cmd->filename = cmd->argv[0] = maintscript_pre_exec(cmd);

-               if (maintscript_set_exec_context(cmd, "dpkg_script_t") < 0)
+               if (maintscript_set_exec_context() < 0)
                       ohshite(_("cannot set security execution context for "
                                 "maintainer script"));

--
2.11.0

--- End Message ---
--- Begin Message ---
Hi!

On Thu, 2017-02-23 at 16:28:58 +0100, Laurent Bigonville wrote:
> On Wed, 8 Feb 2017 05:37:20 +0100 Guillem Jover <[email protected]> wrote:
> > Thanks, but this patch feels all wrong to me. This is similar to what
> > RPM has been using supposedly w/o problems up to now. I also refactored
> > the function setexecfilecon() upstream so that both RPM and dpkg could
> > use it w/o having to duplicate the same code.
> >
> > Why can't the SELinux policy be changed/corrected to fix the
> > aforementioned problem? Is that not possible?

> FTR: https://marc.info/?l=selinux&m=148536819617953&w=2

Ok, given upstream's reply, I'm just going to close this report.

Thanks,
Guillem

--- End Message ---

Reply via email to