[coreboot-gerrit] Patch set updated for coreboot: cbfstool: add extended file attributes for cbfs_file

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Tue Sep 1 00:17:30 CEST 2015


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/10934

-gerrit

commit 464478eed1a946734ccf7d2307d8729881d39325
Author: Patrick Georgi <pgeorgi at chromium.org>
Date:   Wed Jul 15 20:49:00 2015 +0200

    cbfstool: add extended file attributes for cbfs_file
    
    cbfs_file_first_attr(struct cbfs_file *) and
    cbfs_file_next_attr(struct cbfs_file *, struct cbfs_file_attribute *)
    help navigate through extended attributes.
    
    cbfs_add_file_attr(header, tag, size) adds a new file attribute to
    header.
    
    Change-Id: I325965286c44f31abd95df684d340cebb0e68b75
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
---
 util/cbfstool/cbfs.h       | 11 ++++++
 util/cbfstool/cbfs_image.c | 85 +++++++++++++++++++++++++++++++++++++++++++---
 util/cbfstool/cbfs_image.h | 14 ++++++++
 3 files changed, 105 insertions(+), 5 deletions(-)

diff --git a/util/cbfstool/cbfs.h b/util/cbfstool/cbfs.h
index 3f80a04..185bdde 100644
--- a/util/cbfstool/cbfs.h
+++ b/util/cbfstool/cbfs.h
@@ -21,6 +21,10 @@
 
 #include <stdint.h>
 
+/* cbfstool will fail when trying to build a cbfs_file header that's larger
+ * than MAX_CBFS_FILE_HEADER_BUFFER. 1K should give plenty of room. */
+#define MAX_CBFS_FILE_HEADER_BUFFER 1024
+
 /* create a magic number in host-byte order.
  * b3 is the high order byte.
  * in the coreboot tools, we go with the 32-bit
@@ -77,6 +81,7 @@ struct cbfs_file {
 	/* length of file data */
 	uint32_t len;
 	uint32_t type;
+	/* offset to struct cbfs_file_attribute or 0 */
 	uint32_t attributes_offset;
 	/* length of header incl. variable data */
 	uint32_t offset;
@@ -95,6 +100,11 @@ struct cbfs_file_attribute {
 	uint8_t data[0];
 } __PACKED;
 
+/* Depending on how the header was initialized, it may be backed with 0x00 or
+ * 0xff. Support both. */
+#define CBFS_FILE_ATTR_TAG_UNUSED 0
+#define CBFS_FILE_ATTR_TAG_UNUSED2 0xffffffff
+
 struct cbfs_stage {
 	uint32_t compression;
 	uint64_t entry;
@@ -155,6 +165,7 @@ struct cbfs_payload {
 #define CBFS_COMPONENT_NULL 0xFFFFFFFF
 
 #define CBFS_SUBHEADER(_p) ( (void *) ((((uint8_t *) (_p)) + ntohl((_p)->offset))) )
+
 /* cbfs_image.c */
 uint32_t get_cbfs_entry_type(const char *name, uint32_t default_value);
 uint32_t get_cbfs_compression(const char *name, uint32_t unknown);
diff --git a/util/cbfstool/cbfs_image.c b/util/cbfstool/cbfs_image.c
index e71d598..49ff2cd 100644
--- a/util/cbfstool/cbfs_image.c
+++ b/util/cbfstool/cbfs_image.c
@@ -997,11 +997,8 @@ int cbfs_is_valid_entry(struct cbfs_image *image, struct cbfs_file *entry)
 struct cbfs_file *cbfs_create_file_header(int type,
 			    size_t len, const char *name)
 {
-	// assume that there won't be file names of ~1000 bytes
-	const int bufsize = 1024;
-
-	struct cbfs_file *entry = malloc(bufsize);
-	memset(entry, CBFS_CONTENT_DEFAULT_VALUE, bufsize);
+	struct cbfs_file *entry = malloc(MAX_CBFS_FILE_HEADER_BUFFER);
+	memset(entry, CBFS_CONTENT_DEFAULT_VALUE, MAX_CBFS_FILE_HEADER_BUFFER);
 	memcpy(entry->magic, CBFS_FILE_MAGIC, sizeof(entry->magic));
 	entry->type = htonl(type);
 	entry->len = htonl(len);
@@ -1022,6 +1019,84 @@ int cbfs_create_empty_entry(struct cbfs_file *entry, int type,
 	return 0;
 }
 
+struct cbfs_file_attribute *cbfs_file_first_attr(struct cbfs_file *file)
+{
+	/* attributes_offset should be 0 when there is no attribute, but all
+	 * values that point into the cbfs_file header are invalid, too. */
+	if (ntohl(file->attributes_offset) <= sizeof(*file))
+		return NULL;
+
+	/* There needs to be enough space for the file header and one
+	 * attribute header for this to make sense. */
+	if (ntohl(file->offset) <=
+		sizeof(*file) + sizeof(struct cbfs_file_attribute))
+		return NULL;
+
+	return (struct cbfs_file_attribute *)
+		(((uint8_t *)file) + ntohl(file->attributes_offset));
+}
+
+struct cbfs_file_attribute *cbfs_file_next_attr(struct cbfs_file *file,
+	struct cbfs_file_attribute *attr)
+{
+	/* ex falso sequitur quodlibet */
+	if (attr == NULL)
+		return NULL;
+
+	/* Is there enough space for another attribute? */
+	if ((uint8_t *)attr + ntohl(attr->len) +
+		sizeof(struct cbfs_file_attribute) >=
+		(uint8_t *)file + ntohl(file->offset))
+		return NULL;
+
+	struct cbfs_file_attribute *next = (struct cbfs_file_attribute *)
+		(((uint8_t *)attr) + ntohl(attr->len));
+	/* If any, "unused" attributes must come last. */
+	if (ntohl(next->tag) == CBFS_FILE_ATTR_TAG_UNUSED)
+		return NULL;
+	if (ntohl(next->tag) == CBFS_FILE_ATTR_TAG_UNUSED2)
+		return NULL;
+
+	return next;
+}
+
+struct cbfs_file_attribute *cbfs_add_file_attr(struct cbfs_file *header,
+					       uint32_t tag,
+					       uint32_t size)
+{
+	struct cbfs_file_attribute *attr, *next;
+	next = cbfs_file_first_attr(header);
+	do {
+		attr = next;
+		next = cbfs_file_next_attr(header, attr);
+	} while (next != NULL);
+	uint32_t header_size = ntohl(header->offset) + size;
+	if (header_size > MAX_CBFS_FILE_HEADER_BUFFER) {
+		DEBUG("exceeding allocated space for cbfs_file headers");
+		return NULL;
+	}
+	/* attr points to the last valid attribute now.
+	 * If NULL, we have to create the first one. */
+	if (attr == NULL) {
+		/* New attributes start where the header ends.
+		 * header->offset is later set to accomodate the
+		 * additional structure. */
+		header->attributes_offset = header->offset;
+		attr = (struct cbfs_file_attribute *)
+			(((uint8_t *)header) +
+			ntohl(header->attributes_offset));
+	} else {
+		attr = (struct cbfs_file_attribute *)
+			(((uint8_t *)attr) +
+			ntohl(attr->len));
+	}
+	header->offset = htonl(header_size);
+	memset(attr, CBFS_CONTENT_DEFAULT_VALUE, size);
+	attr->tag = htonl(tag);
+	attr->len = htonl(size);
+	return attr;
+}
+
 /* Finds a place to hold whole data in same memory page. */
 static int is_in_same_page(uint32_t start, uint32_t size, uint32_t page)
 {
diff --git a/util/cbfstool/cbfs_image.h b/util/cbfstool/cbfs_image.h
index 7a9b484..aea8260 100644
--- a/util/cbfstool/cbfs_image.h
+++ b/util/cbfstool/cbfs_image.h
@@ -170,4 +170,18 @@ int cbfs_merge_empty_entry(struct cbfs_image *image, struct cbfs_file *entry,
 
 /* Returns the size of a cbfs file header with no extensions */
 size_t cbfs_calculate_file_header_size(const char *name);
+
+/* Given a cbfs_file, return the first file attribute, or NULL. */
+struct cbfs_file_attribute *cbfs_file_first_attr(struct cbfs_file *file);
+
+/* Given a cbfs_file and a cbfs_file_attribute, return the attribute that
+ * follows it, or NULL. */
+struct cbfs_file_attribute *cbfs_file_next_attr(struct cbfs_file *file,
+	struct cbfs_file_attribute *attr);
+
+/* Adds to header a new extended attribute tagged 'tag', sized 'size'.
+ * Returns pointer to the new attribute, or NULL on error. */
+struct cbfs_file_attribute *cbfs_add_file_attr(struct cbfs_file *header,
+					       uint32_t tag,
+					       uint32_t size);
 #endif



More information about the coreboot-gerrit mailing list