Skip to content
This repository has been archived by the owner on Aug 3, 2022. It is now read-only.

Commit

Permalink
Merge "Extend mkyaffs2image to support setting SELinux security conte…
Browse files Browse the repository at this point in the history
…xts in yaffs2 images."
  • Loading branch information
kruton authored and android code review committed Apr 6, 2012
2 parents 6232e2d + 84f79e8 commit 64a7dfb
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 15 deletions.
6 changes: 6 additions & 0 deletions Android.mk
Expand Up @@ -17,6 +17,12 @@ LOCAL_C_INCLUDES += $(LOCAL_PATH)/yaffs2

LOCAL_MODULE := mkyaffs2image

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)

$(call dist-for-goals, dist_files, $(LOCAL_BUILT_MODULE))
123 changes: 108 additions & 15 deletions yaffs2/utils/mkyaffs2image.c
Expand Up @@ -32,6 +32,16 @@
#include <string.h>
#include <unistd.h>

#ifdef HAVE_SELINUX
#define XATTR_NAME_SELINUX "security.selinux"
#include <selinux/selinux.h>
#include <selinux/label.h>

static struct selabel_handle *sehnd;
static unsigned int seprefixlen;
static char *mntpoint;
#endif

#include <private/android_filesystem_config.h>

#include "yaffs_ecc.h"
Expand Down Expand Up @@ -247,12 +257,23 @@ static int write_chunk(__u8 *data, __u32 objId, __u32 chunkId, __u32 nBytes)

}

static int write_object_header(int objId, yaffs_ObjectType t, struct stat *s, int parent, const char *name, int equivalentObj, const char * alias)
static int write_object_header(int objId, yaffs_ObjectType t, struct stat *s, int parent, const char *name, int equivalentObj, const char * alias, const char *secontext)
{
__u8 bytes[chunkSize];


yaffs_ObjectHeader *oh = (yaffs_ObjectHeader *)bytes;
#ifdef HAVE_SELINUX
char *xb = (char *)bytes + sizeof(*oh);
int xnamelen = strlen(XATTR_NAME_SELINUX) + 1;
int xvalsize = 0;
int xreclen = 0;

if (secontext) {
xvalsize = strlen(secontext) + 1;
xreclen = sizeof(int) + xnamelen + xvalsize;
}
#endif

memset(bytes,0xff,sizeof(bytes));

Expand All @@ -261,7 +282,16 @@ static int write_object_header(int objId, yaffs_ObjectType t, struct stat *s, in
oh->parentObjectId = parent;

strncpy(oh->name,name,YAFFS_MAX_NAME_LENGTH);


#ifdef HAVE_SELINUX
if (xreclen) {
memcpy(xb, &xreclen, sizeof(int));
xb += sizeof(int);
strcpy(xb, XATTR_NAME_SELINUX);
xb += xnamelen;
memcpy(xb, secontext, xvalsize);
}
#endif

if(t != YAFFS_OBJECT_TYPE_HARDLINK)
{
Expand Down Expand Up @@ -310,6 +340,7 @@ static int process_directory(int parent, const char *path, int fixstats)

DIR *dir;
struct dirent *entry;
char *secontext = NULL;

nDirectories++;

Expand All @@ -325,14 +356,41 @@ static int process_directory(int parent, const char *path, int fixstats)
strcmp(entry->d_name,".."))
{
char full_name[500];
#ifdef HAVE_SELINUX
char *suffix, dest_name[500];
int ret;
#endif
struct stat stats;
int equivalentObj;
int newObj;

sprintf(full_name,"%s/%s",path,entry->d_name);

lstat(full_name,&stats);


#ifdef HAVE_SELINUX
if (sehnd) {
suffix = full_name + seprefixlen;
ret = snprintf(dest_name,
sizeof dest_name,
"%s%s", mntpoint,
suffix);
if (ret < 0 ||
(size_t) ret >= sizeof dest_name) {
fprintf(stderr,
"snprintf failed on %s%s\n",
mntpoint, suffix);
exit(1);
}
if (selabel_lookup(sehnd, &secontext,
dest_name,
stats.st_mode) < 0) {
perror("selabel_lookup");
exit(1);
}
}
#endif

if(S_ISLNK(stats.st_mode) ||
S_ISREG(stats.st_mode) ||
S_ISDIR(stats.st_mode) ||
Expand All @@ -356,7 +414,7 @@ static int process_directory(int parent, const char *path, int fixstats)
{
/* we need to make a hard link */
//printf("hard link to object %d\n",equivalentObj);
error = write_object_header(newObj, YAFFS_OBJECT_TYPE_HARDLINK, &stats, parent, entry->d_name, equivalentObj, NULL);
error = write_object_header(newObj, YAFFS_OBJECT_TYPE_HARDLINK, &stats, parent, entry->d_name, equivalentObj, NULL, secontext);
}
else
{
Expand All @@ -373,13 +431,13 @@ static int process_directory(int parent, const char *path, int fixstats)
readlink(full_name,symname,sizeof(symname) -1);

//printf("symlink to \"%s\"\n",symname);
error = write_object_header(newObj, YAFFS_OBJECT_TYPE_SYMLINK, &stats, parent, entry->d_name, -1, symname);
error = write_object_header(newObj, YAFFS_OBJECT_TYPE_SYMLINK, &stats, parent, entry->d_name, -1, symname, secontext);

}
else if(S_ISREG(stats.st_mode))
{
//printf("file, ");
error = write_object_header(newObj, YAFFS_OBJECT_TYPE_FILE, &stats, parent, entry->d_name, -1, NULL);
error = write_object_header(newObj, YAFFS_OBJECT_TYPE_FILE, &stats, parent, entry->d_name, -1, NULL, secontext);

if(error >= 0)
{
Expand Down Expand Up @@ -415,27 +473,27 @@ static int process_directory(int parent, const char *path, int fixstats)
else if(S_ISSOCK(stats.st_mode))
{
//printf("socket\n");
error = write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL);
error = write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL, secontext);
}
else if(S_ISFIFO(stats.st_mode))
{
//printf("fifo\n");
error = write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL);
error = write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL, secontext);
}
else if(S_ISCHR(stats.st_mode))
{
//printf("character device\n");
error = write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL);
error = write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL, secontext);
}
else if(S_ISBLK(stats.st_mode))
{
//printf("block device\n");
error = write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL);
error = write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL, secontext);
}
else if(S_ISDIR(stats.st_mode))
{
//printf("directory\n");
error = write_object_header(newObj, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, parent, entry->d_name, -1, NULL);
error = write_object_header(newObj, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, parent, entry->d_name, -1, NULL, secontext);
// NCB modified 10/9/2001 process_directory(1,full_name);
process_directory(newObj,full_name,fixstats);
}
Expand All @@ -447,7 +505,6 @@ static int process_directory(int parent, const char *path, int fixstats)
}
}
}

closedir(dir);
}

Expand All @@ -458,12 +515,14 @@ static int process_directory(int parent, const char *path, int fixstats)
static void usage(void)
{
fprintf(stderr,"mkyaffs2image: image building tool for YAFFS2 built "__DATE__"\n");
fprintf(stderr,"usage: mkyaffs2image [-f] [-c <size>] [-s <size>] dir image_file [convert]\n");
fprintf(stderr,"usage: mkyaffs2image [-f] [-c <size>] [-s <size>] dir image_file [file_contexts mountpoint] [convert]\n");
fprintf(stderr," -f fix file stat (mods, user, group) for device\n");
fprintf(stderr," -c <size> set the chunk (NAND page) size. default: 2048\n");
fprintf(stderr," -s <size> set the spare (NAND OOB) size. default: 64\n");
fprintf(stderr," dir the directory tree to be converted\n");
fprintf(stderr," image_file the output file to hold the image\n");
fprintf(stderr," file_contexts the file contexts configuration used to assign SELinux file context attributes\n");
fprintf(stderr," mountpoint the directory where this image be mounted on the device\n");
fprintf(stderr," 'convert' produce a big-endian image from a little-endian machine\n");
}

Expand All @@ -474,6 +533,7 @@ int main(int argc, char *argv[])
int opt;
char *image;
char *dir;
char *secontext = NULL;

while ((opt = getopt(argc, argv, "fc:s:")) != -1) {
switch (opt) {
Expand All @@ -497,20 +557,44 @@ int main(int argc, char *argv[])
exit(1);
}

if ((argc - optind < 2) || (argc - optind > 3)) {
if ((argc - optind < 2) || (argc - optind > 4)) {
usage();
exit(1);
}

dir = argv[optind];
#ifdef HAVE_SELINUX
seprefixlen = strlen(dir);
#endif
image = argv[optind + 1];

if (optind + 2 < argc) {
if (!strncmp(argv[optind + 2], "convert", strlen("convert")))
convert_endian = 1;
else {
#ifdef HAVE_SELINUX
struct selinux_opt seopts[] = {
{ SELABEL_OPT_PATH, argv[optind + 2] }
};
sehnd = selabel_open(SELABEL_CTX_FILE, seopts, 1);
if (!sehnd) {
perror(argv[optind + 2]);
usage();
exit(1);
}
if (optind + 3 >= argc) {
usage();
exit(1);
}
mntpoint = argv[optind + 3];
if (optind + 4 < argc) {
if (!strncmp(argv[optind + 4], "convert", strlen("convert")))
convert_endian = 1;
}
#else
usage();
exit(1);
#endif
}
}

Expand Down Expand Up @@ -550,7 +634,16 @@ int main(int argc, char *argv[])
}

//printf("Processing directory %s into image file %s\n",dir,image);
error = write_object_header(1, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, 1,"", -1, NULL);
#ifdef HAVE_SELINUX
if (sehnd) {
if (selabel_lookup(sehnd, &secontext, mntpoint, stats.st_mode) < 0) {
perror("selabel_lookup");
exit(1);
}
}
#endif

error = write_object_header(1, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, 1,"", -1, NULL, secontext);
if(error)
error = process_directory(YAFFS_OBJECTID_ROOT,dir,fixstats);

Expand Down

0 comments on commit 64a7dfb

Please sign in to comment.