Skip to contentSkip to conversation

cramfs fixes and symlink support

PATCH Superseded Tyler Hall 2 participants 5 messages Mar 22, 2017 – Apr 7, 2017 Cramfs filesystem

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

Tyler Hall

author
#0 lore raw

cover cramfs fixes and symlink support

This adds initial support for symlinks in cramfs and fixes cramfs so that it can be tested in the sandbox. "cramfs: block pointers are 32 bits" fixes a crash on 64-bit which I have experienced on ARMv8 as well as the sandbox.

Tyler Hall (3):
cmd: cramfs: use map_sysmem for sandbox support
cramfs: block pointers are 32 bits
cramfs: basic symlink support

 cmd/cramfs.c       | 13 ++++++++---
 fs/cramfs/cramfs.c | 64 +++++++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 61 insertions(+), 16 deletions(-)
Signature · 1 line
2.12.0
author
#1 lore raw

PATCH 1/3 cmd: cramfs: use map_sysmem for sandbox support

As with most other commands, this needs to factor in the sysmem offset in the sandbox or it will try to dereference the simulated physical address directly.

---
 cmd/cramfs.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
cmd/cramfs.c +10 -3
index 965ca4e60d..34be8554a7 100644
@@ -18,6 +18,7 @@
 #include <jffs2/jffs2.h>
 #include <jffs2/load_kernel.h>
 #include <cramfs/cramfs_fs.h>
+#include <asm/io.h>
 
 /* enable/disable debugging messages */
 #define	DEBUG_CRAMFS
@@ -95,6 +96,7 @@ int do_cramfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	char *filename;
 	int size;
 	ulong offset = load_addr;
+	char *offset_virt;
 
 	struct part_info part;
 	struct mtd_device dev;
@@ -111,7 +113,7 @@ int do_cramfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	dev.id = &id;
 	part.dev = &dev;
 	/* fake the address offset */
-	part.offset = addr - OFFSET_ADJUSTMENT;
+	part.offset = (u64) map_sysmem(addr - OFFSET_ADJUSTMENT, 0);
 
 	/* pre-set Boot file name */
 	if ((filename = getenv("bootfile")) == NULL) {
@@ -127,9 +129,10 @@ int do_cramfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		filename = argv[2];
 	}
 
+	offset_virt = map_sysmem(offset, 0);
 	size = 0;
 	if (cramfs_check(&part))
-		size = cramfs_load ((char *) offset, &part, filename);
+		size = cramfs_load (offset_virt, &part, filename);
 
 	if (size > 0) {
 		printf("### CRAMFS load complete: %d bytes loaded to 0x%lx\n",
@@ -139,6 +142,9 @@ int do_cramfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		printf("### CRAMFS LOAD ERROR<%x> for %s!\n", size, filename);
 	}
 
+	unmap_sysmem(offset_virt);
+	unmap_sysmem((void *)part.offset);
+
 	return !(size > 0);
 }
 
@@ -172,7 +178,7 @@ int do_cramfs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	dev.id = &id;
 	part.dev = &dev;
 	/* fake the address offset */
-	part.offset = addr - OFFSET_ADJUSTMENT;
+	part.offset = (u64) map_sysmem(addr - OFFSET_ADJUSTMENT, 0);
 
 	if (argc == 2)
 		filename = argv[1];
@@ -180,6 +186,7 @@ int do_cramfs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	ret = 0;
 	if (cramfs_check(&part))
 		ret = cramfs_ls (&part, filename);
+	unmap_sysmem((void *)part.offset);
 
 	return ret ? 0 : 1;
 }
Signature · 1 line
2.12.0
#2 lore raw

PATCH 1/3 cmd: cramfs: use map_sysmem for sandbox support

Quoted 5 lines · Tyler Hall

As with most other commands, this needs to factor in the sysmem offset in the sandbox or it will try to dereference the simulated physical address directly.

This series introduces a few problems such as kmopti2 not building. Please use travis-ci to get a most-of-the-world build done prior to resubmission, thanks!

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170407/5e0e2588/attachment.sig>
author
#3 lore raw

PATCH 2/3 cramfs: block pointers are 32 bits

In reply to Tyler Hall

Using a variably-sized type is incorrect here since we're reading a fixed file format. Fixes cramfs on 64-bit platforms.

---
 fs/cramfs/cramfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/cramfs/cramfs.c +1 -1
index 05ed27240a..ca8bc5e12b 100644
@@ -162,7 +162,7 @@ static int cramfs_uncompress (unsigned long begin, unsigned long offset,
 			      unsigned long loadoffset)
 {
 	struct cramfs_inode *inode = (struct cramfs_inode *) (begin + offset);
-	unsigned long *block_ptrs = (unsigned long *)
+	u32 *block_ptrs = (u32 *)
 		(begin + (CRAMFS_GET_OFFSET (inode) << 2));
 	unsigned long curr_block = (CRAMFS_GET_OFFSET (inode) +
 				    (((CRAMFS_24 (inode->size)) +
Signature · 1 line
2.12.0
author
#4 lore raw

PATCH 3/3 cramfs: basic symlink support

In reply to Tyler Hall

Handle symlinks to files in the current directory. Other cases could be handled with additional code, but this is a start.

Add explicit errors for absolute paths and links found in the middle of a path (directories). Other cases like '..' or '.' will result with the file not being found as when those path components are explicitly provided.

Add a helper to decompress a null-terminated link name which is shared with cramfs_list_inode.

---
 fs/cramfs/cramfs.c | 62 +++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 50 insertions(+), 12 deletions(-)
fs/cramfs/cramfs.c +50 -12
index ca8bc5e12b..228f599d44 100644
@@ -49,6 +49,9 @@ extern flash_info_t flash_info[];
 #define PART_OFFSET(x)	((ulong)x->offset)
 #endif
 
+static int cramfs_uncompress (unsigned long begin, unsigned long offset,
+			      unsigned long loadoffset);
+
 static int cramfs_read_super (struct part_info *info)
 {
 	unsigned long root_offset;
@@ -94,6 +97,22 @@ static int cramfs_read_super (struct part_info *info)
 	return 0;
 }
 
+/* Unpack to an allocated buffer, trusting in the inode's size field. */
+static char *cramfs_uncompress_link (unsigned long begin, unsigned long offset)
+{
+	struct cramfs_inode *inode = (struct cramfs_inode *)(begin + offset);
+	unsigned long size = CRAMFS_24 (inode->size);
+	char *link = malloc (size + 1);
+
+	if (!link || cramfs_uncompress (begin, offset, (unsigned long)link) != size) {
+		free (link);
+		link = NULL;
+	} else {
+		link[size] = '\0';
+	}
+	return link;
+}
+
 static unsigned long cramfs_resolve (unsigned long begin, unsigned long offset,
 				     unsigned long size, int raw,
 				     char *filename)
@@ -143,6 +162,33 @@ static unsigned long cramfs_resolve (unsigned long begin, unsigned long offset,
 						       p);
 			} else if (S_ISREG (CRAMFS_16 (inode->mode))) {
 				return offset + inodeoffset;
+			} else if (S_ISLNK (CRAMFS_16 (inode->mode))) {
+				unsigned long ret;
+				char *link;
+				if (p && strlen(p)) {
+					printf ("unsupported symlink to \
+						 non-terminal path\n");
+					return 0;
+				}
+				link = cramfs_uncompress_link (begin,
+						offset + inodeoffset);
+				if (!link) {
+					printf ("%*.*s: Error reading link\n",
+						namelen, namelen, name);
+					return 0;
+				} else if (link[0] == '/') {
+					printf ("unsupported symlink to \
+						 absolute path\n");
+					free (link);
+					return 0;
+				}
+				ret = cramfs_resolve (begin,
+						      offset,
+						      size,
+						      raw,
+						      strtok(link, "/"));
+				free (link);
+				return ret;
 			} else {
 				printf ("%*.*s: unsupported file type (%x)\n",
 					namelen, namelen, name,
@@ -235,20 +281,12 @@ static int cramfs_list_inode (struct part_info *info, unsigned long offset)
 		CRAMFS_24 (inode->size), namelen, namelen, name);
 
 	if ((CRAMFS_16 (inode->mode) & S_IFMT) == S_IFLNK) {
-		/* symbolic link.
-		 * Unpack the link target, trusting in the inode's size field.
-		 */
-		unsigned long size = CRAMFS_24 (inode->size);
-		char *link = malloc (size);
-
-		if (link != NULL && cramfs_uncompress (PART_OFFSET(info), offset,
-						       (unsigned long) link)
-		    == size)
-			printf (" -> %*.*s\n", (int) size, (int) size, link);
+		char *link = cramfs_uncompress_link (PART_OFFSET(info), offset);
+		if (link)
+			printf (" -> %s\n", link);
 		else
 			printf (" [Error reading link]\n");
-		if (link)
-			free (link);
+		free (link);
 	} else
 		printf ("\n");
 
Signature · 1 line
2.12.0