]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: fix reloading multiple confexts at the same time
authorLuca Boccassi <luca.boccassi@gmail.com>
Wed, 11 Mar 2026 14:20:21 +0000 (14:20 +0000)
committerLuca Boccassi <luca.boccassi@gmail.com>
Wed, 11 Mar 2026 16:54:33 +0000 (16:54 +0000)
[] has higher precedence than pointer dereference, hence hilarity
ensues as soon as there are multuple images

Originally reported on yeswehack.com as:
YWH-PGM9780-122

Follow-up for dfdeb0b1cbb05a213f0965eedfe0e7ef06cd39d3

src/core/namespace.c
test/units/TEST-50-DISSECT.dissect.sh

index 9727d725eb7dfe4cb5c021460fba7ae6f231fd16..6e4ec80dc96d4e13f4d22f7aa6b730badd413222 100644 (file)
@@ -3877,7 +3877,7 @@ static int handle_mount_from_grandchild(
                 if (r < 0)
                         return log_oom_debug();
 
-                *fd_layers[(*n_fd_layers)++] = TAKE_FD(tree_fd);
+                (*fd_layers)[(*n_fd_layers)++] = TAKE_FD(tree_fd);
         }
         m->overlay_layers = strv_free(m->overlay_layers);
         m->overlay_layers = TAKE_PTR(new_layers);
index 7a68e62fb0067a3ca3a620cca3cb9197d8ee6393..f87bda82ce295f103b0d6abae8de2ac5a3d47dde 100755 (executable)
@@ -649,13 +649,20 @@ VDIR="/tmp/${VBASE}.v"
 mkdir "$VDIR"
 rm -rf /tmp/markers/
 mkdir /tmp/markers/
+CDIR1="/tmp/${VBASE}_confext_a"
+CDIR2="/tmp/${VBASE}_confext_b"
+mkdir -p "$CDIR1/etc/extension-release.d/" "$CDIR2/etc/extension-release.d/"
+echo "ID=_any" >"$CDIR1/etc/extension-release.d/extension-release.${VBASE}_confext_a"
+touch "$CDIR1/etc/${VBASE}_confext_a.marker"
+echo "ID=_any" >"$CDIR2/etc/extension-release.d/extension-release.${VBASE}_confext_b"
+touch "$CDIR2/etc/${VBASE}_confext_b.marker"
 cat >/run/systemd/system/testservice-50g.service <<EOF
 [Service]
 Type=notify-reload
 EnvironmentFile=-/usr/lib/systemd/systemd-asan-env
 PrivateTmp=disconnected
 BindPaths=/tmp/markers/
-ExtensionDirectories=-${VDIR}
+ExtensionDirectories=-${VDIR} ${CDIR1} ${CDIR2}
 ExecStart=bash -o pipefail -x -c ' \\
     trap "{ \\
         systemd-notify --reloading; \\
@@ -674,12 +681,16 @@ systemctl is-active testservice-50g.service
 # First reload; at reload time, the marker file in /etc should be picked up.
 systemctl reload testservice-50g.service
 grep -q -F "${VBASE}_1.marker" /tmp/markers/50g
+grep -q -F "${VBASE}_confext_a.marker" /tmp/markers/50g
+grep -q -F "${VBASE}_confext_b.marker" /tmp/markers/50g
 # Make a version 2 and reload again; this time we should see the v2 marker
 mkdir -p "$VDIR/${VBASE}_2/etc/extension-release.d/"
 echo "ID=_any" >"$VDIR/${VBASE}_2/etc/extension-release.d/extension-release.${VBASE}_2"
 touch "$VDIR/${VBASE}_2/etc/${VBASE}_2.marker"
 systemctl reload testservice-50g.service
 grep -q -F "${VBASE}_2.marker" /tmp/markers/50g
+grep -q -F "${VBASE}_confext_a.marker" /tmp/markers/50g
+grep -q -F "${VBASE}_confext_b.marker" /tmp/markers/50g
 # Do it for a couple more times (to make sure we're tearing down old overlays)
 for _ in {1..5}; do systemctl reload testservice-50g.service; done
 systemctl stop testservice-50g.service
@@ -690,13 +701,17 @@ rm -f /run/systemd/system/testservice-50g.service
 # this time)
 VDIR2="/tmp/${VBASE}.raw.v"
 mkdir "$VDIR2"
+CIMG1="/tmp/${VBASE}_confext_a.raw"
+CIMG2="/tmp/${VBASE}_confext_b.raw"
+mksquashfs "$CDIR1" "$CIMG1" -noappend
+mksquashfs "$CDIR2" "$CIMG2" -noappend
 cat >/run/systemd/system/testservice-50h.service <<EOF
 [Service]
 Type=notify-reload
 EnvironmentFile=-/usr/lib/systemd/systemd-asan-env
 PrivateTmp=disconnected
 BindPaths=/tmp/markers/
-ExtensionImages=-$VDIR2
+ExtensionImages=-$VDIR2 ${CIMG1} ${CIMG2}
 ExecStart=bash -o pipefail -x -c ' \\
     trap "{ \\
         systemd-notify --reloading; \\
@@ -713,15 +728,21 @@ systemctl is-active testservice-50h.service
 # First reload should pick up the v1 marker
 systemctl reload testservice-50h.service
 grep -q -F "${VBASE}_1.marker" /tmp/markers/50h
+grep -q -F "${VBASE}_confext_a.marker" /tmp/markers/50h
+grep -q -F "${VBASE}_confext_b.marker" /tmp/markers/50h
 # Second reload should pick up the v2 marker
 mksquashfs "$VDIR/${VBASE}_2" "$VDIR2/${VBASE}_2.raw" -noappend
 systemctl reload testservice-50h.service
 grep -q -F "${VBASE}_2.marker" /tmp/markers/50h
-# Test that removing all the extensions don't cause any issues
+grep -q -F "${VBASE}_confext_a.marker" /tmp/markers/50h
+grep -q -F "${VBASE}_confext_b.marker" /tmp/markers/50h
+# Test that removing all the vpick extensions don't cause any issues
 rm -rf "${VDIR2:?}"/*
 systemctl reload testservice-50h.service
 systemctl is-active testservice-50h.service
-grep -q -F "no-marker" /tmp/markers/50h
+(! grep -q -F "${VBASE}_2.marker" /tmp/markers/50h)
+grep -q -F "${VBASE}_confext_a.marker" /tmp/markers/50h
+grep -q -F "${VBASE}_confext_b.marker" /tmp/markers/50h
 systemctl stop testservice-50h.service
 rm -f /run/systemd/system/testservice-50h.service
 
@@ -733,7 +754,7 @@ EnvironmentFile=-/usr/lib/systemd/systemd-asan-env
 PrivateTmp=disconnected
 BindPaths=/tmp/markers/
 RootImage=$MINIMAL_IMAGE.raw
-ExtensionDirectories=-${VDIR}
+ExtensionDirectories=-${VDIR} ${CDIR1} ${CDIR2}
 NotifyAccess=all
 ExecStart=bash -x -o pipefail -c ' \
     trap '"'"' \
@@ -755,6 +776,8 @@ systemctl is-active testservice-50i.service
 mv "$VDIR/.${VBASE}_2" "$VDIR/${VBASE}_2/"
 systemctl reload testservice-50i.service
 grep -q -F "${VBASE}_2.marker" /tmp/markers/50i
+grep -q -F "${VBASE}_confext_a.marker" /tmp/markers/50i
+grep -q -F "${VBASE}_confext_b.marker" /tmp/markers/50i
 # Ensure that we are also still seeing files exclusive to the root image
 grep -q -F "MARKER=1" /tmp/markers/50i
 systemctl stop testservice-50i.service
@@ -768,7 +791,7 @@ EnvironmentFile=-/usr/lib/systemd/systemd-asan-env
 PrivateTmp=disconnected
 BindPaths=/tmp/markers/
 RootDirectory=/tmp/vpickminimg
-ExtensionDirectories=-${VDIR}
+ExtensionDirectories=-${VDIR} ${CDIR1} ${CDIR2}
 NotifyAccess=all
 ExecStart=bash -x -o pipefail -c ' \
     trap '"'"' \
@@ -786,6 +809,8 @@ systemctl start testservice-50j.service
 systemctl is-active testservice-50j.service
 systemctl reload testservice-50j.service
 grep -q -F "${VBASE}_2.marker" /tmp/markers/50j
+grep -q -F "${VBASE}_confext_a.marker" /tmp/markers/50j
+grep -q -F "${VBASE}_confext_b.marker" /tmp/markers/50j
 grep -q -F "MARKER=1" /tmp/markers/50j
 systemctl stop testservice-50j.service
 rm -f /run/systemd/system/testservice-50j.service
@@ -797,7 +822,7 @@ EnvironmentFile=-/usr/lib/systemd/systemd-asan-env
 PrivateTmp=disconnected
 BindPaths=/tmp/markers/
 RootImage=$MINIMAL_IMAGE.raw
-ExtensionImages=-$VDIR2 /tmp/app0.raw
+ExtensionImages=-$VDIR2 /tmp/app0.raw ${CIMG1} ${CIMG2}
 PrivateUsers=yes
 NotifyAccess=all
 ExecStart=bash -x -o pipefail -c ' \
@@ -822,20 +847,26 @@ fi
 mksquashfs "$VDIR/${VBASE}_1" "$VDIR2/${VBASE}_1.raw" -noappend
 systemctl reload testservice-50k.service
 grep -q -F "${VBASE}_1.marker" /tmp/markers/50k
+grep -q -F "${VBASE}_confext_a.marker" /tmp/markers/50k
+grep -q -F "${VBASE}_confext_b.marker" /tmp/markers/50k
 # Second reload should pick up the v2 marker
 mksquashfs "$VDIR/${VBASE}_2" "$VDIR2/${VBASE}_2.raw" -noappend
 systemctl reload testservice-50k.service
 grep -q -F "${VBASE}_2.marker" /tmp/markers/50k
-# Test that removing all the extensions don't cause any issues
+grep -q -F "${VBASE}_confext_a.marker" /tmp/markers/50k
+grep -q -F "${VBASE}_confext_b.marker" /tmp/markers/50k
+# Test that removing all the vpick extensions don't cause any issues
 rm -rf "${VDIR2:?}"/*
 systemctl reload testservice-50k.service
 systemctl is-active testservice-50k.service
 grep -q -F "MARKER=1" /tmp/markers/50k
+grep -q -F "${VBASE}_confext_a.marker" /tmp/markers/50k
+grep -q -F "${VBASE}_confext_b.marker" /tmp/markers/50k
 systemctl stop testservice-50k.service
 rm -f /run/systemd/system/testservice-50k.service
 
 systemctl daemon-reload
-rm -rf "$VDIR" "$VDIR2" /tmp/vpickminimg /tmp/markers/
+rm -rf "$VDIR" "$VDIR2" "$CDIR1" "$CDIR2" "$CIMG1" "$CIMG2" /tmp/vpickminimg /tmp/markers/
 
 # Check dissect shortcut for verity images
 cat >/run/systemd/system/testservice-50m.service <<EOF