1
0
mirror of https://gitlab.com/fdroid/fdroidserver.git synced 2024-11-20 13:50:12 +01:00

NDK Install: Handle symlinks present in NDK zip

This commit is contained in:
Gaurav Ujjwal 2021-10-22 23:42:31 +05:30 committed by Hans-Christoph Steiner
parent b12ece1eba
commit aead3310bd
2 changed files with 79 additions and 2 deletions

View File

@ -4338,7 +4338,19 @@ def _install_ndk(ndk):
with zipfile.ZipFile(zipball) as zipfp: with zipfile.ZipFile(zipball) as zipfp:
for info in zipfp.infolist(): for info in zipfp.infolist():
permbits = info.external_attr >> 16 permbits = info.external_attr >> 16
if stat.S_ISDIR(permbits) or stat.S_IXUSR & permbits: if stat.S_ISLNK(permbits):
link = os.path.join(ndk_base, info.filename)
link_target = zipfp.read(info).decode()
link_dir = os.path.dirname(link)
os.makedirs(link_dir, 0o755, True) # ensure intermediate directories are created
os.symlink(link_target, link)
real_target = os.path.realpath(link)
if not real_target.startswith(ndk_base):
os.remove(link)
logging.error(_('Unexpected symlink target: {link} -> {target}')
.format(link=link, target=real_target))
elif stat.S_ISDIR(permbits) or stat.S_IXUSR & permbits:
zipfp.extract(info.filename, path=ndk_base) zipfp.extract(info.filename, path=ndk_base)
os.chmod(os.path.join(ndk_base, info.filename), 0o755) # nosec bandit B103 os.chmod(os.path.join(ndk_base, info.filename), 0o755) # nosec bandit B103
else: else:

View File

@ -20,7 +20,8 @@ import unittest
import textwrap import textwrap
import yaml import yaml
import gzip import gzip
from zipfile import ZipFile import stat
from zipfile import ZipFile, ZipInfo
from unittest import mock from unittest import mock
from pathlib import Path from pathlib import Path
@ -2116,6 +2117,70 @@ class CommonTest(unittest.TestCase):
_ignored # silence the linters _ignored # silence the linters
fdroidserver.common._install_ndk(r) fdroidserver.common._install_ndk(r)
def test_install_ndk_with_symlinks(self):
"""Some NDK zipballs might have symlinks in them."""
def fake_download(url, zipball):
print(url, zipball)
unix_st_mode = (
stat.S_IFLNK
| stat.S_IRUSR
| stat.S_IWUSR
| stat.S_IXUSR
| stat.S_IRGRP
| stat.S_IWGRP
| stat.S_IXGRP
| stat.S_IROTH
| stat.S_IWOTH
| stat.S_IXOTH
)
with ZipFile(zipball, 'w') as zipfp:
zipfp.writestr('ndk/' + os.path.basename(url), url)
zipInfo = ZipInfo('ndk/basename')
zipInfo.create_system = 3
zipInfo.external_attr = unix_st_mode << 16
zipfp.writestr(zipInfo, os.path.basename(url))
zipInfo = ZipInfo('ndk/bad_abs_link')
zipInfo.create_system = 3
zipInfo.external_attr = unix_st_mode << 16
zipfp.writestr(zipInfo, '/etc/passwd')
zipInfo = ZipInfo('ndk/bad_rel_link')
zipInfo.create_system = 3
zipInfo.external_attr = unix_st_mode << 16
zipfp.writestr(zipInfo, '../../../../../../../etc/passwd')
zipInfo = ZipInfo('ndk/bad_rel_link2')
zipInfo.create_system = 3
zipInfo.external_attr = unix_st_mode << 16
zipfp.writestr(zipInfo, 'foo/../../../../../../../../../etc/passwd')
sdk_path = tempfile.mkdtemp(
prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir
)
config = {'sdk_path': sdk_path}
fdroidserver.common.config = config
r = 'r20'
sha256 = '57435158f109162f41f2f43d5563d2164e4d5d0364783a9a6fab3ef12cb06ce0'
with mock.patch(
'fdroidserver.net.download_file', side_effect=fake_download
) as _ignored, mock.patch(
'fdroidserver.common.get_ndk_version', return_value=r
) as _ignored, mock.patch(
'fdroidserver.common.sha256sum', return_value=sha256
):
_ignored # silence the linters
fdroidserver.common._install_ndk(r)
self.assertTrue(os.path.exists(os.path.join(sdk_path, 'ndk', 'r20')))
self.assertTrue(os.path.exists(os.path.join(sdk_path, 'ndk', 'r20', 'basename')))
self.assertFalse(os.path.exists(os.path.join(sdk_path, 'ndk', 'r20', 'bad_abs_link')))
self.assertFalse(os.path.exists(os.path.join(sdk_path, 'ndk', 'r20', 'bad_rel_link')))
self.assertFalse(os.path.exists(os.path.join(sdk_path, 'ndk', 'r20', 'bad_rel_link2')))
os.system('ls -l ' + os.path.join(sdk_path, 'ndk', 'r20'))
def test_fill_config_defaults(self): def test_fill_config_defaults(self):
"""Test the auto-detection of NDKs installed in standard paths""" """Test the auto-detection of NDKs installed in standard paths"""
sdk_path = tempfile.mkdtemp( sdk_path = tempfile.mkdtemp(