From 4bc8637a74d533fdefc4ad6079ea4d723fc4be1e Mon Sep 17 00:00:00 2001 From: Tim Eertmoed Date: Wed, 2 Sep 2026 21:20:52 +0200 Subject: [PATCH] Freigaben einbinden: Mount im Namensraum des Wirts Eine Freigabe wurde nie eingebunden -- "mount error(1): Operation not permitted". Gemessen: mit denselben Optionen und Zugangsdaten gelingt die Einbindung aus einer normalen Root-Shell sofort. Ursache ist der eigene Mount-Namensraum des Dienstes (ProtectSystem, ProtectHome, PrivateTmp, ReadWritePaths); darin laesst sich kein neues Dateisystem einbinden. Nachgebaut und belegt: derselbe Aufruf scheitert in einem transienten Unit mit dieser Haertung und gelingt, sobald er ueber nsenter im Namensraum des Wirts laeuft. Von dort wird der Mount in den Namensraum des Dienstes weitergegeben, die Anwendung sieht ihn also -- geprueft, inklusive Lesbarkeit fuer den Dienstbenutzer. mount-cifs und umount laufen deshalb ueber nsenter. Ohne nsenter im System bleibt das Verhalten unveraendert. Die Haertung des Dienstes bleibt vollstaendig erhalten. Co-Authored-By: Claude Opus 5 --- deploy/tesm-helper | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/deploy/tesm-helper b/deploy/tesm-helper index c508b21..cd7dfc1 100644 --- a/deploy/tesm-helper +++ b/deploy/tesm-helper @@ -258,8 +258,19 @@ case "$verb" in # Kommandozeile (Prozessliste) und nie ueber die Umgebung # (/proc//environ). read_stdin_limited > "$creds" - mkdir -p "$target" - if mount -t cifs "$share" "$target" \ + # Der aufrufende Dienst laeuft in einem eigenen Mount-Namensraum + # (ProtectSystem, PrivateTmp, ReadWritePaths). Ein Einbinden *darin* + # scheitert mit "mount error(1): Operation not permitted" -- gemessen: mit + # denselben Optionen und denselben Zugangsdaten gelingt es aus einer + # normalen Root-Shell sofort. Deshalb wird im Namensraum des Wirts + # eingebunden; von dort wird der Mount in den Namensraum des Dienstes + # weitergegeben (er haengt als "slave" darunter), die Anwendung sieht ihn + # also. Die Zugangsdatei unter /run ist ueber die Grenze lesbar, /run ist + # nicht privatisiert. + im_wirt=(nsenter --mount=/proc/1/ns/mnt --) + command -v nsenter >/dev/null 2>&1 || im_wirt=() + "${im_wirt[@]}" mkdir -p "$target" + if "${im_wirt[@]}" mount -t cifs "$share" "$target" \ -o "credentials=$creds,uid=$(id -u tesm 2>/dev/null || echo 0),gid=$(id -g tesm 2>/dev/null || echo 0),file_mode=0640,dir_mode=0750,vers=3.1.1,seal" then shred -u "$creds" 2>/dev/null || rm -f "$creds" @@ -271,8 +282,13 @@ case "$verb" in umount) check_mount_target "${1:?Ziel fehlt}" - umount -l "$1" || true - rmdir "$1" 2>/dev/null || true + # Gegenstueck zu mount-cifs: der Mount liegt im Namensraum des Wirts, also + # muss er auch dort geloest werden. Ein umount im Dienst-Namensraum wuerde + # ihn nur dort ausblenden und die Freigabe bliebe eingebunden. + im_wirt=(nsenter --mount=/proc/1/ns/mnt --) + command -v nsenter >/dev/null 2>&1 || im_wirt=() + "${im_wirt[@]}" umount -l "$1" || true + "${im_wirt[@]}" rmdir "$1" 2>/dev/null || true ;; apt-install)