summaryrefslogtreecommitdiffstats
path: root/tools/fs_config
diff options
context:
space:
mode:
authorNick Kralevich <nnk@google.com>2013-09-07 17:10:29 -0700
committerNick Kralevich <nnk@google.com>2013-09-10 12:30:43 -0700
commit0eb17d944704b3eb140bb9dded299d3be3aed77e (patch)
treef6094d060480c466998c1e255839943757641730 /tools/fs_config
parent00fcdfede678c274675436d0008fc4a668ef711c (diff)
downloadbuild-0eb17d944704b3eb140bb9dded299d3be3aed77e.zip
build-0eb17d944704b3eb140bb9dded299d3be3aed77e.tar.gz
build-0eb17d944704b3eb140bb9dded299d3be3aed77e.tar.bz2
Update OTA to understand SELinux labels and capabilities
Update the OTA generation script to understand SELinux file labels and file capabilities. Make fs_config aware of SELinux labels and file capabilities, and optionally output those elements whenever we output the UID / GID / file perms. The information is emitted as a key=value pair to allow for future extensibility. Pass the SELinux file label and capabilities to the newly created set_metadata() and set_metadata_recursive() calls. When the OTA script fixes up filesystem permissions, it will also fix up the SELinux labels and file capabilities. If no SELinux label and capabilities are available for the file, use the old set_perm and set_perm_recursive calls. Bug: 8985290 Bug: 10183961 Bug: 10186213 Change-Id: I4fcfb2c234dbfb965cee9e62f060092a4274d22d
Diffstat (limited to 'tools/fs_config')
-rw-r--r--tools/fs_config/Android.mk1
-rw-r--r--tools/fs_config/fs_config.c95
2 files changed, 91 insertions, 5 deletions
diff --git a/tools/fs_config/Android.mk b/tools/fs_config/Android.mk
index 5ef32dd..02deabb 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 f6760cc..f594c1e 100644
--- a/tools/fs_config/fs_config.c
+++ b/tools/fs_config/fs_config.c
@@ -15,10 +15,16 @@
*/
#include <stdio.h>
+#include <stdlib.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
+#include <inttypes.h>
+
+#include <selinux/selinux.h>
+#include <selinux/label.h>
+#include <selinux/android.h>
#include "private/android_filesystem_config.h"
@@ -27,21 +33,67 @@
// filename along with its desired uid, gid, and mode (in octal).
// The leading slash should be stripped from the input.
//
+// After the first 4 columns, optional key=value pairs are emitted
+// for each file. Currently, the following keys are supported:
+// * -S: selabel=[selinux_label]
+// * -C: capabilities=[hex capabilities value]
+//
// 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, for example, -S is used:
+//
+// system/etc/dbus.conf 1002 1002 440 selabel=u:object_r:system_file:s0
+// data/app 1000 1000 771 selabel=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] [-C]\n");
+}
+
int main(int argc, char** argv) {
char buffer[1024];
+ const char* context_file = NULL;
+ struct selabel_handle* sehnd = NULL;
+ int print_capabilities = 0;
+ int opt;
+ while((opt = getopt(argc, argv, "CS:")) != -1) {
+ switch(opt) {
+ case 'C':
+ print_capabilities = 1;
+ break;
+ 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 +116,40 @@ 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(" selabel=%s", secontext);
+ free(full_name);
+ freecon(secontext);
+ }
+
+ if (print_capabilities) {
+ printf(" capabilities=0x%" PRIx64, capabilities);
+ }
+
+ printf("\n");
}
return 0;
}