All of lore.kernel.org
 help / color / mirror / Atom feed
* [meta-selinux][RFC 00/10] Label file system in build.
@ 2015-06-07  0:36 Philip Tricca
  2015-06-07  0:36 ` [meta-selinux][RFC 01/10] policycoreutils: Add FTS_NOCHDIR flag to fts_open Philip Tricca
                   ` (9 more replies)
  0 siblings, 10 replies; 12+ messages in thread
From: Philip Tricca @ 2015-06-07  0:36 UTC (permalink / raw)
  To: yocto

This is a request for comment (RFC) on some patches to enable labing the
root file system of an SELinux image. Having to relabel a system as part
of the "first boot" has been a significant limitation so hopefully the
maintainers will agree at least that the functionality is needed /
useful.

Currently these patches will copy any xattrs in the 'security' namespace
which covers my use case: SELinux and eventually IMA as part of some work
in a different layer (meta-measured). Additional xattrs can likely be
supported without much trouble but I haven't tested anything beyond
SELinux. Eventually I imagine this should go upstream into
openembedded-core but since SELinux is the use case I'm submitting the
patch against meta-selinux first for feedback and testing.

Approach:
These patches ride on an existing patch set in openembedded-core that
add the '-d' option to mke2fs to copy files into the newly created file
system. I've added another function called as part of the recursive
traversal to copy xattrs for each file system object processed.

The algorithm for creating an xattr block is straight forward. We query
the existing xattrs on a file using 'lgetfattr' and then process them one
at a time getting their values (lgetxattr) and building a disk block in
the required format. Creating the xattr disk block is a bit of a pain but
it's mostly a mechanical process of copying data from source to
destination in the proper format. The block is then associated with right
inode by way of the i_file_acl member of the ext2_inode structure and
written to disk.

Caching:
The ext* file systems allow for xattrs to be shared between inodes when
their contents are identical as a way to save space. SELinux benefits
from this greatly as many files have the same label. My implementation of
a cache to enable xattr block sharing is grossly inefficient but
functional.

I'm currently looking for examples of similar caching techniques (likely
from the SELinux tools) to better inform this implementation. I expect to
change the caching implementation but in the meantime I thought I'd get
an RFC out to get early feedback / testing.

Thanks,
Philip
--

Philip Tricca (10):
  policycoreutils: Add FTS_NOCHDIR flag to fts_open.
  selinux-image: Add new image class to label the rootfs.
  e2fsprogs: Add bbappend and apply initial xattr patch.
  e2fsprogs: Add patch to build xattr code.
  e2fsprogs: Add patch make calls necessary to label file system root
    and do cleanup.
  e2fsprogs: Add patch to call xattr copy function in populate_fs.
  e2fsprogs: Add xattr security prefix data to
    lib/ext2fs/ext2_ext_attr.h
  e2fsprogs: Add patch to copy xattr block from source file.
  e2fsprogs: Add patch to hold xattr header and block number in a
    structure for the cache.
  e2fsprogs: Add patch to implement simple linked list as cache for
    existing xattr blocks.

 classes/selinux-image.bbclass                      |   8 +
 .../e2fsprogs/Makefile.in-build-xattr.o.patch      |  96 ++++++
 ...ib-ext2fs-ext2_ext_attr.h-add-xattr-index.patch |  20 ++
 .../misc-create_inode.c-label-fs-objects.patch     |  30 ++
 .../misc-mke2fs.c-label-root-dir-and-cleanup.patch |  40 +++
 .../e2fsprogs/misc-xattr-copy-xattrs.patch         |  69 ++++
 .../misc-xattr-create-xattr-block-node.patch       | 126 ++++++++
 .../e2fsprogs/misc-xattr-create-xattr-block.patch  | 351 +++++++++++++++++++++
 .../e2fsprogs/misc-xattr-create-xattr-cache.patch  | 217 +++++++++++++
 .../e2fsprogs/e2fsprogs_1.42.9.bbappend            |  12 +
 .../images/core-image-selinux-minimal.bb           |   2 +-
 recipes-security/images/core-image-selinux.bb      |   2 +-
 .../policycoreutils-setfiles-path.patch            |  27 ++
 recipes-security/selinux/policycoreutils_2.3.bb    |   1 +
 14 files changed, 999 insertions(+), 2 deletions(-)
 create mode 100644 classes/selinux-image.bbclass
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/Makefile.in-build-xattr.o.patch
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/lib-ext2fs-ext2_ext_attr.h-add-xattr-index.patch
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/misc-create_inode.c-label-fs-objects.patch
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/misc-mke2fs.c-label-root-dir-and-cleanup.patch
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-copy-xattrs.patch
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block-node.patch
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block.patch
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-cache.patch
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
 create mode 100644 recipes-security/selinux/policycoreutils/policycoreutils-setfiles-path.patch

-- 
2.1.4



^ permalink raw reply	[flat|nested] 12+ messages in thread

* [meta-selinux][RFC 01/10] policycoreutils: Add FTS_NOCHDIR flag to fts_open.
  2015-06-07  0:36 [meta-selinux][RFC 00/10] Label file system in build Philip Tricca
@ 2015-06-07  0:36 ` Philip Tricca
  2015-06-07  0:37 ` [meta-selinux][RFC 02/10] selinux-image: Add new image class to label the rootfs Philip Tricca
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Philip Tricca @ 2015-06-07  0:36 UTC (permalink / raw)
  To: yocto

This works around a bug in the libc currently in use. FTS functions are
supposed to change the current working directory as they walk the file
hierarchy. The fts_accpath member of the FTSENT structure relies on this
behavior and without it the path is not relative to cwd as expected.
Supplying the FTS_NOCHDIR disables this optimization and causes
fts_accpath to be relative to the directory where the traversal started.

An alternative fix could replace the use of fts_accpath with fts_path
which is absolute.

Signed-off-by: Philip Tricca <flihp@twobit.us>
---
 .../policycoreutils-setfiles-path.patch            | 27 ++++++++++++++++++++++
 recipes-security/selinux/policycoreutils_2.3.bb    |  1 +
 2 files changed, 28 insertions(+)
 create mode 100644 recipes-security/selinux/policycoreutils/policycoreutils-setfiles-path.patch

diff --git a/recipes-security/selinux/policycoreutils/policycoreutils-setfiles-path.patch b/recipes-security/selinux/policycoreutils/policycoreutils-setfiles-path.patch
new file mode 100644
index 0000000..c87af98
--- /dev/null
+++ b/recipes-security/selinux/policycoreutils/policycoreutils-setfiles-path.patch
@@ -0,0 +1,27 @@
+Subject: Replace fts_accpath with fts_path in restore.c.
+Author: Philip Tricca <flihp@twobit.us>
+
+To label filesystems in an alternative root directory we need to use the
+'-r' flag with the setfiles utility. The current implementation uses the
+fts_accpath member of the FTSENT structure which is reletive to the "current
+directory". This fails in the pseudo environment but for a reason I don't
+fully understand.
+
+This patch replaces the use of fts_accpath with fts_path which is relative
+to the root specified in the traversal. By invoking setfiles with an absolute
+path we're ensured that fts_path will be an absolute path to the file being
+relabeled.
+
+Index: policycoreutils/setfiles/setfiles.c
+===================================================================
+--- policycoreutils.orig/setfiles/setfiles.c
++++ policycoreutils/setfiles/setfiles.c
+@@ -194,7 +194,7 @@ int main(int argc, char **argv)
+ 		r_opts.expand_realpath = 0;
+ 		r_opts.abort_on_error = 1;
+ 		r_opts.add_assoc = 1;
+-		r_opts.fts_flags = FTS_PHYSICAL | FTS_XDEV;
++		r_opts.fts_flags = FTS_PHYSICAL | FTS_XDEV | FTS_NOCHDIR;
+ 		ctx_validate = 1;
+ 	} else {
+ 		/*
diff --git a/recipes-security/selinux/policycoreutils_2.3.bb b/recipes-security/selinux/policycoreutils_2.3.bb
index 447e6c9..2dee62e 100644
--- a/recipes-security/selinux/policycoreutils_2.3.bb
+++ b/recipes-security/selinux/policycoreutils_2.3.bb
@@ -13,4 +13,5 @@ SRC_URI += "\
 	file://policycoreutils-semanage-edit-user.patch \
 	file://policycoreutils-process-ValueError-for-sepolicy-seobject.patch \
 	file://policycoreutils-fix-TypeError-for-seobject.py.patch \
+	file://policycoreutils-setfiles-path.patch \
 	"
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [meta-selinux][RFC 02/10] selinux-image: Add new image class to label the rootfs.
  2015-06-07  0:36 [meta-selinux][RFC 00/10] Label file system in build Philip Tricca
  2015-06-07  0:36 ` [meta-selinux][RFC 01/10] policycoreutils: Add FTS_NOCHDIR flag to fts_open Philip Tricca
@ 2015-06-07  0:37 ` Philip Tricca
  2015-06-07  0:37 ` [meta-selinux][RFC 03/10] e2fsprogs: Add bbappend and apply initial xattr patch Philip Tricca
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Philip Tricca @ 2015-06-07  0:37 UTC (permalink / raw)
  To: yocto

Signed-off-by: Philip Tricca <flihp@twobit.us>
---
 classes/selinux-image.bbclass                         | 8 ++++++++
 recipes-security/images/core-image-selinux-minimal.bb | 2 +-
 recipes-security/images/core-image-selinux.bb         | 2 +-
 3 files changed, 10 insertions(+), 2 deletions(-)
 create mode 100644 classes/selinux-image.bbclass

diff --git a/classes/selinux-image.bbclass b/classes/selinux-image.bbclass
new file mode 100644
index 0000000..362ca5c
--- /dev/null
+++ b/classes/selinux-image.bbclass
@@ -0,0 +1,8 @@
+selinux_set_labels () {
+    POL_TYPE=$(sed -n -e "s&SELINUXTYPE[:space:]*=[:space:]*\([0-9A-Za-z_]\+\)&\1&p" ${IMAGE_ROOTFS}/${sysconfdir}/selinux/config)
+    setfiles -r ${IMAGE_ROOTFS} ${IMAGE_ROOTFS}/${sysconfdir}/selinux/${POL_TYPE}/contexts/files/file_contexts ${IMAGE_ROOTFS} || exit 1;
+}
+
+IMAGE_PREPROCESS_COMMAND += "selinux_set_labels ;"
+
+inherit core-image
diff --git a/recipes-security/images/core-image-selinux-minimal.bb b/recipes-security/images/core-image-selinux-minimal.bb
index 45cd847..45bb099 100644
--- a/recipes-security/images/core-image-selinux-minimal.bb
+++ b/recipes-security/images/core-image-selinux-minimal.bb
@@ -12,4 +12,4 @@ IMAGE_INSTALL = "\
 	packagegroup-selinux-minimal \
 "
 
-inherit core-image
+inherit selinux-image
diff --git a/recipes-security/images/core-image-selinux.bb b/recipes-security/images/core-image-selinux.bb
index e186bdc..70b525e 100644
--- a/recipes-security/images/core-image-selinux.bb
+++ b/recipes-security/images/core-image-selinux.bb
@@ -11,4 +11,4 @@ IMAGE_INSTALL = "\
 	packagegroup-core-selinux \
 "   
 
-inherit core-image
+inherit selinux-image
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [meta-selinux][RFC 03/10] e2fsprogs: Add bbappend and apply initial xattr patch.
  2015-06-07  0:36 [meta-selinux][RFC 00/10] Label file system in build Philip Tricca
  2015-06-07  0:36 ` [meta-selinux][RFC 01/10] policycoreutils: Add FTS_NOCHDIR flag to fts_open Philip Tricca
  2015-06-07  0:37 ` [meta-selinux][RFC 02/10] selinux-image: Add new image class to label the rootfs Philip Tricca
@ 2015-06-07  0:37 ` Philip Tricca
  2015-06-07  0:37 ` [meta-selinux][RFC 04/10] e2fsprogs: Add patch to build xattr code Philip Tricca
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Philip Tricca @ 2015-06-07  0:37 UTC (permalink / raw)
  To: yocto

Signed-off-by: Philip Tricca <flihp@twobit.us>
---
 .../e2fsprogs/misc-xattr-copy-xattrs.patch         | 69 ++++++++++++++++++++++
 .../e2fsprogs/e2fsprogs_1.42.9.bbappend            |  5 ++
 2 files changed, 74 insertions(+)
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-copy-xattrs.patch
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend

diff --git a/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-copy-xattrs.patch b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-copy-xattrs.patch
new file mode 100644
index 0000000..7423c4e
--- /dev/null
+++ b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-copy-xattrs.patch
@@ -0,0 +1,69 @@
+Copy xattr blocks as part of the '-d' option to mke2fs. Initial implementation
+only supports xattrs with the 'security.' prefix. Copying xattrs is necessary
+to boot SELinux images without setting labels on firstboot.
+
+To build the xattr disk block we process the output from listxattr and
+lgetxattr from the source file system object. It's then associated with the
+inode and written to disk. ext2|3|4 saves space by allowing inodes to share
+identical xattr blocks. We maintain a primitive cache (a linked list) of the
+existing xattr blocks and only create new ones when when we must.
+
+Currently this cache keeps the full xattr block around on the heap so it's
+pretty inefficient. Still, the memory overhead is only on the order of single
+digit megabytes for core-image-selinux.
+
+TODO:
+  - Test additional xattrs with the 'security.' prefix like IMA.
+
+Signed-off-by: Philip Tricca <flihp@twobit.us>
+
+Index: e2fsprogs-1.42.9/misc/xattr.c
+===================================================================
+--- /dev/null
++++ e2fsprogs-1.42.9/misc/xattr.c
+@@ -0,0 +1,34 @@
++#include "xattr.h"
++
++#include <stdio.h>
++
++#ifdef XATTR_DEBUG
++#define XATTR_STDERR(fmt, args...) fprintf (stderr, fmt, ##args)
++#else
++#define XATTR_STDERR(fmt, args...) do {} while (0)
++#endif
++
++
++/* Free remaining resources after all files have been processed. */
++void
++xattr_cleanup ()
++{
++	XATTR_STDERR ("Cleaning up resources from xattrs.\n");
++}
++
++/* This is the entry point to the xattr module. This function copies the xattrs
++ * from the file at 'path' to the file system object at 'ino'.
++ *
++ * Parameters:
++ *   fs:  the file system object for the fs we're operating on
++ *   ino: inode for the object we're labeling
++ *   path: path to the object we're copying xattrs from
++ */
++errcode_t
++set_inode_xattr (ext2_filsys fs, ext2_ino_t ino, const char *path)
++{
++	errcode_t ret = 0;
++
++	XATTR_STDERR ("Copying xattrs from %s to inode 0x%x.\n", path, ino);
++	return ret;
++}
+Index: e2fsprogs-1.42.9/misc/xattr.h
+===================================================================
+--- /dev/null
++++ e2fsprogs-1.42.9/misc/xattr.h
+@@ -0,0 +1,6 @@
++#include "et/com_err.h"
++#include "ext2fs/ext2fs.h"
++
++/* Copy xattrs from source file to destination inode */
++errcode_t set_inode_xattrs(ext2_filsys fs, ext2_ino_t ino, const char *name);
++void xattr_cleanup ();
diff --git a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
new file mode 100644
index 0000000..7f0198e
--- /dev/null
+++ b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
@@ -0,0 +1,5 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI += " \
+    file://misc-xattr-copy-xattrs.patch \
+"
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [meta-selinux][RFC 04/10] e2fsprogs: Add patch to build xattr code.
  2015-06-07  0:36 [meta-selinux][RFC 00/10] Label file system in build Philip Tricca
                   ` (2 preceding siblings ...)
  2015-06-07  0:37 ` [meta-selinux][RFC 03/10] e2fsprogs: Add bbappend and apply initial xattr patch Philip Tricca
@ 2015-06-07  0:37 ` Philip Tricca
  2015-06-07  0:37 ` [meta-selinux][RFC 05/10] e2fsprogs: Add patch make calls necessary to label file system root and do cleanup Philip Tricca
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Philip Tricca @ 2015-06-07  0:37 UTC (permalink / raw)
  To: yocto

Signed-off-by: Philip Tricca <flihp@twobit.us>
---
 .../e2fsprogs/Makefile.in-build-xattr.o.patch      | 96 ++++++++++++++++++++++
 .../e2fsprogs/e2fsprogs_1.42.9.bbappend            |  1 +
 2 files changed, 97 insertions(+)
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/Makefile.in-build-xattr.o.patch

diff --git a/recipes-devtools/e2fsprogs/e2fsprogs/Makefile.in-build-xattr.o.patch b/recipes-devtools/e2fsprogs/e2fsprogs/Makefile.in-build-xattr.o.patch
new file mode 100644
index 0000000..ae976ea
--- /dev/null
+++ b/recipes-devtools/e2fsprogs/e2fsprogs/Makefile.in-build-xattr.o.patch
@@ -0,0 +1,96 @@
+Add rules to Makefile.in in both misc/ and debugfs/ to build xattr.o.
+
+Signed-off-by: Philip Tricca <flihp@twobit.us>
+
+Index: e2fsprogs-1.42.9/misc/Makefile.in
+===================================================================
+--- e2fsprogs-1.42.9.orig/misc/Makefile.in
++++ e2fsprogs-1.42.9/misc/Makefile.in
+@@ -43,7 +43,7 @@ LPROGS=		@E2INITRD_PROG@
+ TUNE2FS_OBJS=	tune2fs.o util.o
+ MKLPF_OBJS=	mklost+found.o
+ MKE2FS_OBJS=	mke2fs.o util.o profile.o prof_err.o default_profile.o \
+-			create_inode.o
++			create_inode.o xattr.o
+ CHATTR_OBJS=	chattr.o
+ LSATTR_OBJS=	lsattr.o
+ UUIDGEN_OBJS=	uuidgen.o
+@@ -62,7 +62,7 @@ PROFILED_TUNE2FS_OBJS=	profiled/tune2fs.
+ PROFILED_MKLPF_OBJS=	profiled/mklost+found.o
+ PROFILED_MKE2FS_OBJS=	profiled/mke2fs.o profiled/util.o profiled/profile.o \
+ 			profiled/prof_err.o profiled/default_profile.o \
+-			profiled/create_inode.o
++			profiled/create_inode.o profiled/xattr.o
+ PROFILED_CHATTR_OBJS=	profiled/chattr.o
+ PROFILED_LSATTR_OBJS=	profiled/lsattr.o
+ PROFILED_UUIDGEN_OBJS=	profiled/uuidgen.o
+@@ -84,7 +84,8 @@ SRCS=	$(srcdir)/tune2fs.c $(srcdir)/mklo
+ 		$(srcdir)/uuidgen.c $(srcdir)/blkid.c $(srcdir)/logsave.c \
+ 		$(srcdir)/filefrag.c $(srcdir)/base_device.c \
+ 		$(srcdir)/ismounted.c $(srcdir)/../e2fsck/profile.c \
+-		$(srcdir)/e2undo.c $(srcdir)/e2freefrag.c $(srcdir)/create_inode.c
++		$(srcdir)/e2undo.c $(srcdir)/e2freefrag.c $(srcdir)/create_inode.c \
++		$(srcdir)/xattr.c
+ 
+ LIBS= $(LIBEXT2FS) $(LIBCOM_ERR) 
+ DEPLIBS= $(LIBEXT2FS) $(DEPLIBCOM_ERR)
+@@ -634,7 +635,8 @@ mke2fs.o: $(srcdir)/mke2fs.c $(top_build
+  $(srcdir)/util.h profile.h prof_err.h $(top_srcdir)/version.h \
+  $(srcdir)/nls-enable.h $(top_srcdir)/lib/quota/mkquota.h $(srcdir)/create_inode.h\
+  $(top_srcdir)/lib/quota/quotaio.h $(top_srcdir)/lib/quota/dqblk_v2.h \
+- $(top_srcdir)/lib/quota/quotaio_tree.h $(top_srcdir)/lib/../e2fsck/dict.h
++ $(top_srcdir)/lib/quota/quotaio_tree.h $(top_srcdir)/lib/../e2fsck/dict.h \
++ $(srcdir)/xattr.h
+ chattr.o: $(srcdir)/chattr.c $(top_builddir)/lib/config.h \
+  $(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
+  $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/et/com_err.h \
+@@ -716,3 +718,5 @@ create_inode.o: $(srcdir)/create_inode.h
+  $(top_builddir)/lib/config.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
+  $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/e2p/e2p.h \
+  $(srcdir)/nls-enable.h
++xattr.o: $(srcdir)/xattr.h $(srcdir)/xattr.c \
++ $(top_builddir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2fs.h
+Index: e2fsprogs-1.42.9/debugfs/Makefile.in
+===================================================================
+--- e2fsprogs-1.42.9.orig/debugfs/Makefile.in
++++ e2fsprogs-1.42.9/debugfs/Makefile.in
+@@ -18,7 +18,7 @@ MK_CMDS=	_SS_DIR_OVERRIDE=../lib/ss ../l
+ 
+ DEBUG_OBJS= debug_cmds.o debugfs.o util.o ncheck.o icheck.o ls.o \
+ 	lsdel.o dump.o set_fields.o logdump.o htree.o unused.o e2freefrag.o \
+-	filefrag.o extent_cmds.o extent_inode.o zap.o create_inode.o
++	filefrag.o extent_cmds.o extent_inode.o zap.o create_inode.o xattr.o
+ 
+ RO_DEBUG_OBJS= ro_debug_cmds.o ro_debugfs.o util.o ncheck.o icheck.o ls.o \
+ 	lsdel.o logdump.o htree.o e2freefrag.o filefrag.o extent_cmds.o \
+@@ -29,12 +29,16 @@ SRCS= debug_cmds.c $(srcdir)/debugfs.c $
+ 	$(srcdir)/dump.c $(srcdir)/set_fields.c ${srcdir}/logdump.c \
+ 	$(srcdir)/htree.c $(srcdir)/unused.c ${srcdir}/../misc/e2freefrag.c \
+ 	$(srcdir)/filefrag.c $(srcdir)/extent_inode.c $(srcdir)/zap.c \
+-	$(srcdir)/../misc/create_inode.c
++	$(srcdir)/../misc/create_inode.c $(srcdir)/../misc/xattr.c
+ 
+ CREATE_INODE_DEPS= $(srcdir)/../misc/create_inode.h \
+ 	$(srcdir)/../misc/create_inode.c $(top_builddir)/lib/config.h \
+ 	$(srcdir)/../lib/ext2fs/ext2fs.h $(srcdir)/../lib/et/com_err.h \
+-	$(srcdir)/../lib/e2p/e2p.h $(srcdir)/../misc/nls-enable.h
++	$(srcdir)/../lib/e2p/e2p.h $(srcdir)/../misc/nls-enable.h \
++	$(srcdir)/../misc/xattr.h
++
++XATTR_DEPS= $(srcdir)/../misc/xattr.h $(srcdir)/../misc/xattr.h \
++    $(srcdir)/../lib/et/com_err.h $(srcdir)/../lib/ext2fs/ext2fs.h
+ 
+ LIBS= $(LIBEXT2FS) $(LIBE2P) $(LIBSS) $(LIBCOM_ERR) $(LIBBLKID) \
+ 	$(LIBUUID)
+@@ -92,6 +96,11 @@ create_inode.o: $(CREATE_INODE_DEPS)
+ 	$(Q) $(CC) -c $(ALL_CFLAGS) -I$(srcdir) \
+ 		 $(srcdir)/../misc/create_inode.c -DDEBUGFS -o $@
+ 
++xattr.o: $(XATTR_DEPS)
++	$(E) "  CC $@"
++	$(Q) $(CC) -c $(ALL_CFLAGS) -I$(srcdir) \
++		$(srcdir)/../misc/xattr.c -o $@
++
+ debugfs.8: $(DEP_SUBSTITUTE) $(srcdir)/debugfs.8.in
+ 	$(E) "	SUBST $@"
+ 	$(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/debugfs.8.in debugfs.8
diff --git a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
index 7f0198e..35bdcb7 100644
--- a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
+++ b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
@@ -2,4 +2,5 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
 
 SRC_URI += " \
     file://misc-xattr-copy-xattrs.patch \
+    file://Makefile.in-build-xattr.o.patch \
 "
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [meta-selinux][RFC 05/10] e2fsprogs: Add patch make calls necessary to label file system root and do cleanup.
  2015-06-07  0:36 [meta-selinux][RFC 00/10] Label file system in build Philip Tricca
                   ` (3 preceding siblings ...)
  2015-06-07  0:37 ` [meta-selinux][RFC 04/10] e2fsprogs: Add patch to build xattr code Philip Tricca
@ 2015-06-07  0:37 ` Philip Tricca
  2015-06-07  0:37 ` [meta-selinux][RFC 06/10] e2fsprogs: Add patch to call xattr copy function in populate_fs Philip Tricca
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Philip Tricca @ 2015-06-07  0:37 UTC (permalink / raw)
  To: yocto

Signed-off-by: Philip Tricca <flihp@twobit.us>
---
 .../misc-mke2fs.c-label-root-dir-and-cleanup.patch | 40 ++++++++++++++++++++++
 .../e2fsprogs/e2fsprogs_1.42.9.bbappend            |  1 +
 2 files changed, 41 insertions(+)
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/misc-mke2fs.c-label-root-dir-and-cleanup.patch

diff --git a/recipes-devtools/e2fsprogs/e2fsprogs/misc-mke2fs.c-label-root-dir-and-cleanup.patch b/recipes-devtools/e2fsprogs/e2fsprogs/misc-mke2fs.c-label-root-dir-and-cleanup.patch
new file mode 100644
index 0000000..436cff4
--- /dev/null
+++ b/recipes-devtools/e2fsprogs/e2fsprogs/misc-mke2fs.c-label-root-dir-and-cleanup.patch
@@ -0,0 +1,40 @@
+Add call to 'set_inode_xattr' to copy xattrs for the root directory in the file
+system. The 'populate_fs' function operates on every file in a directory so the
+root of the tree must be labeled independently.
+
+Add call to xattr_cleanup to deallocate xattr cache after populate_fs is done.
+
+Signed-off-by: Philip Tricca <flihp@twobit.us>
+
+Index: e2fsprogs-1.42.9/misc/mke2fs.c
+===================================================================
+--- e2fsprogs-1.42.9.orig/misc/mke2fs.c
++++ e2fsprogs-1.42.9/misc/mke2fs.c
+@@ -56,6 +56,7 @@ extern int optind;
+ #include "../version.h"
+ #include "quota/mkquota.h"
+ #include "create_inode.h"
++#include "xattr.h"
+ 
+ #define STRIDE_LENGTH 8
+ 
+@@ -2744,6 +2745,11 @@ no_journal:
+ 		hdlinks.count = 0;
+ 		current_fs = fs;
+ 		root = EXT2_ROOT_INO;
++		retval = set_inode_xattr (fs, EXT2_ROOT_INO, root_dir);
++		if (retval) {
++			fprintf(stderr, "%s", _("Error setting xattr for inode: 0x%x\n"), EXT2_ROOT_INO);
++			return retval;
++		}
+ 		retval = populate_fs(root, root_dir);
+ 		if (retval) {
+ 			fprintf(stderr, "%s",
+@@ -2751,6 +2757,7 @@ no_journal:
+ 			return retval;
+ 		} else if (!quiet)
+ 			printf("%s", _("done\n"));
++		xattr_cleanup();
+ 	}
+ 
+ 	if (!quiet)
diff --git a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
index 35bdcb7..fe72a4c 100644
--- a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
+++ b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
@@ -3,4 +3,5 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
 SRC_URI += " \
     file://misc-xattr-copy-xattrs.patch \
     file://Makefile.in-build-xattr.o.patch \
+    file://misc-mke2fs.c-label-root-dir-and-cleanup.patch \
 "
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [meta-selinux][RFC 06/10] e2fsprogs: Add patch to call xattr copy function in populate_fs.
  2015-06-07  0:36 [meta-selinux][RFC 00/10] Label file system in build Philip Tricca
                   ` (4 preceding siblings ...)
  2015-06-07  0:37 ` [meta-selinux][RFC 05/10] e2fsprogs: Add patch make calls necessary to label file system root and do cleanup Philip Tricca
@ 2015-06-07  0:37 ` Philip Tricca
  2015-06-07  0:37 ` [meta-selinux][RFC 07/10] e2fsprogs: Add xattr security prefix data to lib/ext2fs/ext2_ext_attr.h Philip Tricca
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Philip Tricca @ 2015-06-07  0:37 UTC (permalink / raw)
  To: yocto

Signed-off-by: Philip Tricca <flihp@twobit.us>
---
 .../misc-create_inode.c-label-fs-objects.patch     | 30 ++++++++++++++++++++++
 .../e2fsprogs/e2fsprogs_1.42.9.bbappend            |  1 +
 2 files changed, 31 insertions(+)
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/misc-create_inode.c-label-fs-objects.patch

diff --git a/recipes-devtools/e2fsprogs/e2fsprogs/misc-create_inode.c-label-fs-objects.patch b/recipes-devtools/e2fsprogs/e2fsprogs/misc-create_inode.c-label-fs-objects.patch
new file mode 100644
index 0000000..9532b8e
--- /dev/null
+++ b/recipes-devtools/e2fsprogs/e2fsprogs/misc-create_inode.c-label-fs-objects.patch
@@ -0,0 +1,30 @@
+Add call to 'set_inode_xattrs' in populate_fs function. This rides on the
+recursive nature of populate_fs and copies xattrs for each file system object
+except for the root directory that we handle separately.
+
+Signed-off-by: Philip Tricca <flihp@twobit.us>
+
+Index: e2fsprogs-1.42.9/misc/create_inode.c
+===================================================================
+--- e2fsprogs-1.42.9.orig/misc/create_inode.c
++++ e2fsprogs-1.42.9/misc/create_inode.c
+@@ -1,5 +1,6 @@
+ #include "create_inode.h"
+ #include <limits.h>
++#include "xattr.h"
+ 
+ #if __STDC_VERSION__ < 199901L
+ # if __GNUC__ >= 2
+@@ -549,6 +550,12 @@ errcode_t populate_fs(ext2_ino_t parent_
+ 			return retval;
+ 		}
+ 
++		if ((retval = set_inode_xattr (current_fs, ino, name))) {
++			com_err(__func__, retval,
++				_("while setting xattrs for \"%s\""), name);
++			return retval;
++		}
++
+ 		/* Save the hardlink ino */
+ 		if (save_inode) {
+ 			/*
diff --git a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
index fe72a4c..990141b 100644
--- a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
+++ b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
@@ -4,4 +4,5 @@ SRC_URI += " \
     file://misc-xattr-copy-xattrs.patch \
     file://Makefile.in-build-xattr.o.patch \
     file://misc-mke2fs.c-label-root-dir-and-cleanup.patch \
+    file://misc-create_inode.c-label-fs-objects.patch \
 "
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [meta-selinux][RFC 07/10] e2fsprogs: Add xattr security prefix data to lib/ext2fs/ext2_ext_attr.h
  2015-06-07  0:36 [meta-selinux][RFC 00/10] Label file system in build Philip Tricca
                   ` (5 preceding siblings ...)
  2015-06-07  0:37 ` [meta-selinux][RFC 06/10] e2fsprogs: Add patch to call xattr copy function in populate_fs Philip Tricca
@ 2015-06-07  0:37 ` Philip Tricca
  2015-06-07  0:37 ` [meta-selinux][RFC 08/10] e2fsprogs: Add patch to copy xattr block from source file Philip Tricca
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Philip Tricca @ 2015-06-07  0:37 UTC (permalink / raw)
  To: yocto

Signed-off-by: Philip Tricca <flihp@twobit.us>
---
 .../lib-ext2fs-ext2_ext_attr.h-add-xattr-index.patch | 20 ++++++++++++++++++++
 recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend |  1 +
 2 files changed, 21 insertions(+)
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/lib-ext2fs-ext2_ext_attr.h-add-xattr-index.patch

diff --git a/recipes-devtools/e2fsprogs/e2fsprogs/lib-ext2fs-ext2_ext_attr.h-add-xattr-index.patch b/recipes-devtools/e2fsprogs/e2fsprogs/lib-ext2fs-ext2_ext_attr.h-add-xattr-index.patch
new file mode 100644
index 0000000..b87c414
--- /dev/null
+++ b/recipes-devtools/e2fsprogs/e2fsprogs/lib-ext2fs-ext2_ext_attr.h-add-xattr-index.patch
@@ -0,0 +1,20 @@
+Add xattr name index for xattrs with the 'security' prefix. These are defined
+in the ext(2|3|4)/xattr.h in the kernel. We use the EXT2 prefix for consistency
+with e2fslibs naming.
+
+Signed-off-by: Philip Tricca <flihp@twobit.us>
+
+Index: e2fsprogs-1.42.9/lib/ext2fs/ext2_ext_attr.h
+===================================================================
+--- e2fsprogs-1.42.9.orig/lib/ext2fs/ext2_ext_attr.h
++++ e2fsprogs-1.42.9/lib/ext2fs/ext2_ext_attr.h
+@@ -15,6 +15,9 @@
+ /* Maximum number of references to one attribute block */
+ #define EXT2_EXT_ATTR_REFCOUNT_MAX	1024
+ 
++/* Name indexes */
++#define EXT2_XATTR_INDEX_SECURITY               6
++
+ struct ext2_ext_attr_header {
+ 	__u32	h_magic;	/* magic number for identification */
+ 	__u32	h_refcount;	/* reference count */
diff --git a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
index 990141b..1bb9a36 100644
--- a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
+++ b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
@@ -5,4 +5,5 @@ SRC_URI += " \
     file://Makefile.in-build-xattr.o.patch \
     file://misc-mke2fs.c-label-root-dir-and-cleanup.patch \
     file://misc-create_inode.c-label-fs-objects.patch \
+    file://lib-ext2fs-ext2_ext_attr.h-add-xattr-index.patch \
 "
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [meta-selinux][RFC 08/10] e2fsprogs: Add patch to copy xattr block from source file.
  2015-06-07  0:36 [meta-selinux][RFC 00/10] Label file system in build Philip Tricca
                   ` (6 preceding siblings ...)
  2015-06-07  0:37 ` [meta-selinux][RFC 07/10] e2fsprogs: Add xattr security prefix data to lib/ext2fs/ext2_ext_attr.h Philip Tricca
@ 2015-06-07  0:37 ` Philip Tricca
  2015-06-07  0:37 ` [meta-selinux][RFC 09/10] e2fsprogs: Add patch to hold xattr header and block number in a structure for the cache Philip Tricca
  2015-06-07  0:37 ` [meta-selinux][RFC 10/10] e2fsprogs: Add patch to implement simple linked list as cache for existing xattr blocks Philip Tricca
  9 siblings, 0 replies; 12+ messages in thread
From: Philip Tricca @ 2015-06-07  0:37 UTC (permalink / raw)
  To: yocto

Signed-off-by: Philip Tricca <flihp@twobit.us>
---
 .../e2fsprogs/misc-xattr-create-xattr-block.patch  | 351 +++++++++++++++++++++
 .../e2fsprogs/e2fsprogs_1.42.9.bbappend            |   1 +
 2 files changed, 352 insertions(+)
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block.patch

diff --git a/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block.patch b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block.patch
new file mode 100644
index 0000000..b843f1b
--- /dev/null
+++ b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block.patch
@@ -0,0 +1,351 @@
+To build the xattr disk block we process the output from listxattr and
+lgetxattr from the source file system object. This data is formated in a disk
+block according to the format specified in the kernel ext2 file system driver.
+See the comment block at the beginning of fs/ext2/xattr.c for details, a brief
+description follows but the kernel source file is authoritative.
+
+Creating the xattr disk block is pretty painful. Each block has an obligatory
+header. After this header is a series of structures each describing an entry
+(aka an attribute). This requires iterating over all entries for a file and
+writing a data structure into the block for each. The value for each entry (the
+actual data) is written to the block as well but these are written simply as
+padded data. Unlike entries which grow down into the block beginning
+immediately after the xattr header, values are written to the end of the xattr
+block growing back towards the entries.
+
+Currently we only process attributes with the 'security.' prefix as our use
+case is SELinux labels and IMA. Additional prefixes can likely be supported with
+minimal effort but none have been tested.
+
+Once the xattr block has been created it is written to disk. The xattr block is
+associated with the appropriate file system object through the i_file_acl inode
+member and the inode is updated on disk.
+
+Signed-off-by: Philip Tricca <flihp@twobit.us>
+
+Index: e2fsprogs-1.42.9/misc/xattr.c
+===================================================================
+--- e2fsprogs-1.42.9.orig/misc/xattr.c
++++ e2fsprogs-1.42.9/misc/xattr.c
+@@ -1,6 +1,23 @@
+ #include "xattr.h"
+ 
++#include <attr/xattr.h>
++#include <ctype.h>
++#include <errno.h>
++#include <ext2fs/ext2_ext_attr.h>
++#include <linux/xattr.h>
++#include <stdint.h>
+ #include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++#include <unistd.h>
++
++#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
++#define HEADER(ptr) ((struct ext2_ext_attr_header *)(ptr))
++#define ENTRY(ptr)  ((struct ext2_ext_attr_entry *)(ptr))
++#define FIRST_ENTRY(ptr) ENTRY(HEADER(ptr) + 1)
++#define VALUE(hdr, ent) (((char*)hdr) + (ent->e_value_offs))
+ 
+ #ifdef XATTR_DEBUG
+ #define XATTR_STDERR(fmt, args...) fprintf (stderr, fmt, ##args)
+@@ -8,6 +25,28 @@
+ #define XATTR_STDERR(fmt, args...) do {} while (0)
+ #endif
+ 
++/* structure for mapping xattr name prefix data */
++typedef struct xattr_prefix {
++	int index;
++	char *name;
++	size_t length;
++} xattr_prefix_t;
++
++xattr_prefix_t xattr_prefixes [] = {
++/* Only interested in security prefix. Can support others though.
++	{
++		.index = EXT2_XATTR_INDEX_USER,
++		.name = XATTR_USER_PREFIX,
++		.length = XATTR_USER_PREFIX_LEN,
++	},
++*/
++	{
++		.index = EXT2_XATTR_INDEX_SECURITY,
++		.name = XATTR_SECURITY_PREFIX,
++		.length = XATTR_SECURITY_PREFIX_LEN,
++	},
++	{ 0 },
++};
+ 
+ /* Free remaining resources after all files have been processed. */
+ void
+@@ -16,6 +55,211 @@ xattr_cleanup ()
+ 	XATTR_STDERR ("Cleaning up resources from xattrs.\n");
+ }
+ 
++/* Get value for named xattr from file at path.
++ * Returns pointer to allocated block for value and length in length param.
++ * If no value, return NULL pointer and length of 0.
++ * On error return NULL pointer and length set to -1.
++ */
++static char*
++xattr_get_value (const char *path, const char *name, ssize_t *length)
++{
++	char *value = NULL;
++
++	*length = lgetxattr (path, name, NULL, 0);
++	if (*length == -1) {
++		com_err (__func__, errno, "lgetattr");
++		goto out;
++	}
++	if (*length == 0) {
++		fprintf (stderr, "xattr %s has value length 0\n", name);
++		goto out;
++	}
++	value = calloc (1, *length);
++	if (value == NULL) {
++		com_err (__func__, errno, "calloc");
++		goto out;
++	}
++	*length = lgetxattr (path, name, value, *length);
++	if (*length == -1) {
++		com_err (__func__, errno, "lgetattr");
++		goto value_err;
++	}
++out:
++	return value;
++
++value_err:
++	if (value)
++		free (value);
++	return NULL;
++}
++
++/* Get all attribute names for file at path. Return pointer to allocated memory
++ * block holding all names and the length through parameter size.
++ * If no xattrs: return NULL and set size to 0
++ * If error: return NULL and set size to -1
++ */
++static char*
++xattr_get_names (const char *path, ssize_t *size)
++{
++	char *names = NULL;
++
++	*size = llistxattr (path, NULL, 0);
++	if (*size == -1) {
++		com_err (__func__, errno, "llistxattr");
++		goto out;
++	}
++	if (*size == 0) {
++		/* no xattrs */
++		goto out;
++	}
++	names = calloc (1, *size);
++	if (names == NULL) {
++		com_err (__func__, errno, "calloc");
++		goto out;
++	}
++	*size = llistxattr (path, names, *size);
++	if (*size == -1) {
++		com_err (__func__, errno, "llistxattr");
++		goto cleanup;
++	}
++	if (*size == 0) {
++		fprintf (stdout, "Conflicting data, no xattrs for file: %s\n", path);
++		goto cleanup;
++	}
++out:
++	return names;
++
++cleanup:
++	if (names)
++		free (names);
++	return NULL;
++}
++
++/* return pointer to next string in xattr name block, don't go beyond length
++ */
++static inline char*
++next_name (char *name, size_t length)
++{
++	int i = 0;
++
++	for (i = 0; i < length; ++i)
++		if (name [i] == '\0') {
++			++i;
++			break;
++		}
++
++	return name + i;
++}
++
++/* Find entry in xattr_table with matching prefix. */
++static const xattr_prefix_t*
++xattr_find_prefix (char *name, size_t length)
++{
++	int i = 0;
++
++	XATTR_STDERR ("find_attr_data: searching for prefix from xattr name: %s\n", name);
++	for (i = 0; xattr_prefixes[i].index != 0; ++i) {
++		if (!strncmp (name, xattr_prefixes[i].name, MIN (length, xattr_prefixes[i].length))) {
++			XATTR_STDERR ("found match in table with index: %d\n", xattr_prefixes[i].index);
++			return &xattr_prefixes[i];
++		}
++	}
++	return NULL;
++}
++
++/* Query file at path for attributes. build up structure the file system
++ * expects of an extended attribute disk block (header parameter).
++ *
++ * The main loop walks through the xattr names one at a time. It gets the value
++ * for each named xattr and copies the data into the xattr block pointed to by
++ * the header parameter. To do this the loop also tracks the location of the
++ * associated entry and value. Values start at the end of the buffer and grow
++ * back towards the header while the entries start immediately after the header
++ * and grow towards the end of the block.
++ *
++ * See the comment block at the beginning of the xattr.c file in the ext2 file
++ * system code in the kernel: fs/ext2/xattr.c
++ * Assume the xattr block pointed to by header parameter is initialized to 0s.
++ */
++static int
++xattr_build_block (const char *path,
++		struct ext2_ext_attr_header **header,
++		size_t header_length)
++{
++	struct ext2_ext_attr_entry *entry = NULL;
++	char *names = NULL, *value = NULL, *name_curr = NULL;
++	ssize_t names_length = 0, value_length = 0;
++	size_t name_length = 0, value_index = 0, len_rem = 0;
++	const xattr_prefix_t *prefix = NULL;
++	int ret = 0;
++
++	XATTR_STDERR ("xattr_build_block for file: %s\n", path);
++	*header = NULL;
++	names = xattr_get_names (path, &names_length);
++	if (names == NULL) {
++		// no xattrs for file @ path or error
++		ret = names_length;
++		goto out;
++	}
++	*header = calloc (1, header_length);
++	if (*header == NULL) {
++		com_err (__func__, errno, "calloc");
++		goto out;
++	}
++	(*header)->h_magic = EXT2_EXT_ATTR_MAGIC;
++	(*header)->h_blocks = 1;
++	/* Values start at end of buffer. NOTE: It must be moved before a value can
++	 * be stored.
++	 */
++	value_index = header_length;
++	for (name_curr = names, entry = FIRST_ENTRY(*header), len_rem = names_length;
++		name_curr < names + names_length;
++		len_rem = names_length - (name_curr - names),
++			name_curr = next_name (name_curr, len_rem),
++			entry = EXT2_EXT_ATTR_NEXT(entry))
++	{
++		XATTR_STDERR ("xattr_build_block: processing xattr with name %s\n", name_curr);
++		name_length = strnlen (name_curr, len_rem);
++		prefix = xattr_find_prefix (name_curr, name_length);
++		if (!prefix) {
++			fprintf (stderr, "Don't currently handle xattr: %s\n", name_curr);
++			continue;
++		}
++		value = xattr_get_value (path, name_curr, &value_length);
++		if (value == NULL) {
++			// no xattr value or error
++			fprintf (stderr, "failed to get value, skipping\n");
++			goto next;
++		}
++		/* setup offsets and lengths for name and value */
++		entry->e_name_len = name_length - prefix->length;
++		entry->e_name_index = prefix->index;
++		/* Can't know these till we know the length of the value. */
++		entry->e_value_offs = value_index -= EXT2_EXT_ATTR_SIZE(value_length);
++		entry->e_value_size = value_length;
++		/* Check to be sure entry name and value don't overlap before copy. */
++		if (EXT2_EXT_ATTR_NAME(entry) + entry->e_name_len > VALUE(*header, entry)) {
++			fprintf (stderr, "xattr entry name and value overlap! Too much xattr data.");
++			ret = -1;
++			goto out;
++		}
++		/* copy name and value data then calculate the hash */
++		memcpy (EXT2_EXT_ATTR_NAME(entry),
++			name_curr + prefix->length,
++			entry->e_name_len);
++		memcpy (VALUE(*header, entry), value, entry->e_value_size);
++		entry->e_hash = ext2fs_ext_attr_hash_entry (entry, VALUE(*header, entry));
++next:
++		if (value)
++			free (value);
++	}
++	XATTR_STDERR ("xattr_build_block: done building xattr buffer\n");
++out:
++	if (names)
++		free (names);
++	return ret;
++}
++
+ /* This is the entry point to the xattr module. This function copies the xattrs
+  * from the file at 'path' to the file system object at 'ino'.
+  *
+@@ -28,7 +272,56 @@ errcode_t
+ set_inode_xattr (ext2_filsys fs, ext2_ino_t ino, const char *path)
+ {
+ 	errcode_t ret = 0;
++	char *buf = NULL;
++	struct ext2_inode inode = { 0 };
++	blk_t block = 0;
++	struct ext2_ext_attr_header *header = NULL;
++	uint32_t newcount = 0;
+ 
+ 	XATTR_STDERR ("Copying xattrs from %s to inode 0x%x.\n", path, ino);
++	/* Populate the xattr block for the file at path */
++	if (ret = xattr_build_block (path, &header, fs->blocksize)) {
++		goto out;
++	}
++	if (header == NULL) {
++		XATTR_STDERR ("set_inode_xattrs: no xattrs for %s\n", path);
++		goto out;
++	}
++	if (ret = ext2fs_read_inode (fs, ino, &inode)) {
++		com_err(__func__, ret, "ext2fs_read_inode");
++		goto out;
++	}
++	if (ret = ext2fs_alloc_block (fs, 0, NULL, &block)) {
++		com_err(__func__, ret, "ext2fs_alloc_block: returned %d", ret);
++		goto out;
++	}
++	ext2fs_mark_block_bitmap2 (fs->block_map, block);
++	XATTR_STDERR ("writing xattr block 0x%x to disk:\n", block);
++	if (ret = ext2fs_write_ext_attr (fs, block, header)) {
++		com_err(__func__, ret, "ext2fs_write_ext_attr: returned %d", ret);
++		goto out;
++	}
++	/* point inode for current file to xattr block, update block count and
++	 * write inode to disk
++	 */
++	inode.i_file_acl = block;
++	if (ret = ext2fs_adjust_ea_refcount2(fs,
++					block,
++					(char*)header,
++					1,
++					&newcount))
++	{
++		com_err(__func__, ret, "ext2fs_adjust_ea_refcount");
++		goto out;
++	}
++	if (ret = ext2fs_iblk_add_blocks (fs, &inode, 1)) {
++		com_err(__func__, ret, "ext2fs_iblk_add_blocks failed");
++		goto out;
++	}
++	if (ret = ext2fs_write_inode (fs, ino, &inode))
++		com_err(__func__, ret, "ext2fs_write_inode: returned %d", ret);
++out:
++	if (header)
++		free (header);
+ 	return ret;
+ }
diff --git a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
index 1bb9a36..d2cefbf 100644
--- a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
+++ b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
@@ -6,4 +6,5 @@ SRC_URI += " \
     file://misc-mke2fs.c-label-root-dir-and-cleanup.patch \
     file://misc-create_inode.c-label-fs-objects.patch \
     file://lib-ext2fs-ext2_ext_attr.h-add-xattr-index.patch \
+    file://misc-xattr-create-xattr-block.patch \
 "
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [meta-selinux][RFC 09/10] e2fsprogs: Add patch to hold xattr header and block number in a structure for the cache.
  2015-06-07  0:36 [meta-selinux][RFC 00/10] Label file system in build Philip Tricca
                   ` (7 preceding siblings ...)
  2015-06-07  0:37 ` [meta-selinux][RFC 08/10] e2fsprogs: Add patch to copy xattr block from source file Philip Tricca
@ 2015-06-07  0:37 ` Philip Tricca
  2015-06-07  0:37 ` [meta-selinux][RFC 10/10] e2fsprogs: Add patch to implement simple linked list as cache for existing xattr blocks Philip Tricca
  9 siblings, 0 replies; 12+ messages in thread
From: Philip Tricca @ 2015-06-07  0:37 UTC (permalink / raw)
  To: yocto

Signed-off-by: Philip Tricca <flihp@twobit.us>
---
 .../misc-xattr-create-xattr-block-node.patch       | 126 +++++++++++++++++++++
 .../e2fsprogs/e2fsprogs_1.42.9.bbappend            |   1 +
 2 files changed, 127 insertions(+)
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block-node.patch

diff --git a/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block-node.patch b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block-node.patch
new file mode 100644
index 0000000..cff47ed
--- /dev/null
+++ b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block-node.patch
@@ -0,0 +1,126 @@
+Add two new functions to manage a cache of xattr blocks as well as a new struct
+to build a linked list of xattr blocks.
+
+xattr_add_block: Adds a block to the cache. This function is supplied with a
+pointer to the head of a linked list of xattr blocks and an xattr block to add.
+The purpose of this cache is to allow sharing of what would otherwise be
+duplicate xattr blocks and so duplicates are not allowed in this cache. If an
+identical block is already in the cache a pointer to this block will be
+returned.
+
+xattr_rm_block: Removes a block from the cache. This function is supplied with
+a pointer to the cache and a node that shall be removed from the cache. The
+cache is searched for the node and the node is removed if found.
+
+Both functions are integrated into the 'set_inode_xattr'. Here the logic is
+rearranged to cope with associating preexisting xattr blocks with inodes as
+well as creating new blocks when necessary.
+
+Signed-off-by: Philip Tricca <flihp@twobit.us>
+
+Index: e2fsprogs-1.42.9/misc/xattr.c
+===================================================================
+--- e2fsprogs-1.42.9.orig/misc/xattr.c
++++ e2fsprogs-1.42.9/misc/xattr.c
+@@ -25,6 +25,19 @@
+ #define XATTR_STDERR(fmt, args...) do {} while (0)
+ #endif
+ 
++/* nodes for simple linked list to track xattr blocks, calling it a cache
++ * would be a stretch ...
++ */
++typedef struct xattr_node xattr_node_t;
++
++struct xattr_node {
++	struct ext2_ext_attr_header *header;
++	blk_t block;
++	struct xattr_node *next;
++};
++
++xattr_node_t *xattr_list_head = NULL;
++
+ /* structure for mapping xattr name prefix data */
+ typedef struct xattr_prefix {
+ 	int index;
+@@ -48,6 +61,17 @@ xattr_prefix_t xattr_prefixes [] = {
+ 	{ 0 },
+ };
+ 
++/* free xattr node and the buffer holding the xattr block */
++static void
++xattr_free_node (xattr_node_t *node)
++{
++	if (node) {
++		if (node->header)
++			free (node->header);
++		free (node);
++	}
++}
++
+ /* Free remaining resources after all files have been processed. */
+ void
+ xattr_cleanup ()
+@@ -260,6 +284,28 @@ out:
+ 	return ret;
+ }
+ 
++/* Add an xattr node to the list specified by head. This function will update
++ * head as necessary. It will return a pointer to the xattr_node_t added to the
++ * list. In the event that an identical xattr block is already on the list this
++ * function will return a pointer to the pre-existing node.
++ */
++static xattr_node_t*
++xattr_add_block (xattr_node_t **head, xattr_node_t *node)
++{
++	XATTR_STDERR ("Adding xattr to the the node list.\n");
++	return node;
++}
++
++/* Remove xattr node from list. Returns pointer to the node being removed.
++ * NOTE: We're not comparing the xattr blocks, just the nodes.
++ */
++static xattr_node_t*
++xattr_rm_block (xattr_node_t **head, xattr_node_t *node)
++{
++	XATTR_STDERR ("Removing xattr from the node list.\n");
++	return node;
++}
++
+ /* This is the entry point to the xattr module. This function copies the xattrs
+  * from the file at 'path' to the file system object at 'ino'.
+  *
+@@ -274,16 +320,21 @@ set_inode_xattr (ext2_filsys fs, ext2_in
+ 	errcode_t ret = 0;
+ 	char *buf = NULL;
+ 	struct ext2_inode inode = { 0 };
+-	blk_t block = 0;
+-	struct ext2_ext_attr_header *header = NULL;
++	xattr_node_t *node = NULL, *node_tmp = NULL;
+ 	uint32_t newcount = 0;
+ 
+ 	XATTR_STDERR ("Copying xattrs from %s to inode 0x%x.\n", path, ino);
++	/* Create an xattr_node_t for it and add it to the cache if appropriate */
++	if (!(node = calloc (1, sizeof (xattr_node_t)))) {
++		com_err (__func__, errno, "calloc");
++		ret = errno;
++		goto out;
++	}
+ 	/* Populate the xattr block for the file at path */
+-	if (ret = xattr_build_block (path, &header, fs->blocksize)) {
++	if (ret = xattr_build_block (path, &(node->header), fs->blocksize)) {
+ 		goto out;
+ 	}
+-	if (header == NULL) {
++	if (node->header == NULL) {
+ 		XATTR_STDERR ("set_inode_xattrs: no xattrs for %s\n", path);
+ 		goto out;
+ 	}
+@@ -321,7 +372,6 @@ set_inode_xattr (ext2_filsys fs, ext2_in
+ 	if (ret = ext2fs_write_inode (fs, ino, &inode))
+ 		com_err(__func__, ret, "ext2fs_write_inode: returned %d", ret);
+ out:
+-	if (header)
+-		free (header);
++	xattr_free_node (node);
+ 	return ret;
+ }
diff --git a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
index d2cefbf..241a9bf 100644
--- a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
+++ b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
@@ -7,4 +7,5 @@ SRC_URI += " \
     file://misc-create_inode.c-label-fs-objects.patch \
     file://lib-ext2fs-ext2_ext_attr.h-add-xattr-index.patch \
     file://misc-xattr-create-xattr-block.patch \
+    file://misc-xattr-create-xattr-block-node.patch \
 "
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [meta-selinux][RFC 10/10] e2fsprogs: Add patch to implement simple linked list as cache for existing xattr blocks.
  2015-06-07  0:36 [meta-selinux][RFC 00/10] Label file system in build Philip Tricca
                   ` (8 preceding siblings ...)
  2015-06-07  0:37 ` [meta-selinux][RFC 09/10] e2fsprogs: Add patch to hold xattr header and block number in a structure for the cache Philip Tricca
@ 2015-06-07  0:37 ` Philip Tricca
  2015-06-10  6:03   ` Philip Tricca
  9 siblings, 1 reply; 12+ messages in thread
From: Philip Tricca @ 2015-06-07  0:37 UTC (permalink / raw)
  To: yocto

Signed-off-by: Philip Tricca <flihp@twobit.us>
---
 .../e2fsprogs/misc-xattr-create-xattr-cache.patch  | 217 +++++++++++++++++++++
 .../e2fsprogs/e2fsprogs_1.42.9.bbappend            |   1 +
 2 files changed, 218 insertions(+)
 create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-cache.patch

diff --git a/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-cache.patch b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-cache.patch
new file mode 100644
index 0000000..ba09e2b
--- /dev/null
+++ b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-cache.patch
@@ -0,0 +1,217 @@
+Implement the xattr block cache as a sorted linked list. This requires the add
+and rm functions be able to compare xattr blocks. This is implemented as two
+functions. The first compares individual entries and the second compares the
+whole xattr block by iterating over and comparing individual entries.
+
+The xattr block cache keeps memory allocated on the heap around across
+invocations of the set_inode_xattr function. To free this memory we implement
+an xattr_cleanup function that iterates over the cache freeing resources
+associated with each node.
+
+Signed-off-by: Philip Tricca <flihp@twobit.us>
+
+Index: e2fsprogs-1.42.9/misc/xattr.c
+===================================================================
+--- e2fsprogs-1.42.9.orig/misc/xattr.c
++++ e2fsprogs-1.42.9/misc/xattr.c
+@@ -76,7 +76,16 @@ xattr_free_node (xattr_node_t *node)
+ void
+ xattr_cleanup ()
+ {
++	xattr_node_t *curr = NULL, *tmp = NULL;
++	size_t count = 0;
++
+ 	XATTR_STDERR ("Cleaning up resources from xattrs.\n");
++	for (curr = xattr_list_head; curr != NULL; ++count) {
++                tmp = curr;
++                curr = curr->next;
++                xattr_free_node (tmp);
++	}
++	XATTR_STDERR ("Freed %d xattr_node_ts.\n", count);
+ }
+ 
+ /* Get value for named xattr from file at path.
+@@ -284,6 +293,77 @@ out:
+ 	return ret;
+ }
+ 
++/* Compre two extended attribute entries. This includes the entry and the value.
++ * if a < b return -1
++ * if a == b return 0
++ * if a > b return 1
++ */
++static int
++xattr_compare_entry (struct ext2_ext_attr_header *header_a,
++		struct ext2_ext_attr_entry *entry_a,
++		struct ext2_ext_attr_header *header_b,
++		struct ext2_ext_attr_entry *entry_b)
++{
++	int ret = 0;
++
++	if (entry_a->e_hash != entry_b->e_hash ||
++		entry_a->e_name_index != entry_b->e_name_index ||
++		entry_a->e_name_len != entry_b->e_name_len ||
++		entry_a->e_value_size != entry_b->e_value_size)
++	{
++		if (ret = memcmp (EXT2_EXT_ATTR_NAME(entry_a),
++				EXT2_EXT_ATTR_NAME(entry_b),
++				MIN (entry_a->e_name_len, entry_b->e_name_len)))
++			return ret;
++		if (entry_a->e_value_block != 0 || entry_b->e_value_block != 0)
++			return -EIO;
++		return memcmp (VALUE(header_a, entry_a),
++				VALUE(header_b, entry_b),
++				MIN(entry_a->e_value_size, entry_b->e_value_size));
++	}
++}
++
++/* Compare two extended attribute blocks. This includes the header as well as
++ *   all entries and values.
++ * Algorithm is almost straight from the ext2 kernel drive with the exception
++ *   of adding lt and gt behavior to get sorting.
++ * If a < b return < 0
++ * If a == b return 0
++ * If a > b return > 0
++ */
++static int
++xattr_compare_block (struct ext2_ext_attr_header *header_a,
++					 struct ext2_ext_attr_header *header_b)
++{
++	struct ext2_ext_attr_entry *entry_a = NULL, *entry_b = NULL;
++	int ret = 0;
++
++	XATTR_STDERR ("comparing xattr blocks at 0x%x and 0x%x\n", header_a, header_b);
++	for (entry_a = FIRST_ENTRY(header_a), entry_b = FIRST_ENTRY(header_b);
++		!EXT2_EXT_IS_LAST_ENTRY(entry_a) && !EXT2_EXT_IS_LAST_ENTRY(entry_b);
++		entry_a = EXT2_EXT_ATTR_NEXT(entry_a), entry_b = EXT2_EXT_ATTR_NEXT(entry_b))
++	{
++		xattr_pp_value (VALUE(header_a, entry_a), entry_a->e_value_size);
++		xattr_pp_value (VALUE(header_b, entry_b), entry_b->e_value_size);
++		if (ret = xattr_compare_entry (header_a, entry_a, header_b, entry_b)) {
++			XATTR_STDERR ("entries do not match: %d\n", ret);
++			return ret;
++		} else {
++			XATTR_STDERR ("entries match!\n");
++		}
++	}
++	/* All entries checked were equal. Handle edge case where entry_a is a
++	 * subset of entry_b: test to see if either block had more entries than the
++	 * other. More entries -> block is greater than the other.
++	 */
++	if (EXT2_EXT_IS_LAST_ENTRY(entry_a) && !EXT2_EXT_IS_LAST_ENTRY(entry_b))
++		return -1;
++	if (!EXT2_EXT_IS_LAST_ENTRY(entry_a) && EXT2_EXT_IS_LAST_ENTRY(entry_b))
++		return 1;
++	if (EXT2_EXT_IS_LAST_ENTRY(entry_a) && EXT2_EXT_IS_LAST_ENTRY(entry_b))
++		return 0;
++}
++
+ /* Add an xattr node to the list specified by head. This function will update
+  * head as necessary. It will return a pointer to the xattr_node_t added to the
+  * list. In the event that an identical xattr block is already on the list this
+@@ -292,7 +372,37 @@ out:
+ static xattr_node_t*
+ xattr_add_block (xattr_node_t **head, xattr_node_t *node)
+ {
++	xattr_node_t *curr_node = NULL, *prev_node = NULL;
++	int ret = 0;
++
+ 	XATTR_STDERR ("Adding xattr to the the node list.\n");
++	if (node == NULL)
++		return NULL;
++	/* list is empty, node becomes first node */
++	if (!(*head)) {
++		*head = node;
++		return node;
++	}
++	for (prev_node = NULL, curr_node = *head;
++		curr_node != NULL;
++		prev_node = curr_node, curr_node = curr_node->next)
++	{
++		/* When the supplied node is "less than" the current node we add it to
++		 * the list before the current ndoe.
++		 */
++		if ((ret = xattr_compare_block (node->header, curr_node->header)) < 0) {
++			node->next = curr_node;
++			if (prev_node)
++				prev_node->next = node;
++			else /* edge case: we added node to the head of the list */
++				*head = node;
++			return node;
++		} else if (ret == 0) { /* found a match */
++			return curr_node;
++		}
++	}
++	/* reached end of list, new node should be last */
++	prev_node->next = node;
+ 	return node;
+ }
+ 
+@@ -302,8 +412,27 @@ xattr_add_block (xattr_node_t **head, xa
+ static xattr_node_t*
+ xattr_rm_block (xattr_node_t **head, xattr_node_t *node)
+ {
++	xattr_node_t *curr_node = NULL, *prev_node = NULL;
++
+ 	XATTR_STDERR ("Removing xattr from the node list.\n");
+-	return node;
++	/* no list, or empty list: nothing to search though */
++	if (!head || !(*head))
++		return NULL;
++
++	for (prev_node = NULL, curr_node = *head;
++		curr_node != NULL;
++		prev_node = curr_node, curr_node = curr_node->next)
++	{
++		if (node == curr_node) {
++			if (prev_node)
++				prev_node->next = curr_node->next;
++			else
++				*head = curr_node->next;
++			return curr_node;
++		}
++	}
++	/* reached end of list, no match */
++	return NULL;
+ }
+ 
+ /* This is the entry point to the xattr module. This function copies the xattrs
+@@ -342,23 +471,23 @@ set_inode_xattr (ext2_filsys fs, ext2_in
+ 		com_err(__func__, ret, "ext2fs_read_inode");
+ 		goto out;
+ 	}
+-	if (ret = ext2fs_alloc_block (fs, 0, NULL, &block)) {
++	if (ret = ext2fs_alloc_block (fs, 0, NULL, &(node->block))) {
+ 		com_err(__func__, ret, "ext2fs_alloc_block: returned %d", ret);
+ 		goto out;
+ 	}
+-	ext2fs_mark_block_bitmap2 (fs->block_map, block);
+-	XATTR_STDERR ("writing xattr block 0x%x to disk:\n", block);
+-	if (ret = ext2fs_write_ext_attr (fs, block, header)) {
++	ext2fs_mark_block_bitmap2 (fs->block_map, node->block);
++	XATTR_STDERR ("writing xattr block 0x%x to disk:\n", node->block);
++	if (ret = ext2fs_write_ext_attr (fs, node->block, node->header)) {
+ 		com_err(__func__, ret, "ext2fs_write_ext_attr: returned %d", ret);
+ 		goto out;
+ 	}
+ 	/* point inode for current file to xattr block, update block count and
+ 	 * write inode to disk
+ 	 */
+-	inode.i_file_acl = block;
++	inode.i_file_acl = node->block;
+ 	if (ret = ext2fs_adjust_ea_refcount2(fs,
+-					block,
+-					(char*)header,
++					node->block,
++					(char*)(node->header),
+ 					1,
+ 					&newcount))
+ 	{
+@@ -371,6 +500,7 @@ set_inode_xattr (ext2_filsys fs, ext2_in
+ 	}
+ 	if (ret = ext2fs_write_inode (fs, ino, &inode))
+ 		com_err(__func__, ret, "ext2fs_write_inode: returned %d", ret);
++	return ret;
+ out:
+ 	xattr_free_node (node);
+ 	return ret;
diff --git a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
index 241a9bf..8756d76 100644
--- a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
+++ b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
@@ -8,4 +8,5 @@ SRC_URI += " \
     file://lib-ext2fs-ext2_ext_attr.h-add-xattr-index.patch \
     file://misc-xattr-create-xattr-block.patch \
     file://misc-xattr-create-xattr-block-node.patch \
+    file://misc-xattr-create-xattr-cache.patch \
 "
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [meta-selinux][RFC 10/10] e2fsprogs: Add patch to implement simple linked list as cache for existing xattr blocks.
  2015-06-07  0:37 ` [meta-selinux][RFC 10/10] e2fsprogs: Add patch to implement simple linked list as cache for existing xattr blocks Philip Tricca
@ 2015-06-10  6:03   ` Philip Tricca
  0 siblings, 0 replies; 12+ messages in thread
From: Philip Tricca @ 2015-06-10  6:03 UTC (permalink / raw)
  To: yocto

It looks like I screwed up this patch when I was rewriting some git
history. I'm working up a fix.

Philip

On 06/06/2015 05:37 PM, Philip Tricca wrote:
> Signed-off-by: Philip Tricca <flihp@twobit.us>
> ---
>  .../e2fsprogs/misc-xattr-create-xattr-cache.patch  | 217 +++++++++++++++++++++
>  .../e2fsprogs/e2fsprogs_1.42.9.bbappend            |   1 +
>  2 files changed, 218 insertions(+)
>  create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-cache.patch
> 
> diff --git a/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-cache.patch b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-cache.patch
> new file mode 100644
> index 0000000..ba09e2b
> --- /dev/null
> +++ b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-cache.patch
> @@ -0,0 +1,217 @@
> +Implement the xattr block cache as a sorted linked list. This requires the add
> +and rm functions be able to compare xattr blocks. This is implemented as two
> +functions. The first compares individual entries and the second compares the
> +whole xattr block by iterating over and comparing individual entries.
> +
> +The xattr block cache keeps memory allocated on the heap around across
> +invocations of the set_inode_xattr function. To free this memory we implement
> +an xattr_cleanup function that iterates over the cache freeing resources
> +associated with each node.
> +
> +Signed-off-by: Philip Tricca <flihp@twobit.us>
> +
> +Index: e2fsprogs-1.42.9/misc/xattr.c
> +===================================================================
> +--- e2fsprogs-1.42.9.orig/misc/xattr.c
> ++++ e2fsprogs-1.42.9/misc/xattr.c
> +@@ -76,7 +76,16 @@ xattr_free_node (xattr_node_t *node)
> + void
> + xattr_cleanup ()
> + {
> ++	xattr_node_t *curr = NULL, *tmp = NULL;
> ++	size_t count = 0;
> ++
> + 	XATTR_STDERR ("Cleaning up resources from xattrs.\n");
> ++	for (curr = xattr_list_head; curr != NULL; ++count) {
> ++                tmp = curr;
> ++                curr = curr->next;
> ++                xattr_free_node (tmp);
> ++	}
> ++	XATTR_STDERR ("Freed %d xattr_node_ts.\n", count);
> + }
> + 
> + /* Get value for named xattr from file at path.
> +@@ -284,6 +293,77 @@ out:
> + 	return ret;
> + }
> + 
> ++/* Compre two extended attribute entries. This includes the entry and the value.
> ++ * if a < b return -1
> ++ * if a == b return 0
> ++ * if a > b return 1
> ++ */
> ++static int
> ++xattr_compare_entry (struct ext2_ext_attr_header *header_a,
> ++		struct ext2_ext_attr_entry *entry_a,
> ++		struct ext2_ext_attr_header *header_b,
> ++		struct ext2_ext_attr_entry *entry_b)
> ++{
> ++	int ret = 0;
> ++
> ++	if (entry_a->e_hash != entry_b->e_hash ||
> ++		entry_a->e_name_index != entry_b->e_name_index ||
> ++		entry_a->e_name_len != entry_b->e_name_len ||
> ++		entry_a->e_value_size != entry_b->e_value_size)
> ++	{
> ++		if (ret = memcmp (EXT2_EXT_ATTR_NAME(entry_a),
> ++				EXT2_EXT_ATTR_NAME(entry_b),
> ++				MIN (entry_a->e_name_len, entry_b->e_name_len)))
> ++			return ret;
> ++		if (entry_a->e_value_block != 0 || entry_b->e_value_block != 0)
> ++			return -EIO;
> ++		return memcmp (VALUE(header_a, entry_a),
> ++				VALUE(header_b, entry_b),
> ++				MIN(entry_a->e_value_size, entry_b->e_value_size));
> ++	}
> ++}
> ++
> ++/* Compare two extended attribute blocks. This includes the header as well as
> ++ *   all entries and values.
> ++ * Algorithm is almost straight from the ext2 kernel drive with the exception
> ++ *   of adding lt and gt behavior to get sorting.
> ++ * If a < b return < 0
> ++ * If a == b return 0
> ++ * If a > b return > 0
> ++ */
> ++static int
> ++xattr_compare_block (struct ext2_ext_attr_header *header_a,
> ++					 struct ext2_ext_attr_header *header_b)
> ++{
> ++	struct ext2_ext_attr_entry *entry_a = NULL, *entry_b = NULL;
> ++	int ret = 0;
> ++
> ++	XATTR_STDERR ("comparing xattr blocks at 0x%x and 0x%x\n", header_a, header_b);
> ++	for (entry_a = FIRST_ENTRY(header_a), entry_b = FIRST_ENTRY(header_b);
> ++		!EXT2_EXT_IS_LAST_ENTRY(entry_a) && !EXT2_EXT_IS_LAST_ENTRY(entry_b);
> ++		entry_a = EXT2_EXT_ATTR_NEXT(entry_a), entry_b = EXT2_EXT_ATTR_NEXT(entry_b))
> ++	{
> ++		xattr_pp_value (VALUE(header_a, entry_a), entry_a->e_value_size);
> ++		xattr_pp_value (VALUE(header_b, entry_b), entry_b->e_value_size);
> ++		if (ret = xattr_compare_entry (header_a, entry_a, header_b, entry_b)) {
> ++			XATTR_STDERR ("entries do not match: %d\n", ret);
> ++			return ret;
> ++		} else {
> ++			XATTR_STDERR ("entries match!\n");
> ++		}
> ++	}
> ++	/* All entries checked were equal. Handle edge case where entry_a is a
> ++	 * subset of entry_b: test to see if either block had more entries than the
> ++	 * other. More entries -> block is greater than the other.
> ++	 */
> ++	if (EXT2_EXT_IS_LAST_ENTRY(entry_a) && !EXT2_EXT_IS_LAST_ENTRY(entry_b))
> ++		return -1;
> ++	if (!EXT2_EXT_IS_LAST_ENTRY(entry_a) && EXT2_EXT_IS_LAST_ENTRY(entry_b))
> ++		return 1;
> ++	if (EXT2_EXT_IS_LAST_ENTRY(entry_a) && EXT2_EXT_IS_LAST_ENTRY(entry_b))
> ++		return 0;
> ++}
> ++
> + /* Add an xattr node to the list specified by head. This function will update
> +  * head as necessary. It will return a pointer to the xattr_node_t added to the
> +  * list. In the event that an identical xattr block is already on the list this
> +@@ -292,7 +372,37 @@ out:
> + static xattr_node_t*
> + xattr_add_block (xattr_node_t **head, xattr_node_t *node)
> + {
> ++	xattr_node_t *curr_node = NULL, *prev_node = NULL;
> ++	int ret = 0;
> ++
> + 	XATTR_STDERR ("Adding xattr to the the node list.\n");
> ++	if (node == NULL)
> ++		return NULL;
> ++	/* list is empty, node becomes first node */
> ++	if (!(*head)) {
> ++		*head = node;
> ++		return node;
> ++	}
> ++	for (prev_node = NULL, curr_node = *head;
> ++		curr_node != NULL;
> ++		prev_node = curr_node, curr_node = curr_node->next)
> ++	{
> ++		/* When the supplied node is "less than" the current node we add it to
> ++		 * the list before the current ndoe.
> ++		 */
> ++		if ((ret = xattr_compare_block (node->header, curr_node->header)) < 0) {
> ++			node->next = curr_node;
> ++			if (prev_node)
> ++				prev_node->next = node;
> ++			else /* edge case: we added node to the head of the list */
> ++				*head = node;
> ++			return node;
> ++		} else if (ret == 0) { /* found a match */
> ++			return curr_node;
> ++		}
> ++	}
> ++	/* reached end of list, new node should be last */
> ++	prev_node->next = node;
> + 	return node;
> + }
> + 
> +@@ -302,8 +412,27 @@ xattr_add_block (xattr_node_t **head, xa
> + static xattr_node_t*
> + xattr_rm_block (xattr_node_t **head, xattr_node_t *node)
> + {
> ++	xattr_node_t *curr_node = NULL, *prev_node = NULL;
> ++
> + 	XATTR_STDERR ("Removing xattr from the node list.\n");
> +-	return node;
> ++	/* no list, or empty list: nothing to search though */
> ++	if (!head || !(*head))
> ++		return NULL;
> ++
> ++	for (prev_node = NULL, curr_node = *head;
> ++		curr_node != NULL;
> ++		prev_node = curr_node, curr_node = curr_node->next)
> ++	{
> ++		if (node == curr_node) {
> ++			if (prev_node)
> ++				prev_node->next = curr_node->next;
> ++			else
> ++				*head = curr_node->next;
> ++			return curr_node;
> ++		}
> ++	}
> ++	/* reached end of list, no match */
> ++	return NULL;
> + }
> + 
> + /* This is the entry point to the xattr module. This function copies the xattrs
> +@@ -342,23 +471,23 @@ set_inode_xattr (ext2_filsys fs, ext2_in
> + 		com_err(__func__, ret, "ext2fs_read_inode");
> + 		goto out;
> + 	}
> +-	if (ret = ext2fs_alloc_block (fs, 0, NULL, &block)) {
> ++	if (ret = ext2fs_alloc_block (fs, 0, NULL, &(node->block))) {
> + 		com_err(__func__, ret, "ext2fs_alloc_block: returned %d", ret);
> + 		goto out;
> + 	}
> +-	ext2fs_mark_block_bitmap2 (fs->block_map, block);
> +-	XATTR_STDERR ("writing xattr block 0x%x to disk:\n", block);
> +-	if (ret = ext2fs_write_ext_attr (fs, block, header)) {
> ++	ext2fs_mark_block_bitmap2 (fs->block_map, node->block);
> ++	XATTR_STDERR ("writing xattr block 0x%x to disk:\n", node->block);
> ++	if (ret = ext2fs_write_ext_attr (fs, node->block, node->header)) {
> + 		com_err(__func__, ret, "ext2fs_write_ext_attr: returned %d", ret);
> + 		goto out;
> + 	}
> + 	/* point inode for current file to xattr block, update block count and
> + 	 * write inode to disk
> + 	 */
> +-	inode.i_file_acl = block;
> ++	inode.i_file_acl = node->block;
> + 	if (ret = ext2fs_adjust_ea_refcount2(fs,
> +-					block,
> +-					(char*)header,
> ++					node->block,
> ++					(char*)(node->header),
> + 					1,
> + 					&newcount))
> + 	{
> +@@ -371,6 +500,7 @@ set_inode_xattr (ext2_filsys fs, ext2_in
> + 	}
> + 	if (ret = ext2fs_write_inode (fs, ino, &inode))
> + 		com_err(__func__, ret, "ext2fs_write_inode: returned %d", ret);
> ++	return ret;
> + out:
> + 	xattr_free_node (node);
> + 	return ret;
> diff --git a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
> index 241a9bf..8756d76 100644
> --- a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
> +++ b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend
> @@ -8,4 +8,5 @@ SRC_URI += " \
>      file://lib-ext2fs-ext2_ext_attr.h-add-xattr-index.patch \
>      file://misc-xattr-create-xattr-block.patch \
>      file://misc-xattr-create-xattr-block-node.patch \
> +    file://misc-xattr-create-xattr-cache.patch \
>  "
> 



^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2015-06-10  6:03 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-06-07  0:36 [meta-selinux][RFC 00/10] Label file system in build Philip Tricca
2015-06-07  0:36 ` [meta-selinux][RFC 01/10] policycoreutils: Add FTS_NOCHDIR flag to fts_open Philip Tricca
2015-06-07  0:37 ` [meta-selinux][RFC 02/10] selinux-image: Add new image class to label the rootfs Philip Tricca
2015-06-07  0:37 ` [meta-selinux][RFC 03/10] e2fsprogs: Add bbappend and apply initial xattr patch Philip Tricca
2015-06-07  0:37 ` [meta-selinux][RFC 04/10] e2fsprogs: Add patch to build xattr code Philip Tricca
2015-06-07  0:37 ` [meta-selinux][RFC 05/10] e2fsprogs: Add patch make calls necessary to label file system root and do cleanup Philip Tricca
2015-06-07  0:37 ` [meta-selinux][RFC 06/10] e2fsprogs: Add patch to call xattr copy function in populate_fs Philip Tricca
2015-06-07  0:37 ` [meta-selinux][RFC 07/10] e2fsprogs: Add xattr security prefix data to lib/ext2fs/ext2_ext_attr.h Philip Tricca
2015-06-07  0:37 ` [meta-selinux][RFC 08/10] e2fsprogs: Add patch to copy xattr block from source file Philip Tricca
2015-06-07  0:37 ` [meta-selinux][RFC 09/10] e2fsprogs: Add patch to hold xattr header and block number in a structure for the cache Philip Tricca
2015-06-07  0:37 ` [meta-selinux][RFC 10/10] e2fsprogs: Add patch to implement simple linked list as cache for existing xattr blocks Philip Tricca
2015-06-10  6:03   ` Philip Tricca

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.