summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Edgecumbe <git@esotericnonsense.com>2019-09-07 12:15:26 +0200
committerDaniel Edgecumbe <git@esotericnonsense.com>2019-09-09 16:49:41 +0200
commitca8f13e11d422fa01bc031ff0610442b82ea6b65 (patch)
tree9288416157205c37f7a6a25f09b3472cb8b88fa1
parenta3cb799a8f63186b843db6a57da12d74a9320686 (diff)
downloadmkinitcpio-ca8f13e11d422fa01bc031ff0610442b82ea6b65.tar.gz
mkinitcpio-ca8f13e11d422fa01bc031ff0610442b82ea6b65.tar.xz
mkinitcpio: Produce reproducible initramfs images
We achieve this by stripping timestamps from within the filesystem, and by using a pipeline to strip inodes from the cpio archive. It functions for at least the 'gzip', 'xz', 'bzip2', 'lz4' and 'cat' compressors. The 'lzop' compressor embeds a runtime timestamp. Motivation: https://reproducible-builds.org Signed-off-by: Daniel Edgecumbe <git@esotericnonsense.com>
-rw-r--r--man/mkinitcpio.8.txt16
-rwxr-xr-xmkinitcpio23
2 files changed, 29 insertions, 10 deletions
diff --git a/man/mkinitcpio.8.txt b/man/mkinitcpio.8.txt
index 931a167..6a9b59e 100644
--- a/man/mkinitcpio.8.txt
+++ b/man/mkinitcpio.8.txt
@@ -301,6 +301,22 @@ These are only the variables that the core of mkinitcpio honor. Additional
hooks may look for other environment variables and should be documented by the
help output for the hook.
+Reproducibility
+---------------
+mkinitcpio aims to create reproducible initramfs images by default.
+
+This means that two subsequent runs of mkinitcpio should produce two files
+that are identical at the binary level.
+
+Timestamps within the initramfs are set to the Unix epoch of 1970-01-01.
+
+Note that in order for the build to be fully reproducible, the compressor
+specified (e.g. gzip, xz) must also produce reproducible archives. At the time
+of writing, as an inexhaustive example, the lzop compressor is incapable of
+producing reproducible archives due to the insertion of a runtime timestamp.
+
+More information can be found at https://reproducible-builds.org.
+
Files
-----
'/etc/mkinitcpio.conf'::
diff --git a/mkinitcpio b/mkinitcpio
index 5583d07..db7a61a 100755
--- a/mkinitcpio
+++ b/mkinitcpio
@@ -211,25 +211,28 @@ build_image() {
;;
esac
- cpio_opts=('-0' '-o' '-H' 'newc')
- (( _optquiet )) && cpio_opts+=('--quiet')
- if (( EUID != 0 )); then
- warning 'Not building as root, ownership cannot be preserved'
- cpio_opts+=('-R' '0:0')
- fi
-
pushd "$BUILDROOT" >/dev/null
- find . -mindepth 1 -printf '%P\0' |
- LANG=C bsdcpio "${cpio_opts[@]}" |
+
+ # Reproducibility: set all timestamps to 0
+ find . -mindepth 1 -execdir touch -hcd "@0" "{}" +
+
+ find . -mindepth 1 -printf '%P\0' | sort -z |
+ LANG=C bsdtar --null -cnf - -T - |
+ LANG=C bsdtar --uid 0 --gid 0 --null -cf - --format=newc @- |
$compress "${COMPRESSION_OPTIONS[@]}" > "$out"
+
pipesave=("${PIPESTATUS[@]}") # save immediately
popd >/dev/null
if (( pipesave[0] )); then
errmsg="find reported an error"
elif (( pipesave[1] )); then
- errmsg="bsdcpio reported an error"
+ errmsg="sort reported an error"
elif (( pipesave[2] )); then
+ errmsg="bsdtar (step 1) reported an error"
+ elif (( pipesave[3] )); then
+ errmsg="bsdtar (step 2) reported an error"
+ elif (( pipesave[4] )); then
errmsg="$compress reported an error"
fi