-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # 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 🙇