Skip to content

🐛 [Crash] linux_filesystem.dart: int.parse crashes on Btrfs/overlay/network mounts with non-numeric Use% value #268

Description

@Toqsick

Summary

LinuxFilesystem.disks() crashes with an unhandled FormatException on systems where df -h returns a non-numeric string in the Use% column. This is a confirmed crash reproducible on Btrfs, overlay filesystems (e.g. Docker, Flatpak sandbox layers), network mounts (NFS, CIFS), and pseudo-filesystems.

Affected File

lib/linux/linux_filesystem.dartdisks() method

Root Cause

// Line ~50 in disks()
devices.add(DeviceInfo(
    values[0],
    values[1],
    values[2],
    values[3],
    int.parse(values[4].substring(0, values[4].length - 1)),  // ← CRASH HERE
    values[5],
    _removableDevices.any((x) => values[5].contains(x))));

int.parse() throws FormatException when values[4] is:

  • "-" — emitted by Btrfs and some overlay mounts when usage is indeterminate
  • "100%" with trailing space variants
  • Empty string when df output is malformed

Additionally, there is no bounds check on values.length. A df line with fewer than 6 columns (e.g. long filesystem names that wrap to the next line) will cause a RangeError on values[4] or values[5].

Reproduction

  1. Run linux-assistant on a system with Btrfs root filesystem, or with Docker/Podman running (overlay mounts active)
  2. Open the Health Check or any page that calls LinuxFilesystem.disks()
  3. App crashes immediately with:
    FormatException: Invalid radix-10 number (at character 1)
    -
    ^
    

Or with a Docker/overlay mount:

RangeError (index): Index out of range: index 5, valid range is 0..4

Affected Systems

  • Any distro with Btrfs as root (openSUSE Tumbleweed default, Fedora optional, Arch)
  • Any system running Docker, Podman, LXC/LXD (overlay mounts)
  • Systems with NFS/Samba mounts that have unusual df output
  • Flatpak sandbox overlay layers

Fix

for (var line in lines) {
  var values = line.split(" ");
  values.removeWhere((x) => x == "");
  
  // Guard against short lines (wrapped filesystem names)
  if (values.length < 6) continue;
  
  if (devicesRead.contains(values[0]) || values[1].endsWith("M")) {
    continue;
  }

  // Strip "%" and parse safely — use 0 as fallback for "-" or empty
  final rawPercent = values[4].substring(0, values[4].length - 1);
  final usedPercent = int.tryParse(rawPercent) ?? 0;

  devices.add(DeviceInfo(
      values[0],
      values[1],
      values[2],
      values[3],
      usedPercent,
      values[5],
      _removableDevices.any((x) => values[5].contains(x))));

  devicesRead.add(values[0]);
}

Severity

P1 — App crash on widely-used configurations. openSUSE Tumbleweed ships Btrfs by default, Fedora offers it as an install option. Docker is installed on millions of Linux systems. This crash affects a significant portion of the user base silently.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions