Repository navigation
Conversation
flatstik
force-pushed
the
fix-1973-mount-point
branch
2 times, most recently
from
October 28, 2026 23:16
116ddd1 to
fee6387
Compare
The protected mount point check (CVE-2025-23021) compared the unresolved path when realpath() failed, that is, when the mount point did not exist yet. Such a path passed when it reached a protected directory through ".." or a symbolic link, for example a link to /etc inside a volume mounted at /media/veracrypt1, or a favorite mount point with "..". Paths starting with the default prefix were then created with mkdir(), which followed them, chowned to the user and mounted on, and the directory remained after dismount. Resolve the longest existing part of a mount point and append the rest, and refuse a mount point whose missing part contains "." or "..", or that cannot be resolved for another reason than a missing directory. The check for directories on the user's PATH resolves paths the same way. Create, chown and remove only exact default mount points (<prefix>N), rather than every path starting with the prefix. A default mount point is created with mkdirat() in a parent directory that only root can change, and given to the user with fchown() through a descriptor opened without following links. Fixes veracrypt#1973
Tests/test_linux_mount_point_protection.py checks that a volume cannot be mounted on a new directory under /etc through a symbolic link in a mounted volume or a favorite mount point with "..", that an existing directory in a mounted volume can still be used, and that a default mount point is created for the user and removed after dismount.
flatstik
force-pushed
the
fix-1973-mount-point
branch
from
October 28, 2026 23:16
fee6387 to
d1d9730
Compare
Member
|
Thanks for working on this. I assigned the issue to myself when it was opened to let people know I was working on it, though that was probably easy to miss. So, I had already started on my fix before you opened this PR, and I have now pushed it as d18cb6f. Your test complements mine by exercising real mounts as root, so I have cherry picked it as 9d599af, preserving your authorship. I ran it against my fix and all checks passed. Thanks for adding that coverage. |
Contributor
Author
|
Thanks for taking the test, and sorry for missing that the issue was assigned to you. I will check assignees before starting on an issue. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1973.
The protected mount point check (CVE-2025-23021) compared the unresolved path when
realpath()failed, that is, when the mount point did not exist yet, so a new mount point reaching a protected directory through..or a symbolic link passed. Every path starting with the default prefix was then created withmkdir(), chowned and later removed by pathname, following the same..or link.IsProtectedSystemDirectoryandIsDirectoryOnUserPathresolve the longest existing part of the mount point and append the rest. A mount point whose missing part contains.or..is refused, since it cannot be checked.<prefix>N,IsDefaultMountPoint) are created, chowned and removed, and used to derive the slot, instead of every path starting with the prefix.mkdirat()in a parent directory that only root can change (checked withfstat()on its descriptor), opened without following links and given to the user withfchown(), as the FUSE-T auxiliary directories are handled, so the path is not resolved again between the checks,mkdir()andchown(). A prefix whose parent other users can change (throughVERACRYPT_MOUNT_PREFIX) is refused instead of creating mount points there.The macOS path is unchanged: it does not create mount points itself.
Tested with
Tests/test_linux_mount_point_protection.py(new, run in the Linux workflow), both reproductions from the issue plus an existing directory inside a mounted volume as mount point and a default mount point:..mounts under /etc on both, and the link fails on ubuntu-24.04: https://github.com/flatstik/VeraCrypt/actions/runs/40607484485Not tested on FreeBSD or OpenBSD, which share the mount point creation.