cramfs fixes and symlink support
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
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
@@ -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
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.
Signed-off-by Tyler Hall <[email protected]>
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>
PATCH 2/3 cramfs: block pointers are 32 bits
In reply to Tyler HallUsing 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
@@ -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
PATCH 3/3 cramfs: basic symlink support
In reply to Tyler HallHandle 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
@@ -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