mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-26 15:28:50 +00:00
cramfs: basic symlink support
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. Signed-off-by: Tyler Hall <tylerwhall@gmail.com>
This commit is contained in:
parent
a6ea791cb9
commit
d39a0d2c84
1 changed files with 50 additions and 12 deletions
|
@ -49,6 +49,9 @@ extern flash_info_t flash_info[];
|
||||||
#define PART_OFFSET(x) ((ulong)x->offset)
|
#define PART_OFFSET(x) ((ulong)x->offset)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int cramfs_uncompress (unsigned long begin, unsigned long offset,
|
||||||
|
unsigned long loadoffset);
|
||||||
|
|
||||||
static int cramfs_read_super (struct part_info *info)
|
static int cramfs_read_super (struct part_info *info)
|
||||||
{
|
{
|
||||||
unsigned long root_offset;
|
unsigned long root_offset;
|
||||||
|
@ -94,6 +97,22 @@ static int cramfs_read_super (struct part_info *info)
|
||||||
return 0;
|
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,
|
static unsigned long cramfs_resolve (unsigned long begin, unsigned long offset,
|
||||||
unsigned long size, int raw,
|
unsigned long size, int raw,
|
||||||
char *filename)
|
char *filename)
|
||||||
|
@ -143,6 +162,33 @@ static unsigned long cramfs_resolve (unsigned long begin, unsigned long offset,
|
||||||
p);
|
p);
|
||||||
} else if (S_ISREG (CRAMFS_16 (inode->mode))) {
|
} else if (S_ISREG (CRAMFS_16 (inode->mode))) {
|
||||||
return offset + inodeoffset;
|
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 {
|
} else {
|
||||||
printf ("%*.*s: unsupported file type (%x)\n",
|
printf ("%*.*s: unsupported file type (%x)\n",
|
||||||
namelen, namelen, name,
|
namelen, namelen, name,
|
||||||
|
@ -235,19 +281,11 @@ static int cramfs_list_inode (struct part_info *info, unsigned long offset)
|
||||||
CRAMFS_24 (inode->size), namelen, namelen, name);
|
CRAMFS_24 (inode->size), namelen, namelen, name);
|
||||||
|
|
||||||
if ((CRAMFS_16 (inode->mode) & S_IFMT) == S_IFLNK) {
|
if ((CRAMFS_16 (inode->mode) & S_IFMT) == S_IFLNK) {
|
||||||
/* symbolic link.
|
char *link = cramfs_uncompress_link (PART_OFFSET(info), offset);
|
||||||
* Unpack the link target, trusting in the inode's size field.
|
if (link)
|
||||||
*/
|
printf (" -> %s\n", link);
|
||||||
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);
|
|
||||||
else
|
else
|
||||||
printf (" [Error reading link]\n");
|
printf (" [Error reading link]\n");
|
||||||
if (link)
|
|
||||||
free (link);
|
free (link);
|
||||||
} else
|
} else
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
|
|
Loading…
Add table
Reference in a new issue