-
Notifications
You must be signed in to change notification settings - Fork 66
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
Manually resolves links relatively to root_dir
, and prevent escape
#328
base: master
Are you sure you want to change the base?
Conversation
509cc4f
to
5ab542e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @HorlogeSkynet , maybe I'm misunderstanding something, but right now I only see the part that prevents "unjust" escapes from the chroot (from absolute links or from going above the root) but I don't see any code that would "bend" "legit" absolute symlinks back into the chroot.
Let me demo what I think we'd need in some form:
def resolve_chroot_symlink(link_location, root_dir):
assert os.path.commonprefix([link_location, root_dir]) == root_dir
while True:
try:
resolved = os.readlink(link_location)
except FileNotFoundError: # includes case "not a symlink"
return link_location
if resolved.startswith('/'):
# i.e. absolute path (with regard to the chroot)
# that we need to move back inside the chroot
resolved = os.path.join(root_dir, resolved.lstrip('/'))
else:
# i.e. relative path that we make absolute
resolved = os.path.join(os.path.dirname(link_location), resolved)
if os.path.commonprefix([resolved, root_dir]) != root_dir:
raise Value('ESCAPE DETECTED') # TODO
link_location = resolved
What do you think?
5ab542e
to
b9004e8
Compare
Dear Sebastian, sorry for the delay. So I tweaked your function a bit in order to :
You will see that I opted for links resolution on the verge of calling I've implemented three short test cases to check our new logic (note : relative symbolic links resolving is already tested by regular rootfs under I also took the liberty to update our Bye ! Thanks for your time 👋 |
root_dir
, and prevent escape
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @HorlogeSkynet kudos for the new tests and the loop detection! 👍 I believe a few details need more work, please see my comments below
b9004e8
to
c97754d
Compare
🙏 My mistake ! There was an empty directory that Git didn't track, I've just fixed this 😉 Waiting for your inputs, thanks for your time 👋 EDIT : If you are tired of these round trips, feel free to directly amend the branch ! |
c97754d
to
5186ad6
Compare
5186ad6
to
568cce4
Compare
568cce4
to
1087c2d
Compare
PR's (finally) ready @hartwork ! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @HorlogeSkynet, sorry for the big delay. I found some remaining issues. Please see my four comments below for details:
a1af721
to
91de73f
Compare
5d9b5ba
to
e40187b
Compare
7dc0126
to
a46f5a7
Compare
ddb9177
to
9911c30
Compare
Dear @python-distro/maintainers, Dear @hartwork (if you haven't muted notifications from this repository 🙃), I've finally taken the time to rework this feature (fix ?). What has been done :
This branch as also been rebased, and hence now "ready". Thanks for your time, |
9911c30
to
af1c8ad
Compare
Hi @HorlogeSkynet, back in 2022-08 — soon two years ago — I implemented a solution on branch |
Explicitly disabling third-programs data sources is not required since 2a89f76 (disabled by default if `root_dir` is set).
af1c8ad
to
7a85cfa
Compare
Hey @hartwork, and thanks for your answer. Indeed, I completely forgot about this (these) discussions, since GitHub archived them... I took a quick glimpse of your branch which I find very complex (but this bug/feature is not trivial at all, and my new algorithm is possibly sill broken). So I'll sum up the situation here again, so @python-distro/maintainers will have the full context to properly review this (these) branches : The idea is to "fix" the
So we (@hartwork and I) worked on these issues without opting for solutions as requiring system privileges or using a third-party dependency.
From here, we see multiple options that I'd like to propose/discuss with you :
Thanks for your time, see you all 👋 |
7a85cfa
to
dc19990
Compare
Implementation reworked and rebased
This patch is a followup of #311 (2a89f76). It appeared that we were not resolving paths when reading from files. This means that a symbolic link present under `root_dir` could be blindly followed _outside_ of `root_dir`, possibly leading to host files. Note : this patch **only** changes `root_dir` behavior.
dc19990
to
5e7a64f
Compare
Dear Sebastian, dear maintainers,
This PR drafts a first implementation to address concerns raised in #311 review.
Currently, paths are not manually resolved, and by following symbolic links, this may lead to outside specified
root_dir
.By using
os.path.realpath
andos.path.commonprefix
, we can verify that important paths are still prefixed byroot_dir
, once they have been resolved.It turned out enforcing those checks was not as easy as I thought :
PermissionError
actually fits, but I was out of option__prevent_root_dir_escape
function might require a renaming tooAt least, the new functional test actually enlightens the issue.
--> A deep review is required, ideas are welcome and commits on this branch too 🙃
Have a nice WE all 🙇