Skip to content
This repository has been archived by the owner on Nov 8, 2023. It is now read-only.

Commit

Permalink
Add support for reloading policy from /data/system.
Browse files Browse the repository at this point in the history
To support runtime policy management, add support for reloading
policy from /data/system.  This can be triggered by setting the
selinux.loadpolicy property to 1, whether from init.rc after
mounting /data or from the system_server (e.g. upon invocation of
a new device admin API for provisioning policy). ueventd and
installd are restarted upon policy reloads to pick up the new
policy configurations relevant to their operation.

Change-Id: I97479aecef8cec23b32f60e09cc778cc5520b691
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
  • Loading branch information
stephensmalley authored and r-craig committed Aug 9, 2012
1 parent d25b850 commit ae6f3d7
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 103 deletions.
11 changes: 5 additions & 6 deletions init/devices.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#ifdef HAVE_SELINUX
#include <selinux/selinux.h>
#include <selinux/label.h>
#include <selinux/android.h>
#endif

#include <private/android_filesystem_config.h>
Expand Down Expand Up @@ -871,12 +872,10 @@ void device_init(void)
struct stat info;
int fd;
#ifdef HAVE_SELINUX
struct selinux_opt seopts[] = {
{ SELABEL_OPT_PATH, "/file_contexts" }
};

if (is_selinux_enabled() > 0)
sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1);
sehandle = NULL;
if (is_selinux_enabled() > 0) {
sehandle = selinux_android_file_context_handle();
}
#endif
/* is 64K enough? udev uses 16MB! */
device_fd = uevent_open_socket(64*1024, true);
Expand Down
111 changes: 26 additions & 85 deletions init/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@
#include <sys/un.h>

#ifdef HAVE_SELINUX
#include <sys/mman.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
#include <selinux/android.h>
#endif

#include <libgen.h>
Expand Down Expand Up @@ -77,7 +77,6 @@ static char qemu[32];

#ifdef HAVE_SELINUX
static int selinux_enabled = 1;
static int selinux_enforcing = 0;
#endif

static struct action *cur_action = NULL;
Expand Down Expand Up @@ -604,9 +603,7 @@ static void import_kernel_nv(char *name, int for_emulator)
if (name_len == 0) return;

#ifdef HAVE_SELINUX
if (!strcmp(name,"enforcing")) {
selinux_enforcing = atoi(value);
} else if (!strcmp(name,"selinux")) {
if (!strcmp(name,"selinux")) {
selinux_enabled = atoi(value);
}
#endif
Expand Down Expand Up @@ -758,93 +755,28 @@ static int bootchart_init_action(int nargs, char **args)
#endif

#ifdef HAVE_SELINUX
void selinux_load_policy(void)
void selinux_init_all_handles(void)
{
const char path_prefix[] = "/sepolicy";
struct selinux_opt seopts[] = {
{ SELABEL_OPT_PATH, "/file_contexts" }
};
char path[PATH_MAX];
int fd, rc, vers;
struct stat sb;
void *map;
sehandle = selinux_android_file_context_handle();
}

sehandle = NULL;
int selinux_reload_policy(void)
{
if (!selinux_enabled) {
INFO("SELinux: Disabled by command line option\n");
return;
return -1;
}

mkdir(SELINUXMNT, 0755);
if (mount("selinuxfs", SELINUXMNT, "selinuxfs", 0, NULL)) {
if (errno == ENODEV) {
/* SELinux not enabled in kernel */
return;
}
ERROR("SELinux: Could not mount selinuxfs: %s\n",
strerror(errno));
return;
}
set_selinuxmnt(SELINUXMNT);
INFO("SELinux: Attempting to reload policy files\n");

vers = security_policyvers();
if (vers <= 0) {
ERROR("SELinux: Unable to read policy version\n");
return;
if (selinux_android_reload_policy() == -1) {
return -1;
}
INFO("SELinux: Maximum supported policy version: %d\n", vers);

snprintf(path, sizeof(path), "%s.%d",
path_prefix, vers);
fd = open(path, O_RDONLY);
while (fd < 0 && errno == ENOENT && --vers) {
snprintf(path, sizeof(path), "%s.%d",
path_prefix, vers);
fd = open(path, O_RDONLY);
}
if (fd < 0) {
ERROR("SELinux: Could not open %s: %s\n",
path, strerror(errno));
return;
}
if (fstat(fd, &sb) < 0) {
ERROR("SELinux: Could not stat %s: %s\n",
path, strerror(errno));
return;
}
map = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (map == MAP_FAILED) {
ERROR("SELinux: Could not map %s: %s\n",
path, strerror(errno));
return;
}
if (sehandle)
selabel_close(sehandle);

rc = security_load_policy(map, sb.st_size);
if (rc < 0) {
ERROR("SELinux: Could not load policy: %s\n",
strerror(errno));
return;
}

rc = security_setenforce(selinux_enforcing);
if (rc < 0) {
ERROR("SELinux: Could not set enforcing mode to %s: %s\n",
selinux_enforcing ? "enforcing" : "permissive", strerror(errno));
return;
}

munmap(map, sb.st_size);
close(fd);
INFO("SELinux: Loaded policy from %s\n", path);

sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1);
if (!sehandle) {
ERROR("SELinux: Could not load file_contexts: %s\n",
strerror(errno));
return;
}
INFO("SELinux: Loaded file contexts from %s\n", seopts[0].value);
return;
selinux_init_all_handles();
return 0;
}
#endif

Expand Down Expand Up @@ -900,8 +832,17 @@ int main(int argc, char **argv)

#ifdef HAVE_SELINUX
INFO("loading selinux policy\n");
selinux_load_policy();
/* These directories were necessarily created before policy load
if (selinux_enabled) {
if (selinux_android_load_policy() < 0) {
selinux_enabled = 0;
INFO("SELinux: Disabled due to failed policy load\n");
} else {
selinux_init_all_handles();
}
} else {
INFO("SELinux: Disabled by command line option\n");
}
/* These directories were necessarily created before initial policy load
* and therefore need their security context restored to the proper value.
* This must happen before /dev is populated by ueventd.
*/
Expand Down
1 change: 1 addition & 0 deletions init/init.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ int load_565rle_image( char *file_name );

#ifdef HAVE_SELINUX
extern struct selabel_handle *sehandle;
extern int selinux_reload_policy(void);
#endif

#endif /* _INIT_INIT_H */
6 changes: 6 additions & 0 deletions init/property_service.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ struct {
{ "persist.sys.", AID_SYSTEM, 0 },
{ "persist.service.", AID_SYSTEM, 0 },
{ "persist.security.", AID_SYSTEM, 0 },
{ "selinux." , AID_SYSTEM, 0 },
{ NULL, 0, 0 }
};

Expand Down Expand Up @@ -334,6 +335,11 @@ int property_set(const char *name, const char *value)
* to prevent them from being overwritten by default values.
*/
write_persistent_property(name, value);
#ifdef HAVE_SELINUX
} else if (strcmp("selinux.reload_policy", name) == 0 &&
strcmp("1", value) == 0) {
selinux_reload_policy();
#endif
}
property_changed(name, value);
return 0;
Expand Down
4 changes: 4 additions & 0 deletions rootdir/init.rc
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,10 @@ service ueventd /sbin/ueventd
critical
seclabel u:r:ueventd:s0

on property:selinux.reload_policy=1
restart ueventd
restart installd

service console /system/bin/sh
class core
console
Expand Down
19 changes: 7 additions & 12 deletions toolbox/restorecon.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
#include <fts.h>
#include <selinux/selinux.h>
#include <selinux/label.h>

#define FCPATH "/file_contexts"
#include <selinux/android.h>

static struct selabel_handle *sehandle;
static const char *progname;
Expand All @@ -17,7 +16,7 @@ static int verbose;

static void usage(void)
{
fprintf(stderr, "usage: %s [-f file_contexts] [-nrRv] pathname...\n", progname);
fprintf(stderr, "usage: %s [-nrRv] pathname...\n", progname);
exit(1);
}

Expand Down Expand Up @@ -54,21 +53,16 @@ static int restore(const char *pathname, const struct stat *sb)

int restorecon_main(int argc, char **argv)
{
struct selinux_opt seopts[] = {
{ SELABEL_OPT_PATH, FCPATH }
};
int ch, recurse = 0, ftsflags = FTS_PHYSICAL;
int i = 0;

progname = argv[0];

do {
ch = getopt(argc, argv, "f:nrRv");
ch = getopt(argc, argv, "nrRv");
if (ch == EOF)
break;
switch (ch) {
case 'f':
seopts[0].value = optarg;
break;
case 'n':
nochange = 1;
break;
Expand All @@ -89,9 +83,10 @@ int restorecon_main(int argc, char **argv)
if (!argc)
usage();

sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1);
sehandle = selinux_android_file_context_handle();

if (!sehandle) {
fprintf(stderr, "Could not load file contexts from %s: %s\n", seopts[0].value,
fprintf(stderr, "Could not load file_contexts: %s\n",
strerror(errno));
return -1;
}
Expand Down

0 comments on commit ae6f3d7

Please sign in to comment.