-
Notifications
You must be signed in to change notification settings - Fork 197
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
unsquashfs - unvalidated filepaths allow writing outside of destination #72
Comments
An issue on Github (#72) shows how some specially crafted Squashfs filesystems containing invalid file names (with '/' and ..) can cause Unsquashfs to write files outside of the destination directory. This commit fixes this exploit by checking all names for validity. In doing so I have also added checks for '.' and for names that are shorter than they should be (names in the file system should not have '\0' terminators). Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
Hello, is this considered a security vulnerability in unsquashfs? If so, has a CVE been assigned to it already? Thanks |
CVE-2021-40153 seems to have been assigned to it. |
I am. You can provide details here, or email me at phillip@squashfs.org.uk |
There is at least one more way to write outside the destination, this time not using This patch helps creating the crafted filesystem:
It renames One possible mitigation is patching unsquashfs to not follow symlinks. |
The other possible mitigation is to disallow two directory entries with the same name. This would appear more correct IMO. |
Iff it can be detected reliable. unsquashfs is not a fsck. :-) |
On Wed, Sep 08, 2021 at 01:30:54AM -0700, richardweinberger wrote:
> The other possible mitigation is to disallow two directory entries
> with the same name. This would appear more correct IMO.
Iff it can be detected reliable. unsquashfs is not a fsck. :-)
I was wondering about that. I think trying to prevent operations through
symlinks is going to be extremely difficult without using the openat2(2)
system call[1]. Trying to do something similar in userspace usually adds a
lot of filedescriptors and turns simple syscalls into convoluted loops,
each operation of which might be raced by other processes.
The best I've thought of for forbidding two directory entries with the
same name is a big hashtable to keep track of what's already been seen.
I've seen other archive formats 'broken' by interleaved records like:
```
foo/
foo/a
bar/
bar/b
foo/a
...
```
Maintaining a hashtable for all entries unsquashed may be a drastic growth
of memory use, so it might need an escape hatch of some sort.
Thanks
1: https://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git/commit/?h=work.openat2&id=fddb5d430ad9fa91b49b1d34d0202ffe2fa0e179
|
Squashfs is a filesystem rather than an archive (for example like tar which can have repeated duplicate pathnames anywhere), and directories are sorted. So it is relatively easy to detect if a directory has duplicate names. I'll probably push the fix on the weekend, I need to do some more testing, and deal with pre-2.1 version filesystems (these had unsorted directories). |
An issue on github (#72) showed how some specially crafted Squashfs filesystems containing invalid file names (with '/' and '..') can cause Unsquashfs to write files outside of the destination directory. Since then it has been shown that specially crafted Squashfs filesystems that contain a symbolic link pointing outside of the destination directory, coupled with an identically named file within the same directory, can cause Unsquashfs to write files outside of the destination directory. Specifically the symbolic link produces a pathname pointing outside of the destination directory, which is then followed when writing the duplicate identically named file within the directory. This commit fixes this exploit by explictly checking for duplicate filenames within a directory. As directories in v2.1, v3.x, and v4.0 filesystems are sorted, this is achieved by checking for consecutively identical filenames. Additionally directories are checked to ensure they are sorted, to avoid attempts to evade the duplicate check. Version 1.x and 2.0 filesystems (where the directories were unsorted) are sorted and then the above duplicate filename check is applied. Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
Thanks for pushing e048580, the fix assumes that filesystems > 2.0 have sorted directories. How does it deal with the case where an attacker creates a crafted filesystem > 2.0 where directory entries are deliberate not sorted? |
In both cases, the To my understanding, if |
True. Thanks for pointing this out. |
This issue got a separate CVE assigned: CVE-2021-41072 |
In some crafted erofs images, fsck.erofs may write outside the destination directory, which may be used to do some dangerous things. This commit fixes by checking all directory entry names with a '/' character when fscking. Squashfs also met the same situation [1], and have already fixed it here [2]. [1] plougher/squashfs-tools#72 [2] plougher/squashfs-tools@79b5a55 Fixes: 412c8f9 ("erofs-utils: fsck: add --extract=X support to extract to path X") Reviewed-by: Guo Xuenan <guoxuenan@huawei.com> Signed-off-by: Guo Xuenan <guoxuenan@huawei.com> Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com> Link: https://lore.kernel.org/r/20230905023207.70314-1-hsiangkao@linux.alibaba.com
Squashfs stores the filename in the directory entry, this is then used by
unsquashfs
to create the new file during the unsquash. The filename is not validated for traversal outside of the destination directory, this allows writing to locations outside of the destination, such as/etc/crontab
which could lead to code execution.To test this, the following change can be made to
mksquashfs
: https://gist.github.com/staaldraad/6799182a78410081238e75d5abec2da0#file-mksquashfs-patchRecompile
mksquashfs
and then create the "bad" squashfs image.The first example is using a directory traversal, (this is easiest done in a Docker container)
This works pretty well since the
unsquashfs
ends up prepending the file data to an existing file, or creating the file+path if it does not exist.The same can be done with a symlink. Same steps as before except additional file is added to the
poc
folder:Attached are two poc squashfs images, one with directory traversal and the other with symlink. Both will end up creating the file
/tmp/poc_squashfs.txt
Sample squashfs images
pocs.zip
The text was updated successfully, but these errors were encountered: