Update OTA installer to understand SELinux filesystem labels

Modify the OTA installer to understand SELinux filesystem labels.

We do this by introducing new set_perm2 / set_perm2_recursive
calls, which understand SELinux filesystem labels. These filesystem
labels are applied at the same time that we apply the
UID / GID / permission changes.

For compatibility, we preserve the behavior of the existing
set_perm / set_perm_recursive calls.

If the destination kernel doesn't support security labels, don't
fail. SELinux isn't enabled on all kernels.

Bug: 8985290
Change-Id: I99800499f01784199e4918a82e3e2db1089cf25b
This commit is contained in:
Nick Kralevich
2013-07-18 15:21:12 -07:00
parent 51c84694b0
commit 627eb30f73
3 changed files with 32 additions and 8 deletions
+7 -2
View File
@@ -23,6 +23,7 @@
#include <errno.h>
#include <dirent.h>
#include <limits.h>
#include <selinux/selinux.h>
#include "DirUtil.h"
@@ -237,7 +238,7 @@ dirUnlinkHierarchy(const char *path)
int
dirSetHierarchyPermissions(const char *path,
int uid, int gid, int dirMode, int fileMode)
int uid, int gid, int dirMode, int fileMode, const char* secontext)
{
struct stat st;
if (lstat(path, &st)) {
@@ -255,6 +256,10 @@ dirSetHierarchyPermissions(const char *path,
return -1;
}
if ((secontext != NULL) && lsetfilecon(path, secontext) && (errno != ENOTSUP)) {
return -1;
}
/* recurse over directory components */
if (S_ISDIR(st.st_mode)) {
DIR *dir = opendir(path);
@@ -271,7 +276,7 @@ dirSetHierarchyPermissions(const char *path,
char dn[PATH_MAX];
snprintf(dn, sizeof(dn), "%s/%s", path, de->d_name);
if (!dirSetHierarchyPermissions(dn, uid, gid, dirMode, fileMode)) {
if (!dirSetHierarchyPermissions(dn, uid, gid, dirMode, fileMode, secontext)) {
errno = 0;
} else if (errno == 0) {
errno = -1;
+1 -1
View File
@@ -54,7 +54,7 @@ int dirUnlinkHierarchy(const char *path);
* Sets directories to <dirMode> and files to <fileMode>. Skips symlinks.
*/
int dirSetHierarchyPermissions(const char *path,
int uid, int gid, int dirMode, int fileMode);
int uid, int gid, int dirMode, int fileMode, const char* secontext);
#ifdef __cplusplus
}
+24 -5
View File
@@ -27,6 +27,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <selinux/selinux.h>
#include "cutils/misc.h"
#include "cutils/properties.h"
@@ -521,9 +522,10 @@ Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) {
Value* SetPermFn(const char* name, State* state, int argc, Expr* argv[]) {
char* result = NULL;
bool recursive = (strcmp(name, "set_perm_recursive") == 0);
bool recursive = (strcmp(name, "set_perm_recursive") == 0) || (strcmp(name, "set_perm2_recursive") == 0);
bool has_selabel = (strcmp(name, "set_perm2") == 0) || (strcmp(name, "set_perm2_recursive") == 0);
int min_args = 4 + (recursive ? 1 : 0);
int min_args = 4 + (has_selabel ? 1 : 0) + (recursive ? 1 : 0);
if (argc < min_args) {
return ErrorAbort(state, "%s() expects %d+ args, got %d",
name, min_args, argc);
@@ -562,8 +564,13 @@ Value* SetPermFn(const char* name, State* state, int argc, Expr* argv[]) {
goto done;
}
for (i = 4; i < argc; ++i) {
dirSetHierarchyPermissions(args[i], uid, gid, dir_mode, file_mode);
char* secontext = NULL;
if (has_selabel) {
secontext = args[4];
}
for (i = 4 + (has_selabel ? 1 : 0); i < argc; ++i) {
dirSetHierarchyPermissions(args[i], uid, gid, dir_mode, file_mode, secontext);
}
} else {
int mode = strtoul(args[2], &end, 0);
@@ -572,7 +579,12 @@ Value* SetPermFn(const char* name, State* state, int argc, Expr* argv[]) {
goto done;
}
for (i = 3; i < argc; ++i) {
char* secontext = NULL;
if (has_selabel) {
secontext = args[3];
}
for (i = 3 + (has_selabel ? 1 : 0); i < argc; ++i) {
if (chown(args[i], uid, gid) < 0) {
printf("%s: chown of %s to %d %d failed: %s\n",
name, args[i], uid, gid, strerror(errno));
@@ -583,6 +595,11 @@ Value* SetPermFn(const char* name, State* state, int argc, Expr* argv[]) {
name, args[i], mode, strerror(errno));
++bad;
}
if (has_selabel && lsetfilecon(args[i], secontext) && (errno != ENOTSUP)) {
printf("%s: lsetfilecon of %s to %s failed: %s\n",
name, args[i], secontext, strerror(errno));
++bad;
}
}
}
result = strdup("");
@@ -1135,6 +1152,8 @@ void RegisterInstallFunctions() {
RegisterFunction("symlink", SymlinkFn);
RegisterFunction("set_perm", SetPermFn);
RegisterFunction("set_perm_recursive", SetPermFn);
RegisterFunction("set_perm2", SetPermFn);
RegisterFunction("set_perm2_recursive", SetPermFn);
RegisterFunction("getprop", GetPropFn);
RegisterFunction("file_getprop", FileGetPropFn);