diff options
author | Kenny Root <kroot@google.com> | 2012-03-30 20:38:32 -0700 |
---|---|---|
committer | Kenny Root <kroot@google.com> | 2012-03-30 21:25:48 -0700 |
commit | 2e5c52322d54d0f98d36b499fcaa31a0e84ca87c (patch) | |
tree | 2c33fab44952f4a63d0c292596f2e14f439005fc | |
parent | 68e3dfd81ddb9367a0c3e0c72148c23a3227ed48 (diff) | |
parent | 8f9b41d95594af0bdafd4f3c22e9e1968ac7342c (diff) | |
download | extras-2e5c52322d54d0f98d36b499fcaa31a0e84ca87c.tar.gz |
resolved conflicts for merge of 8f9b41d9 to master
Change-Id: I9af02b9bba1176174540c849f905dece8ade54d8
-rw-r--r-- | ext4_utils/Android.mk | 36 | ||||
-rw-r--r-- | ext4_utils/contents.c | 49 | ||||
-rw-r--r-- | ext4_utils/contents.h | 2 | ||||
-rw-r--r-- | ext4_utils/make_ext4fs.c | 54 | ||||
-rw-r--r-- | ext4_utils/make_ext4fs.h | 12 | ||||
-rw-r--r-- | ext4_utils/make_ext4fs_main.c | 19 | ||||
-rwxr-xr-x | ext4_utils/mkuserimg.sh | 13 | ||||
-rw-r--r-- | ext4_utils/xattr.h | 23 |
8 files changed, 194 insertions, 14 deletions
diff --git a/ext4_utils/Android.mk b/ext4_utils/Android.mk index ceb3bdbd..d12a6be5 100644 --- a/ext4_utils/Android.mk +++ b/ext4_utils/Android.mk @@ -25,6 +25,12 @@ LOCAL_MODULE := libext4_utils LOCAL_MODULE_TAGS := optional LOCAL_C_INCLUDES += external/zlib +ifeq ($(HAVE_SELINUX), true) +LOCAL_C_INCLUDES += external/libselinux/include +LOCAL_SHARED_LIBRARIES += libselinux +LOCAL_CFLAGS += -DHAVE_SELINUX +endif # HAVE_SELINUX + include $(BUILD_HOST_STATIC_LIBRARY) include $(CLEAR_VARS) @@ -50,6 +56,12 @@ LOCAL_MODULE_TAGS := optional LOCAL_C_INCLUDES += external/zlib LOCAL_SHARED_LIBRARIES := libz +ifeq ($(HAVE_SELINUX), true) +LOCAL_C_INCLUDES += external/libselinux/include +LOCAL_SHARED_LIBRARIES += libselinux +LOCAL_CFLAGS += -DHAVE_SELINUX +endif # HAVE_SELINUX + include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) @@ -59,6 +71,12 @@ LOCAL_MODULE := libext4_utils LOCAL_MODULE_TAGS := optional LOCAL_C_INCLUDES += external/zlib +ifeq ($(HAVE_SELINUX), true) +LOCAL_C_INCLUDES += external/libselinux/include +LOCAL_STATIC_LIBRARIES += libselinux +LOCAL_CFLAGS += -DHAVE_SELINUX +endif # HAVE_SELINUX + include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) @@ -68,6 +86,12 @@ LOCAL_MODULE := make_ext4fs LOCAL_MODULE_TAGS := optional LOCAL_SHARED_LIBRARIES += libext4_utils libz +ifeq ($(HAVE_SELINUX), true) +LOCAL_C_INCLUDES += external/libselinux/include +LOCAL_SHARED_LIBRARIES += libselinux +LOCAL_CFLAGS += -DHAVE_SELINUX +endif # HAVE_SELINUX + include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) @@ -77,6 +101,12 @@ LOCAL_MODULE := ext2simg LOCAL_MODULE_TAGS := optional LOCAL_SHARED_LIBRARIES += libext4_utils libz +ifeq ($(HAVE_SELINUX), true) +LOCAL_C_INCLUDES += external/libselinux/include +LOCAL_SHARED_LIBRARIES += libselinux +LOCAL_CFLAGS += -DHAVE_SELINUX +endif # HAVE_SELINUX + include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) @@ -86,6 +116,12 @@ LOCAL_MODULE := ext2simg LOCAL_MODULE_TAGS := optional LOCAL_STATIC_LIBRARIES += libext4_utils libz +ifeq ($(HAVE_SELINUX), true) +LOCAL_C_INCLUDES += external/libselinux/include +LOCAL_STATIC_LIBRARIES += libselinux +LOCAL_CFLAGS += -DHAVE_SELINUX +endif # HAVE_SELINUX + include $(BUILD_HOST_EXECUTABLE) include $(CLEAR_VARS) diff --git a/ext4_utils/contents.c b/ext4_utils/contents.c index d64f7e02..de38bb0a 100644 --- a/ext4_utils/contents.c +++ b/ext4_utils/contents.c @@ -25,6 +25,7 @@ #include "contents.h" #include "extent.h" #include "indirect.h" +#include "xattr.h" #ifdef USE_MINGW #define S_IFLNK 0 /* used by make_link, not needed under mingw */ @@ -248,3 +249,51 @@ int inode_set_permissions(u32 inode_num, u16 mode, u16 uid, u16 gid, u32 mtime) return 0; } + +#ifdef HAVE_SELINUX +#define XATTR_SELINUX_SUFFIX "selinux" + +/* XXX */ +#define cpu_to_le32(x) (x) +#define cpu_to_le16(x) (x) + +int inode_set_selinux(u32 inode_num, const char *secon) +{ + struct ext4_inode *inode = get_inode(inode_num); + u32 *hdr; + struct ext4_xattr_entry *entry; + size_t name_len = strlen(XATTR_SELINUX_SUFFIX); + size_t value_len = strlen(secon)+1; + size_t size, min_offs; + char *val; + + if (!secon) + return 0; + + if (!inode) + return -1; + + hdr = (u32 *) (inode + 1); + *hdr = cpu_to_le32(EXT4_XATTR_MAGIC); + entry = (struct ext4_xattr_entry *) (hdr+1); + memset(entry, 0, EXT4_XATTR_LEN(name_len)); + entry->e_name_index = EXT4_XATTR_INDEX_SECURITY; + entry->e_name_len = name_len; + memcpy(entry->e_name, XATTR_SELINUX_SUFFIX, name_len); + entry->e_value_size = cpu_to_le32(value_len); + min_offs = (char *)inode + info.inode_size - (char*) entry; + size = EXT4_XATTR_SIZE(value_len); + val = (char *)entry + min_offs - size; + entry->e_value_offs = cpu_to_le16(min_offs - size); + memset(val + size - EXT4_XATTR_PAD, 0, EXT4_XATTR_PAD); + memcpy(val, secon, value_len); + inode->i_extra_isize = cpu_to_le16(sizeof(struct ext4_inode) - EXT4_GOOD_OLD_INODE_SIZE); + + return 0; +} +#else +int inode_set_selinux(u32 inode_num, const char *secon) +{ + return 0; +} +#endif diff --git a/ext4_utils/contents.h b/ext4_utils/contents.h index 3aafb1ee..35867fd1 100644 --- a/ext4_utils/contents.h +++ b/ext4_utils/contents.h @@ -29,6 +29,7 @@ struct dentry { u16 gid; u32 *inode; u32 mtime; + char *secon; }; u32 make_directory(u32 dir_inode_num, u32 entries, struct dentry *dentries, @@ -36,4 +37,5 @@ u32 make_directory(u32 dir_inode_num, u32 entries, struct dentry *dentries, u32 make_file(const char *filename, u64 len); u32 make_link(const char *filename, const char *link); int inode_set_permissions(u32 inode_num, u16 mode, u16 uid, u16 gid, u32 mtime); +int inode_set_selinux(u32 inode_num, const char *secon); #endif diff --git a/ext4_utils/make_ext4fs.c b/ext4_utils/make_ext4fs.c index ccba132b..6cd5adec 100644 --- a/ext4_utils/make_ext4fs.c +++ b/ext4_utils/make_ext4fs.c @@ -98,7 +98,8 @@ static u32 build_default_directory_structure() /* Read a local directory and create the same tree in the generated filesystem. Calls itself recursively with each directory in the given directory */ static u32 build_directory_structure(const char *full_path, const char *dir_path, - u32 dir_inode, fs_config_func_t fs_config_func) + u32 dir_inode, fs_config_func_t fs_config_func, + struct selabel_handle *sehnd) { int entries = 0; struct dentry *dentries; @@ -155,6 +156,18 @@ static u32 build_directory_structure(const char *full_path, const char *dir_path error("can't set android permissions - built without android support"); #endif } +#ifdef HAVE_SELINUX + if (sehnd) { + char *sepath = NULL; + asprintf(&sepath, "/%s", dentries[i].path); + if (selabel_lookup(sehnd, &dentries[i].secon, sepath, stat.st_mode) < 0) { + error("cannot lookup security context for %s", sepath); + } + if (dentries[i].secon) + printf("Labeling %s as %s\n", sepath, dentries[i].secon); + free(sepath); + } +#endif if (S_ISREG(stat.st_mode)) { dentries[i].file_type = EXT4_FT_REG_FILE; @@ -188,7 +201,7 @@ static u32 build_directory_structure(const char *full_path, const char *dir_path entry_inode = make_file(dentries[i].full_path, dentries[i].size); } else if (dentries[i].file_type == EXT4_FT_DIR) { entry_inode = build_directory_structure(dentries[i].full_path, - dentries[i].path, inode, fs_config_func); + dentries[i].path, inode, fs_config_func, sehnd); } else if (dentries[i].file_type == EXT4_FT_SYMLINK) { entry_inode = make_link(dentries[i].full_path, dentries[i].link); } else { @@ -202,11 +215,15 @@ static u32 build_directory_structure(const char *full_path, const char *dir_path dentries[i].mtime); if (ret) error("failed to set permissions on %s\n", dentries[i].path); + ret = inode_set_selinux(entry_inode, dentries[i].secon); + if (ret) + error("failed to set SELinux context on %s\n", dentries[i].path); free(dentries[i].path); free(dentries[i].full_path); free(dentries[i].link); free((void *)dentries[i].filename); + free(dentries[i].secon); } free(dentries); @@ -279,7 +296,8 @@ void reset_ext4fs_info() { free_data_blocks(); } -int make_ext4fs(const char *filename, s64 len) +int make_ext4fs(const char *filename, s64 len, + const char *mountpoint, struct selabel_handle *sehnd) { int fd; int status; @@ -293,7 +311,7 @@ int make_ext4fs(const char *filename, s64 len) return EXIT_FAILURE; } - status = make_ext4fs_internal(fd, NULL, NULL, NULL, 0, 0, 0, 1, 0); + status = make_ext4fs_internal(fd, NULL, mountpoint, NULL, 0, 0, 0, 1, 0, sehnd); close(fd); return status; @@ -301,7 +319,7 @@ int make_ext4fs(const char *filename, s64 len) int make_ext4fs_internal(int fd, const char *directory, char *mountpoint, fs_config_func_t fs_config_func, int gzip, int sparse, - int crc, int wipe, int init_itabs) + int crc, int wipe, int init_itabs, struct selabel_handle *sehnd) { u32 root_inode_num; u16 root_mode; @@ -393,7 +411,8 @@ int make_ext4fs_internal(int fd, const char *directory, root_inode_num = build_default_directory_structure(); #else if (directory) - root_inode_num = build_directory_structure(directory, mountpoint, 0, fs_config_func); + root_inode_num = build_directory_structure(directory, mountpoint, 0, + fs_config_func, sehnd); else root_inode_num = build_default_directory_structure(); #endif @@ -401,6 +420,29 @@ int make_ext4fs_internal(int fd, const char *directory, root_mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; inode_set_permissions(root_inode_num, root_mode, 0, 0, 0); +#ifdef HAVE_SELINUX + if (sehnd) { + char *sepath = NULL; + char *secontext = NULL; + + if (mountpoint[0] == '/') + sepath = strdup(mountpoint); + else + asprintf(&sepath, "/%s", mountpoint); + if (!sepath) + critical_error_errno("malloc"); + if (selabel_lookup(sehnd, &secontext, sepath, S_IFDIR) < 0) { + error("cannot lookup security context for %s", sepath); + } + if (secontext) { + printf("Labeling %s as %s\n", sepath, secontext); + inode_set_selinux(root_inode_num, secontext); + } + free(sepath); + freecon(secontext); + } +#endif + ext4_update_free(); if (init_itabs) diff --git a/ext4_utils/make_ext4fs.h b/ext4_utils/make_ext4fs.h index 4e2c3073..c217c3db 100644 --- a/ext4_utils/make_ext4fs.h +++ b/ext4_utils/make_ext4fs.h @@ -24,14 +24,22 @@ extern "C" { #endif +#ifdef HAVE_SELINUX +#include <selinux/selinux.h> +#include <selinux/label.h> +#else +struct selabel_handle; +#endif + typedef void (*fs_config_func_t)(const char *path, int dir, unsigned *uid, unsigned *gid, unsigned *mode); void reset_ext4fs_info(); -int make_ext4fs(const char *filename, s64 len); +int make_ext4fs(const char *filename, s64 len, + const char *mountpoint, struct selabel_handle *sehnd); int make_ext4fs_internal(int fd, const char *directory, char *mountpoint, fs_config_func_t fs_config_func, int gzip, int sparse, - int crc, int wipe, int init_itabs); + int crc, int wipe, int init_itabs, struct selabel_handle *sehnd); #ifdef __cplusplus } diff --git a/ext4_utils/make_ext4fs_main.c b/ext4_utils/make_ext4fs_main.c index 3aab7954..d5454236 100644 --- a/ext4_utils/make_ext4fs_main.c +++ b/ext4_utils/make_ext4fs_main.c @@ -42,6 +42,7 @@ static void usage(char *path) fprintf(stderr, "%s [ -l <len> ] [ -j <journal size> ] [ -b <block_size> ]\n", basename(path)); fprintf(stderr, " [ -g <blocks per group> ] [ -i <inodes> ] [ -I <inode size> ]\n"); fprintf(stderr, " [ -L <label> ] [ -f ] [ -a <android mountpoint> ]\n"); + fprintf(stderr, " [ -S file_contexts ]\n"); fprintf(stderr, " [ -z | -s ] [ -t ] [ -w ] [ -c ] [ -J ]\n"); fprintf(stderr, " <filename> [<directory>]\n"); } @@ -60,8 +61,12 @@ int main(int argc, char **argv) int init_itabs = 0; int fd; int exitcode; + struct selabel_handle *sehnd = NULL; +#ifdef HAVE_SELINUX + struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "" } }; +#endif - while ((opt = getopt(argc, argv, "l:j:b:g:i:I:L:a:fwzJsct")) != -1) { + while ((opt = getopt(argc, argv, "l:j:b:g:i:I:L:a:fwzJsctS:")) != -1) { switch (opt) { case 'l': info.len = parse_num(optarg); @@ -115,6 +120,16 @@ int main(int argc, char **argv) case 't': init_itabs = 1; break; + case 'S': +#ifdef HAVE_SELINUX + seopts[0].value = optarg; + sehnd = selabel_open(SELABEL_CTX_FILE, seopts, 1); + if (!sehnd) { + perror(optarg); + exit(EXIT_FAILURE); + } +#endif + break; default: /* '?' */ usage(argv[0]); exit(EXIT_FAILURE); @@ -167,7 +182,7 @@ int main(int argc, char **argv) } exitcode = make_ext4fs_internal(fd, directory, mountpoint, fs_config_func, gzip, - sparse, crc, wipe, init_itabs); + sparse, crc, wipe, init_itabs, sehnd); close(fd); return exitcode; diff --git a/ext4_utils/mkuserimg.sh b/ext4_utils/mkuserimg.sh index 3f2d2d44..1136a9e0 100755 --- a/ext4_utils/mkuserimg.sh +++ b/ext4_utils/mkuserimg.sh @@ -1,11 +1,11 @@ -#!/bin/bash +#!/bin/bash -x # # To call this script, make sure make_ext4fs is somewhere in PATH function usage() { cat<<EOT Usage: -mkuserimg.sh [-s] SRC_DIR OUTPUT_FILE EXT_VARIANT MOUNT_POINT SIZE +mkuserimg.sh [-s] SRC_DIR OUTPUT_FILE EXT_VARIANT MOUNT_POINT SIZE [FILE_CONTEXTS] EOT } @@ -17,7 +17,7 @@ if [ "$1" = "-s" ]; then shift fi -if [ $# -ne 4 -a $# -ne 5 ]; then +if [ $# -ne 4 -a $# -ne 5 -a $# -ne 6 ]; then usage exit 1 fi @@ -32,6 +32,7 @@ OUTPUT_FILE=$2 EXT_VARIANT=$3 MOUNT_POINT=$4 SIZE=$5 +FC=$6 case $EXT_VARIANT in ext4) ;; @@ -47,7 +48,11 @@ if [ -z $SIZE ]; then SIZE=128M fi -MAKE_EXT4FS_CMD="make_ext4fs $ENABLE_SPARSE_IMAGE -l $SIZE -a $MOUNT_POINT $OUTPUT_FILE $SRC_DIR" +if [ -n "$FC" ]; then + FCOPT="-S $FC" +fi + +MAKE_EXT4FS_CMD="make_ext4fs $ENABLE_SPARSE_IMAGE $FCOPT -l $SIZE -a $MOUNT_POINT $OUTPUT_FILE $SRC_DIR" echo $MAKE_EXT4FS_CMD $MAKE_EXT4FS_CMD if [ $? -ne 0 ]; then diff --git a/ext4_utils/xattr.h b/ext4_utils/xattr.h new file mode 100644 index 00000000..2c6d9cc4 --- /dev/null +++ b/ext4_utils/xattr.h @@ -0,0 +1,23 @@ +#include <sys/types.h> + +#define EXT4_XATTR_MAGIC 0xEA020000 +#define EXT4_XATTR_INDEX_SECURITY 6 + +struct ext4_xattr_entry { + __u8 e_name_len; + __u8 e_name_index; + __le16 e_value_offs; + __le32 e_value_block; + __le32 e_value_size; + __le32 e_hash; + char e_name[0]; +}; + +#define EXT4_XATTR_PAD_BITS 2 +#define EXT4_XATTR_PAD (1<<EXT4_XATTR_PAD_BITS) +#define EXT4_XATTR_ROUND (EXT4_XATTR_PAD-1) +#define EXT4_XATTR_LEN(name_len) \ + (((name_len) + EXT4_XATTR_ROUND + \ + sizeof(struct ext4_xattr_entry)) & ~EXT4_XATTR_ROUND) +#define EXT4_XATTR_SIZE(size) \ + (((size) + EXT4_XATTR_ROUND) & ~EXT4_XATTR_ROUND) |