1commit 68564ebb50f8afab5a9527c534417e247cca0b27
2Author: Filipe Manana <fdmanana@kernel.org>
3Date: Thu Aug 17 10:20:13 2023 +0100
4
5 libmount: Fix regression when mounting with atime
6
7 A regression was introduced in v2.39 that causes mounting with the atime
8 option to fail:
9
10 $ mkfs.ext4 -F /dev/sdi
11 $ mount -o atime /dev/sdi /mnt/sdi
12 mount: /mnt/sdi: not mount point or bad option.
13 dmesg(1) may have more information after failed mount system call.
14
15 The failure comes from the mount_setattr(2) call returning -EINVAL. This
16 is because we pass an invalid value for the attr_clr argument. From a
17 strace capture we have:
18
19 mount_setattr(4, "", AT_EMPTY_PATH, {attr_set=0, attr_clr=MOUNT_ATTR_NOATIME, propagation=0 /* MS_??? */, userns_fd=0}, 32) = -1 EINVAL (Invalid argument)
20
21 We can't pass MOUNT_ATTR_NOATIME to mount_setattr(2) through the attr_clr
22 argument because all atime options are exclusive, so in order to set atime
23 one has to pass MOUNT_ATTR__ATIME to attr_clr and leave attr_set as
24 MOUNT_ATTR_RELATIME (which is defined as a value of 0).
25
26 This can be read from the man page for mount_setattr(2) and also from the
27 kernel source:
28
29 $ cat fs/namespace.c
30 static int build_mount_kattr(const struct mount_attr *attr, size_t usize,
31 struct mount_kattr *kattr, unsigned int flags)
32 {
33 (...)
34 /*
35 * Since the MOUNT_ATTR_<atime> values are an enum, not a bitmap,
36 * users wanting to transition to a different atime setting cannot
37 * simply specify the atime setting in @attr_set, but must also
38 * specify MOUNT_ATTR__ATIME in the @attr_clr field.
39 * So ensure that MOUNT_ATTR__ATIME can't be partially set in
40 * @attr_clr and that @attr_set can't have any atime bits set if
41 * MOUNT_ATTR__ATIME isn't set in @attr_clr.
42 */
43 if (attr->attr_clr & MOUNT_ATTR__ATIME) {
44 if ((attr->attr_clr & MOUNT_ATTR__ATIME) != MOUNT_ATTR__ATIME)
45 return -EINVAL;
46
47 /*
48 * Clear all previous time settings as they are mutually
49 * exclusive.
50 */
51 kattr->attr_clr |= MNT_RELATIME | MNT_NOATIME;
52 switch (attr->attr_set & MOUNT_ATTR__ATIME) {
53 case MOUNT_ATTR_RELATIME:
54 kattr->attr_set |= MNT_RELATIME;
55 break;
56 case MOUNT_ATTR_NOATIME:
57 kattr->attr_set |= MNT_NOATIME;
58 break;
59 case MOUNT_ATTR_STRICTATIME:
60 break;
61 default:
62 return -EINVAL;
63 }
64 (...)
65
66 So fix this by setting attr_clr MOUNT_ATTR__ATIME if we want to clear any
67 atime related option.
68
69 Signed-off-by: Filipe Manana <fdmanana@kernel.org>
70
71diff --git a/libmount/src/optlist.c b/libmount/src/optlist.c
72index 1e962ec6d..0702adae7 100644
73--- a/libmount/src/optlist.c
74+++ b/libmount/src/optlist.c
75@@ -875,7 +875,18 @@ int mnt_optlist_get_attrs(struct libmnt_optlist *ls, uint64_t *set, uint64_t *cl
76
77 if (opt->ent->mask & MNT_INVERT) {
78 DBG(OPTLIST, ul_debugobj(ls, " clr: %s", opt->ent->name));
79- *clr |= x;
80+ /*
81+ * All atime settings are mutually exclusive so *clr must
82+ * have MOUNT_ATTR__ATIME set.
83+ *
84+ * See the function fs/namespace.c:build_mount_kattr()
85+ * in the linux kernel source.
86+ */
87+ if (x == MOUNT_ATTR_RELATIME || x == MOUNT_ATTR_NOATIME ||
88+ x == MOUNT_ATTR_STRICTATIME)
89+ *clr |= MOUNT_ATTR__ATIME;
90+ else
91+ *clr |= x;
92 } else {
93 DBG(OPTLIST, ul_debugobj(ls, " set: %s", opt->ent->name));
94 *set |= x;
95diff --git a/tests/expected/libmount/context-mount-flags b/tests/expected/libmount/context-mount-flags
96index 960641863..eb71323dd 100644
97--- a/tests/expected/libmount/context-mount-flags
98+++ b/tests/expected/libmount/context-mount-flags
99@@ -3,3 +3,6 @@ ro,nosuid,noexec
100 successfully mounted
101 rw,nosuid,noexec
102 successfully umounted
103+successfully mounted
104+rw,relatime
105+successfully umounted
106diff --git a/tests/ts/libmount/context b/tests/ts/libmount/context
107index f5b47185e..a5d2e81a3 100755
108--- a/tests/ts/libmount/context
109+++ b/tests/ts/libmount/context
110@@ -116,8 +116,15 @@ $TS_CMD_FINDMNT --kernel --mountpoint $MOUNTPOINT -o VFS-OPTIONS -n >> $TS_OUTPU
111
112 ts_run $TESTPROG --umount $MOUNTPOINT >> $TS_OUTPUT 2>> $TS_ERRLOG
113 is_mounted $DEVICE && echo "$DEVICE still mounted" >> $TS_OUTPUT 2>> $TS_ERRLOG
114-ts_finalize_subtest
115
116+# Test that the atime option works after the migration to use the new kernel mount APIs.
117+ts_run $TESTPROG --mount -o atime $DEVICE $MOUNTPOINT >> $TS_OUTPUT 2>> $TS_ERRLOG
118+$TS_CMD_FINDMNT --kernel --mountpoint $MOUNTPOINT -o VFS-OPTIONS -n >> $TS_OUTPUT 2>> $TS_ERRLOG
119+is_mounted $DEVICE || echo "$DEVICE not mounted" >> $TS_OUTPUT 2>> $TS_ERRLOG
120+ts_run $TESTPROG --umount $MOUNTPOINT >> $TS_OUTPUT 2>> $TS_ERRLOG
121+is_mounted $DEVICE && echo "$DEVICE still mounted" >> $TS_OUTPUT 2>> $TS_ERRLOG
122+
123+ts_finalize_subtest
124
125 ts_init_subtest "mount-loopdev"
126 mkdir -p $MOUNTPOINT &> /dev/null
127
128commit 1ec71634aa4ef5ddca23d65c8a296f3614231e8a
129Author: Colin Gillespie <colin@cgillespie.xyz>
130Date: Wed Aug 9 18:28:07 2023 +1000
131
132 libblkid: (bcachefs) fix not detecting large superblocks
133
134 Probing does not detect bcachefs filesystems with a superblock larger
135 than 4KiB. Bcachefs superblocks grow in size and can become much larger
136 than this.
137
138 Increase the superblock maximum size limit to 1MiB.
139
140 Validate the superblock isn't larger than the maximum size defined in
141 the superblocks layout section.
142
143 (cherry picked from commit 48d573797797650d96456979797c0155d58f61cb)
144
145diff --git a/libblkid/src/superblocks/bcache.c b/libblkid/src/superblocks/bcache.c
146index 40e702d75..236877042 100644
147--- a/libblkid/src/superblocks/bcache.c
148+++ b/libblkid/src/superblocks/bcache.c
149@@ -102,6 +102,15 @@ union bcachefs_sb_csum {
150 uint8_t raw[16];
151 } __attribute__((packed));
152
153+struct bcachefs_sb_layout {
154+ uint8_t magic[16];
155+ uint8_t layout_type;
156+ uint8_t sb_max_size_bits;
157+ uint8_t nr_superblocks;
158+ uint8_t pad[5];
159+ uint64_t sb_offset[61];
160+} __attribute__((packed));
161+
162 struct bcachefs_super_block {
163 union bcachefs_sb_csum csum;
164 uint16_t version;
165@@ -123,7 +132,7 @@ struct bcachefs_super_block {
166 uint64_t flags[8];
167 uint64_t features[2];
168 uint64_t compat[2];
169- uint8_t layout[512];
170+ struct bcachefs_sb_layout layout;
171 struct bcachefs_sb_field _start[];
172 } __attribute__((packed));
173
174@@ -143,7 +152,7 @@ struct bcachefs_super_block {
175 /* granularity of offset and length fields within superblock */
176 #define BCACHEFS_SECTOR_SIZE 512
177 /* maximum superblock size */
178-#define BCACHEFS_SB_MAX_SIZE 4096
179+#define BCACHEFS_SB_MAX_SIZE 0x100000
180 /* fields offset within super block */
181 #define BCACHEFS_SB_FIELDS_OFF offsetof(struct bcachefs_super_block, _start)
182 /* tag value for members field */
183@@ -302,6 +311,9 @@ static int probe_bcachefs(blkid_probe pr, const struct blkid_idmag *mag)
184 return BLKID_PROBE_NONE;
185
186 sb_size = BCACHEFS_SB_FIELDS_OFF + BYTES(bcs);
187+ if (sb_size > BCACHEFS_SECTOR_SIZE << bcs->layout.sb_max_size_bits)
188+ return BLKID_PROBE_NONE;
189+
190 if (sb_size > BCACHEFS_SB_MAX_SIZE)
191 return BLKID_PROBE_NONE;
192
193
194commit acbf17ae8f8ee0f941fe98ed12f115f2b349bba8
195Author: Karel Zak <kzak@redhat.com>
196Date: Wed Aug 23 11:53:45 2023 +0200
197
198 libblkid: (bcachefs) fix compiler warning [-Werror=sign-compare]
199
200 Addresses: https://github.com/util-linux/util-linux/pull/2427
201 Signed-off-by: Karel Zak <kzak@redhat.com>
202 (cherry picked from commit 17873d38fc97913c0a31d4bd08cfbfe45c4de5be)
203
204diff --git a/libblkid/src/superblocks/bcache.c b/libblkid/src/superblocks/bcache.c
205index 236877042..6ab3fe9d4 100644
206--- a/libblkid/src/superblocks/bcache.c
207+++ b/libblkid/src/superblocks/bcache.c
208@@ -311,7 +311,7 @@ static int probe_bcachefs(blkid_probe pr, const struct blkid_idmag *mag)
209 return BLKID_PROBE_NONE;
210
211 sb_size = BCACHEFS_SB_FIELDS_OFF + BYTES(bcs);
212- if (sb_size > BCACHEFS_SECTOR_SIZE << bcs->layout.sb_max_size_bits)
213+ if (sb_size > ((uint64_t) BCACHEFS_SECTOR_SIZE << bcs->layout.sb_max_size_bits))
214 return BLKID_PROBE_NONE;
215
216 if (sb_size > BCACHEFS_SB_MAX_SIZE)
217
218commit 6b9fda87c4e5d0c6f945d7565197f157b9fa3d5f
219Author: Thomas Weißschuh <thomas@t-8ch.de>
220Date: Wed Aug 23 11:58:33 2023 +0200
221
222 libblkid: (bcachefs) fix size validation
223
224 Avoid signed shift out-of-bounds.
225
226 Also mark the constants explitly as unsigned instead of casting.
227
228 Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
229 (cherry picked from commit befe455f59de8c7bc66b85ed52aae8cbc95325fa)
230
231diff --git a/libblkid/src/superblocks/bcache.c b/libblkid/src/superblocks/bcache.c
232index 6ab3fe9d4..28ac4b52b 100644
233--- a/libblkid/src/superblocks/bcache.c
234+++ b/libblkid/src/superblocks/bcache.c
235@@ -142,17 +142,19 @@ struct bcachefs_super_block {
236 /* magic string len */
237 #define BCACHE_SB_MAGIC_LEN (sizeof(BCACHE_SB_MAGIC) - 1)
238 /* super block offset */
239-#define BCACHE_SB_OFF 0x1000
240+#define BCACHE_SB_OFF 0x1000U
241 /* supper block offset in kB */
242 #define BCACHE_SB_KBOFF (BCACHE_SB_OFF >> 10)
243 /* magic string offset within super block */
244 #define BCACHE_SB_MAGIC_OFF offsetof(struct bcache_super_block, magic)
245 /* start of checksummed data within superblock */
246-#define BCACHE_SB_CSUMMED_START 8
247+#define BCACHE_SB_CSUMMED_START 8U
248 /* granularity of offset and length fields within superblock */
249-#define BCACHEFS_SECTOR_SIZE 512
250+#define BCACHEFS_SECTOR_SIZE 512U
251+/* maximum superblock size shift */
252+#define BCACHEFS_SB_MAX_SIZE_SHIFT 0x10U
253 /* maximum superblock size */
254-#define BCACHEFS_SB_MAX_SIZE 0x100000
255+#define BCACHEFS_SB_MAX_SIZE (1U << BCACHEFS_SB_MAX_SIZE_SHIFT)
256 /* fields offset within super block */
257 #define BCACHEFS_SB_FIELDS_OFF offsetof(struct bcachefs_super_block, _start)
258 /* tag value for members field */
259@@ -311,12 +313,16 @@ static int probe_bcachefs(blkid_probe pr, const struct blkid_idmag *mag)
260 return BLKID_PROBE_NONE;
261
262 sb_size = BCACHEFS_SB_FIELDS_OFF + BYTES(bcs);
263- if (sb_size > ((uint64_t) BCACHEFS_SECTOR_SIZE << bcs->layout.sb_max_size_bits))
264- return BLKID_PROBE_NONE;
265
266 if (sb_size > BCACHEFS_SB_MAX_SIZE)
267 return BLKID_PROBE_NONE;
268
269+ if (bcs->layout.sb_max_size_bits > BCACHEFS_SB_MAX_SIZE_SHIFT)
270+ return BLKID_PROBE_NONE;
271+
272+ if (sb_size > (BCACHEFS_SECTOR_SIZE << bcs->layout.sb_max_size_bits))
273+ return BLKID_PROBE_NONE;
274+
275 sb = blkid_probe_get_sb_buffer(pr, mag, sb_size);
276 if (!sb)
277 return BLKID_PROBE_NONE;