Skip to content

[flutter_tools, devicelab] Add safety filesystem guard to tests#186748

Merged
auto-submit[bot] merged 5 commits into
flutter:masterfrom
bkonyi:tests_only_tmp
May 26, 2026
Merged

[flutter_tools, devicelab] Add safety filesystem guard to tests#186748
auto-submit[bot] merged 5 commits into
flutter:masterfrom
bkonyi:tests_only_tmp

Conversation

@bkonyi

@bkonyi bkonyi commented May 19, 2026

Copy link
Copy Markdown
Contributor

Implement FSGuardIOOverrides along with custom wrapping proxies (GuardedFile, GuardedDirectory, and GuardedLink) to intercept and isolate filesystem modifications during test execution.

This prevents tests in flutter_tools and devicelab from executing destructive filesystem operations (e.g., writes, deletes, and creations) outside the system temporary directory, while still permitting safe non-modifying operations (like reading templates and source files).

Provides an unstageable environment variable bypass toggle FLUTTER_TEST_DISABLE_FS_GUARD=true to allow developers to safely deactivate the guard for local debugging and custom logging without the risk of committing configuration overrides to git.

Fixes #186419

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label May 19, 2026
@github-actions github-actions Bot added the tool Affects the "flutter" command-line tool. See also t: labels. label May 19, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements a filesystem safety guard to restrict test-related file modifications to the system temporary directory. Feedback identifies a potential null pointer exception in framework.dart, a test case in io_test.dart that fails to apply the guard, and a non-portable hardcoded path in utils_test.dart. The reviewer also recommended deduplicating the guard logic across the repository.

runner.keepVmAliveUntilTaskRunRequested();
return runner.whenDone;
return IOOverrides.runWithIOOverrides(() async {
final runner = _TaskRunner(task, processManager!);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The use of the non-null assertion operator (!) on processManager could lead to a runtime error. The task function's signature allows processManager to be null, and the _TaskRunner constructor is designed to handle this by providing a default LocalProcessManager. Please remove the ! to avoid a potential null pointer exception and restore the original safe behavior.

Suggested change
final runner = _TaskRunner(task, processManager!);
final runner = _TaskRunner(task, processManager);

Comment thread packages/flutter_tools/test/general.shard/base/io_test.dart
Comment thread dev/devicelab/test/utils_test.dart Outdated
expect(tempFile.readAsStringSync(), 'safe-devicelab-content');

// Modifying outside system temp should fail and throw our guarded exception
final unsafeFile = io.File('/tmp_unsafe_devicelab.txt');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The hardcoded path /tmp_unsafe_devicelab.txt assumes a POSIX-like filesystem structure and may not be valid or behave as expected on all platforms, such as Windows. To ensure this test is platform-agnostic, consider creating the unsafe file in a directory relative to the project root but guaranteed to be outside the temporary directory.

@@ -0,0 +1,606 @@
// Copyright 2014 The Flutter Authors. All rights reserved.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This file is an exact copy of dev/devicelab/lib/framework/fs_safety.dart. This significant code duplication makes maintenance more difficult, as any changes or bug fixes would need to be applied in both places. Please consider extracting this file system guard logic into a shared utility or package that both flutter_tools and devicelab can depend on to avoid duplication.

@github-actions github-actions Bot removed the CICD Run CI/CD label May 19, 2026
@bkonyi bkonyi added CICD Run CI/CD and removed tool Affects the "flutter" command-line tool. See also t: labels. labels May 19, 2026
@github-actions github-actions Bot added tool Affects the "flutter" command-line tool. See also t: labels. and removed CICD Run CI/CD labels May 19, 2026
@bkonyi bkonyi added the CICD Run CI/CD label May 19, 2026
@github-actions github-actions Bot removed the CICD Run CI/CD label May 19, 2026
@bkonyi bkonyi added autosubmit Merge PR when tree becomes green via auto submit App CICD Run CI/CD and removed autosubmit Merge PR when tree becomes green via auto submit App labels May 19, 2026
@github-actions github-actions Bot removed the CICD Run CI/CD label May 21, 2026
@bkonyi bkonyi added the CICD Run CI/CD label May 21, 2026
@flutter-dashboard

Copy link
Copy Markdown

This pull request is not mergeable in its current state, likely because of a merge conflict. Pre-submit CI jobs were not triggered. Pushing a new commit to this branch that resolves the issue will result in pre-submit jobs being scheduled.

bkonyi added 2 commits May 21, 2026 11:10
Implement `FSGuardIOOverrides` along with custom wrapping proxies
(`GuardedFile`, `GuardedDirectory`, and `GuardedLink`) to intercept
and isolate filesystem modifications during test execution.

This prevents tests in `flutter_tools` and `devicelab` from executing
destructive filesystem operations (e.g., writes, deletes, and creations)
outside the system temporary directory, while still permitting safe
non-modifying operations (like reading templates and source files).

Provides an unstageable environment variable bypass toggle
`FLUTTER_TEST_DISABLE_FS_GUARD=true` to allow developers to safely
deactivate the guard for local debugging and custom logging without
the risk of committing configuration overrides to git.

Fixes flutter#186419
…gration

1. Remove the `FSGuardIOOverrides` wrapper from active devicelab task execution in `framework.dart`. Active tasks are real builds and compiles that must write to host log folders and checkout paths.
2. Restrict `FSGuardIOOverrides` to only permit modifications inside the system temporary directory, the active Flutter repository installation root, and the directory specified by `FLUTTER_TEST_OUTPUTS_DIR` during unit tests.
3. Update the native assets build runner mock `FakeFlutterNativeAssetsBuildRunner` to configure build input paths inside the system temporary directory instead of using relative package paths.
4. Fix the `TestBed` startup sequence in `testbed.dart` to ensure test overrides are active during initial `isRunningOnBot` checks.
5. Add standard `// flutter_ignore: package_path_import` to `fs_safety.dart` to satisfy the forbidden imports check regarding `package:path` imports.
6. Remove the forbidden `package:path` import from `io_test.dart` by joining paths natively using string interpolation with `Platform.pathSeparator`.

Fixes flutter#186419
@github-actions github-actions Bot removed the CICD Run CI/CD label May 21, 2026
@bkonyi bkonyi added the CICD Run CI/CD label May 21, 2026
@github-actions github-actions Bot removed the CICD Run CI/CD label May 21, 2026
@bkonyi bkonyi added the CICD Run CI/CD label May 21, 2026
@bkonyi bkonyi requested review from a team as code owners May 21, 2026 16:10
@github-actions github-actions Bot added team-ios Owned by iOS platform team team-macos Owned by the macOS platform team and removed CICD Run CI/CD labels May 21, 2026
@bkonyi bkonyi added the CICD Run CI/CD label May 21, 2026
@bkonyi bkonyi requested review from hellohuanlin and jtmcdole May 22, 2026 01:07
Comment on lines +50 to 62
final packageDir = io.Platform.isWindows ? '$tempPath\\$package' : '$tempPath/$package';
final sharedDir = io.Platform.isWindows
? '$tempPath\\build-out-dir-shared'
: '$tempPath/build-out-dir-shared';
final input = BuildInputBuilder()
..setupShared(
packageRoot: Uri.parse('$package/'),
packageRoot: Uri.file('$packageDir/'),
packageName: package,
outputDirectoryShared: Uri.parse('build-out-dir-shared'),
outputFile: Uri.file('output.json'),
outputDirectoryShared: Uri.file('$sharedDir/'),
outputFile: Uri.file(
io.Platform.isWindows ? '$packageDir\\output.json' : '$packageDir/output.json',
),
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit / cleanup / nice-to-have?

extension FsPathJoin on String {
  String joinPath(String other) => io.Platform.isWindows ? '$this\\$other' : '$this/$other';
}

final String canonical = path.canonicalize(dirPath);

// Check if it is root
if (canonical == '/' || canonical == r'C:\' || canonical.length <= 3) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so /x and /xx is banned?

Comment thread dev/devicelab/lib/framework/fs_safety.dart
Comment on lines +123 to +124
'${io.Directory.systemTemp.path}${io.Platform.pathSeparator}fs_guard_test_safe.txt',
);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we not allowed to use path to join?

Comment on lines +51 to +53
final sharedDir = io.Platform.isWindows
? '$tempPath\\build-out-dir-shared'
: '$tempPath/build-out-dir-shared';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto on "can we just use path to join"?

- Restrict the dangerous directory length check to Windows to prevent banning short paths (like /x or /fl) on POSIX.
- Explicitly wrap the FSGuardIOOverrides test in io_test.dart with IOOverrides.runWithIOOverrides.
- Make unsafe test paths in io_test.dart and utils_test.dart platform-agnostic using package:path.

Fixes flutter#186419
@github-actions github-actions Bot removed the CICD Run CI/CD label May 26, 2026
@bkonyi bkonyi added the CICD Run CI/CD label May 26, 2026
@bkonyi bkonyi added the autosubmit Merge PR when tree becomes green via auto submit App label May 26, 2026
@auto-submit auto-submit Bot added this pull request to the merge queue May 26, 2026
Merged via the queue into flutter:master with commit 69a048f May 26, 2026
174 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label May 26, 2026
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request May 27, 2026
flutter/flutter@f3a4b98...c8f2f16

2026-05-27 98614782+auto-submit[bot]@users.noreply.github.com Reverts "[Flutter GPU] Add explicit draw counts (#186639)" (flutter/flutter#187170)
2026-05-27 engine-flutter-autoroll@skia.org Roll Dart SDK from 7dcea971af6b to f3db7b7d9801 (2 revisions) (flutter/flutter#187144)
2026-05-27 bdero@google.com [Flutter GPU] Add explicit draw counts (flutter/flutter#186639)
2026-05-27 engine-flutter-autoroll@skia.org Roll Skia from f9db7748563e to fa944af10f91 (1 revision) (flutter/flutter#187139)
2026-05-27 bdero@google.com [Flutter GPU] Flutter GPU ShaderLibrary in-place reload for shader hot reload (flutter/flutter#186793)
2026-05-27 engine-flutter-autoroll@skia.org Roll Skia from a692cbf38952 to f9db7748563e (8 revisions) (flutter/flutter#187135)
2026-05-27 burak.karahan@mail.ru Use local semantics tester in Material button tests (flutter/flutter#186667)
2026-05-27 rmolivares@renzo-olivares.dev Filter out `a: text input` from `team-framework` PR triage  (flutter/flutter#187129)
2026-05-27 bkonyi@google.com [Engine] Fix silent buffer mismatch bug in FML Win32 CommandLineFromPlatform (flutter/flutter#187120)
2026-05-27 srawlins@google.com examples: Remove unused parameters (flutter/flutter#185819)
2026-05-27 116356835+AbdeMohlbi@users.noreply.github.com Remove another `String.valueOf` (flutter/flutter#186628)
2026-05-27 alex.medinsh@gmail.com Print trace when skipping flavor-specific and platform-specific assets (flutter/flutter#187045)
2026-05-26 adilhanney@disroot.org Fix `InteractiveViewer` memory leak from undisposed `CurvedAnimation`s (flutter/flutter#185826)
2026-05-26 meylis@divine.video Fix AccessibilityBridge startup crash on vendor-modified Android (flutter/flutter#184630)
2026-05-26 keertip@users.noreply.github.com Update data driven fixes docs (flutter/flutter#186217)
2026-05-26 ahmedsameha1@gmail.com Add more 0x0 size tests part10 (flutter/flutter#186201)
2026-05-26 46920873+gabrimatic@users.noreply.github.com Disable spell check for obscured text (flutter/flutter#186329)
2026-05-26 chris@bracken.jp [iOS] Migrate VSyncClient and DisplayLinkManager to Swift (flutter/flutter#187001)
2026-05-26 bkonyi@google.com [flutter_tools, devicelab] Add safety filesystem guard to tests (flutter/flutter#186748)
2026-05-26 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from Itd2Jq_ZIABH2rW7B... to k9EizfEGJO4WwQN9-... (flutter/flutter#187115)
2026-05-26 engine-flutter-autoroll@skia.org Roll Dart SDK from 00e625453c43 to 7dcea971af6b (1 revision) (flutter/flutter#187117)
2026-05-26 rmacnak@google.com Remove use of deprecated copy_trees. (flutter/flutter#187091)
2026-05-26 15619084+vashworth@users.noreply.github.com Use resolved implementation plugins with SwiftPM (flutter/flutter#187097)
2026-05-26 engine-flutter-autoroll@skia.org Roll Skia from 27a819894f7c to a692cbf38952 (3 revisions) (flutter/flutter#187109)
2026-05-26 engine-flutter-autoroll@skia.org Roll Packages from 69cf959 to fc795e5 (4 revisions) (flutter/flutter#187114)
2026-05-26 mvincentong@gmail.com Handle simctl process exceptions during discovery (flutter/flutter#186501)
2026-05-26 mvincentong@gmail.com Clarify precache enabled platforms help (flutter/flutter#186878)
2026-05-26 bkonyi@google.com [tool] Refactor artifacts.dart to use enhanced enums and reduce duplication (flutter/flutter#187063)
2026-05-26 jason-simmons@users.noreply.github.com Build script updates for syncing engine sources and building artifacts on linux-arm64 (flutter/flutter#186917)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC boetger@google.com,stuartmorgan@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
creatorpiyush pushed a commit to creatorpiyush/packages that referenced this pull request Jun 10, 2026
…r#11795)

flutter/flutter@f3a4b98...c8f2f16

2026-05-27 98614782+auto-submit[bot]@users.noreply.github.com Reverts "[Flutter GPU] Add explicit draw counts (#186639)" (flutter/flutter#187170)
2026-05-27 engine-flutter-autoroll@skia.org Roll Dart SDK from 7dcea971af6b to f3db7b7d9801 (2 revisions) (flutter/flutter#187144)
2026-05-27 bdero@google.com [Flutter GPU] Add explicit draw counts (flutter/flutter#186639)
2026-05-27 engine-flutter-autoroll@skia.org Roll Skia from f9db7748563e to fa944af10f91 (1 revision) (flutter/flutter#187139)
2026-05-27 bdero@google.com [Flutter GPU] Flutter GPU ShaderLibrary in-place reload for shader hot reload (flutter/flutter#186793)
2026-05-27 engine-flutter-autoroll@skia.org Roll Skia from a692cbf38952 to f9db7748563e (8 revisions) (flutter/flutter#187135)
2026-05-27 burak.karahan@mail.ru Use local semantics tester in Material button tests (flutter/flutter#186667)
2026-05-27 rmolivares@renzo-olivares.dev Filter out `a: text input` from `team-framework` PR triage  (flutter/flutter#187129)
2026-05-27 bkonyi@google.com [Engine] Fix silent buffer mismatch bug in FML Win32 CommandLineFromPlatform (flutter/flutter#187120)
2026-05-27 srawlins@google.com examples: Remove unused parameters (flutter/flutter#185819)
2026-05-27 116356835+AbdeMohlbi@users.noreply.github.com Remove another `String.valueOf` (flutter/flutter#186628)
2026-05-27 alex.medinsh@gmail.com Print trace when skipping flavor-specific and platform-specific assets (flutter/flutter#187045)
2026-05-26 adilhanney@disroot.org Fix `InteractiveViewer` memory leak from undisposed `CurvedAnimation`s (flutter/flutter#185826)
2026-05-26 meylis@divine.video Fix AccessibilityBridge startup crash on vendor-modified Android (flutter/flutter#184630)
2026-05-26 keertip@users.noreply.github.com Update data driven fixes docs (flutter/flutter#186217)
2026-05-26 ahmedsameha1@gmail.com Add more 0x0 size tests part10 (flutter/flutter#186201)
2026-05-26 46920873+gabrimatic@users.noreply.github.com Disable spell check for obscured text (flutter/flutter#186329)
2026-05-26 chris@bracken.jp [iOS] Migrate VSyncClient and DisplayLinkManager to Swift (flutter/flutter#187001)
2026-05-26 bkonyi@google.com [flutter_tools, devicelab] Add safety filesystem guard to tests (flutter/flutter#186748)
2026-05-26 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from Itd2Jq_ZIABH2rW7B... to k9EizfEGJO4WwQN9-... (flutter/flutter#187115)
2026-05-26 engine-flutter-autoroll@skia.org Roll Dart SDK from 00e625453c43 to 7dcea971af6b (1 revision) (flutter/flutter#187117)
2026-05-26 rmacnak@google.com Remove use of deprecated copy_trees. (flutter/flutter#187091)
2026-05-26 15619084+vashworth@users.noreply.github.com Use resolved implementation plugins with SwiftPM (flutter/flutter#187097)
2026-05-26 engine-flutter-autoroll@skia.org Roll Skia from 27a819894f7c to a692cbf38952 (3 revisions) (flutter/flutter#187109)
2026-05-26 engine-flutter-autoroll@skia.org Roll Packages from 69cf959 to fc795e5 (4 revisions) (flutter/flutter#187114)
2026-05-26 mvincentong@gmail.com Handle simctl process exceptions during discovery (flutter/flutter#186501)
2026-05-26 mvincentong@gmail.com Clarify precache enabled platforms help (flutter/flutter#186878)
2026-05-26 bkonyi@google.com [tool] Refactor artifacts.dart to use enhanced enums and reduce duplication (flutter/flutter#187063)
2026-05-26 jason-simmons@users.noreply.github.com Build script updates for syncing engine sources and building artifacts on linux-arm64 (flutter/flutter#186917)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC boetger@google.com,stuartmorgan@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
via-guy pushed a commit to via-guy/flutter that referenced this pull request Jun 26, 2026
…ter#186748)

Implement `FSGuardIOOverrides` along with custom wrapping proxies
(`GuardedFile`, `GuardedDirectory`, and `GuardedLink`) to intercept and
isolate filesystem modifications during test execution.

This prevents tests in `flutter_tools` and `devicelab` from executing
destructive filesystem operations (e.g., writes, deletes, and creations)
outside the system temporary directory, while still permitting safe
non-modifying operations (like reading templates and source files).

Provides an unstageable environment variable bypass toggle
`FLUTTER_TEST_DISABLE_FS_GUARD=true` to allow developers to safely
deactivate the guard for local debugging and custom logging without the
risk of committing configuration overrides to git.

Fixes flutter#186419
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD team-ios Owned by iOS platform team team-macos Owned by the macOS platform team tool Affects the "flutter" command-line tool. See also t: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[flutter/dart] Is it possible to ask for permission for dangerous operations for Flutter contributors

2 participants