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:
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user