Bug File Mtimes Don't Match SOURCE_DATE_EPOCH A Reproducibility Issue
This article addresses a critical bug report concerning file modification times (mtimes) not matching the SOURCE_DATE_EPOCH
in Linux and Windows builds of the me3 project. This discrepancy impacts build reproducibility, a cornerstone of modern software development practices. Understanding the root cause and potential solutions is crucial for maintaining the integrity and reliability of the software.
What Happened?
The core issue revolves around file timestamps in built artifacts. Specifically, Linux builds since version v0.6.0 exhibit modification times (mtimes) of 0 (January 1, 1970, 00:00:00 UTC), instead of aligning with the designated SOURCE_DATE_EPOCH
. This is problematic because the SOURCE_DATE_EPOCH
is intended to ensure deterministic builds, where the same source code produces identical binaries regardless of the build environment or time.
$ TZ=UTC \ls -l --time-style=full-iso me3-linux-amd64-v0.6.1/
total 296
drwxr-xr-x. 1 jn jn 16 1970-01-01 00:00:00.000000000 +0000 bin
-rw-r--r--. 1 jn jn 268440 1970-01-01 00:00:00.000000000 +0000 CHANGELOG.pdf
-rw-r--r--. 1 jn jn 112 1970-01-01 00:00:00.000000000 +0000 eldenring-default.me3
drwxr-xr-x. 1 jn jn 16 1970-01-01 00:00:00.000000000 +0000 eldenring-mods
-rwxr-xr-x. 1 jn jn 201 1970-01-01 00:00:00.000000000 +0000 launch-eldenring-mods
-rwxr-xr-x. 1 jn jn 202 1970-01-01 00:00:00.000000000 +0000 launch-nightreign-mods
-rw-r--r--. 1 jn jn 9723 1970-01-01 00:00:00.000000000 +0000 LICENSE-APACHE
-rw-r--r--. 1 jn jn 1023 1970-01-01 00:00:00.000000000 +0000 LICENSE-MIT
-rw-r--r--. 1 jn jn 114 1970-01-01 00:00:00.000000000 +0000 nightreign-default.me3
drwxr-xr-x. 1 jn jn 16 1970-01-01 00:00:00.000000000 +0000 nightreign-mods
In the provided example, all files within the Linux build exhibit a timestamp of 1970-01-01 00:00:00 UTC, commonly known as the Unix epoch. This timestamp indicates that the file mtimes were not correctly set during the build process, directly contradicting the purpose of the SOURCE_DATE_EPOCH
variable.
For Windows builds, the situation is slightly different. While the mtimes appear consistent and normal, they still deviate from the designated SOURCE_DATE_EPOCH
. This suggests a separate issue in the Windows build process that prevents the proper application of the timestamp.
To illustrate, consider the build of v0.6.1. The build log specifies a SOURCE_DATE_EPOCH
of 1751259921, corresponding to 2025-06-30 05:05:21 UTC. However, the files within the uploaded artifact's Windows zip have a different mtime:
$ git log -1 --format={{content}}#39;%ct\n%ci' 4da60d7
1751259921
2025-06-30 05:05:21 +0000
$ TZ=UTC stat -c {{content}}#39;%Y\n%y' me3-artifacts-15964925004/me3-windows-amd64/bin/me3.exe
1751262543
2025-06-30 05:49:03.000000000 +0000
The mtime of 2025-06-30 05:49:03 UTC for the Windows executable is traced back to the signing step in the build process. This suggests that the signing process might be modifying the file timestamps, overriding the intended SOURCE_DATE_EPOCH
. The signing process, while crucial for security and authenticity on Windows, appears to be interfering with the build's reproducibility.
Impact of Mtime Discrepancies
The incorrect mtimes have several implications:
- Compromised Reproducibility: The primary goal of
SOURCE_DATE_EPOCH
is to ensure that builds are reproducible. When mtimes deviate, it becomes impossible to verify that the same source code produces the same binary. This is critical for security audits, debugging, and ensuring consistent behavior across different environments. - Build System Inconsistencies: The difference in behavior between Linux and Windows builds indicates underlying inconsistencies in the build system. This can lead to unexpected issues and make it harder to maintain and debug the build process.
- Potential Security Concerns: While not immediately a security vulnerability, deviations from expected build behavior can mask potential security issues. Reproducible builds are a key component of a secure software supply chain.
Root Cause Analysis
To effectively address the mtime discrepancy, a thorough root cause analysis is essential. Several factors could contribute to this issue:
- Incorrect Usage of
SOURCE_DATE_EPOCH
: The build scripts might not be correctly utilizing theSOURCE_DATE_EPOCH
variable. It's crucial to ensure that all file operations during the build process respect this variable. - Build Tooling Issues: The build tools themselves (e.g., compilers, archivers) might not be properly handling
SOURCE_DATE_EPOCH
. Some tools might ignore the variable or have bugs that prevent it from being applied correctly. - Operating System Specific Behavior: The way mtimes are handled can vary between operating systems. This might explain the difference between Linux and Windows builds.
- Signing Process Interference (Windows): As observed, the signing process on Windows seems to be a primary culprit. Understanding how the signing process modifies file timestamps is critical.
- File System Interactions: The file system used during the build process could also play a role. Certain file systems might have limitations or quirks related to timestamp handling.
Specific Areas to Investigate
- Makefile Review: A detailed review of the
Makefile
(or equivalent build configuration) is necessary. Ensure that theSOURCE_DATE_EPOCH
variable is being used correctly in all file operations, such as copying, archiving, and compression. - Build Toolchain Examination: Investigate how the build tools (e.g.,
gcc
,ld
,zip
) interact withSOURCE_DATE_EPOCH
. Consult their documentation and check for known issues related to timestamp handling. - Signing Process Analysis (Windows): Deeply analyze the signing process on Windows. Determine if it's possible to preserve the original mtimes during signing or if there are alternative signing methods that don't modify timestamps.
- Build Environment Configuration: Verify that the build environment is correctly configured to use
SOURCE_DATE_EPOCH
. This includes setting the variable in the environment and ensuring that all relevant tools have access to it.
Proposed Solutions and Mitigation Strategies
Addressing the mtime mismatch requires a multi-faceted approach. Here are some potential solutions and mitigation strategies:
- Correct
SOURCE_DATE_EPOCH
Usage: Ensure that theSOURCE_DATE_EPOCH
variable is correctly used throughout the build process. This might involve modifying build scripts, adjusting tool configurations, or using specialized tools that handleSOURCE_DATE_EPOCH
automatically. - Toolchain Updates: If the build tools are not correctly handling
SOURCE_DATE_EPOCH
, consider updating them to versions that have better support. Alternatively, explore using different tools that are known to work well withSOURCE_DATE_EPOCH
. - Signing Process Adjustments (Windows): Investigate methods to preserve mtimes during the signing process on Windows. This might involve using specific signing tools or options that don't modify timestamps. Another approach is to set the mtime to the
SOURCE_DATE_EPOCH
after signing, although this requires careful execution to avoid introducing new issues. - Timestamp Normalization: As a workaround, consider implementing a post-build step that normalizes file mtimes to the
SOURCE_DATE_EPOCH
. This can ensure reproducible builds even if the initial mtimes are incorrect. However, this approach should be used cautiously, as it masks the underlying problem and might not be suitable for all scenarios. - Build System Refactoring: If the build system is complex and difficult to maintain, consider refactoring it to improve its clarity and ensure correct handling of
SOURCE_DATE_EPOCH
. This might involve using a dedicated build system (e.g., CMake, Meson) that provides better support for reproducible builds.
Specific Steps for Windows Signing
Given the interference of the signing process on Windows, here are more detailed steps to address this:
- Investigate Signing Tools: Research the signing tools being used (e.g.,
signtool.exe
) and their options. Some tools might have options to preserve timestamps or allow setting a custom timestamp during signing. - Alternative Signing Methods: Explore alternative signing methods that might not modify timestamps. This could involve using different signing algorithms or tools.
- Post-Signing Timestamping: As a last resort, consider setting the mtime to the
SOURCE_DATE_EPOCH
after signing. This requires careful implementation to ensure that the timestamp is set correctly and consistently.
Version
The bug was identified in version v0.6.1 (Latest) of the me3 project.
Operating System
The issue was observed on both Linux and Windows operating systems, indicating a platform-agnostic problem with the build process.
Relevant Log Output
(No specific log output was provided in the initial bug report, but relevant log snippets from build processes have been included in the analysis above.)
The discrepancy between file mtimes and the SOURCE_DATE_EPOCH
in me3 builds poses a significant challenge to build reproducibility. This article has outlined the issue, analyzed potential root causes, and proposed several solutions and mitigation strategies. By addressing this bug, the me3 project can enhance its build integrity, improve software reliability, and ensure a more secure software supply chain. Further investigation and targeted solutions are necessary to ensure that future builds accurately reflect the intended SOURCE_DATE_EPOCH
, thereby upholding the principles of reproducible builds.