summaryrefslogtreecommitdiffstats
path: root/bitbake
diff options
context:
space:
mode:
authorJoshua Watt <JPEWhacker@gmail.com>2022-08-03 09:04:41 -0500
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-10-11 21:57:28 +0100
commitace871c199796a5ed730a3a95eae5bb26e342b03 (patch)
tree9c14ecb4997892765d86b0840e26dabf8c0d3f5e /bitbake
parentc4745d9c7d18e1df0c0aaae1ba69dd70a0e98490 (diff)
downloadpoky-ace871c199796a5ed730a3a95eae5bb26e342b03.tar.gz
bitbake: siggen: Fix insufficent entropy in sigtask file names
Signature generation uses mkstemp() to get a file descriptor to a unique file and then write the signature into it. However, the unique file name generation in glibc is based on the system timestamp, which means that with highly parallel builds it is more likely than one might expect expected that a conflict will occur between two different builder nodes. When operating over NFS (such as a shared sstate cache), this can cause race conditions and rare failures (particularly with NFS servers that may not correctly implement O_EXCL). The signature generation code is particularly susceptible to races since a single "sigtask." prefix used for all signatures from all tasks, which makes collision even more likely. To work around this, add an internal implementation of mkstemp() that adds additional truly random entropy to the file name to eliminate conflicts. (Bitbake rev: 63bb5591e833de0e7b552963ad9bc4b39e56fda9) Signed-off-by: Joshua Watt <JPEWhacker@gmail.com> Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com> (cherry picked from commit 97955f3c1c738aa4b4478a6ec10a08094ffc689d) Signed-off-by: Steve Sakoman <steve@sakoman.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r--bitbake/lib/bb/siggen.py2
-rw-r--r--bitbake/lib/bb/utils.py21
2 files changed, 22 insertions, 1 deletions
diff --git a/bitbake/lib/bb/siggen.py b/bitbake/lib/bb/siggen.py
index 9fa568f614..bd6fc204fa 100644
--- a/bitbake/lib/bb/siggen.py
+++ b/bitbake/lib/bb/siggen.py
@@ -419,7 +419,7 @@ class SignatureGeneratorBasic(SignatureGenerator):
419 bb.error("Taskhash mismatch %s versus %s for %s" % (computed_taskhash, self.taskhash[tid], tid)) 419 bb.error("Taskhash mismatch %s versus %s for %s" % (computed_taskhash, self.taskhash[tid], tid))
420 sigfile = sigfile.replace(self.taskhash[tid], computed_taskhash) 420 sigfile = sigfile.replace(self.taskhash[tid], computed_taskhash)
421 421
422 fd, tmpfile = tempfile.mkstemp(dir=os.path.dirname(sigfile), prefix="sigtask.") 422 fd, tmpfile = bb.utils.mkstemp(dir=os.path.dirname(sigfile), prefix="sigtask.")
423 try: 423 try:
424 with bb.compress.zstd.open(fd, "wt", encoding="utf-8", num_threads=1) as f: 424 with bb.compress.zstd.open(fd, "wt", encoding="utf-8", num_threads=1) as f:
425 json.dump(data, f, sort_keys=True, separators=(",", ":"), cls=SetEncoder) 425 json.dump(data, f, sort_keys=True, separators=(",", ":"), cls=SetEncoder)
diff --git a/bitbake/lib/bb/utils.py b/bitbake/lib/bb/utils.py
index 95b3c89805..92d44c5260 100644
--- a/bitbake/lib/bb/utils.py
+++ b/bitbake/lib/bb/utils.py
@@ -28,6 +28,8 @@ import signal
28import collections 28import collections
29import copy 29import copy
30import ctypes 30import ctypes
31import random
32import tempfile
31from subprocess import getstatusoutput 33from subprocess import getstatusoutput
32from contextlib import contextmanager 34from contextlib import contextmanager
33from ctypes import cdll 35from ctypes import cdll
@@ -1756,3 +1758,22 @@ def is_local_uid(uid=''):
1756 if str(uid) == line_split[2]: 1758 if str(uid) == line_split[2]:
1757 return True 1759 return True
1758 return False 1760 return False
1761
1762def mkstemp(suffix=None, prefix=None, dir=None, text=False):
1763 """
1764 Generates a unique filename, independent of time.
1765
1766 mkstemp() in glibc (at least) generates unique file names based on the
1767 current system time. When combined with highly parallel builds, and
1768 operating over NFS (e.g. shared sstate/downloads) this can result in
1769 conflicts and race conditions.
1770
1771 This function adds additional entropy to the file name so that a collision
1772 is independent of time and thus extremely unlikely.
1773 """
1774 entropy = "".join(random.choices("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", k=20))
1775 if prefix:
1776 prefix = prefix + entropy
1777 else:
1778 prefix = tempfile.gettempprefix() + entropy
1779 return tempfile.mkstemp(suffix=suffix, prefix=prefix, dir=dir, text=text)