Update min apk version/add more apk version checks

* Minimum version: 2.7.2 (which fixes two CVEs)
* Check the minimum apk version before doing something with apk and
  before entering the chroot manually (previously, it has just checked
  the apk-tools-static version, which gets used to set up the chroot)
* Reword the message for an outdated APK version. Most likely it is
  just the outdated http cache, instead of a man-in-the-middle attack.

See also:
b849b481a0
This commit is contained in:
Oliver Smith 2017-06-23 17:04:49 +02:00
parent f547ff5c6e
commit fb1e8ec73b
No known key found for this signature in database
GPG Key ID: 5AE7F5513E0885CB
5 changed files with 39 additions and 8 deletions

View File

@ -18,10 +18,36 @@ along with pmbootstrap. If not, see <http://www.gnu.org/licenses/>.
"""
import logging
import pmb.chroot
import pmb.config
import pmb.parse.apkindex
import pmb.parse.other
def check_min_version(args, suffix="native"):
"""
Check the minimum apk version, before running it the first time in the
current session (lifetime of one pmbootstrap call).
"""
# Skip if we already did this
if suffix in args.cache["apk_min_version_checked"]:
return
# Read the version from apk and from the config
pkgver = pmb.chroot.root(args, ["apk", "--version"], suffix,
return_stdout=True)
pkgver = pkgver.split(" ")[1].split(",")[0]
pkgver_min = pmb.config.apk_tools_static_min_version.split("-")[0]
# Compare
if pmb.parse.apkindex.compare_version(pkgver, pkgver_min) == -1:
raise RuntimeError("You have an outdated version of the 'apk' package"
" manager installed (your version: " + pkgver +
", expected at least: " + pkgver_min + "). Delete"
" your http cache and zap all chroots, then try again:"
" 'pmbootstrap zap -hc'")
args.cache["apk_min_version_checked"].append(suffix)
def install(args, packages, suffix="native", build=True):
"""
:param build: automatically build the package, when it does not exist yet
@ -30,6 +56,7 @@ def install(args, packages, suffix="native", build=True):
False!
"""
# Initialize chroot
check_min_version(args, suffix)
pmb.chroot.init(args, suffix)
# Filter already installed packages
@ -63,6 +90,7 @@ def upgrade(args, suffix="native", update_index=True):
"""
Upgrade all packages installed in a chroot
"""
check_min_version(args, suffix)
pmb.chroot.init(args, suffix)
if update_index:
pmb.chroot.root(args, ["apk", "update"], suffix)
@ -77,9 +105,11 @@ def installed(args, suffix="native"):
:returns: { "hello-world": {"package": "hello-world-1-r2", "pkgrel": "2",
"pkgver": "1", "pkgname": "hello-world"}, ...}
"""
ret = {}
check_min_version(args, suffix)
list = pmb.chroot.user(args, ["apk", "info", "-vv"], suffix,
return_stdout=True)
# Parse the output into a dictionary
ret = {}
for line in list.split("\n"):
if not line.rstrip():
continue

View File

@ -163,11 +163,11 @@ def init(args):
version_min = pmb.config.apk_tools_static_min_version
apk_name = "apk-tools-static-" + version + ".apk"
if pmb.parse.apkindex.compare_version(version, version_min) == -1:
raise RuntimeError("Server provides an outdated version of"
" apk-tools-static: " + version +
" (expected at least " + version_min +
"). Looks like a downgrade attack from a"
" malicious server! Switch the server (-m) and try again!")
raise RuntimeError("You have an outdated version of apk-tools-static"
" (your version: " + version +
", expected at least:"
" " + version_min + "). Delete your http cache and zap"
" all chroots, then try again: 'pmbootstrap zap -hc'")
apk_static = download(args, apk_name)
extract(args, version, apk_static)

View File

@ -36,7 +36,7 @@ apk_keys_path = pmb_src + "/keys"
# Update this frequently to prevent a MITM attack with an outdated version
# (which may contain a vulnerable apk/libressl, and allows an attacker to
# exploit the system!)
apk_tools_static_min_version = "2.7.1-r0"
apk_tools_static_min_version = "2.7.2-r0"
# Config file/commandline default values
# $WORK gets replaced with the actual value for args.work (which may be

View File

@ -201,7 +201,7 @@ def arguments():
setattr(args, "arch_native", pmb.parse.arch.alpine_native())
# Add a caching dict
setattr(args, "cache", {"apkindex": {}})
setattr(args, "cache", {"apkindex": {}, "apk_min_version_checked": []})
# Add and verify the deviceinfo (only after initialization)
if args.action != "init":

View File

@ -66,6 +66,7 @@ def main():
elif args.action == "checksum":
pmb.build.checksum(args, args.package)
elif args.action == "chroot":
pmb.chroot.apk.check_min_version(args, args.suffix)
pmb.chroot.root(args, args.command, args.suffix, log=False)
elif args.action == "index":
pmb.build.index_repo(args)