mksquashfs: Wrap line longer than 80 chars

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
mksquashfs: fix "new" variable leak in dir_scan1()

Fix leak in dir_scan1() where new returned by excluded() was
not freed.  Normally new will be null unless exclude files and
wildcards have been used.

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
mksquashfs: optimise excluded() when dealing with non-anchored excludes

Non anchored excludes (specified with the "... name" syntax to exclude
files matching name in any directory) are implemented with the
"stickypath" path variable.  This is an exclude specification which
"sticks" as it is present in every directory.

This was previously implemented by adding the stickypath to each
new set of paths returned from the excluded() function, as obviously,
we want stickypath to be present in the next sub-directory.

However, this has the undesirable effect that the new paths variable
"new" is always returned holding at least one entry (the stickypath).
This partially breaks the original design intention of excluded() where
by putting the exclude specifications only in the directories where
they are applicable, for the majority of the time dir_scan1() will have
an empty set of paths to check for exclude matches, thus eliminating
the overhead of exclude matching.

Fix this by not implementing stickypaths as an entry added to the
new set of paths returned from excluded(), instead explictly match
against stickypath if it exists.  This slightly complicates
excluded() requiring a new helper function excluded_match() split out
of excluded(), but the benefit is the new variable in the majority
of cases now gets returned empty (NULL) for stickypaths which was the
original intention.

Also get rid of init_subdir() and instead initialise new in
add_subdir() when first called.  This not only eliminates code (so the
overall changes are 15 lines shorter than before despite the
addition of the new excluded_match() helper function) but it also
means "new" is never allocated in the event we don't get
any matches.

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
mksquashfs: eliminate redundant label

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
mksquashfs: Move strdupping of filename/subpath to scan1_opendir()

This simplifies the logic, eliminating the need to strdup on the
recursive call to dir_scan1(), and eliminating the need to free
them on recursive dir_scan1() failure.

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
mksquashfs: rewrite some ugly code in scan1_opendir()

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
mksquashfs: optimise subpathname() calling in dir_scan1()

Small optimisation - subpath is only needed if there are
exclude actions specified, or if the dir_ent is a directory.
In other cases don't calculate subpath as it is not needed.

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
action: fix memory leak in move_dir()

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
mksquashfs: ensure block_list is always initialised in write_file_blocks()

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
mksquashfs: ensure block_list is always initialised in write_file_blocks_dup()

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
mksquashfs: ensure buffer_list is always initialised in write_file_blocks_dup()

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
mksquashfs: Get rid of unused defs in squashfs_xattr_{entry|val} structs

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
read_fs: prevent buffer {over|under}flow in read_block() with corrupted filesystems

Prevent buffer overflow and underflow in read_block() with corrupted
filesystems.

Overflow is easy to understand, read_block() is called to read the next
metadata block pointed to by <start>...  Often the buffer passed in is
large enough to hold the expected return bytes, which can be less than
SQUASHFS_METADATA_SIZE.  For example filesystem tables are compressed
in SQUASHFS_METADATA_SIZEd chunks, the last compressed chunk will normally
be smaller than SQUASHFS_METADATA_SIZE, so when read_block() is called,
the passed buffer is only large enough to hold the expected size.

Underflow is rather more subtle, when read_block() is called, it is
expected that the returned block will fill the expected amount of
bytes in the filesystem table (stored as an array).  If the returned
block is smaller than expected, then there will be uninitialised
data in the filesystem table which will cause unexpected behaviour later.

Fix both cases by passing in an additional parameter <expected>
which contains the expected number of bytes in the metadata block.
Refuse to read blocks which are larger than expected to avoid
buffer overflow and also return error if the block proves to be
smaller than expected, to avoid using unitialised data.

For the callers where the expected number of bytes is unknown support
<expected> containing 0, in which case the metadata block is checked to
ensure it doesn't overflow a SQUASHFS_METADATA_SIZEd buffer.  Callers of
read_block() with <expected> == 0 are expected to pass in a
SQUASHFS_METADATA_SIZEd buffer.  For instance with compressor specific
options data, the correct length is only known by the compressor specific
code, and this is later called to check the length.

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
read_fs: When reading id_table pass expected number of bytes to read_block()

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
read_fs: When reading fragment_table pass expected number of bytes to read_block()

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
read_fs: When reading lookup_table pass expected number of bytes to read_block()

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
read_fs: check metadata blocks are expected size in scan_inode_table()

Note we can't use expected in read_block() here because at the time
of calling read_block() we don't know what the expected size is.

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
read_fs: check the root inode block is found in scan_inode_table()

Further hardening of read_fs.  If the filesystem is corrupted we may
get the situation where in the inode_table metatadata block scan we
fail to find the metadata block containing the root inode.  In this
case *root_inode_block will be used unitialised.

Add code to check against the small possibility this happens.  In the
majority of cases if the filesystem is corrupted we will fail to read
a metadata block in the block scan, and so we will never get to this
place in the code, however, it could happen and so it needs to be
guarded against.

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
read_fs: When reading directory pass expected number of bytes to read_block()

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
codec_wrappers: rename block_size in uncompress() to outsize

Rename block_size parameter in uncompress() call to outsize, as it
now holds the size of the output buffer, which can be less than
block_size.

Also in the wrappers where the uncompressed length is available
in the header, don't bother calling the codec if outsize is too
small.

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>