cramfs fixes and symlink support
v2 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.
Changes in v2:
* Add missing include and pointer cast needed on some architectures
https://travis-ci.org/tylerwhall/u-boot/builds/221383040
Tyler Hall (3):
cmd: cramfs: use map_sysmem for sandbox support
cramfs: block pointers are 32 bits
cramfs: basic symlink support
cmd/cramfs.c | 14 +++++++++--- fs/cramfs/cramfs.c | 64 +++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 62 insertions(+), 16 deletions(-)
Signature · 1 line
2.12.2
PATCH v2 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 | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
cmd/cramfs.c +11 -3
@@ -13,11 +13,13 @@#include <common.h> #include <command.h> #include <malloc.h> +#include <mapmem.h> #include <linux/list.h> #include <linux/ctype.h> #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 +97,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 +114,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 )(uintptr_t )map_sysmem (addr -OFFSET_ADJUSTMENT ,0 );/* pre-set Boot file name */ if ((filename =getenv ("bootfile" )) ==NULL ) {
@@ -127,9 +130,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 +143,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 *)(uintptr_t )part.offset); +return !(size >0 ); }
@@ -172,7 +179,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 )(uintptr_t )map_sysmem (addr -OFFSET_ADJUSTMENT ,0 );if (argc ==2 ) filename = argv[1 ];
@@ -180,6 +187,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 *)(uintptr_t )part.offset);return ret ?0 :1 ; }
Signature · 1 line
2.12.2
PATCH v2 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]>
Applied to u-boot/master, 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/20170419/93c9205a/attachment.sig>
PATCH v2 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.2
PATCH v2 2/3 cramfs: block pointers are 32 bits
Quoted 4 lines · Tyler Hall
Using a variably-sized type is incorrect here since we're reading a fixed file format. Fixes cramfs on 64-bit platforms.
Signed-off-by Tyler Hall <[email protected]>
Applied to u-boot/master, 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/20170419/f7213835/attachment.sig>
PATCH v2 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.2
PATCH v2 3/3 cramfs: basic symlink support
Quoted 8 lines · 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.
Quoted 4 lines
Add a helper to decompress a null-terminated link name which is shared with
cramfs_list_inode.Signed-off-by Tyler Hall <[email protected]>
Applied to u-boot/master, 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/20170419/d30c29ee/attachment.sig>
v2 cover cramfs fixes and symlink support
In reply to Tyler HallQuoted 9 lines · Tyler Hall
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.
Changes in v2:
* Add missing include and pointer cast needed on some architectures
Quoted 8 lines
Tyler Hall (3):
cmd: cramfs: usemap_sysmemfor sandbox support
cramfs: block pointers are 32 bits
cramfs: basic symlink supportcmd/cramfs.c | 14 +++++++++--- fs/cramfs/cramfs.c | 64 +++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 62 insertions(+), 16 deletions(-)
Thanks for pushing this through travis-ci as well. Assuming there's no further comments I'll pick this up in a few days.
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/20170412/937c4264/attachment.sig>