summaryrefslogtreecommitdiffstats
path: root/tools/fs_config
diff options
context:
space:
mode:
authorNick Kralevich <nnk@google.com>2013-07-17 17:43:09 -0700
committerNick Kralevich <nnk@google.com>2013-07-18 15:04:22 -0700
commitfbbd79530adc6ddd6bbfb3c5fc60ba5ec0ce5f2d (patch)
treeb7cec73cd0ba7d7bc7e305e842f9d590288f83ae /tools/fs_config
parent0a2c858bb650f3daca550bf26d17286ecee56cd8 (diff)
downloadbuild-fbbd79530adc6ddd6bbfb3c5fc60ba5ec0ce5f2d.tar.gz
build-fbbd79530adc6ddd6bbfb3c5fc60ba5ec0ce5f2d.tar.bz2
build-fbbd79530adc6ddd6bbfb3c5fc60ba5ec0ce5f2d.zip
Update OTA to understand SELinux filesystem labels
Make fs_config aware of SELinux contexts, and output the context whenever we output the UID / GID / file perms. Pass the selinux context to the set_perm2() and set_perm2_recursive() calls. When the OTA script fixes up filesystem permissions, it will also fix up the SELinux context on the files. Bug: 8985290 Change-Id: I6419b64c06309a93ac6b2f2cf9fc7f8815adeaf3
Diffstat (limited to 'tools/fs_config')
-rw-r--r--tools/fs_config/Android.mk1
-rw-r--r--tools/fs_config/fs_config.c80
2 files changed, 76 insertions, 5 deletions
diff --git a/tools/fs_config/Android.mk b/tools/fs_config/Android.mk
index 5ef32dd34..02deabbf7 100644
--- a/tools/fs_config/Android.mk
+++ b/tools/fs_config/Android.mk
@@ -17,6 +17,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := fs_config.c
LOCAL_MODULE := fs_config
+LOCAL_STATIC_LIBRARIES := libselinux
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_HOST_EXECUTABLE)
diff --git a/tools/fs_config/fs_config.c b/tools/fs_config/fs_config.c
index f6760cc5a..60c323800 100644
--- a/tools/fs_config/fs_config.c
+++ b/tools/fs_config/fs_config.c
@@ -15,11 +15,16 @@
*/
#include <stdio.h>
+#include <stdlib.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
+#include <selinux/selinux.h>
+#include <selinux/label.h>
+#include <selinux/android.h>
+
#include "private/android_filesystem_config.h"
// This program takes a list of files and directories (indicated by a
@@ -29,19 +34,56 @@
//
// Example input:
//
-// system/etc/dbus.conf
-// data/app/
+// system/etc/dbus.conf
+// data/app/
//
// Output:
//
-// system/etc/dbus.conf 1002 1002 440
-// data/app 1000 1000 771
+// system/etc/dbus.conf 1002 1002 440
+// data/app 1000 1000 771
+//
+// or if -S is used:
+//
+// system/etc/dbus.conf 1002 1002 440 u:object_r:system_file:s0
+// data/app 1000 1000 771 u:object_r:apk_data_file:s0
//
// Note that the output will omit the trailing slash from
// directories.
+static struct selabel_handle* get_sehnd(const char* context_file) {
+ struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, context_file } };
+ struct selabel_handle* sehnd = selabel_open(SELABEL_CTX_FILE, seopts, 1);
+
+ if (!sehnd) {
+ perror("error running selabel_open");
+ exit(EXIT_FAILURE);
+ }
+ return sehnd;
+}
+
+static void usage() {
+ fprintf(stderr, "Usage: fs_config [-S context_file]\n");
+}
+
int main(int argc, char** argv) {
char buffer[1024];
+ const char* context_file = NULL;
+ struct selabel_handle* sehnd = NULL;
+ int opt;
+ while((opt = getopt(argc, argv, "S:")) != -1) {
+ switch(opt) {
+ case 'S':
+ context_file = optarg;
+ break;
+ default:
+ usage();
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (context_file != NULL) {
+ sehnd = get_sehnd(context_file);
+ }
while (fgets(buffer, 1023, stdin) != NULL) {
int is_dir = 0;
@@ -64,7 +106,35 @@ int main(int argc, char** argv) {
unsigned uid = 0, gid = 0, mode = 0;
uint64_t capabilities;
fs_config(buffer, is_dir, &uid, &gid, &mode, &capabilities);
- printf("%s %d %d %o\n", buffer, uid, gid, mode);
+ printf("%s %d %d %o", buffer, uid, gid, mode);
+
+ if (sehnd != NULL) {
+ size_t buffer_strlen = strnlen(buffer, sizeof(buffer));
+ if (buffer_strlen >= sizeof(buffer)) {
+ fprintf(stderr, "non null terminated buffer, aborting\n");
+ exit(EXIT_FAILURE);
+ }
+ size_t full_name_size = buffer_strlen + 2;
+ char* full_name = (char*) malloc(full_name_size);
+ if (full_name == NULL) {
+ perror("malloc");
+ exit(EXIT_FAILURE);
+ }
+
+ full_name[0] = '/';
+ strncpy(full_name + 1, buffer, full_name_size - 1);
+ full_name[full_name_size - 1] = '\0';
+
+ char* secontext;
+ if (selabel_lookup(sehnd, &secontext, full_name, ( mode | (is_dir ? S_IFDIR : S_IFREG)))) {
+ secontext = strdup("u:object_r:unlabeled:s0");
+ }
+
+ printf(" %s", secontext);
+ free(full_name);
+ freecon(secontext);
+ }
+ printf("\n");
}
return 0;
}