lib/oe/gpg_sign.py: Avoid race when creating .sig files in detach_sign

Move the signature file into place only after it is successfully signed.
This to avoid race and corrupted .sig files in cases multiple onging
builds write to a shared sstate-cache dir.

(From OE-Core rev: b4ec08ea9efebac262d43f47d95a356fe2829de9)

Signed-off-by: Tobias Hagelborn <tobiasha@axis.com>
Signed-off-by: Peter Kjellerstedt <peter.kjellerstedt@axis.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Tobias Hagelborn 2023-03-30 17:38:09 +02:00 committed by Richard Purdie
parent 899ec32f42
commit 5a34ddf76d

View File

@ -5,11 +5,12 @@
#
"""Helper module for GPG signing"""
import os
import bb
import subprocess
import os
import shlex
import subprocess
import tempfile
class LocalSigner(object):
"""Class for handling local (on the build host) signing"""
@ -73,8 +74,6 @@ class LocalSigner(object):
cmd += ['--homedir', self.gpg_path]
if armor:
cmd += ['--armor']
if output_suffix:
cmd += ['-o', input_file + "." + output_suffix]
if use_sha256:
cmd += ['--digest-algo', "SHA256"]
@ -83,19 +82,27 @@ class LocalSigner(object):
if self.gpg_version > (2,1,):
cmd += ['--pinentry-mode', 'loopback']
cmd += [input_file]
try:
if passphrase_file:
with open(passphrase_file) as fobj:
passphrase = fobj.readline();
job = subprocess.Popen(cmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
(_, stderr) = job.communicate(passphrase.encode("utf-8"))
if not output_suffix:
output_suffix = 'asc' if armor else 'sig'
output_file = input_file + "." + output_suffix
with tempfile.TemporaryDirectory(dir=os.path.dirname(output_file)) as tmp_dir:
tmp_file = os.path.join(tmp_dir, os.path.basename(output_file))
cmd += ['-o', tmp_file]
if job.returncode:
bb.fatal("GPG exited with code %d: %s" % (job.returncode, stderr.decode("utf-8")))
cmd += [input_file]
job = subprocess.Popen(cmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
(_, stderr) = job.communicate(passphrase.encode("utf-8"))
if job.returncode:
bb.fatal("GPG exited with code %d: %s" % (job.returncode, stderr.decode("utf-8")))
os.rename(tmp_file, output_file)
except IOError as e:
bb.error("IO error (%s): %s" % (e.errno, e.strerror))
raise Exception("Failed to sign '%s'" % input_file)