diff options
author | Stephen Smalley <sds@tycho.nsa.gov> | 2012-03-19 10:25:53 -0400 |
---|---|---|
committer | Stephen Smalley <sds@tycho.nsa.gov> | 2012-03-19 10:25:53 -0400 |
commit | 0ca91b300c711079816fa67b4148cac3cd1eef8c (patch) | |
tree | b36267726fb0452e58b7a569198100d535abb706 | |
parent | 6670f53f78cd44a6cb484785b2837439e2ba9178 (diff) | |
download | libselinux-0ca91b300c711079816fa67b4148cac3cd1eef8c.tar.gz |
Add a selinux_android_restorecon interface for use by the frameworks.
-rw-r--r-- | include/selinux/android.h | 2 | ||||
-rw-r--r-- | src/android.c | 65 |
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; +} |