@@ -89,19 +89,27 @@ function extension_prepare_config__netboot_defaults_and_validate() {
8989 exit_with_error " ${EXTENSION} : ROOTFS_COMPRESSION=none requires ROOTFS_EXPORT_DIR (otherwise nothing is produced)"
9090 fi
9191
92- # Keep ROOTFS_EXPORT_DIR confined to a fixed base under ${SRC}/output, so a
93- # stray typo or accidental absolute path can never let rsync --delete touch
94- # the host filesystem outside that subtree. Any user value (relative or
95- # absolute) is treated as a sub-path of the base; an absolute `/srv/nfs`
96- # becomes `${SRC}/output/netboot-export//srv/nfs` (the ordinary path-join
97- # semantics make this a plain sub-directory). If a NFS server on the build
98- # host expects `/srv/...`, symlink `${SRC}/output/netboot-export` there.
99- if [[ -n " ${ROOTFS_EXPORT_DIR} " ]]; then
100- case " ${ROOTFS_EXPORT_DIR} " in
101- * ..* ) exit_with_error " ${EXTENSION} : ROOTFS_EXPORT_DIR must not contain '..'" " ${ROOTFS_EXPORT_DIR} " ;;
102- esac
103- declare -g ROOTFS_EXPORT_DIR=" ${SRC} /output/netboot-export/${ROOTFS_EXPORT_DIR} "
104- fi
92+ _netboot_normalize_export_dir
93+ }
94+
95+ # Confine ROOTFS_EXPORT_DIR to a fixed base under ${SRC}/output so rsync --delete
96+ # can never escape that subtree. Any user value (relative or absolute) becomes a
97+ # sub-path of the base: `/srv/nfs` turns into `${SRC}/output/netboot-export//srv/nfs`
98+ # (path-join semantics make it a plain sub-directory). If the build host also
99+ # serves NFS, symlink `${SRC}/output/netboot-export` to the export root.
100+ #
101+ # Called from both extension_prepare_config (covers no-docker builds and the
102+ # in-container phase of docker builds) and host_pre_docker_launch (covers the
103+ # on-host phase of docker builds, before the docker bind-mount).
104+ function _netboot_normalize_export_dir() {
105+ [[ -z " ${ROOTFS_EXPORT_DIR} " ]] && return 0
106+ # Already normalized — extension_prepare_config may fire after host_pre_docker_launch
107+ # has already run on the host side.
108+ [[ " ${ROOTFS_EXPORT_DIR} " == " ${SRC} /output/netboot-export/" * ]] && return 0
109+ case " ${ROOTFS_EXPORT_DIR} " in
110+ * ..* ) exit_with_error " ${EXTENSION} : ROOTFS_EXPORT_DIR must not contain '..'" " ${ROOTFS_EXPORT_DIR} " ;;
111+ esac
112+ declare -g ROOTFS_EXPORT_DIR=" ${SRC} /output/netboot-export/${ROOTFS_EXPORT_DIR} "
105113}
106114
107115# Ensure NFS-root client support is built into the kernel.
@@ -144,6 +152,9 @@ function post_customize_image__netboot_skip_firstlogin_wizard() {
144152# target and point ROOTFS_EXPORT_DIR at the container path for rsync.
145153function host_pre_docker_launch__netboot_mount_export_dir() {
146154 [[ -z " ${ROOTFS_EXPORT_DIR} " ]] && return 0
155+ # Host-phase normalization: extension_prepare_config runs inside the container,
156+ # which is too late — docker needs an absolute source path for the bind-mount below.
157+ _netboot_normalize_export_dir
147158 declare container_export_dir=" /armbian/netboot-export"
148159 mkdir -p " ${ROOTFS_EXPORT_DIR} "
149160 display_alert " ${EXTENSION} : bind-mounting ROOTFS_EXPORT_DIR into container" " ${ROOTFS_EXPORT_DIR} -> ${container_export_dir} " " info"
0 commit comments