Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add squashfuse_extract tool #14

Merged
merged 21 commits into from
Oct 10, 2016
Merged

Add squashfuse_extract tool #14

merged 21 commits into from
Oct 10, 2016

Conversation

probonopd
Copy link
Contributor

@probonopd probonopd commented Oct 9, 2016

The squashfuse_extract can extract files, directories, and symlinks from a squashfs image. Closes #13 and partly #9.

Copy link
Collaborator

@chipturner chipturner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks nice, thanks for the contribution. I commented on a lot of minor issues, please feel free to fix them as you see fit, but the buffer overflow definitely should be addressed before landing.

die("sqfs_traverse_open error");
while (sqfs_traverse_next(&trv, &err)) {
if (!trv.dir_end) {
if((startsWith(path_to_extract, trv.path) != 0) || (strcmp("-a", path_to_extract) == 0)){
Copy link
Collaborator

@chipturner chipturner Oct 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could factor the second strcmp out into a one-time check, and then make this code a little clearer. also it might be nice to split this very long while/nested if block into separate functions or other factorings to make it a little easier to digest

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to change as you see fit; for me it is OK as it is

fprintf(stderr, "inode.base.inode_type: %i\n", inode.base.inode_type);
fprintf(stderr, "inode.xtra.reg.file_size: %lu\n", inode.xtra.reg.file_size);
strcpy(prefixed_path_to_extract, "");
strcat(strcat(prefixed_path_to_extract, prefix), trv.path);
Copy link
Collaborator

@chipturner chipturner Oct 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a potential buffer overflow; rather than a 1024 limit, you should allocate it dynamically once you know each trv.path (variable length array)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing this out; fixed in b4618fc

strcpy(prefixed_path_to_extract, "");
strcat(strcat(prefixed_path_to_extract, prefix), trv.path);
if(inode.base.inode_type == SQUASHFS_DIR_TYPE){
fprintf(stderr, "inode.xtra.dir.parent_inode: %ui\n", inode.xtra.dir.parent_inode);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider putting these fprintf's into a debug mode and disable by default

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could but then I would have to implement fancier arg parsing - do you know how to do that without bloating the code?

die("fopen error");
while (bytes_already_read < inode.xtra.reg.file_size)
{
char *buf = malloc(bytes_at_a_time);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for explicit malloc/free -- you can use a VLA here, too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in 8276a81

fprintf(stderr, "Extract to: %s\n", prefixed_path_to_extract);
// Read the file in chunks
off_t bytes_already_read = 0;
size_t bytes_at_a_time = 1024;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd go with at least 64k, or up to 1mb; 1024 is pretty small and less efficient

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in b4618fc

}
fclose(f);
} else if(inode.base.inode_type == SQUASHFS_SYMLINK_TYPE){
size_t size = 1024;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in 8276a81

} else if(inode.base.inode_type == SQUASHFS_SYMLINK_TYPE){
size_t size = 1024;
char *buf = malloc(size);
sqfs_readlink(&fs, &inode, buf, &size);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there an error code you can check here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in 9e83e5d

#define ERR_OPEN (-3)

static void usage() {
fprintf(stderr, "Usage: %s ARCHIVE PATH_TO_EXTRACT\n", PROGNAME);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a nice future enhancement would be to support extracting multiple files

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but that's for a later version


prefix = "squashfs-root/";

if(access(prefix, F_OK ) == -1 ) {
Copy link
Collaborator

@chipturner chipturner Oct 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style nit: space before the open paren of if statements; similar issue in other places

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in d743c1f


#define PROGNAME "squashfuse_extract"

#define ERR_MISC (-1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exit codes should be positive, not negative

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in 59ae332

@probonopd
Copy link
Contributor Author

Thanks for your thorough review @chipturner. I have addressed your points. Now I would like to get rid of the following compiler warnings, can you give me hints on how to do that?

extract.c: In function ‘sqfs_stat’:
extract.c:51:17: warning: implicit declaration of function ‘sqfs_makedev’ [-Wimplicit-function-declaration]
   st->st_rdev = sqfs_makedev(inode->xtra.dev.major,
                 ^
extract.c: In function ‘main’:
extract.c:148:91: warning: pointer targets in passing argument 4 of ‘sqfs_read_range’ differ in signedness [-Wpointer-sign]
                         if (sqfs_read_range(&fs, &inode, (sqfs_off_t) bytes_already_read, &bytes_at_a_time, buf))
                                                                                           ^
In file included from squashfuse.h:29:0,
                 from extract.c:1:
file.h:60:10: note: expected ‘sqfs_off_t * {aka long int *}’ but argument is of type ‘size_t * {aka long unsigned int *}’
 sqfs_err sqfs_read_range(sqfs *fs, sqfs_inode *inode, sqfs_off_t start,
          ^
  CCLD     squashfuse_extract
make[1]: Leaving directory '/home/me/squashfuse'

@chipturner chipturner merged commit 7a7480e into vasi:master Oct 10, 2016
@chipturner
Copy link
Collaborator

Looks good, thanks!

@chipturner
Copy link
Collaborator

To fix that warning, you probably need to switch from long int to a size_t (size_t is unsigned)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants