Skip to content
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

SafeTarfile: Update relative symlinks instead of dropping #770

Closed
wants to merge 2 commits into from

Conversation

AndrewFasano
Copy link

@AndrewFasano AndrewFasano commented Feb 14, 2024

This is a partial fix for #769. With this change, 172 of the 173 missing symlinks are correctly extracted

If I rebase this on top of #768 then the final symlink is extracted correctly (/mnt/mtd/ubifs_app -> ubifs_app).

While this fixes the bug, I'm not positive my path handling is correct/secure for all possible symlinks.

@AndrewFasano
Copy link
Author

Updated to hopefully fix the pyright check. I can't for the life of me figure out how to get pytest to work locally though.

Copy link
Contributor

@e3krisztian e3krisztian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have looked at and tried to understand what is going on here (as this is quite a big change) - I have made some comments.

However in the end I have ended up with an alternative PR #775 based on your work here (added you as co-author to the fix-commits if you do not mind), but with smaller changes.

@AndrewFasano may I ask you to look at #775 and validate the code/run some tests with fw-s to check if that indeed fixes the symlink extraction problems?

Comment on lines +84 to +86
rel_target = (extract_root / rel_target.relative_to("/")).relative_to(
extract_root
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
rel_target = (extract_root / rel_target.relative_to("/")).relative_to(
extract_root
)
rel_target = rel_target.relative_to("/"))

Comment on lines +93 to +94
symlink_depth = len(tarinfo.name.split("/"))
target_depth = len(rel_target.parts)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A stored absolute path can contain relative parts, like /bin/../etc/./shadow, these depth calculations would not work with a path like this, and could lead to the link pointing somewhere else.

Comment on lines +121 to +124
resolved_path = (extract_root / tarinfo.name).parent / rel_target

# If the resolved path points outside of extract_root, we need to fix it!
if not is_safe_path(extract_root, resolved_path):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the real fix, that saves the busybox symlinks.

I am not sure the fix attempt of violating symlinks is needed below.

@e3krisztian
Copy link
Contributor

If I rebase this on top of #768 then the final symlink is extracted correctly (/mnt/mtd/ubifs_app -> ubifs_app).

Looking at the file

$ tar tvf DCS-6517B1_FW_v2.00.03.zip_extract/DCS-6517B1_FW_v2.00.03.pkg_extract/44-17853067.gzip_extract/gzip.uncompressed | rg ubifs_app
lrwxrwxrwx richard/richard       0 2017-05-24 10:52 mnt/ubifs_app -> mtd
lrwxrwxrwx richard/richard       0 2017-05-24 10:52 mnt/mtd/ubifs_app -> ubifs_app
lrwxrwxrwx richard/richard       0 2017-07-11 14:17 www/classes/panoviewer_lib.exe -> /mnt/ubifs_app/panoviewer_lib.exe
lrwxrwxrwx richard/richard       0 2017-07-11 14:17 www/classes/panoviewer.dmg -> /mnt/ubifs_app/panoviewer.dmg

It looks bad at the archive level.
I do not know the reason behind removing symlink loops, but it does look like a symlink loop.
Do you have any idea how such a symlink could be useful?

@e3krisztian
Copy link
Contributor

#775 got merged, which was inspired by and has the same goal as this PR.

@AndrewFasano thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants