All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] mkfs.ubifs: cleanups + extended attribute support
@ 2015-11-12  9:31 Marc Kleine-Budde
  2015-11-12  9:31 ` [PATCH v2 1/5] mkfs.ubifs: change add_directory argument to 'existing' Marc Kleine-Budde
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Marc Kleine-Budde @ 2015-11-12  9:31 UTC (permalink / raw)
  To: linux-mtd; +Cc: kernel

Hello,

this series applies to current git master. The first 3 patches are cleanup
patches, in the 4th adds extended attributes support. Patch 5 adds a option to
write the used inode number to an extended attribute, so that other offline
tools like IMA, that process the inode number can work. See description of
patch 5 for a detailed explanation.

regards,
Marc

changes since v1:
- add Daniel Walter's reviewed by to patches 1-3
- add option to build without xattr support - patches 4,5 (as Daniel suggested)
- switch from dynamically allocated attr value buffer to fixed size array on stack,
  as inode numbers where not stable between mkfs.ubifs invocations - patch 4

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

* [PATCH v2 1/5] mkfs.ubifs: change add_directory argument to 'existing'
  2015-11-12  9:31 [PATCH v2 0/5] mkfs.ubifs: cleanups + extended attribute support Marc Kleine-Budde
@ 2015-11-12  9:31 ` Marc Kleine-Budde
  2015-11-12  9:31 ` [PATCH v2 2/5] mkfs.ubifs: use xmalloc/xzalloc for allocating memory Marc Kleine-Budde
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Marc Kleine-Budde @ 2015-11-12  9:31 UTC (permalink / raw)
  To: linux-mtd; +Cc: kernel, Sascha Hauer, Marc Kleine-Budde

From: Sascha Hauer <s.hauer@pengutronix.de>

A 'non_existing' argument which is only used with !non_existing
is just too confusing. Change this to positive logic.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Daniel Walter <dwalter@sigma-star.at>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index ca17e2bca3ac..1b816ae483e0 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -1395,12 +1395,12 @@ static int add_non_dir(const char *path_name, ino_t *inum, unsigned int nlink,
  * @dir_name: directory path name
  * @dir_inum: UBIFS inode number of directory
  * @st: directory inode statistics
- * @non_existing: non-zero if this function is called for a directory which
- *                does not exist on the host file-system and it is being
- *                created because it is defined in the device table file.
+ * @existing: zero if this function is called for a directory which
+ *            does not exist on the host file-system and it is being
+ *            created because it is defined in the device table file.
  */
 static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
-			 int non_existing)
+			 int existing)
 {
 	struct dirent *entry;
 	DIR *dir = NULL;
@@ -1416,7 +1416,7 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 	unsigned long long dir_creat_sqnum = ++c->max_sqnum;
 
 	dbg_msg(2, "%s", dir_name);
-	if (!non_existing) {
+	if (existing) {
 		dir = opendir(dir_name);
 		if (dir == NULL)
 			return sys_err_msg("cannot open directory '%s'",
@@ -1434,7 +1434,7 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 	 * Before adding the directory itself, we have to iterate over all the
 	 * entries the device table adds to this directory and create them.
 	 */
-	for (; !non_existing;) {
+	for (; existing;) {
 		struct stat dent_st;
 
 		errno = 0;
@@ -1492,7 +1492,7 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 		inum = ++c->highest_inum;
 
 		if (S_ISDIR(dent_st.st_mode)) {
-			err = add_directory(name, inum, &dent_st, 0);
+			err = add_directory(name, inum, &dent_st, 1);
 			if (err)
 				goto out_free;
 			nlink += 1;
@@ -1544,7 +1544,7 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 		inum = ++c->highest_inum;
 
 		if (S_ISDIR(nh_elt->mode)) {
-			err = add_directory(name, inum, &fake_st, 1);
+			err = add_directory(name, inum, &fake_st, 0);
 			if (err)
 				goto out_free;
 			nlink += 1;
@@ -1570,14 +1570,14 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 		goto out_free;
 
 	free(name);
-	if (!non_existing && closedir(dir) == -1)
+	if (existing && closedir(dir) == -1)
 		return sys_err_msg("error closing directory '%s'", dir_name);
 
 	return 0;
 
 out_free:
 	free(name);
-	if (!non_existing)
+	if (existing)
 		closedir(dir);
 	return -1;
 }
@@ -1624,7 +1624,7 @@ static int write_data(void)
 	}
 
 	head_flags = 0;
-	err = add_directory(root, UBIFS_ROOT_INO, &root_st, !root);
+	err = add_directory(root, UBIFS_ROOT_INO, &root_st, !!root);
 	if (err)
 		return err;
 	err = add_multi_linked_files();
-- 
2.6.1

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

* [PATCH v2 2/5] mkfs.ubifs: use xmalloc/xzalloc for allocating memory
  2015-11-12  9:31 [PATCH v2 0/5] mkfs.ubifs: cleanups + extended attribute support Marc Kleine-Budde
  2015-11-12  9:31 ` [PATCH v2 1/5] mkfs.ubifs: change add_directory argument to 'existing' Marc Kleine-Budde
@ 2015-11-12  9:31 ` Marc Kleine-Budde
  2015-11-12  9:31 ` [PATCH v2 3/5] mkfs.ubifs: simplify make_path with xasprintf Marc Kleine-Budde
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Marc Kleine-Budde @ 2015-11-12  9:31 UTC (permalink / raw)
  To: linux-mtd; +Cc: kernel, Sascha Hauer, Marc Kleine-Budde

From: Sascha Hauer <s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Daniel Walter <dwalter@sigma-star.at>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 64 ++++++++-----------------------------
 1 file changed, 14 insertions(+), 50 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 1b816ae483e0..049219b52cc5 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -259,13 +259,8 @@ static int is_contained(const char *file, const char *dir)
 	file_base = dirname(copy);
 
 	/* Turn the paths into the canonical form */
-	real_file = malloc(PATH_MAX);
-	if (!real_file)
-		goto out_free;
-
-	real_dir = malloc(PATH_MAX);
-	if (!real_dir)
-		goto out_free;
+	real_file = xmalloc(PATH_MAX);
+	real_dir = xmalloc(PATH_MAX);
 
 	if (!realpath(file_base, real_file)) {
 		perror("Could not canonicalize file path");
@@ -500,9 +495,7 @@ static int get_options(int argc, char**argv)
 		case 'r':
 		case 'd':
 			root_len = strlen(optarg);
-			root = malloc(root_len + 2);
-			if (!root)
-				return err_msg("cannot allocate memory");
+			root = xmalloc(root_len + 2);
 
 			/*
 			 * The further code expects '/' at the end of the root
@@ -910,9 +903,7 @@ static int add_to_index(union ubifs_key *key, char *name, int lnum, int offs,
 	struct idx_entry *e;
 
 	dbg_msg(3, "LEB %d offs %d len %d", lnum, offs, len);
-	e = malloc(sizeof(struct idx_entry));
-	if (!e)
-		return err_msg("out of memory");
+	e = xmalloc(sizeof(struct idx_entry));
 	e->next = NULL;
 	e->prev = idx_list_last;
 	e->key = *key;
@@ -1193,9 +1184,7 @@ static struct inum_mapping *lookup_inum_mapping(dev_t dev, ino_t inum)
 			return im;
 		im = im->next;
 	}
-	im = malloc(sizeof(struct inum_mapping));
-	if (!im)
-		return NULL;
+	im = xmalloc(sizeof(struct inum_mapping));
 	im->next = hash_table[k];
 	im->prev = NULL;
 	im->dev = dev;
@@ -1355,9 +1344,7 @@ static int add_non_dir(const char *path_name, ino_t *inum, unsigned int nlink,
 			/* New entry */
 			im->use_inum = *inum;
 			im->use_nlink = 1;
-			im->path_name = malloc(strlen(path_name) + 1);
-			if (!im->path_name)
-				return err_msg("out of memory");
+			im->path_name = xmalloc(strlen(path_name) + 1);
 			strcpy(im->path_name, path_name);
 		} else {
 			/* Existing entry */
@@ -1707,21 +1694,14 @@ static int write_index(void)
 	head_flags = LPROPS_INDEX;
 	/* Allocate index node */
 	idx_sz = ubifs_idx_node_sz(c, c->fanout);
-	idx = malloc(idx_sz);
-	if (!idx)
-		return err_msg("out of memory");
+	idx = xmalloc(idx_sz);
 	/* Make an array of pointers to sort the index list */
 	sz = idx_cnt * sizeof(struct idx_entry *);
 	if (sz / sizeof(struct idx_entry *) != idx_cnt) {
 		free(idx);
 		return err_msg("index is too big (%zu entries)", idx_cnt);
 	}
-	idx_ptr = malloc(sz);
-	if (!idx_ptr) {
-		free(idx);
-		return err_msg("out of memory - needed %zu bytes for index",
-			       sz);
-	}
+	idx_ptr = xmalloc(sz);
 	idx_ptr[0] = idx_list_first;
 	for (i = 1; i < idx_cnt; i++)
 		idx_ptr[i] = idx_ptr[i - 1]->next;
@@ -2164,13 +2144,8 @@ static int init(void)
 	c->lpt_first = UBIFS_LOG_LNUM + c->log_lebs;
 	c->lpt_last = c->lpt_first + c->lpt_lebs - 1;
 
-	c->lpt = malloc(c->main_lebs * sizeof(struct ubifs_lprops));
-	if (!c->lpt)
-		return err_msg("unable to allocate LPT");
-
-	c->ltab = malloc(c->lpt_lebs * sizeof(struct ubifs_lprops));
-	if (!c->ltab)
-		return err_msg("unable to allocate LPT ltab");
+	c->lpt = xmalloc(c->main_lebs * sizeof(struct ubifs_lprops));
+	c->ltab = xmalloc(c->lpt_lebs * sizeof(struct ubifs_lprops));
 
 	/* Initialize LPT's own lprops */
 	for (i = 0; i < c->lpt_lebs; i++) {
@@ -2182,23 +2157,12 @@ static int init(void)
 	c->dark_wm = ALIGN(UBIFS_MAX_NODE_SZ, c->min_io_size);
 	dbg_msg(1, "dead_wm %d  dark_wm %d", c->dead_wm, c->dark_wm);
 
-	leb_buf = malloc(c->leb_size);
-	if (!leb_buf)
-		return err_msg("out of memory");
-
-	node_buf = malloc(NODE_BUFFER_SIZE);
-	if (!node_buf)
-		return err_msg("out of memory");
-
-	block_buf = malloc(UBIFS_BLOCK_SIZE);
-	if (!block_buf)
-		return err_msg("out of memory");
+	leb_buf = xmalloc(c->leb_size);
+	node_buf = xmalloc(NODE_BUFFER_SIZE);
+	block_buf = xmalloc(UBIFS_BLOCK_SIZE);
 
 	sz = sizeof(struct inum_mapping *) * HASH_TABLE_SIZE;
-	hash_table = malloc(sz);
-	if (!hash_table)
-		return err_msg("out of memory");
-	memset(hash_table, 0, sz);
+	hash_table = xzalloc(sz);
 
 	err = init_compression();
 	if (err)
-- 
2.6.1

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

* [PATCH v2 3/5] mkfs.ubifs: simplify make_path with xasprintf
  2015-11-12  9:31 [PATCH v2 0/5] mkfs.ubifs: cleanups + extended attribute support Marc Kleine-Budde
  2015-11-12  9:31 ` [PATCH v2 1/5] mkfs.ubifs: change add_directory argument to 'existing' Marc Kleine-Budde
  2015-11-12  9:31 ` [PATCH v2 2/5] mkfs.ubifs: use xmalloc/xzalloc for allocating memory Marc Kleine-Budde
@ 2015-11-12  9:31 ` Marc Kleine-Budde
  2015-11-12  9:31 ` [PATCH v2 4/5] mkfs.ubifs: Add extended attribute support Marc Kleine-Budde
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Marc Kleine-Budde @ 2015-11-12  9:31 UTC (permalink / raw)
  To: linux-mtd; +Cc: kernel, Sascha Hauer, Marc Kleine-Budde

From: Sascha Hauer <s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Daniel Walter <dwalter@sigma-star.at>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 049219b52cc5..a99c61382304 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -227,13 +227,9 @@ static char *make_path(const char *dir, const char *name)
 {
 	char *s;
 
-	s = malloc(strlen(dir) + strlen(name) + 2);
-	if (!s)
-		return NULL;
-	strcpy(s, dir);
-	if (dir[strlen(dir) - 1] != '/')
-		strcat(s, "/");
-	strcat(s, name);
+	xasprintf(&s, "%s%s%s",
+		  dir, dir[strlen(dir) - 1] == '/' ? "" : "/", name);
+
 	return s;
 }
 
-- 
2.6.1

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

* [PATCH v2 4/5] mkfs.ubifs: Add extended attribute support
  2015-11-12  9:31 [PATCH v2 0/5] mkfs.ubifs: cleanups + extended attribute support Marc Kleine-Budde
                   ` (2 preceding siblings ...)
  2015-11-12  9:31 ` [PATCH v2 3/5] mkfs.ubifs: simplify make_path with xasprintf Marc Kleine-Budde
@ 2015-11-12  9:31 ` Marc Kleine-Budde
  2015-11-12  9:31 ` [PATCH v2 5/5] mkfs.ubifs: Optionally create extended attribute with inode number Marc Kleine-Budde
  2015-11-12  9:53 ` [PATCH v2 0/5] mkfs.ubifs: cleanups + extended attribute support Richard Weinberger
  5 siblings, 0 replies; 9+ messages in thread
From: Marc Kleine-Budde @ 2015-11-12  9:31 UTC (permalink / raw)
  To: linux-mtd; +Cc: kernel, Sascha Hauer, Marc Kleine-Budde

From: Sascha Hauer <s.hauer@pengutronix.de>

This adds extended attribute support to mkfs.ubifs. When creating
an image from a directory tree the existing extended attributes are
added to the UBIFS image.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 ubifs-utils/mkfs.ubifs/key.h        |  18 ++++
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 205 +++++++++++++++++++++++++++++++-----
 ubifs-utils/mkfs.ubifs/ubifs.h      |   9 ++
 3 files changed, 205 insertions(+), 27 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/key.h b/ubifs-utils/mkfs.ubifs/key.h
index d3a02d4ff1a6..39379fd48178 100644
--- a/ubifs-utils/mkfs.ubifs/key.h
+++ b/ubifs-utils/mkfs.ubifs/key.h
@@ -119,6 +119,24 @@ static inline void dent_key_init(const struct ubifs_info *c,
 }
 
 /**
+ * xent_key_init - initialize extended attribute entry key.
+ * @c: UBIFS file-system description object
+ * @key: key to initialize
+ * @inum: host inode number
+ * @nm: extended attribute entry name and length
+ */
+static inline void xent_key_init(const struct ubifs_info *c,
+				 union ubifs_key *key, ino_t inum,
+				 const struct qstr *nm)
+{
+	uint32_t hash = c->key_hash(nm->name, nm->len);
+
+	ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
+	key->u32[0] = inum;
+	key->u32[1] = hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS);
+}
+
+/**
  * data_key_init - initialize data key.
  * @c: UBIFS file-system description object
  * @key: key to initialize
diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index a99c61382304..30cd10c25819 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -25,6 +25,10 @@
 #include "mkfs.ubifs.h"
 #include <crc32.h>
 #include "common.h"
+#include <sys/types.h>
+#ifndef WITHOUT_XATTR
+#include <attr/xattr.h>
+#endif
 
 /* Size (prime number) of hash table for link counting */
 #define HASH_TABLE_SIZE 10099
@@ -980,20 +984,170 @@ static int add_node(union ubifs_key *key, char *name, void *node, int len)
 	return 0;
 }
 
+#ifdef WITHOUT_XATTR
+static inline int inode_add_xattr(struct ubifs_ino_node *host_ino,
+				  const char *path_name, struct stat *st, ino_t inum)
+{
+	(void)host_ino;
+	(void)path_name;
+	(void)st;
+	(void)inum;
+
+	return 0;
+}
+#else
+static int add_xattr(struct stat *st, ino_t inum, const void *data,
+		     unsigned int data_len, struct qstr *nm)
+{
+	struct ubifs_ino_node *ino;
+	struct ubifs_dent_node *xent;
+	union ubifs_key xkey, nkey;
+	int len, ret;
+
+	xent = xzalloc(sizeof(*xent) + nm->len + 1);
+	ino = xzalloc(sizeof(*ino) + data_len);
+
+	xent_key_init(c, &xkey, inum, nm);
+	xent->ch.node_type = UBIFS_XENT_NODE;
+	key_write(&xkey, &xent->key);
+
+	len = UBIFS_XENT_NODE_SZ + nm->len + 1;
+
+	xent->ch.len = len;
+	xent->padding1 = 0;
+	xent->type = UBIFS_ITYPE_DIR;
+	xent->nlen = cpu_to_le16(nm->len);
+
+	memcpy(xent->name, nm->name, nm->len + 1);
+
+	inum = ++c->highest_inum;
+	creat_sqnum = ++c->max_sqnum;
+
+	xent->inum = cpu_to_le64(inum);
+
+	ret = add_node(&xkey, nm->name, xent, len);
+	if (ret)
+		goto out;
+
+	ino->creat_sqnum = cpu_to_le64(creat_sqnum);
+	ino->nlink      = cpu_to_le32(st->st_nlink);
+	/*
+	 * The time fields are updated assuming the default time granularity
+	 * of 1 second. To support finer granularities, utime() would be needed.
+	 */
+	ino->atime_sec  = cpu_to_le64(st->st_atime);
+	ino->ctime_sec  = cpu_to_le64(st->st_ctime);
+	ino->mtime_sec  = cpu_to_le64(st->st_mtime);
+	ino->atime_nsec = 0;
+	ino->ctime_nsec = 0;
+	ino->mtime_nsec = 0;
+	ino->uid        = cpu_to_le32(st->st_uid);
+	ino->gid        = cpu_to_le32(st->st_gid);
+	ino->compr_type = cpu_to_le16(c->default_compr);
+	ino->ch.node_type = UBIFS_INO_NODE;
+
+	ino_key_init(&nkey, inum);
+	key_write(&nkey, &ino->key);
+
+	ino->size       = cpu_to_le64(data_len);
+	ino->mode       = cpu_to_le32(S_IFREG);
+	ino->data_len   = cpu_to_le32(data_len);
+	ino->flags      = cpu_to_le32(UBIFS_XATTR_FL);
+
+	if (data_len)
+		memcpy(&ino->data, data, data_len);
+
+	ret = add_node(&nkey, nm->name, ino, UBIFS_INO_NODE_SZ + data_len) ;
+
+out:
+	free(xent);
+	free(ino);
+
+	return ret;
+}
+
+static int inode_add_xattr(struct ubifs_ino_node *host_ino,
+			   const char *path_name, struct stat *st, ino_t inum)
+{
+	int ret;
+	struct qstr nm;
+	void *buf = NULL;
+	ssize_t len;
+	ssize_t pos = 0;
+
+	len = llistxattr(path_name, NULL, 0);
+	if (len < 0) {
+		if (errno == ENOENT)
+			return 0;
+
+		sys_err_msg("llistxattr failed on %s", path_name);
+
+		return len;
+	}
+
+	if (len == 0)
+		goto noxattr;
+
+	buf = xmalloc(len);
+
+	len = llistxattr(path_name, buf, len);
+	if (len < 0) {
+		sys_err_msg("llistxattr failed on %s", path_name);
+		goto out_free;
+	}
+
+	while (pos < len) {
+		char attrbuf[1024] = { };
+		char *name;
+		ssize_t attrsize;
+
+		name = buf + pos;
+		pos += strlen(name) + 1;
+
+		attrsize = lgetxattr(path_name, name, attrbuf, sizeof(attrbuf) - 1);
+		if (attrsize < 0) {
+			sys_err_msg("lgetxattr failed on %s", path_name);
+			goto out_free;
+		}
+
+		nm.name = name;
+		nm.len = strlen(name);
+
+		host_ino->xattr_cnt++;
+		host_ino->xattr_size += CALC_DENT_SIZE(nm.len);
+		host_ino->xattr_size += CALC_XATTR_BYTES(attrsize);
+		host_ino->xattr_names += nm.len;
+
+		ret = add_xattr(st, inum, attrbuf, attrsize, &nm);
+		if (ret < 0)
+			goto out_free;
+	}
+
+noxattr:
+	free(buf);
+	return 0;
+
+out_free:
+	free(buf);
+
+	return -1;
+}
+#endif
+
 /**
- * add_inode_with_data - write an inode.
+ * add_inode - write an inode.
  * @st: stat information of source inode
  * @inum: target inode number
  * @data: inode data (for special inodes e.g. symlink path etc)
  * @data_len: inode data length
  * @flags: source inode flags
  */
-static int add_inode_with_data(struct stat *st, ino_t inum, void *data,
-			       unsigned int data_len, int flags)
+static int add_inode(struct stat *st, ino_t inum, void *data,
+		     unsigned int data_len, int flags, const char *xattr_path)
 {
 	struct ubifs_ino_node *ino = node_buf;
 	union ubifs_key key;
-	int len, use_flags = 0;
+	int len, use_flags = 0, ret;
 
 	if (c->default_compr != UBIFS_COMPR_NONE)
 		use_flags |= UBIFS_COMPR_FL;
@@ -1037,18 +1191,13 @@ static int add_inode_with_data(struct stat *st, ino_t inum, void *data,
 
 	len = UBIFS_INO_NODE_SZ + data_len;
 
-	return add_node(&key, NULL, ino, len);
-}
+	if (xattr_path) {
+		ret = inode_add_xattr(ino, xattr_path, st, inum);
+		if (ret < 0)
+			return ret;
+	}
 
-/**
- * add_inode - write an inode.
- * @st: stat information of source inode
- * @inum: target inode number
- * @flags: source inode flags
- */
-static int add_inode(struct stat *st, ino_t inum, int flags)
-{
-	return add_inode_with_data(st, inum, NULL, 0, flags);
+	return add_node(&key, NULL, ino, len);
 }
 
 /**
@@ -1064,8 +1213,8 @@ static int add_inode(struct stat *st, ino_t inum, int flags)
  * is being created does not exist at the host file system, but is defined by
  * the device table.
  */
-static int add_dir_inode(DIR *dir, ino_t inum, loff_t size, unsigned int nlink,
-			 struct stat *st)
+static int add_dir_inode(const char *path_name, DIR *dir, ino_t inum, loff_t size,
+			 unsigned int nlink, struct stat *st)
 {
 	int fd, flags = 0;
 
@@ -1080,7 +1229,7 @@ static int add_dir_inode(DIR *dir, ino_t inum, loff_t size, unsigned int nlink,
 			flags = 0;
 	}
 
-	return add_inode(st, inum, flags);
+	return add_inode(st, inum, NULL, 0, flags, path_name);
 }
 
 /**
@@ -1089,12 +1238,12 @@ static int add_dir_inode(DIR *dir, ino_t inum, loff_t size, unsigned int nlink,
  * @inum: target inode number
  * @flags: source inode flags
  */
-static int add_dev_inode(struct stat *st, ino_t inum, int flags)
+static int add_dev_inode(const char *path_name, struct stat *st, ino_t inum, int flags)
 {
 	union ubifs_dev_desc dev;
 
 	dev.huge = cpu_to_le64(makedev(major(st->st_rdev), minor(st->st_rdev)));
-	return add_inode_with_data(st, inum, &dev, 8, flags);
+	return add_inode(st, inum, &dev, 8, flags, path_name);
 }
 
 /**
@@ -1117,7 +1266,7 @@ static int add_symlink_inode(const char *path_name, struct stat *st, ino_t inum,
 	if (len > UBIFS_MAX_INO_DATA)
 		return err_msg("symlink too long for %s", path_name);
 
-	return add_inode_with_data(st, inum, buf, len, flags);
+	return add_inode(st, inum, buf, len, flags, path_name);
 }
 
 /**
@@ -1275,12 +1424,14 @@ static int add_file(const char *path_name, struct stat *st, ino_t inum,
 			return err;
 		}
 	} while (ret != 0);
+
 	if (close(fd) == -1)
 		return sys_err_msg("failed to close file '%s'", path_name);
 	if (file_size != st->st_size)
 		return err_msg("file size changed during writing file '%s'",
 			       path_name);
-	return add_inode(st, inum, flags);
+
+	return add_inode(st, inum, NULL, 0, flags, path_name);
 }
 
 /**
@@ -1360,15 +1511,15 @@ static int add_non_dir(const char *path_name, ino_t *inum, unsigned int nlink,
 	if (S_ISREG(st->st_mode))
 		return add_file(path_name, st, *inum, flags);
 	if (S_ISCHR(st->st_mode))
-		return add_dev_inode(st, *inum, flags);
+		return add_dev_inode(path_name, st, *inum, flags);
 	if (S_ISBLK(st->st_mode))
-		return add_dev_inode(st, *inum, flags);
+		return add_dev_inode(path_name, st, *inum, flags);
 	if (S_ISLNK(st->st_mode))
 		return add_symlink_inode(path_name, st, *inum, flags);
 	if (S_ISSOCK(st->st_mode))
-		return add_inode(st, *inum, flags);
+		return add_inode(st, *inum, NULL, 0, flags, NULL);
 	if (S_ISFIFO(st->st_mode))
-		return add_inode(st, *inum, flags);
+		return add_inode(st, *inum, NULL, 0, flags, NULL);
 
 	return err_msg("file '%s' has unknown inode type", path_name);
 }
@@ -1548,7 +1699,7 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 
 	creat_sqnum = dir_creat_sqnum;
 
-	err = add_dir_inode(dir, dir_inum, size, nlink, st);
+	err = add_dir_inode(dir ? dir_name : NULL, dir, dir_inum, size, nlink, st);
 	if (err)
 		goto out_free;
 
diff --git a/ubifs-utils/mkfs.ubifs/ubifs.h b/ubifs-utils/mkfs.ubifs/ubifs.h
index 434b651859b3..2f080a8ce708 100644
--- a/ubifs-utils/mkfs.ubifs/ubifs.h
+++ b/ubifs-utils/mkfs.ubifs/ubifs.h
@@ -42,6 +42,15 @@
  */
 #define UBIFS_TRUN_KEY UBIFS_KEY_TYPES_CNT
 
+/*
+ * How much a directory entry/extended attribute entry adds to the parent/host
+ * inode.
+ */
+#define CALC_DENT_SIZE(name_len) ALIGN(UBIFS_DENT_NODE_SZ + (name_len) + 1, 8)
+
+/* How much an extended attribute adds to the host inode */
+#define CALC_XATTR_BYTES(data_len) ALIGN(UBIFS_INO_NODE_SZ + (data_len) + 1, 8)
+
 /* The below union makes it easier to deal with keys */
 union ubifs_key
 {
-- 
2.6.1

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

* [PATCH v2 5/5] mkfs.ubifs: Optionally create extended attribute with inode number
  2015-11-12  9:31 [PATCH v2 0/5] mkfs.ubifs: cleanups + extended attribute support Marc Kleine-Budde
                   ` (3 preceding siblings ...)
  2015-11-12  9:31 ` [PATCH v2 4/5] mkfs.ubifs: Add extended attribute support Marc Kleine-Budde
@ 2015-11-12  9:31 ` Marc Kleine-Budde
  2015-11-12  9:53 ` [PATCH v2 0/5] mkfs.ubifs: cleanups + extended attribute support Richard Weinberger
  5 siblings, 0 replies; 9+ messages in thread
From: Marc Kleine-Budde @ 2015-11-12  9:31 UTC (permalink / raw)
  To: linux-mtd; +Cc: kernel, Sascha Hauer, Marc Kleine-Budde

From: Sascha Hauer <s.hauer@pengutronix.de>

This is done to allow creating images suitable for IMA directory
appraisal. IMA creates a hash for directories and attaches this
hash to the directory itself as an extended attribute. Among other
things the inode numbers of the files are hashed. So, to create
a valid hash in the UBIFS image the evmctl tool needs to know
the inode numbers which the files in the UBIFS image will have.
evmctl will read the inode numbers from the user.image-inode-number
extended attribute. Since extended attributes are inodes themselves
the inode numbers for the generated image will change when the
extended attributes change, so to generate a correctly hashed
UBIFS image, both evmctl and mkfs.ubifs must be run twice:

1) execute evmctl to iterate over the directory tree. This will
   create the security.ima and security.evm extended attributes.
   The existence of the attributes makes sure that subsequent
   calls to mkfs.ubifs will use the same inode numbers. evmctl
   will use the inode numbers from the host filesystem in this
   step which makes the resulting image unusable
2) execute mkfs.ubifs -a. This will create the user.image-inode-number
   extended attributes on files/directories added to the image.
3) execture evmctl again. This time evmctl will pick the inode
   numbers from the user.image-inode-number extended attribute
   instead of the ones from the host filesystem
4) execute mkfs.ubifs again. This will create the correct image.
   The now existing user.image-inode-number extended attributes
   are ignored and not added to the image.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 69 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 68 insertions(+), 1 deletion(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 30cd10c25819..58200dea9732 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -115,6 +115,7 @@ static char *output;
 static int out_fd;
 static int out_ubi;
 static int squash_owner;
+static int do_create_inum_attr;
 
 /* The 'head' (position) which nodes are written */
 static int head_lnum;
@@ -137,7 +138,7 @@ static struct inum_mapping **hash_table;
 /* Inode creation sequence number */
 static unsigned long long creat_sqnum;
 
-static const char *optstring = "d:r:m:o:D:yh?vVe:c:g:f:Fp:k:x:X:j:R:l:j:UQq";
+static const char *optstring = "d:r:m:o:D:yh?vVe:c:g:f:Fp:k:x:X:j:R:l:j:UQqa";
 
 static const struct option longopts[] = {
 	{"root",               1, NULL, 'r'},
@@ -161,6 +162,7 @@ static const struct option longopts[] = {
 	{"log-lebs",           1, NULL, 'l'},
 	{"orph-lebs",          1, NULL, 'p'},
 	{"squash-uids" ,       0, NULL, 'U'},
+	{"set-inode-attr",     0, NULL, 'a'},
 	{NULL, 0, NULL, 0}
 };
 
@@ -201,6 +203,9 @@ static const char *helptext =
 "-V, --version            display version information\n"
 "-g, --debug=LEVEL        display debug information (0 - none, 1 - statistics,\n"
 "                         2 - files, 3 - more details)\n"
+"-a, --set-inum-attr      create user.image-inode-number extended attribute on files\n"
+"                         added to the image. The attribute will contain the inode\n"
+"                         number the file has in the generated image.\n"
 "-h, --help               display this help text\n\n"
 "Note, SIZE is specified in bytes, but it may also be specified in Kilobytes,\n"
 "Megabytes, and Gigabytes if a KiB, MiB, or GiB suffix is used.\n\n"
@@ -616,6 +621,10 @@ static int get_options(int argc, char**argv)
 		case 'U':
 			squash_owner = 1;
 			break;
+		case 'a':
+			do_create_inum_attr = 1;
+			break;
+
 		}
 	}
 
@@ -985,6 +994,14 @@ static int add_node(union ubifs_key *key, char *name, void *node, int len)
 }
 
 #ifdef WITHOUT_XATTR
+static inline int create_inum_attr(ino_t inum, const char *name)
+{
+	(void)inum;
+	(void)name;
+
+	return 0;
+}
+
 static inline int inode_add_xattr(struct ubifs_ino_node *host_ino,
 				  const char *path_name, struct stat *st, ino_t inum)
 {
@@ -996,6 +1013,26 @@ static inline int inode_add_xattr(struct ubifs_ino_node *host_ino,
 	return 0;
 }
 #else
+static int create_inum_attr(ino_t inum, const char *name)
+{
+	char *str;
+	int ret;
+
+	if (!do_create_inum_attr)
+		return 0;
+
+	ret = asprintf(&str, "%llu", (unsigned long long)inum);
+	if (ret < 0)
+		return -1;
+
+	ret = lsetxattr(name, "user.image-inode-number", str, ret, 0);
+
+	free(str);
+
+	return ret;
+}
+
+
 static int add_xattr(struct stat *st, ino_t inum, const void *data,
 		     unsigned int data_len, struct qstr *nm)
 {
@@ -1110,6 +1147,23 @@ static int inode_add_xattr(struct ubifs_ino_node *host_ino,
 			goto out_free;
 		}
 
+		if (!strcmp(name, "user.image-inode-number")) {
+			ino_t inum_from_xattr;
+
+			inum_from_xattr = strtoull(attrbuf, NULL, 10);
+			if (inum != inum_from_xattr) {
+				errno = EINVAL;
+				sys_err_msg("calculated inum (%llu) doesn't match inum from xattr (%llu) size (%zd) on %s",
+					    (unsigned long long)inum,
+					    (unsigned long long)inum_from_xattr,
+					    attrsize,
+					    path_name);
+				goto out_free;
+			}
+
+			continue;
+		}
+
 		nm.name = name;
 		nm.len = strlen(name);
 
@@ -1637,6 +1691,10 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 				goto out_free;
 		}
 
+		err = create_inum_attr(inum, name);
+		if (err)
+			goto out_free;
+
 		err = add_dent_node(dir_inum, entry->d_name, inum, type);
 		if (err)
 			goto out_free;
@@ -1689,6 +1747,10 @@ static int add_directory(const char *dir_name, ino_t dir_inum, struct stat *st,
 				goto out_free;
 		}
 
+		err = create_inum_attr(inum, name);
+		if (err)
+			goto out_free;
+
 		err = add_dent_node(dir_inum, nh_elt->name, inum, type);
 		if (err)
 			goto out_free;
@@ -1758,6 +1820,11 @@ static int write_data(void)
 	}
 
 	head_flags = 0;
+
+	err = create_inum_attr(UBIFS_ROOT_INO, root);
+	if (err)
+		return err;
+
 	err = add_directory(root, UBIFS_ROOT_INO, &root_st, !!root);
 	if (err)
 		return err;
-- 
2.6.1

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

* Re: [PATCH v2 0/5] mkfs.ubifs: cleanups + extended attribute support
  2015-11-12  9:31 [PATCH v2 0/5] mkfs.ubifs: cleanups + extended attribute support Marc Kleine-Budde
                   ` (4 preceding siblings ...)
  2015-11-12  9:31 ` [PATCH v2 5/5] mkfs.ubifs: Optionally create extended attribute with inode number Marc Kleine-Budde
@ 2015-11-12  9:53 ` Richard Weinberger
  2015-11-12  9:56   ` Marc Kleine-Budde
  5 siblings, 1 reply; 9+ messages in thread
From: Richard Weinberger @ 2015-11-12  9:53 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: linux-mtd, kernel

On Thu, Nov 12, 2015 at 10:31 AM, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
> Hello,
>
> this series applies to current git master. The first 3 patches are cleanup
> patches, in the 4th adds extended attributes support. Patch 5 adds a option to
> write the used inode number to an extended attribute, so that other offline
> tools like IMA, that process the inode number can work. See description of
> patch 5 for a detailed explanation.
>
> regards,
> Marc
>
> changes since v1:
> - add Daniel Walter's reviewed by to patches 1-3
> - add option to build without xattr support - patches 4,5 (as Daniel suggested)
> - switch from dynamically allocated attr value buffer to fixed size array on stack,
>   as inode numbers where not stable between mkfs.ubifs invocations - patch 4

Applied and pushed.
And bonus points for rebasing to the latest mtd-utils tree! :-)

-- 
Thanks,
//richard

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

* Re: [PATCH v2 0/5] mkfs.ubifs: cleanups + extended attribute support
  2015-11-12  9:53 ` [PATCH v2 0/5] mkfs.ubifs: cleanups + extended attribute support Richard Weinberger
@ 2015-11-12  9:56   ` Marc Kleine-Budde
  2015-11-12 18:40     ` Brian Norris
  0 siblings, 1 reply; 9+ messages in thread
From: Marc Kleine-Budde @ 2015-11-12  9:56 UTC (permalink / raw)
  To: Richard Weinberger; +Cc: linux-mtd, kernel

[-- Attachment #1: Type: text/plain, Size: 1422 bytes --]

On 11/12/2015 10:53 AM, Richard Weinberger wrote:
> On Thu, Nov 12, 2015 at 10:31 AM, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
>> Hello,
>>
>> this series applies to current git master. The first 3 patches are cleanup
>> patches, in the 4th adds extended attributes support. Patch 5 adds a option to
>> write the used inode number to an extended attribute, so that other offline
>> tools like IMA, that process the inode number can work. See description of
>> patch 5 for a detailed explanation.
>>
>> regards,
>> Marc
>>
>> changes since v1:
>> - add Daniel Walter's reviewed by to patches 1-3
>> - add option to build without xattr support - patches 4,5 (as Daniel suggested)
>> - switch from dynamically allocated attr value buffer to fixed size array on stack,
>>   as inode numbers where not stable between mkfs.ubifs invocations - patch 4
> 
> Applied and pushed.

Thanks.

> And bonus points for rebasing to the latest mtd-utils tree! :-)

I've to pass at least half of the bonus points to the git developers, as
git detected and handled the tree restructuring without any manual
interaction. \o/

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

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

* Re: [PATCH v2 0/5] mkfs.ubifs: cleanups + extended attribute support
  2015-11-12  9:56   ` Marc Kleine-Budde
@ 2015-11-12 18:40     ` Brian Norris
  0 siblings, 0 replies; 9+ messages in thread
From: Brian Norris @ 2015-11-12 18:40 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: Richard Weinberger, linux-mtd, kernel

On Thu, Nov 12, 2015 at 10:56:23AM +0100, Marc Kleine-Budde wrote:
> On 11/12/2015 10:53 AM, Richard Weinberger wrote:
> > And bonus points for rebasing to the latest mtd-utils tree! :-)
> 
> I've to pass at least half of the bonus points to the git developers, as
> git detected and handled the tree restructuring without any manual
> interaction. \o/

+1

I'll also take this time to confess that for the longest time, I didn't
have am.threeWay set in my .gitconfig. That really helps as a maintainer
for applying patches that *aren't* quite rebased to the latest tree.

Brian

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

end of thread, other threads:[~2015-11-12 18:40 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-12  9:31 [PATCH v2 0/5] mkfs.ubifs: cleanups + extended attribute support Marc Kleine-Budde
2015-11-12  9:31 ` [PATCH v2 1/5] mkfs.ubifs: change add_directory argument to 'existing' Marc Kleine-Budde
2015-11-12  9:31 ` [PATCH v2 2/5] mkfs.ubifs: use xmalloc/xzalloc for allocating memory Marc Kleine-Budde
2015-11-12  9:31 ` [PATCH v2 3/5] mkfs.ubifs: simplify make_path with xasprintf Marc Kleine-Budde
2015-11-12  9:31 ` [PATCH v2 4/5] mkfs.ubifs: Add extended attribute support Marc Kleine-Budde
2015-11-12  9:31 ` [PATCH v2 5/5] mkfs.ubifs: Optionally create extended attribute with inode number Marc Kleine-Budde
2015-11-12  9:53 ` [PATCH v2 0/5] mkfs.ubifs: cleanups + extended attribute support Richard Weinberger
2015-11-12  9:56   ` Marc Kleine-Budde
2015-11-12 18:40     ` Brian Norris

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.