summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAles Kozumplik <akozumpl@redhat.com>2011-12-22 14:34:03 +0100
committerAles Kozumplik <akozumpl@redhat.com>2012-01-12 14:27:36 +0100
commit7a8b75d26605cf7a3fde9f624a80d6fb8390fcbd (patch)
treeff5869d8f862b0c1c0112362defa46108612bb80
parentcb2894b361f7f9ee048efdd08604163eb4232b53 (diff)
downloadrpm-7a8b75d26605cf7a3fde9f624a80d6fb8390fcbd.tar.gz
rpm-7a8b75d26605cf7a3fde9f624a80d6fb8390fcbd.tar.bz2
rpm-7a8b75d26605cf7a3fde9f624a80d6fb8390fcbd.zip
selinux: reopen label between transactions if necessary (RhBug: 746073)
-rw-r--r--lib/rpmts.c18
-rw-r--r--lib/rpmts_internal.h8
-rw-r--r--lib/transaction.c17
-rw-r--r--plugins/sepolicy.c2
-rw-r--r--system.h1
5 files changed, 35 insertions, 11 deletions
diff --git a/lib/rpmts.c b/lib/rpmts.c
index 25ce83da7..86411496e 100644
--- a/lib/rpmts.c
+++ b/lib/rpmts.c
@@ -738,19 +738,28 @@ struct selabel_handle * rpmtsSELabelHandle(rpmts ts)
return NULL;
}
-rpmRC rpmtsSELabelInit(rpmts ts, const char *path)
+rpmRC rpmtsSELabelInit(rpmts ts, int open_status, const char *path)
{
#if WITH_SELINUX
if (ts == NULL || path == NULL) {
return RPMRC_FAIL;
}
+ if (open_status) {
+ selinux_status_close();
+ if (selinux_status_open(0) < 0) {
+ return RPMRC_FAIL;
+ }
+ } else if (!selinux_status_updated() && ts->selabelHandle) {
+ return RPMRC_OK;
+ }
+
struct selinux_opt opts[] = {
{SELABEL_OPT_PATH, path}
};
if (ts->selabelHandle) {
- rpmtsSELabelFini(ts);
+ rpmtsSELabelFini(ts, 0);
}
ts->selabelHandle = selabel_open(SELABEL_CTX_FILE, opts, 1);
@@ -761,13 +770,16 @@ rpmRC rpmtsSELabelInit(rpmts ts, const char *path)
return RPMRC_OK;
}
-void rpmtsSELabelFini(rpmts ts)
+void rpmtsSELabelFini(rpmts ts, int close_status)
{
#if WITH_SELINUX
if (ts && ts->selabelHandle) {
selabel_close(ts->selabelHandle);
ts->selabelHandle = NULL;
}
+ if (close_status) {
+ selinux_status_close();
+ }
#endif
}
diff --git a/lib/rpmts_internal.h b/lib/rpmts_internal.h
index 438fd46a4..b4213fea2 100644
--- a/lib/rpmts_internal.h
+++ b/lib/rpmts_internal.h
@@ -70,7 +70,7 @@ struct rpmts_s {
#ifdef __cplusplus
extern "C" {
#endif
-
+
RPM_GNUC_INTERNAL
tsMembers rpmtsMembers(rpmts ts);
@@ -91,16 +91,18 @@ struct selabel_handle * rpmtsSELabelHandle(rpmts ts);
/** \ingroup rpmts
* Initialize selabel
* @param ts transaction set
+ * @param open_status if the func should open selinux status or just check it
* @param path path to contexts file
* @return RPMRC_OK on success, RPMRC_FAIL otherwise
*/
-rpmRC rpmtsSELabelInit(rpmts ts, const char * path);
+rpmRC rpmtsSELabelInit(rpmts ts, int open_status, const char * path);
/** \ingroup rpmts
* Clean up selabel
* @param ts transaction set
+ * @param close_status whether we should close selinux status
*/
-void rpmtsSELabelFini(rpmts ts);
+void rpmtsSELabelFini(rpmts ts, int close_status);
#ifdef __cplusplus
}
diff --git a/lib/transaction.c b/lib/transaction.c
index 88219b779..da2895be0 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -1253,13 +1253,18 @@ static int rpmtsSetup(rpmts ts, rpmprobFilterFlags ignoreSet)
if (rpmtsFlags(ts) & (RPMTRANS_FLAG_JUSTDB | RPMTRANS_FLAG_TEST))
(void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers | RPMTRANS_FLAG_NOCOLLECTIONS));
- /* if SELinux isn't enabled, init fails or test run, don't bother... */
+ /* if SELinux isn't enabled or it is a test run, don't bother... */
if (!is_selinux_enabled() || (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) {
rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_NOCONTEXTS));
}
- if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS)) {
- rpmtsSELabelInit(ts, selinux_file_context_path());
+ if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS) {
+ rpmlog(RPMLOG_DEBUG, "Selinux disabled.\n");
+ } else {
+ if (rpmtsSELabelInit(ts, 1, selinux_file_context_path())) {
+ rpmlog(RPMLOG_WARNING, "Failed to open SELinux handle.\n");
+ rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_NOCONTEXTS));
+ }
}
/*
@@ -1283,7 +1288,7 @@ static int rpmtsSetup(rpmts ts, rpmprobFilterFlags ignoreSet)
static int rpmtsFinish(rpmts ts)
{
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS)) {
- rpmtsSELabelFini(ts);
+ rpmtsSELabelFini(ts, 1);
}
return rpmChrootSet(NULL);
}
@@ -1384,6 +1389,10 @@ static int rpmtsProcess(rpmts ts)
rpmlog(RPMLOG_DEBUG, "========== +++ %s %s-%s 0x%x\n",
rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));
+ if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS)) {
+ rpmtsSELabelInit(ts, 0, selinux_file_context_path());
+ }
+
failed = rpmteProcess(p, rpmteType(p));
if (failed) {
rpmlog(RPMLOG_ERR, "%s: %s %s\n", rpmteNEVRA(p),
diff --git a/plugins/sepolicy.c b/plugins/sepolicy.c
index 291641527..adbbd13bb 100644
--- a/plugins/sepolicy.c
+++ b/plugins/sepolicy.c
@@ -556,7 +556,7 @@ static rpmRC sepolGo(void)
/* re-init selinux and re-read the files contexts, since things may have changed */
selinux_reset_config();
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS)) {
- if (rpmtsSELabelInit(ts, selinux_file_context_path()) == RPMRC_OK) {
+ if (rpmtsSELabelInit(ts, 0, selinux_file_context_path()) == RPMRC_OK) {
/* if this was the first time installing policy, every package before
* policy was installed will be mislabeled (e.g. semodule). So, relabel
* the entire filesystem if this is the case */
diff --git a/system.h b/system.h
index 9b23e45f1..dd3573859 100644
--- a/system.h
+++ b/system.h
@@ -79,6 +79,7 @@ char * stpncpy(char * dest, const char * src, size_t n);
#if WITH_SELINUX
#include <selinux/selinux.h>
#include <selinux/label.h>
+#include <selinux/avc.h>
#else
typedef char * security_context_t;