aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohamad Ayyash <mkayyash@google.com>2016-03-09 16:10:54 -0800
committerChristian Bejram <cbejram@google.com>2016-03-30 21:28:19 -0700
commiteecf5b9117cc5410639081f56cc232898fd15b35 (patch)
treecb3eac411a7ef04824099269058071b05039c896
parent3c27aa234b312b4bf777a5a3f4086e465f04e48b (diff)
downloadsquashfs-tools-marshmallow-dr-lego-release.tar.gz
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.c22
-rw-r--r--squashfs-tools/android.h5
-rw-r--r--squashfs-tools/mksquashfs.c27
-rw-r--r--squashfs-tools/mksquashfs.h10
-rw-r--r--squashfs-tools/xattr.c60
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);