summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2012-03-19 10:25:53 -0400
committerStephen Smalley <sds@tycho.nsa.gov>2012-03-19 10:25:53 -0400
commit0ca91b300c711079816fa67b4148cac3cd1eef8c (patch)
treeb36267726fb0452e58b7a569198100d535abb706
parent6670f53f78cd44a6cb484785b2837439e2ba9178 (diff)
downloadlibselinux-0ca91b300c711079816fa67b4148cac3cd1eef8c.tar.gz
Add a selinux_android_restorecon interface for use by the frameworks.
-rw-r--r--include/selinux/android.h2
-rw-r--r--src/android.c65
2 files changed, 67 insertions, 0 deletions
diff --git a/include/selinux/android.h b/include/selinux/android.h
index 883cff3..31d5d75 100644
--- a/include/selinux/android.h
+++ b/include/selinux/android.h
@@ -17,6 +17,8 @@ extern int selinux_android_setfilecon(const char *pkgdir,
const char *name,
uid_t uid);
+extern int selinux_android_restorecon(const char *file);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/android.c b/src/android.c
index 4768475..89a576c 100644
--- a/src/android.c
+++ b/src/android.c
@@ -13,6 +13,7 @@
#include <selinux/selinux.h>
#include <selinux/context.h>
#include <selinux/android.h>
+#include <selinux/label.h>
#include "callbacks.h"
#include "selinux_internal.h"
@@ -24,6 +25,8 @@
*/
#define SEAPP_CONTEXTS "/seapp_contexts"
+#define FILE_CONTEXTS "/file_contexts"
+
struct seapp_context {
/* input selectors */
char isSystemServer;
@@ -463,3 +466,65 @@ oom:
goto out;
}
+static struct selabel_handle *sehandle = NULL;
+
+static void file_context_init(void)
+{
+
+ struct selinux_opt seopts[] = {
+ { SELABEL_OPT_PATH, FILE_CONTEXTS }
+ };
+
+ sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1);
+ if (!sehandle)
+ selinux_log(SELINUX_ERROR,"%s: Error getting sehandle label (%s)\n",
+ __FUNCTION__, strerror(errno));
+}
+
+static pthread_once_t fc_once = PTHREAD_ONCE_INIT;
+
+int selinux_android_restorecon(const char *pathname)
+{
+
+ __selinux_once(fc_once, file_context_init);
+
+ int ret;
+
+ if (!sehandle)
+ goto bail;
+
+ struct stat sb;
+
+ if (lstat(pathname, &sb) < 0)
+ goto err;
+
+ char *oldcontext, *newcontext;
+
+ if (lgetfilecon(pathname, &oldcontext) < 0)
+ goto err;
+
+ if (selabel_lookup(sehandle, &newcontext, pathname, sb.st_mode) < 0)
+ goto err;
+
+ if (strcmp(newcontext, "<<none>>") && strcmp(oldcontext, newcontext))
+ if (lsetfilecon(pathname, newcontext) < 0)
+ goto err;
+
+ ret = 0;
+out:
+ if (oldcontext)
+ freecon(oldcontext);
+ if (newcontext)
+ freecon(newcontext);
+
+ return ret;
+
+err:
+ selinux_log(SELINUX_ERROR,
+ "%s: Error restoring context for %s (%s)\n",
+ __FUNCTION__, pathname, strerror(errno));
+
+bail:
+ ret = -1;
+ goto out;
+}