diff --git a/SPECS/calamares/0002-partition-extend-device-filtering-to-exclude-vfat.patch b/SPECS/calamares/0002-partition-extend-device-filtering-to-exclude-vfat.patch new file mode 100644 index 0000000000..76577cb30f --- /dev/null +++ b/SPECS/calamares/0002-partition-extend-device-filtering-to-exclude-vfat.patch @@ -0,0 +1,88 @@ +From b39330a306aa02d43a24f7f875a5a358207b8302 Mon Sep 17 00:00:00 2001 +From: kintalix jayanth +Date: Mon, 17 Nov 2025 18:35:04 +0530 +Subject: [PATCH 2/2] partition extend device filtering to exclude vfat/fat32 + media + +Combine iso9660 and vfat/fat32 detection into a unified function +isIso9660VFat(). Use blkid command to identify these filesystem types on +devices and their partitions. Exclude these devices from the list of +install targets in Calamares to prevent installation on read-only USB/media. + +Signed-off-by: kintalix jayanth +--- + src/modules/partition/core/DeviceList.cpp | 24 +++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +diff --git a/src/modules/partition/core/DeviceList.cpp b/src/modules/partition/core/DeviceList.cpp +index 155d23d..ad79a39 100644 +--- a/src/modules/partition/core/DeviceList.cpp ++++ b/src/modules/partition/core/DeviceList.cpp +@@ -48,34 +48,38 @@ hasRootPartition( Device* device ) + * The @p path should point to a device; blkid is used to check the FS type. + */ + static bool +-blkIdCheckIso9660( const QString& path ) ++blkIdCheckIso9660orVFat(const QString &path) + { + // If blkid fails, there's no output, but we don't care + auto r = Calamares::System::runCommand( { "blkid", path }, std::chrono::seconds( 30 ) ); +- return r.getOutput().contains( "iso9660" ); ++ auto output = r.getOutput(); ++ return output.contains("iso9660") ++ || (( output.contains("vfat") ++ || output.contains("fat32") ++ || output.contains("fat")) && output.contains("CDROM")); + } + + /// @brief Convenience to check if @p partition holds an iso9660 filesystem + static bool +-blkIdCheckIso9660P( const Partition* partition ) ++blkIdCheckIso9660orVFatP( const Partition* partition ) + { +- return blkIdCheckIso9660( partition->partitionPath() ); ++ return blkIdCheckIso9660orVFat( partition->partitionPath() ); + } + + /** @brief Check if the @p device is an iso9660 device + * +- * An iso9660 device is **probably** a CD-ROM. If the device holds an +- * iso9660 FS, or any of its partitions do, then we call it an iso9660 device. ++ * An iso9660/vfat device is **probably** a CD-ROM. If the device holds an ++ * iso9660/vfat FS, or any of its partitions do, then we call it an iso9660/vfat device. + */ + static bool +-isIso9660( const Device* device ) ++isIso9660orVFat( const Device* device ) + { + const QString path = device->deviceNode(); + if ( path.isEmpty() ) + { + return false; + } +- if ( blkIdCheckIso9660( path ) ) ++ if ( blkIdCheckIso9660orVFat( path ) ) + { + return true; + } +@@ -83,7 +87,7 @@ isIso9660( const Device* device ) + if ( device->partitionTable() && !device->partitionTable()->children().isEmpty() ) + { + const auto& p = device->partitionTable()->children(); +- return std::any_of( p.cbegin(), p.cend(), blkIdCheckIso9660P ); ++ return std::any_of( p.cbegin(), p.cend(), blkIdCheckIso9660orVFatP); + } + return false; + } +@@ -180,7 +184,7 @@ getDevices( DeviceType which ) + cDebug() << Logger::SubEntry << "Removing device with root filesystem (/) on it" << it; + it = removeInSafeMode( devices, it ); + } +- else if ( writableOnly && isIso9660( *it ) ) ++ else if ( writableOnly && isIso9660orVFat( *it ) ) + { + cDebug() << Logger::SubEntry << "Removing device with iso9660 filesystem (probably a CD) on it" << it; + it = removeInSafeMode( devices, it ); +-- +2.34.1 + diff --git a/SPECS/calamares/calamares.spec b/SPECS/calamares/calamares.spec index d7425e98a5..2460b7a362 100644 --- a/SPECS/calamares/calamares.spec +++ b/SPECS/calamares/calamares.spec @@ -7,7 +7,7 @@ Summary: Installer from a live CD/DVD/USB to disk # https://github.com/calamares/calamares/issues/1051 Name: calamares Version: 3.3.1 -Release: 14%{?dist} +Release: 15%{?dist} License: GPLv3+ Vendor: Intel Corporation Distribution: Edge Microvisor Toolkit @@ -61,6 +61,7 @@ Patch9: ui_redesign.patch Patch10: c69e229be0be9bd7a033776ebe3bec63206b8151.patch Patch11: change-wording-in-welcomepage.patch Patch12: 0001-Change-users-module-to-use-attended_config.json.patch +Patch13: 0002-partition-extend-device-filtering-to-exclude-vfat.patch # Compilation tools BuildRequires: cmake BuildRequires: extra-cmake-modules @@ -162,6 +163,7 @@ mv %{SOURCE56} data/images/wait.png %patch -P 10 -p1 %patch -P 11 -p1 %patch -P 12 -p1 +%patch -P 13 -p1 %build %cmake_kf \ @@ -239,6 +241,10 @@ install -p -m 644 %{SOURCE21} %{buildroot}%{_sysconfdir}/calamares/settings.conf %{_libdir}/libcalamaresui.so %changelog +* Tue Nov 18 2025 kintalix jayanth - 3.3.1-15 +- Prevent installer from listing installation media devices like bootable USB sticks +- formatted with FAT as valid target disks, thus avoiding accidental overwriting using rufus method + * Tue Sep 01 2025 kintalix jayanth - 3.3.1-14 - switched config path to attended_config.json instead of unattended_config.json diff --git a/toolkit/tools/imagegen/diskutils/diskutils.go b/toolkit/tools/imagegen/diskutils/diskutils.go index d62b6031ea..1513f2e817 100644 --- a/toolkit/tools/imagegen/diskutils/diskutils.go +++ b/toolkit/tools/imagegen/diskutils/diskutils.go @@ -11,6 +11,7 @@ import ( "os" "path/filepath" "regexp" + "slices" "strconv" "strings" "time" @@ -931,22 +932,40 @@ func SystemBlockDevices() (systemDevices []SystemBlockDevice, err error) { return systemDevices, nil } -// isReadOnlyISO checks if a device is mounted read-only (ISO on USB/CD). +// isReadOnlyISO checks whether a block device is installation media (ISO9660 or Rufus USB). func isReadOnlyISO(devicePath string) bool { mounts, err := os.ReadFile("/proc/mounts") if err != nil { logger.Log.Debugf("Failed to read /proc/mounts: %v", err) return false } + for _, line := range strings.Split(string(mounts), "\n") { fields := strings.Fields(line) - if len(fields) >= 4 && fields[0] == devicePath && fields[2] == "iso9660" { - options := strings.Split(fields[3], ",") - for _, opt := range options { - if opt == "ro" { - return true - } - } + if len(fields) < 4 { + continue + } + + dev := fields[0] + fsType := fields[2] + options := strings.Split(fields[3], ",") + + // Skip entries that are not part of this device (e.g., /dev/sdb should match /dev/sdb1) + if !strings.HasPrefix(dev, devicePath) { + continue + } + + // Common helper to check for read-only flag + isReadOnly := slices.Contains(options, "ro") + + if fsType == "iso9660" && isReadOnly { + // Case 1: dd USB or CD-based ISO + return true + } else if (fsType == "vfat" || fsType == "fat32" || fsType == "fat") && isReadOnly { + // Case 2: Rufus USB (FAT filesystem but read-only) + return true + } else { + logger.Log.Debugf("Non-installer mount detected on %s (fs=%s, ro=%v)", dev, fsType, isReadOnly) } } return false