Value initialization
In languages which don’t initialize values, this needs to be explicitly done in order to avoid capturing what random bytes are in memory when run.
An example taken from coreboot:
The code used to write a data structure directly without initializing all its fields. The fix was pretty simple once identified:
--- a/util/bimgtool/bimgtool.c
+++ b/util/bimgtool/bimgtool.c
@@ -160,7 +160,7 @@ static const struct crc_t crc_type = {
static int write_binary(FILE *out, FILE *in, struct bimg_header *hdr)
{
static uint8_t file_buf[MAX_RECORD_BYTES];
- struct bimg_data_header data_hdr;
+ struct bimg_data_header data_hdr = { 0 };
size_t n_written;
data_hdr.dest_addr = hdr->entry_addr;
Usage of instrumentation tools able to detect such cases like Valgrind should help identifying such problems.
Introduction
- Which problems do Reproducible Builds Solve?
- Definitions
- History
- Why reproducible builds?
- Making plans
- Academic publications
Achieve deterministic builds
- Commandments of reproducible builds
- Variations in the build environment
- SOURCE_DATE_EPOCH
- Deterministic build systems
- Volatile inputs can disappear
- Stable order for inputs
- Stripping of unreproducible information
- Value initialization
- Version information
- Timestamps
- Timezones
- Locales
- Archive metadata
- Stable order for outputs
- Randomness
- Build path
- System images
- JVM
Define a build environment
- What's in a build environment?
- Recording the build environment
- Definition strategies
- Proprietary operating systems