Skip to content

Commit

Permalink
Set the SELinux security label on new directories.
Browse files Browse the repository at this point in the history
Automatically set the SELinux security label on directories created
by init.rc.  This avoids the need to separately call restorecon on
each such directory from the init.rc file.  Also restorecon /dev
and /dev/socket after initial policy load so that they are labeled
correctly before any other dev nodes or sockets are created.

Change-Id: If6af6c4887cdead949737cebdd673957e9273ead
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
  • Loading branch information
stephensmalley committed Jul 26, 2012
1 parent ff856a2 commit e096e36
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 45 deletions.
18 changes: 2 additions & 16 deletions init/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ int do_mkdir(int nargs, char **args)
mode = strtoul(args[2], 0, 8);
}

ret = mkdir(args[1], mode);
ret = make_dir(args[1], mode);
/* chmod in case the directory already exists */
if (ret == -1 && errno == EEXIST) {
ret = _chmod(args[1], mode);
Expand Down Expand Up @@ -735,26 +735,12 @@ int do_chmod(int nargs, char **args) {
}

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)
if (restorecon(args[i]) < 0)
return -errno;
if (lsetfilecon(args[i], secontext) < 0) {
freecon(secontext);
return -errno;
}
freecon(secontext);
}
#endif
return 0;
}

Expand Down
28 changes: 1 addition & 27 deletions init/devices.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
#define FIRMWARE_DIR2 "/vendor/firmware"

#ifdef HAVE_SELINUX
static struct selabel_handle *sehandle;
extern struct selabel_handle *sehandle;
#endif

static int device_fd = -1;
Expand Down Expand Up @@ -219,32 +219,6 @@ static void make_device(const char *path,
#endif
}


static int make_dir(const char *path, mode_t mode)
{
int rc;

#ifdef HAVE_SELINUX
char *secontext = NULL;

if (sehandle) {
selabel_lookup(sehandle, &secontext, path, mode);
setfscreatecon(secontext);
}
#endif

rc = mkdir(path, mode);

#ifdef HAVE_SELINUX
if (secontext) {
freecon(secontext);
setfscreatecon(NULL);
}
#endif
return rc;
}


static void add_platform_device(const char *name)
{
int name_len = strlen(name);
Expand Down
6 changes: 6 additions & 0 deletions init/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,12 @@ 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
* and therefore need their security context restored to the proper value.
* This must happen before /dev is populated by ueventd.
*/
restorecon("/dev");
restorecon("/dev/socket");
#endif

is_charger = !strcmp(bootmode, "charger");
Expand Down
53 changes: 51 additions & 2 deletions init/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,12 @@ int mkdir_recursive(const char *pathname, mode_t mode)
memcpy(buf, pathname, width);
buf[width] = 0;
if (stat(buf, &info) != 0) {
ret = mkdir(buf, mode);
ret = make_dir(buf, mode);
if (ret && errno != EEXIST)
return ret;
}
}
ret = mkdir(pathname, mode);
ret = make_dir(pathname, mode);
if (ret && errno != EEXIST)
return ret;
return 0;
Expand Down Expand Up @@ -451,3 +451,52 @@ void import_kernel_cmdline(int in_qemu,
ptr = x;
}
}

int make_dir(const char *path, mode_t mode)
{
int rc;

#ifdef HAVE_SELINUX
char *secontext = NULL;

if (sehandle) {
selabel_lookup(sehandle, &secontext, path, mode);
setfscreatecon(secontext);
}
#endif

rc = mkdir(path, mode);

#ifdef HAVE_SELINUX
if (secontext) {
int save_errno = errno;
freecon(secontext);
setfscreatecon(NULL);
errno = save_errno;
}
#endif
return rc;
}

int restorecon(const char *pathname)
{
#ifdef HAVE_SELINUX
char *secontext = NULL;
struct stat sb;
int i;

if (is_selinux_enabled() <= 0 || !sehandle)
return 0;

if (lstat(pathname, &sb) < 0)
return -errno;
if (selabel_lookup(sehandle, &secontext, pathname, sb.st_mode) < 0)
return -errno;
if (lsetfilecon(pathname, secontext) < 0) {
freecon(secontext);
return -errno;
}
freecon(secontext);
#endif
return 0;
}
2 changes: 2 additions & 0 deletions init/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,6 @@ int wait_for_file(const char *filename, int timeout);
void open_devnull_stdio(void);
void get_hardware_name(char *hardware, unsigned int *revision);
void import_kernel_cmdline(int in_qemu, void (*import_kernel_nv)(char *name, int in_qemu));
int make_dir(const char *path, mode_t mode);
int restorecon(const char *pathname);
#endif

0 comments on commit e096e36

Please sign in to comment.