diff options
author | Mohamad Ayyash <mkayyash@google.com> | 2016-03-09 16:10:54 -0800 |
---|---|---|
committer | Christian Bejram <cbejram@google.com> | 2016-03-30 21:28:19 -0700 |
commit | eecf5b9117cc5410639081f56cc232898fd15b35 (patch) | |
tree | cb3eac411a7ef04824099269058071b05039c896 | |
parent | 3c27aa234b312b4bf777a5a3f4086e465f04e48b (diff) | |
download | squashfs-tools-marshmallow-dr-lego-release.tar.gz |
Add security.capabilities to squashfsandroid-lego-6.0.1_r2android-lego-6.0.1_r1marshmallow-dr-lego-release
BUG: 25671916
BUG: 23356656
BUG: 21035850
Change-Id: I3361260fc87e4036f34b246b61fc36fdb194a0e5
Signed-off-by: Mohamad Ayyash <mkayyash@google.com>
Signed-off-by: Christian Bejram <cbejram@google.com>
-rw-r--r-- | squashfs-tools/android.c | 22 | ||||
-rw-r--r-- | squashfs-tools/android.h | 5 | ||||
-rw-r--r-- | squashfs-tools/mksquashfs.c | 27 | ||||
-rw-r--r-- | squashfs-tools/mksquashfs.h | 10 | ||||
-rw-r--r-- | squashfs-tools/xattr.c | 60 |
5 files changed, 99 insertions, 25 deletions
diff --git a/squashfs-tools/android.c b/squashfs-tools/android.c index 4881d50..2e53f5a 100644 --- a/squashfs-tools/android.c +++ b/squashfs-tools/android.c @@ -30,6 +30,7 @@ #include "android.h" #include "private/android_filesystem_config.h" +#include "private/android_filesystem_capability.h" #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) @@ -43,10 +44,9 @@ void alloc_mounted_path(const char *mount_point, const char *subpath, char **mou strcat(*mounted_path, subpath); } -void android_fs_config(const char *path, struct stat *stat, const char *target_out_path) { - unsigned long capabilities = 0; +void android_fs_config(const char *path, struct stat *stat, const char *target_out_path, uint64_t *capabilities) { fs_config(path, S_ISDIR(stat->st_mode), target_out_path, - &stat->st_uid, &stat->st_gid, &stat->st_mode, &capabilities); + &stat->st_uid, &stat->st_gid, &stat->st_mode, capabilities); } @@ -91,3 +91,19 @@ char *set_selabel(const char *path, unsigned int mode, struct selabel_handle *se perror("Selabel handle is NULL."); exit(EXIT_FAILURE); } + +struct vfs_cap_data set_caps(uint64_t capabilities) { + struct vfs_cap_data cap_data; + memset(&cap_data, 0, sizeof(cap_data)); + + if (capabilities == 0) + return cap_data; + + cap_data.magic_etc = VFS_CAP_REVISION | VFS_CAP_FLAGS_EFFECTIVE; + cap_data.data[0].permitted = (uint32_t) capabilities; + cap_data.data[0].inheritable = 0; + cap_data.data[1].permitted = (uint32_t) (capabilities >> 32); + cap_data.data[1].inheritable = 0; + + return cap_data; +} diff --git a/squashfs-tools/android.h b/squashfs-tools/android.h index c2e7018..656b628 100644 --- a/squashfs-tools/android.h +++ b/squashfs-tools/android.h @@ -17,9 +17,12 @@ #ifndef _ANDROID_H_ #define _ANDROID_H_ +#include <stdint.h> + void alloc_mounted_path(const char *mount_point, const char *subpath, char **mounted_path); -void android_fs_config(const char *path, struct stat *stat, const char *target_out_path); +void android_fs_config(const char *path, struct stat *stat, const char *target_out_path, uint64_t *capabilities); struct selabel_handle *get_sehnd(const char *context_file); char *set_selabel(const char *path, unsigned int mode, struct selabel_handle *sehnd); +struct vfs_cap_data set_caps(uint64_t capabilities); #endif diff --git a/squashfs-tools/mksquashfs.c b/squashfs-tools/mksquashfs.c index c330e99..6c81710 100644 --- a/squashfs-tools/mksquashfs.c +++ b/squashfs-tools/mksquashfs.c @@ -3036,6 +3036,11 @@ inline struct dir_ent *create_dir_entry(char *name, char *source_name, dir_ent->our_dir = dir; dir_ent->inode = NULL; dir_ent->next = NULL; +/* ANDROID CHANGES START*/ +#ifdef ANDROID + dir_ent->capabilities = 0; +#endif +/* ANDROID CHANGES END */ return dir_ent; } @@ -3060,10 +3065,10 @@ inline void add_dir_entry(struct dir_ent *dir_ent, struct dir_info *sub_dir, rel_path = mounted_path; while (rel_path && *rel_path == '/') rel_path++; - android_fs_config(rel_path, &inode_info->buf, target_out_path); + android_fs_config(rel_path, &inode_info->buf, target_out_path, &dir_ent->capabilities); free(mounted_path); } else { - android_fs_config(pathname(dir_ent), &inode_info->buf, target_out_path); + android_fs_config(pathname(dir_ent), &inode_info->buf, target_out_path, &dir_ent->capabilities); } } #endif @@ -3132,6 +3137,11 @@ void dir_scan(squashfs_inode *inode, char *pathname, { struct stat buf; struct dir_ent *dir_ent; +/* ANDROID CHANGES START*/ +#ifdef ANDROID + uint64_t caps = 0; +#endif +/* ANDROID CHANGES END */ root_dir = dir_scan1(pathname, "", paths, _readdir, 1); if(root_dir == NULL) @@ -3162,16 +3172,23 @@ void dir_scan(squashfs_inode *inode, char *pathname, pathname, strerror(errno)); /* ANDROID CHANGES START*/ #ifdef ANDROID - if (android_config) + if (android_config) { if (mount_point) - android_fs_config(mount_point, &buf, target_out_path); + android_fs_config(mount_point, &buf, target_out_path, &caps); else - android_fs_config(pathname, &buf, target_out_path); + android_fs_config(pathname, &buf, target_out_path, &caps); + } #endif /* ANDROID CHANGES END */ dir_ent->inode = lookup_inode(&buf); } +/* ANDROID CHANGES START*/ +#ifdef ANDROID + dir_ent->capabilities = caps; +#endif +/* ANDROID CHANGES END */ + dir_ent->dir = root_dir; root_dir->dir_ent = dir_ent; diff --git a/squashfs-tools/mksquashfs.h b/squashfs-tools/mksquashfs.h index 55708a3..0a091cb 100644 --- a/squashfs-tools/mksquashfs.h +++ b/squashfs-tools/mksquashfs.h @@ -24,6 +24,11 @@ * mksquashfs.h * */ +/* ANDROID CHANGES START*/ +#ifdef ANDROID +#include <stdint.h> +#endif +/* ANDROID CHANGES END */ struct dir_info { char *pathname; @@ -46,6 +51,11 @@ struct dir_ent { struct dir_info *dir; struct dir_info *our_dir; struct dir_ent *next; +/* ANDROID CHANGES START*/ +#ifdef ANDROID + uint64_t capabilities; +#endif +/* ANDROID CHANGES END */ }; struct inode_info { diff --git a/squashfs-tools/xattr.c b/squashfs-tools/xattr.c index a405234..fa24fae 100644 --- a/squashfs-tools/xattr.c +++ b/squashfs-tools/xattr.c @@ -46,6 +46,7 @@ /* ANDROID CHANGES START*/ #ifdef ANDROID #include "android.h" +#include "private/android_filesystem_capability.h" static struct selabel_handle *sehnd = NULL; #endif /* ANDROID CHANGES END */ @@ -129,20 +130,35 @@ static int get_prefix(struct xattr_list *xattr, char *name) /* ANDROID CHANGES START*/ #ifdef ANDROID -static int read_xattrs_from_context_file(char *filename, int mode, - struct selabel_handle *sehnd, struct xattr_list **xattrs) +static struct xattr_list *next_xattr_list(int *xattr_count, struct xattr_list **xattrs) { + struct xattr_list *x; + x = realloc(*xattrs, ++*xattr_count * sizeof(struct xattr_list)); + if (x == NULL) MEM_ERROR(); + *xattrs = x; + return &x[*xattr_count - 1]; +} + +static void read_selinux_xattr_from_sehnd(char *filename, int mode, + struct selabel_handle *sehnd, struct xattr_list *xattrs) { char *attr_val; - struct xattr_list *x = malloc(sizeof(*x)); - if(x == NULL) - MEM_ERROR(); - x->type = get_prefix(x, "security.selinux"); + xattrs->type = get_prefix(xattrs, "security.selinux"); attr_val = set_selabel(filename, mode, sehnd); - x->value = (void *)attr_val; - x->vsize = strlen(attr_val); - *xattrs = x; - return 1; + xattrs->value = (void *)attr_val; + xattrs->vsize = strlen(attr_val); +} + +static void set_caps_xattr(uint64_t caps, struct xattr_list *xattrs) +{ + struct vfs_cap_data *attr_val; + attr_val = malloc(sizeof(*attr_val)); + if (attr_val == NULL) MEM_ERROR(); + + xattrs->type = get_prefix(xattrs, "security.capability"); + *attr_val = set_caps(caps); + xattrs->value = attr_val; + xattrs->vsize = sizeof(*attr_val); } #endif /* ANDROID CHANGES END */ @@ -645,8 +661,16 @@ int read_xattrs(void *d) struct dir_ent *dir_ent = d; struct inode_info *inode = dir_ent->inode; char *filename = pathname(dir_ent); +/* ANDROID CHANGES START*/ +#ifdef ANDROID + // NOTE: xattr_list has to point to an array of xattr_list elements + struct xattr_list *xattr_list = NULL, *next_xattr = NULL; + int xattrs = 0; +#else struct xattr_list *xattr_list; int xattrs; +#endif +/* ANDROID CHANGES END */ if(no_xattrs || IS_PSEUDO(inode) || inode->root_entry) return SQUASHFS_INVALID_XATTR; @@ -659,15 +683,19 @@ int read_xattrs(void *d) if (mount_point) { char *mounted_path; alloc_mounted_path(mount_point, subpathname(dir_ent), &mounted_path); - xattrs = read_xattrs_from_context_file(mounted_path, inode->buf.st_mode, - sehnd, &xattr_list); + next_xattr = next_xattr_list(&xattrs, &xattr_list); + read_selinux_xattr_from_sehnd(mounted_path, inode->buf.st_mode, + sehnd, next_xattr); free(mounted_path); } else { - xattrs = read_xattrs_from_context_file(filename, inode->buf.st_mode, - sehnd, &xattr_list); + next_xattr = next_xattr_list(&xattrs, &xattr_list); + read_selinux_xattr_from_sehnd(filename, inode->buf.st_mode, + sehnd, next_xattr); } - } else { - xattrs = read_xattrs_from_system(filename, &xattr_list); + } + if (dir_ent->capabilities != 0) { + next_xattr = next_xattr_list(&xattrs, &xattr_list); + set_caps_xattr(dir_ent->capabilities, next_xattr); } #else xattrs = read_xattrs_from_system(filename, &xattr_list); |