summaryrefslogtreecommitdiff
path: root/src/android.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/android.c')
-rw-r--r--src/android.c103
1 files changed, 94 insertions, 9 deletions
diff --git a/src/android.c b/src/android.c
index 4768475..ad7a018 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"
@@ -22,7 +23,15 @@
* setting credentials for app processes and setting permissions
* on app data directories.
*/
-#define SEAPP_CONTEXTS "/seapp_contexts"
+static char const * const seapp_contexts_file[] = {
+ "/data/system/seapp_contexts",
+ "/seapp_contexts",
+ 0 };
+
+static const struct selinux_opt seopts[] = {
+ { SELABEL_OPT_PATH, "/data/system/file_contexts" },
+ { SELABEL_OPT_PATH, "/file_contexts" },
+ { 0, NULL } };
struct seapp_context {
/* input selectors */
@@ -83,21 +92,23 @@ static int seapp_context_cmp(const void *A, const void *B)
static struct seapp_context **seapp_contexts = NULL;
static int nspec = 0;
-static void seapp_context_init(void)
+int selinux_android_seapp_context_reload(void)
{
- FILE *fp;
+ FILE *fp = NULL;
char line_buf[BUFSIZ];
- const char *path = SEAPP_CONTEXTS;
char *token;
unsigned lineno;
struct seapp_context *cur;
char *p, *name = NULL, *value = NULL, *saveptr;
size_t len;
+ int i = 0, ret;
+
+ while ((fp==NULL) && seapp_contexts_file[i])
+ fp = fopen(seapp_contexts_file[i++], "r");
- fp = fopen(path, "r");
if (!fp) {
- selinux_log(SELINUX_ERROR, "%s: could not open %s", __FUNCTION__, path);
- return;
+ selinux_log(SELINUX_ERROR, "%s: could not open any seapp_contexts file", __FUNCTION__);
+ return -1;
}
nspec = 0;
@@ -216,20 +227,30 @@ static void seapp_context_init(void)
}
#endif
+ ret = 0;
+
out:
fclose(fp);
- return;
+ return ret;
err:
selinux_log(SELINUX_ERROR, "%s: Error reading %s, line %u, name %s, value %s\n",
- __FUNCTION__, path, lineno, name, value);
+ __FUNCTION__, seapp_contexts_file[i - 1], lineno, name, value);
+ ret = -1;
goto out;
oom:
selinux_log(SELINUX_ERROR,
"%s: Out of memory\n", __FUNCTION__);
+ ret = -1;
goto out;
}
+
+static void seapp_context_init(void)
+{
+ selinux_android_seapp_context_reload();
+}
+
static pthread_once_t once = PTHREAD_ONCE_INIT;
int selinux_android_setfilecon(const char *pkgdir,
@@ -463,3 +484,67 @@ oom:
goto out;
}
+static struct selabel_handle *sehandle = NULL;
+
+static void file_context_init(void)
+{
+ int i = 0;
+
+ sehandle = NULL;
+ while ((sehandle == NULL) && seopts[i].value) {
+ sehandle = selabel_open(SELABEL_CTX_FILE, &seopts[i], 1);
+ i++;
+ }
+
+ 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;
+}