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
This commit is contained in:
Nick Kralevich
2013-07-17 17:43:09 -07:00
parent 0a2c858bb6
commit fbbd79530a
5 changed files with 108 additions and 32 deletions

View File

@@ -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;
}