org.osbuild.{dnf,yum}: use safe tempfiles

As a general rule, using temporary files with predictable names is a
security risk. It probably isn't _actually_ a security risk inside
osbuild stages, since they're usually running in some kind of isolated
container environment, but it's still a better idea to use tempfiles.

This makes the dnf and yum stages put their temporary files into a
temporary directory that gets deleted after dnf/yum finishes.
This commit is contained in:
Will Woods 2019-11-08 19:19:33 -05:00 committed by Tom Gundersen
parent 93a3f68a31
commit 8b8493cf04
2 changed files with 45 additions and 39 deletions

View file

@ -6,9 +6,10 @@ import os
import pathlib
import subprocess
import sys
import tempfile
def write_repofile(f, repoid, repo):
def write_repofile(f, repoid, repo, keydir):
f.write(f"[{repoid}]\n")
def write_option(key, value):
@ -23,7 +24,7 @@ def write_repofile(f, repoid, repo):
write_option(key, value)
if "gpgkey" in repo:
keyfile = f"/tmp/{repoid}.asc"
keyfile = f"{keydir}/{repoid}.asc"
with open(keyfile, "w") as key:
key.write(repo["gpgkey"])
write_option("gpgcheck", 1)
@ -62,10 +63,6 @@ def main(tree, options):
weak_deps = options.get("install_weak_deps", True)
exclude_packages = options.get("exclude_packages", [])
with open("/tmp/dnf.conf", "w") as conf:
for repoid, repo in enumerate(repos):
write_repofile(conf, f"repo{repoid}", repo)
script = f"""
set -e
mkdir -p {tree}/dev {tree}/sys {tree}/proc
@ -90,22 +87,29 @@ def main(tree, options):
print(f"setting up API VFS in target tree failed: {err.returncode}")
return err.returncode
base_cmd = [
"dnf", "-yv",
"--installroot", tree,
"--forcearch", basearch,
"--setopt", "reposdir=",
"--setopt", f"install_weak_deps={weak_deps}",
"--releasever", releasever,
"--disableplugin=generate_completion_cache", # supress error that completion db can't be opened
"--config", "/tmp/dnf.conf"
]
with tempfile.TemporaryDirectory(prefix="org.osbuild.dnf.") as confdir:
dnfconf = f"{confdir}/dnf.conf"
cmd = base_cmd + [operation] + packages
for x in exclude_packages:
cmd += ["--exclude", x]
print(" ".join(cmd), flush=True)
subprocess.run(cmd, check=True)
with open(dnfconf, "w") as conf:
for num, repo in enumerate(repos):
write_repofile(conf, f"repo{num}", repo, confdir)
base_cmd = [
"dnf", "-yv",
"--installroot", tree,
"--forcearch", basearch,
"--setopt", "reposdir=",
"--setopt", f"install_weak_deps={weak_deps}",
"--releasever", releasever,
"--disableplugin=generate_completion_cache", # supress error that completion db can't be opened
"--config", dnfconf
]
cmd = base_cmd + [operation] + packages
for x in exclude_packages:
cmd += ["--exclude", x]
print(" ".join(cmd), flush=True)
subprocess.run(cmd, check=True)
# verify metadata checksum
for repoid, repo in enumerate(repos):

View file

@ -3,9 +3,9 @@
import json
import subprocess
import sys
import tempfile
def write_repofile(f, repoid, repo):
def write_repofile(f, repoid, repo, keydir):
f.write(f"[{repoid}]\n")
def write_option(key, value):
@ -20,7 +20,7 @@ def write_repofile(f, repoid, repo):
write_option(key, value)
if "gpgkey" in repo:
keyfile = f"/tmp/{repoid}.asc"
keyfile = f"{keydir}/{repoid}.asc"
with open(keyfile, "w") as key:
key.write(repo["gpgkey"])
write_option("gpgcheck", 1)
@ -34,10 +34,6 @@ def main(tree, options):
operation = options.get("operation", "install")
verbosity = options.get("verbosity", "info")
with open("/tmp/yum.conf", "w") as conf:
for repoid, repo in enumerate(repos):
write_repofile(conf, f"repo{repoid}", repo)
script = f"""
set -e
mkdir -p {tree}/dev {tree}/sys {tree}/proc
@ -51,18 +47,24 @@ def main(tree, options):
print(f"setting up API VFS in target tree failed: {err.returncode}")
return err.returncode
cmd = [
"yum", "--assumeyes",
f"--installroot={tree}",
"--setopt=\"reposdir=\"",
f"--releasever={releasever}",
f"--rpmverbosity={verbosity}",
"--config=/tmp/yum.conf",
operation
] + packages
with tempfile.TemporaryDirectory(prefix="org.osbuild.yum.") as confdir:
yumconf = f"{confdir}/yum.conf"
with open(yumconf, "w") as conf:
for num, repo in enumerate(repos):
write_repofile(conf, f"repo{num}", repo, confdir)
print(" ".join(cmd), flush=True)
return subprocess.run(cmd, check=False).returncode
cmd = [
"yum", "--assumeyes",
f"--installroot={tree}",
"--setopt=\"reposdir=\"",
f"--releasever={releasever}",
f"--rpmverbosity={verbosity}",
f"--config={yumconf}",
operation
] + packages
print(" ".join(cmd), flush=True)
return subprocess.run(cmd, check=False).returncode
if __name__ == '__main__':