Extend init and ueventd for SE Android.
Add SE Android support for init and ueventd.
init:
- Load policy at boot.
- Set the security context for service daemons and their sockets.
- New built-in commands: setcon, setenforce, restorecon, setsebool.
- New option for services: seclabel.
ueventd:
- Set the security context for device directories and nodes.
Change-Id: I98ed752cde503c94d99dfa5b5a47e3c33db16aac
diff --git a/init/builtins.c b/init/builtins.c
index 3781dcd..9aa2345 100644
--- a/init/builtins.c
+++ b/init/builtins.c
@@ -33,6 +33,11 @@
#include <cutils/partition_utils.h>
#include <sys/system_properties.h>
+#ifdef HAVE_SELINUX
+#include <selinux/selinux.h>
+#include <selinux/label.h>
+#endif
+
#include "init.h"
#include "keywords.h"
#include "property_service.h"
@@ -436,6 +441,28 @@
}
+int do_setcon(int nargs, char **args) {
+#ifdef HAVE_SELINUX
+ if (is_selinux_enabled() <= 0)
+ return 0;
+ if (setcon(args[1]) < 0) {
+ return -errno;
+ }
+#endif
+ return 0;
+}
+
+int do_setenforce(int nargs, char **args) {
+#ifdef HAVE_SELINUX
+ if (is_selinux_enabled() <= 0)
+ return 0;
+ if (security_setenforce(atoi(args[1])) < 0) {
+ return -errno;
+ }
+#endif
+ return 0;
+}
+
int do_setkey(int nargs, char **args)
{
struct kbentry kbe;
@@ -649,6 +676,64 @@
return 0;
}
+int do_restorecon(int nargs, char **args) {
+#ifdef HAVE_SELINUX
+ char *secontext = NULL;
+ struct stat sb;
+ int i;
+
+ if (is_selinux_enabled() <= 0 || !sehandle)
+ return 0;
+
+ for (i = 1; i < nargs; i++) {
+ if (lstat(args[i], &sb) < 0)
+ return -errno;
+ if (selabel_lookup(sehandle, &secontext, args[i], sb.st_mode) < 0)
+ return -errno;
+ if (lsetfilecon(args[i], secontext) < 0) {
+ freecon(secontext);
+ return -errno;
+ }
+ freecon(secontext);
+ }
+#endif
+ return 0;
+}
+
+int do_setsebool(int nargs, char **args) {
+#ifdef HAVE_SELINUX
+ SELboolean *b = alloca(nargs * sizeof(SELboolean));
+ char *v;
+ int i;
+
+ if (is_selinux_enabled() <= 0)
+ return 0;
+
+ for (i = 1; i < nargs; i++) {
+ char *name = args[i];
+ v = strchr(name, '=');
+ if (!v) {
+ ERROR("setsebool: argument %s had no =\n", name);
+ return -EINVAL;
+ }
+ *v++ = 0;
+ b[i-1].name = name;
+ if (!strcmp(v, "1") || !strcasecmp(v, "true") || !strcasecmp(v, "on"))
+ b[i-1].value = 1;
+ else if (!strcmp(v, "0") || !strcasecmp(v, "false") || !strcasecmp(v, "off"))
+ b[i-1].value = 0;
+ else {
+ ERROR("setsebool: invalid value %s\n", v);
+ return -EINVAL;
+ }
+ }
+
+ if (security_set_boolean_list(nargs - 1, b, 0) < 0)
+ return -errno;
+#endif
+ return 0;
+}
+
int do_loglevel(int nargs, char **args) {
if (nargs == 2) {
klog_set_level(atoi(args[1]));