RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
Bug 1898089 - dnf reposync doesn't handle well relative paths
Summary: dnf reposync doesn't handle well relative paths
Keywords:
Status: CLOSED WONTFIX
Alias: None
Product: Red Hat Enterprise Linux 8
Classification: Red Hat
Component: dnf-plugins-core
Version: 8.2
Hardware: All
OS: Linux
high
medium
Target Milestone: rc
: 8.0
Assignee: Marek Blaha
QA Contact: swm-qe
Mariya Pershina
URL:
Whiteboard:
Depends On: 1600722
Blocks: 2203766
TreeView+ depends on / blocked
 
Reported: 2020-11-16 11:03 UTC by Christophe Besson
Modified: 2023-12-15 20:06 UTC (History)
21 users (show)

Fixed In Version: dnf-plugins-core-4.0.21-21.el8
Doc Type: Bug Fix
Doc Text:
Clone Of:
: 2203766 (view as bug list)
Environment:
Last Closed: 2023-05-24 13:45:53 UTC
Type: Bug
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)

Description Christophe Besson 2020-11-16 11:03:47 UTC
Description of problem:
A customer is trying to synchronize a 3rd party repository (provided by AWS) but reposync fails due to the use of relative paths in their repo metadata.
DNF `download` or `install` operations work well though.

Version-Release number of selected component (if applicable):
python3-dnf-plugins-core-4.0.17-5.el8.noarch
dnf-plugins-core-4.0.17-5.el8.noarch

How reproducible:
100%

Steps to Reproduce:
# mkdir /home/repo/demo
# cd /home/repo/demo
# cat << EOF >/etc/yum.repos.d/ostest.repo 
[ostest]
name=Amazon Linux 2 core repository
baseurl=https://cdn.amazonlinux.com/2/core/2.0/x86_64/fe6d29c66b12f1f7b8332066ccb4dad2c9a880ed0b4fc64421b517623daa8ba0
gpgcheck=no
enabled=1
EOF
# dnf reposync --config /etc/yum.repos.d/ostest.repo

Actual results:
# dnf reposync --config /etc/yum.repos.d/ostest.repo
Updating Subscription Management repositories.
Repository ostest is listed more than once in the configuration
Amazon Linux 2 core repository                                                                                                                                 19 kB/s | 3.7 kB     00:00    
Error: Download target '/blobstore/275b551f5847ecc2a49c890313e5fc38bb0c6112250f46f9dadde4bdf854665f/tcp_wrappers-7.6-77.amzn2.0.2.x86_64.rpm' is outside of download path '/home/repo/demo/ostest'.

Expected results:
# dnf reposync --config /etc/yum.repos.d/ostest.repo 
Updating Subscription Management repositories.
Repository ostest is listed more than once in the configuration
Amazon Linux 2 core repository                                                                                                                                 33 kB/s | 3.7 kB     00:00    
(1/22389): libiec61883-1.2.0-10.amzn2.x86_64.rpm                                                                                                              492 kB/s |  37 kB     00:00    
(2/22389): setools-3.3.8-2.amzn2.0.2.x86_64.rpm                                                                                                               203 kB/s |  16 kB     00:00    
(3/22389): tcp_wrappers-7.6-77.amzn2.0.2.x86_64.rpm                                                                                                           913 kB/s |  79 kB     00:00    
(4/22389): cups-filters-libs-1.0.35-22.amzn2.0.2.x86_64.rpm                                                                                                   2.2
[...]

Additional info:
The issue happens with reposync, in `/usr/lib/python3.6/site-packages/dnf-plugins/reposync.py`
~~~
166     def pkg_download_path(self, pkg):
167         repo_target = self.repo_target(pkg.repo)
168         pkg_download_path = os.path.realpath(
169             os.path.join(repo_target, pkg.location))
170         # join() ensures repo_target ends with a path separator (otherwise the
171         # check would pass if pkg_download_path was a "sibling" path component
172         # of repo_target that has the same prefix).
173         if not pkg_download_path.startswith(os.path.join(repo_target, '')):
174             raise dnf.exceptions.Error(
175                 _("Download target '{}' is outside of download path '{}'.").format(
176                     pkg_download_path, repo_target))
177         return pkg_download_path
~~~

Indeed the primary.xml metadata file from that repo refers to relative paths valid only on the system which provides them.
~~~
(Pdb) p repo_target
'/home/repo/demo/ostest'
(Pdb) p pkg.location
'../../../../../blobstore/275b551f5847ecc2a49c890313e5fc38bb0c6112250f46f9dadde4bdf854665f/tcp_wrappers-7.6-77.amzn2.0.2.x86_64.rpm'
(Pdb) p pkg_download_path
'/blobstore/275b551f5847ecc2a49c890313e5fc38bb0c6112250f46f9dadde4bdf854665f/tcp_wrappers-7.6-77.amzn2.0.2.x86_64.rpm'
~~~

The implementation to find out the real path doesn't seem bad, but the check afterwards seems wrong (lines 173-176) in this case.
As a workaround, bypassing this check by commenting out those lines works for me.

Comment 2 Michael Young 2021-09-24 14:38:25 UTC
I have come across this issue on CentOS 8. However I think the check that that the download path is valid because if dnf reposync can write outside the download path then it might result in files being places they shouldn't be written to and a malicious or hacked repo might even be able to compromise the mirroring server. It would be nice to be able to strip out the ../ parts of the rpm path but that would mean that --download-metadata would result in metadata that didn't match the mirrored contents. Perhaps a safe_write_path option would work (defaulting to the download_path) so a server owner could allow writing outside the download_path in controlled situations.

Comment 3 Marek Blaha 2021-10-07 09:08:41 UTC
We do need to keep the check in place. It was implemented as part of fix for CVE-2018-10897 (see https://access.redhat.com/security/cve/cve-2018-10897).

But on the other hand we are also aware of those repositories that use relative parent paths, which reposync currently cannot handle.

Based on the comment#2 I've implemented this small patch https://github.com/rpm-software-management/dnf-plugins-core/pull/441
What it basically does is:

- it separates --download-path (path where repository is downloaded to) and --safe-write-path (filesystem path where reposync is allowed to write)
- safe_write_path defaults to repository download path
- currently the --safe-write-path can be used only for syncing a single repository (must be used together with --repoid=<repoid>). I'm not sure this is needed but the intention was to make user think about directories where particular repository needs access.
- the PR also clarifies the error message printed in case reposync is trying to write into forbidden locations. The package name and package location as written in repository metadata were added to this message.

Let's say we have `dummy` repository which contains this package in its primary.xml:

<package type="rpm">
  <name>foo</name>
  <arch>x86_64</arch>
  <version epoch="0" ver="1.0.1" rel="0"/>
  <location href="../pool/foo-1.0.1-0.x86_64.rpm"/>
</package>

To synchronize this repo user needs to specify, that reposync needs write access also to the parent directory of download path:

$ dnf reposync --repoid=dummy --norepopath --download-path=/tmp/synced-repositories/dummy --safe-write-path=/tmp/synced-repositories

Without --safe-write-path reposync produces an error:

$ dnf reposync --repoid=dummy --norepopath --download-path=/tmp/synced-repositories/dummy
Error: Download target '/tmp/synced-repositories/pool/foo-1.0.1-0.x86_64.rpm' for location '../pool/foo-1.0.1-0.x86_64.rpm' of 'foo' package is outside of safe write path '/tmp/synced-repositories/dummy/'.

Any comments either here or in the pull request are appreciated.

Comment 4 Christophe Besson 2021-10-07 09:10:58 UTC
Looks like a safe approach

Comment 5 Stefan Strandberg 2021-12-30 14:22:54 UTC
I've tested this and it appears to work as expected and resolve the issue in what I believe to be a safe manner.  I would be in favor of going forward with this solution, ideally sooner rather than later so that we aren't using manually patched code.

Comment 9 Stewart Smith 2022-05-30 18:26:34 UTC
I've also just submitted https://github.com/rpm-software-management/dnf-plugins-core/pull/457 that lets you make a more functional mirror of Amazon Linux style repositories. Would love some feedback!

Comment 10 Levente Farkas 2022-06-13 11:06:18 UTC
(In reply to Stewart Smith from comment #9)
> I've also just submitted
> https://github.com/rpm-software-management/dnf-plugins-core/pull/457 that
> lets you make a more functional mirror of Amazon Linux style repositories.
> Would love some feedback!

this works! and would be nice to add to the official rpm too!

Comment 11 Stewart Smith 2022-06-13 15:52:42 UTC
Thanks for testing it out!

I'm hoping to get some review / merge of the above PR before I back-port it into Amazon Linux 2022. I'm sure some user feedback on the functionality on it on GitHub could be appreciated.

Comment 12 naresh.sukhija_ext 2022-06-14 08:58:51 UTC
Is it possible to get a RHEL8 test RPM package python3-dnf-plugins-core with the enhancemenced script /usr/lib/python3.6/site-packages/dnf-plugins/reposync.py ?

Comment 23 Stewart Smith 2023-03-23 22:22:44 UTC
https://github.com/rpm-software-management/dnf-plugins-core/pull/481 is a PR from my colleague that implements what was discussed elsewhere as a good first step that increased assurance of not re-introducing a path traversal bug: a simple flattening of the directory structure.

Comment 26 Jaroslav Mracek 2023-05-05 11:46:25 UTC
The patch is merged, therefore moving it to post.

Comment 31 Kyle Walker 2023-05-24 13:45:53 UTC
Due to security concerns related to the possible reintroduction of CVE-2018-10897 (see https://access.redhat.com/security/cve/cve-2018-10897), this Request for Feature Enhancement will not be delivered within the Red Hat Enterprise Linux release and this RFE is being closed as WONTFIX.

End users that wish to make use of the Unsupported "--safe-write-path" option are free to utilize the community solution merged in the MR below:

    https://github.com/rpm-software-management/dnf-plugins-core/pull/441

A build which includes the above is available via the following unsupported COPR build as well:

    https://copr.fedorainfracloud.org/coprs/rpmsoftwaremanagement/dnf-nightly/

Please note that the above falls outside the scope of the posted Service Level Agreements and supported procedures. It is provided as-is and no support is extended or implied.


Note You need to log in before you can comment on or make changes to this bug.