diff options
author | Rasmus Villemoes <ravi@prevas.dk> | 2024-11-06 16:02:58 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2024-11-19 11:26:24 +0000 |
commit | b5b4fad3e9ba828d411e32229e8a20a171954968 (patch) | |
tree | 6e95cd9c05dc8b9670a0c4d4f290bbe980b3d050 | |
parent | 131872001abf6c76bd1ed7e31cc68c88ede8ca2c (diff) | |
download | poky-b5b4fad3e9ba828d411e32229e8a20a171954968.tar.gz |
dosfstools: add backported patch for honouring SOURCE_DATE_EPOCH
Currently, file system images created with mkfs.vfat are not
reproducible, because both the file system creation time and the
volume id are derived from the current time.
Upstream has added a patch for deriving those from SOURCE_DATE_EPOCH,
when defined, many years ago, but unfortunately there is no official
release containing that patch.
The issue [1] is 2.5 years old, so there's no reason to believe such a
release would be just around the corner.
The patch applies cleanly, and e.g. Arch Linux already uses this exact
combination of source tarball and this single patch [2], so I think
this should be ok. It certainly works for the images I've tested on.
[1] https://github.com/dosfstools/dosfstools/issues/179
[2] https://gitlab.archlinux.org/archlinux/packaging/packages/dosfstools/-/blob/main/PKGBUILD?ref_type=heads
(From OE-Core rev: bf9e6bf884bc780547d3dc88c3977c8102e1faeb)
Signed-off-by: Rasmus Villemoes <ravi@prevas.dk>
Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r-- | meta/recipes-devtools/dosfstools/dosfstools/source-date-epoch.patch | 158 | ||||
-rw-r--r-- | meta/recipes-devtools/dosfstools/dosfstools_4.2.bb | 2 |
2 files changed, 160 insertions, 0 deletions
diff --git a/meta/recipes-devtools/dosfstools/dosfstools/source-date-epoch.patch b/meta/recipes-devtools/dosfstools/dosfstools/source-date-epoch.patch new file mode 100644 index 0000000000..e3a649e55a --- /dev/null +++ b/meta/recipes-devtools/dosfstools/dosfstools/source-date-epoch.patch | |||
@@ -0,0 +1,158 @@ | |||
1 | From 8da7bc93315cb0c32ad868f17808468b81fa76ec Mon Sep 17 00:00:00 2001 | ||
2 | From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= <bjorn.forsman@gmail.com> | ||
3 | Date: Wed, 5 Dec 2018 19:52:51 +0100 | ||
4 | Subject: [PATCH] Honor the SOURCE_DATE_EPOCH variable | ||
5 | MIME-Version: 1.0 | ||
6 | Content-Type: text/plain; charset=UTF-8 | ||
7 | Content-Transfer-Encoding: 8bit | ||
8 | |||
9 | Implement the SOURCE_DATE_EPOCH specification[1] for reproducible | ||
10 | builds. If SOURCE_DATE_EPOCH is set, use it as timestamp instead of the | ||
11 | current time. | ||
12 | |||
13 | [1] https://reproducible-builds.org/specs/source-date-epoch/ | ||
14 | |||
15 | Upstream-Status: Backport [https://github.com/dosfstools/dosfstools/commit/8da7bc93315cb0c32ad868f17808468b81fa76ec] | ||
16 | Signed-off-by: Bjørn Forsman <bjorn.forsman@gmail.com> | ||
17 | --- | ||
18 | src/boot.c | 23 +++++++++++++++++++++-- | ||
19 | src/common.c | 18 ++++++++++++++++-- | ||
20 | src/mkfs.fat.c | 19 ++++++++++++++++--- | ||
21 | 3 files changed, 53 insertions(+), 7 deletions(-) | ||
22 | |||
23 | diff --git a/src/boot.c b/src/boot.c | ||
24 | index 4de450d..8f78e1c 100644 | ||
25 | --- a/src/boot.c | ||
26 | +++ b/src/boot.c | ||
27 | @@ -33,6 +33,8 @@ | ||
28 | #include <stdlib.h> | ||
29 | #include <sys/types.h> | ||
30 | #include <time.h> | ||
31 | +#include <errno.h> | ||
32 | +#include <ctype.h> | ||
33 | |||
34 | #include "common.h" | ||
35 | #include "fsck.fat.h" | ||
36 | @@ -672,6 +674,7 @@ void write_volume_label(DOS_FS * fs, char *label) | ||
37 | { | ||
38 | time_t now; | ||
39 | struct tm *mtime; | ||
40 | + char *source_date_epoch = NULL; | ||
41 | off_t offset; | ||
42 | int created; | ||
43 | DIR_ENT de; | ||
44 | @@ -687,8 +690,24 @@ void write_volume_label(DOS_FS * fs, char *label) | ||
45 | if (de.name[0] == 0xe5) | ||
46 | de.name[0] = 0x05; | ||
47 | |||
48 | - now = time(NULL); | ||
49 | - mtime = (now != (time_t)-1) ? localtime(&now) : NULL; | ||
50 | + source_date_epoch = getenv("SOURCE_DATE_EPOCH"); | ||
51 | + if (source_date_epoch) { | ||
52 | + char *tmp = NULL; | ||
53 | + long long conversion = 0; | ||
54 | + errno = 0; | ||
55 | + conversion = strtoll(source_date_epoch, &tmp, 10); | ||
56 | + now = conversion; | ||
57 | + if (!isdigit((unsigned char)*source_date_epoch) || *tmp != '\0' | ||
58 | + || errno != 0 || (long long)now != conversion) { | ||
59 | + die("SOURCE_DATE_EPOCH is too big or contains non-digits: \"%s\"", | ||
60 | + source_date_epoch); | ||
61 | + } | ||
62 | + mtime = gmtime(&now); | ||
63 | + } else { | ||
64 | + now = time(NULL); | ||
65 | + mtime = (now != (time_t)-1) ? localtime(&now) : NULL; | ||
66 | + } | ||
67 | + | ||
68 | if (mtime && mtime->tm_year >= 80 && mtime->tm_year <= 207) { | ||
69 | de.time = htole16((unsigned short)((mtime->tm_sec >> 1) + | ||
70 | (mtime->tm_min << 5) + | ||
71 | diff --git a/src/common.c b/src/common.c | ||
72 | index 6a2e396..4f1afcb 100644 | ||
73 | --- a/src/common.c | ||
74 | +++ b/src/common.c | ||
75 | @@ -30,6 +30,7 @@ | ||
76 | #include <string.h> | ||
77 | #include <stdarg.h> | ||
78 | #include <errno.h> | ||
79 | +#include <ctype.h> | ||
80 | #include <wctype.h> | ||
81 | #include <termios.h> | ||
82 | #include <sys/time.h> | ||
83 | @@ -298,8 +299,21 @@ void check_atari(void) | ||
84 | uint32_t generate_volume_id(void) | ||
85 | { | ||
86 | struct timeval now; | ||
87 | - | ||
88 | - if (gettimeofday(&now, NULL) != 0 || now.tv_sec == (time_t)-1 || now.tv_sec < 0) { | ||
89 | + char *source_date_epoch = NULL; | ||
90 | + | ||
91 | + source_date_epoch = getenv("SOURCE_DATE_EPOCH"); | ||
92 | + if (source_date_epoch) { | ||
93 | + char *tmp = NULL; | ||
94 | + long long conversion = 0; | ||
95 | + errno = 0; | ||
96 | + conversion = strtoll(source_date_epoch, &tmp, 10); | ||
97 | + if (!isdigit((unsigned char)*source_date_epoch) || *tmp != '\0' | ||
98 | + || errno != 0) { | ||
99 | + die("SOURCE_DATE_EPOCH is too big or contains non-digits: \"%s\"", | ||
100 | + source_date_epoch); | ||
101 | + } | ||
102 | + return (uint32_t)conversion; | ||
103 | + } else if (gettimeofday(&now, NULL) != 0 || now.tv_sec == (time_t)-1 || now.tv_sec < 0) { | ||
104 | srand(getpid()); | ||
105 | /* rand() returns int from [0,RAND_MAX], therefore only 31 bits */ | ||
106 | return (((uint32_t)(rand() & 0xFFFF)) << 16) | ((uint32_t)(rand() & 0xFFFF)); | ||
107 | diff --git a/src/mkfs.fat.c b/src/mkfs.fat.c | ||
108 | index 37fc8ff..1948635 100644 | ||
109 | --- a/src/mkfs.fat.c | ||
110 | +++ b/src/mkfs.fat.c | ||
111 | @@ -1074,7 +1074,7 @@ static void setup_tables(void) | ||
112 | } | ||
113 | |||
114 | /* If is not available then generate random 32 bit disk signature */ | ||
115 | - if (invariant) | ||
116 | + if (invariant || getenv("SOURCE_DATE_EPOCH")) | ||
117 | disk_sig = volume_id; | ||
118 | else if (!disk_sig) | ||
119 | disk_sig = generate_volume_id(); | ||
120 | @@ -1287,7 +1287,7 @@ static void setup_tables(void) | ||
121 | de->name[0] = 0x05; | ||
122 | de->attr = ATTR_VOLUME; | ||
123 | if (create_time != (time_t)-1) { | ||
124 | - if (!invariant) | ||
125 | + if (!invariant && !getenv("SOURCE_DATE_EPOCH")) | ||
126 | ctime = localtime(&create_time); | ||
127 | else | ||
128 | ctime = gmtime(&create_time); | ||
129 | @@ -1477,6 +1477,7 @@ int main(int argc, char **argv) | ||
130 | int blocks_specified = 0; | ||
131 | struct timeval create_timeval; | ||
132 | long long conversion; | ||
133 | + char *source_date_epoch = NULL; | ||
134 | |||
135 | enum {OPT_HELP=1000, OPT_INVARIANT, OPT_MBR, OPT_VARIANT, OPT_CODEPAGE, OPT_OFFSET}; | ||
136 | const struct option long_options[] = { | ||
137 | @@ -1497,8 +1498,20 @@ int main(int argc, char **argv) | ||
138 | program_name = p + 1; | ||
139 | } | ||
140 | |||
141 | - if (gettimeofday(&create_timeval, NULL) == 0 && create_timeval.tv_sec != (time_t)-1) | ||
142 | + source_date_epoch = getenv("SOURCE_DATE_EPOCH"); | ||
143 | + if (source_date_epoch) { | ||
144 | + errno = 0; | ||
145 | + conversion = strtoll(source_date_epoch, &tmp, 10); | ||
146 | + create_time = conversion; | ||
147 | + if (!isdigit((unsigned char)*source_date_epoch) || *tmp != '\0' | ||
148 | + || errno != 0 || (long long)create_time != conversion) { | ||
149 | + die("SOURCE_DATE_EPOCH is too big or contains non-digits: \"%s\"", | ||
150 | + source_date_epoch); | ||
151 | + } | ||
152 | + } else if (gettimeofday(&create_timeval, NULL) == 0 && create_timeval.tv_sec != (time_t)-1) { | ||
153 | create_time = create_timeval.tv_sec; | ||
154 | + } | ||
155 | + | ||
156 | volume_id = generate_volume_id(); | ||
157 | check_atari(); | ||
158 | |||
diff --git a/meta/recipes-devtools/dosfstools/dosfstools_4.2.bb b/meta/recipes-devtools/dosfstools/dosfstools_4.2.bb index 47d81dac8d..175fa265ef 100644 --- a/meta/recipes-devtools/dosfstools/dosfstools_4.2.bb +++ b/meta/recipes-devtools/dosfstools/dosfstools_4.2.bb | |||
@@ -13,6 +13,8 @@ SRC_URI = "${GITHUB_BASE_URI}/download/v${PV}/${BP}.tar.gz \ | |||
13 | " | 13 | " |
14 | SRC_URI[sha256sum] = "64926eebf90092dca21b14259a5301b7b98e7b1943e8a201c7d726084809b527" | 14 | SRC_URI[sha256sum] = "64926eebf90092dca21b14259a5301b7b98e7b1943e8a201c7d726084809b527" |
15 | 15 | ||
16 | SRC_URI += "file://source-date-epoch.patch" | ||
17 | |||
16 | inherit autotools gettext pkgconfig update-alternatives github-releases | 18 | inherit autotools gettext pkgconfig update-alternatives github-releases |
17 | 19 | ||
18 | EXTRA_OECONF = "--enable-compat-symlinks --without-iconv" | 20 | EXTRA_OECONF = "--enable-compat-symlinks --without-iconv" |