From 00c97a78471b9757271ae67807a8913049658f3a Mon Sep 17 00:00:00 2001 From: renxudong Date: Sun, 11 Aug 2019 01:18:34 -0400 Subject: [PATCH 6/8] unsquash-4-get-fs-table-start-and-end-points --- squashfs-tools/read_xattrs.c | 14 +++++++++++-- squashfs-tools/unsquash-4.c | 48 ++++++++++++++++++++++++++++++++++++++------ squashfs-tools/xattr.c | 4 ++-- squashfs-tools/xattr.h | 4 ++-- 4 files changed, 58 insertions(+), 12 deletions(-) diff --git a/squashfs-tools/read_xattrs.c b/squashfs-tools/read_xattrs.c index 42106f5..9c66387 100644 --- a/squashfs-tools/read_xattrs.c +++ b/squashfs-tools/read_xattrs.c @@ -2,7 +2,7 @@ * Read a squashfs filesystem. This is a highly compressed read only * filesystem. * - * Copyright (c) 2010, 2012, 2013 + * Copyright (c) 2010, 2012, 2013, 2019 * Phillip Lougher * * This program is free software; you can redistribute it and/or @@ -148,7 +148,7 @@ static int read_xattr_entry(struct xattr_list *xattr, * Read and decompress the xattr id table and the xattr metadata. * This is cached in memory for later use by get_xattr() */ -int read_xattrs_from_disk(int fd, struct squashfs_super_block *sBlk) +int read_xattrs_from_disk(int fd, struct squashfs_super_block *sBlk, int flag, long long *table_start) { int res, bytes, i, indexes, index_bytes, ids; long long *index, start, end; @@ -170,6 +170,16 @@ int read_xattrs_from_disk(int fd, struct squashfs_super_block *sBlk) SQUASHFS_INSWAP_XATTR_TABLE(&id_table); + if(flag) { + /* + * id_table.xattr_table_start stores the start of the compressed xattr + * * metadata blocks. This by definition is also the end of the previous + * filesystem table - the id lookup table. + */ + *table_start = id_table.xattr_table_start; + return id_table.xattr_ids; + } + /* * Allocate and read the index to the xattr id table metadata * blocks diff --git a/squashfs-tools/unsquash-4.c b/squashfs-tools/unsquash-4.c index c335d7c..b501871 100644 --- a/squashfs-tools/unsquash-4.c +++ b/squashfs-tools/unsquash-4.c @@ -361,7 +361,7 @@ corrupted: } -static int read_uids_guids() +static int read_uids_guids(long long *table_start) { int res, i; int bytes = SQUASHFS_ID_BYTES(sBlk.s.no_ids); @@ -384,6 +384,14 @@ static int read_uids_guids() } SQUASHFS_INSWAP_ID_BLOCKS(id_index_table, indexes); + /* + * id_index_table[0] stores the start of the compressed id blocks. + * This by definition is also the end of the previous filesystem + * table - this may be the exports table if it is present, or the + * fragments table if it isn't. + */ + *table_start = id_index_table[0]; + for(i = 0; i < indexes; i++) { int expected = (i + 1) != indexes ? SQUASHFS_METADATA_SIZE : bytes & (SQUASHFS_METADATA_SIZE - 1); @@ -402,11 +410,42 @@ static int read_uids_guids() } +static int parse_exports_table(long long *table_start) +{ + int res; + int indexes = SQUASHFS_LOOKUP_BLOCKS(sBlk.s.inodes); + long long export_index_table[indexes]; + + res = read_fs_bytes(fd, sBlk.s.lookup_table_start, + SQUASHFS_LOOKUP_BLOCK_BYTES(sBlk.s.inodes), export_index_table); + if(res == FALSE) { + ERROR("parse_exports_table: failed to read export index table\n"); + return FALSE; + } + SQUASHFS_INSWAP_LOOKUP_BLOCKS(export_index_table, indexes); + + /* + * export_index_table[0] stores the start of the compressed export blocks. + * This by definition is also the end of the previous filesystem + * table - the fragment table. + */ + *table_start = export_index_table[0]; + + return TRUE; +} + + int read_filesystem_tables_4() { - long long directory_table_end; + long long directory_table_end, table_start; + + if(read_xattrs_from_disk(fd, &sBlk.s, no_xattrs, &table_start) == 0) + return FALSE; - if(read_uids_guids() == FALSE) + if(read_uids_guids(&table_start) == FALSE) + return FALSE; + + if(parse_exports_table(&table_start) == FALSE) return FALSE; if(read_fragment_table(&directory_table_end) == FALSE) @@ -423,8 +462,5 @@ int read_filesystem_tables_4() if(no_xattrs) sBlk.s.xattr_id_table_start = SQUASHFS_INVALID_BLK; - if(read_xattrs_from_disk(fd, &sBlk.s) == 0) - return FALSE; - return TRUE; } diff --git a/squashfs-tools/xattr.c b/squashfs-tools/xattr.c index b46550c..dddba7b 100644 --- a/squashfs-tools/xattr.c +++ b/squashfs-tools/xattr.c @@ -85,7 +85,7 @@ extern int mangle(char *, char *, int, int, int, int); extern char *pathname(struct dir_ent *); /* helper functions and definitions from read_xattrs.c */ -extern int read_xattrs_from_disk(int, struct squashfs_super_block *); +extern int read_xattrs_from_disk(int, struct squashfs_super_block *, int, long long *); extern struct xattr_list *get_xattr(int, unsigned int *, int); extern struct prefix prefix_table[]; @@ -635,7 +635,7 @@ int get_xattrs(int fd, struct squashfs_super_block *sBlk) TRACE("get_xattrs\n"); - res = read_xattrs_from_disk(fd, sBlk); + res = read_xattrs_from_disk(fd, sBlk, FALSE, NULL); if(res == SQUASHFS_INVALID_BLK || res == 0) goto done; ids = res; diff --git a/squashfs-tools/xattr.h b/squashfs-tools/xattr.h index 9260255..13e5519 100644 --- a/squashfs-tools/xattr.h +++ b/squashfs-tools/xattr.h @@ -73,7 +73,7 @@ extern void save_xattrs(); extern void restore_xattrs(); extern unsigned int xattr_bytes, total_xattr_bytes; extern void write_xattr(char *, unsigned int); -extern int read_xattrs_from_disk(int, struct squashfs_super_block *); +extern int read_xattrs_from_disk(int, struct squashfs_super_block *, int, long long *); extern struct xattr_list *get_xattr(int, unsigned int *, int); extern void free_xattr(struct xattr_list *, int); #else @@ -115,7 +115,7 @@ static inline void write_xattr(char *pathname, unsigned int xattr) } -static inline int read_xattrs_from_disk(int fd, struct squashfs_super_block *sBlk) +static inline int read_xattrs_from_disk(int fd, struct squashfs_super_block *sBlk, int flag, long long *table_start) { if(sBlk->xattr_id_table_start != SQUASHFS_INVALID_BLK) { fprintf(stderr, "Xattrs in filesystem! These are not " -- 1.8.3.1