From 74ab1bfbbdfdfca5e98bd06b86e170857cf0a1ff Mon Sep 17 00:00:00 2001 From: Todd Volkert Date: Mon, 10 Dec 2018 13:39:50 -0800 Subject: [PATCH] Ensure that cache dirs and files have appropriate permissions (#24669) Fixes https://github.com/flutter/flutter/issues/24413 --- bin/internal/update_dart_sdk.sh | 6 ++++- packages/flutter_tools/lib/src/base/os.dart | 27 +++++++++++++++------ packages/flutter_tools/lib/src/cache.dart | 21 ++++++++++------ 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/bin/internal/update_dart_sdk.sh b/bin/internal/update_dart_sdk.sh index 630e3157a35..7b280560796 100755 --- a/bin/internal/update_dart_sdk.sh +++ b/bin/internal/update_dart_sdk.sh @@ -27,9 +27,11 @@ if [ ! -f "$ENGINE_STAMP" ] || [ "$ENGINE_VERSION" != `cat "$ENGINE_STAMP"` ]; t case "$(uname -s)" in Darwin) DART_ZIP_NAME="dart-sdk-darwin-x64.zip" + IS_USER_EXECUTABLE="-perm +100" ;; Linux) DART_ZIP_NAME="dart-sdk-linux-x64.zip" + IS_USER_EXECUTABLE="-perm /u+x" ;; *) echo "Unknown operating system. Cannot install Dart SDK." @@ -48,7 +50,7 @@ if [ ! -f "$ENGINE_STAMP" ] || [ "$ENGINE_VERSION" != `cat "$ENGINE_STAMP"` ]; t # install the new sdk rm -rf -- "$DART_SDK_PATH" - mkdir -p -- "$DART_SDK_PATH" + mkdir -m 755 -p -- "$DART_SDK_PATH" DART_SDK_ZIP="$FLUTTER_ROOT/bin/cache/$DART_ZIP_NAME" curl --continue-at - --location --output "$DART_SDK_ZIP" "$DART_SDK_URL" 2>&1 || { @@ -70,6 +72,8 @@ if [ ! -f "$ENGINE_STAMP" ] || [ "$ENGINE_VERSION" != `cat "$ENGINE_STAMP"` ]; t exit 1 } rm -f -- "$DART_SDK_ZIP" + find "$DART_SDK_PATH" -type d -exec chmod 755 {} \; + find "$DART_SDK_PATH" -type f $IS_USER_EXECUTABLE -exec chmod a+x,a+r {} \; echo "$ENGINE_VERSION" > "$ENGINE_STAMP" # delete any temporary sdk path diff --git a/packages/flutter_tools/lib/src/base/os.dart b/packages/flutter_tools/lib/src/base/os.dart index 54f59641462..6736e2defca 100644 --- a/packages/flutter_tools/lib/src/base/os.dart +++ b/packages/flutter_tools/lib/src/base/os.dart @@ -25,7 +25,15 @@ abstract class OperatingSystemUtils { OperatingSystemUtils._private(); /// Make the given file executable. This may be a no-op on some platforms. - ProcessResult makeExecutable(File file); + void makeExecutable(File file); + + /// Updates the specified file system [entity] to have the file mode + /// bits set to the value defined by [mode], which can be specified in octal + /// (e.g. `644`) or symbolically (e.g. `u+x`). + /// + /// On operating systems that do not support file mode bits, this will be a + /// no-op. + void chmod(FileSystemEntity entity, String mode); /// Return the path (with symlinks resolved) to the given executable, or null /// if `which` was not able to locate the binary. @@ -78,8 +86,13 @@ class _PosixUtils extends OperatingSystemUtils { _PosixUtils() : super._private(); @override - ProcessResult makeExecutable(File file) { - return processManager.runSync(['chmod', 'a+x', file.path]); + void makeExecutable(File file) { + chmod(file, 'a+x'); + } + + @override + void chmod(FileSystemEntity entity, String mode) { + processManager.runSync(['chmod', mode, entity.path]); } @override @@ -152,11 +165,11 @@ class _PosixUtils extends OperatingSystemUtils { class _WindowsUtils extends OperatingSystemUtils { _WindowsUtils() : super._private(); - // This is a no-op. @override - ProcessResult makeExecutable(File file) { - return ProcessResult(0, 0, null, null); - } + void makeExecutable(File file) {} + + @override + void chmod(FileSystemEntity entity, String mode) {} @override List _which(String execName, {bool all = false}) { diff --git a/packages/flutter_tools/lib/src/cache.dart b/packages/flutter_tools/lib/src/cache.dart index dfa33772555..63e3d6586ba 100644 --- a/packages/flutter_tools/lib/src/cache.dart +++ b/packages/flutter_tools/lib/src/cache.dart @@ -145,8 +145,10 @@ class Cache { /// Return a directory in the cache dir. For `pkg`, this will return `bin/cache/pkg`. Directory getCacheDir(String name) { final Directory dir = fs.directory(fs.path.join(getRoot().path, name)); - if (!dir.existsSync()) + if (!dir.existsSync()) { dir.createSync(recursive: true); + os.chmod(dir, '755'); + } return dir; } @@ -194,8 +196,10 @@ class Cache { final Directory thirdPartyDir = getArtifactDirectory('third_party'); final Directory serviceDir = fs.directory(fs.path.join(thirdPartyDir.path, serviceName)); - if (!serviceDir.existsSync()) + if (!serviceDir.existsSync()) { serviceDir.createSync(recursive: true); + os.chmod(serviceDir, '755'); + } final File cachedFile = fs.file(fs.path.join(serviceDir.path, url.pathSegments.last)); if (!cachedFile.existsSync()) { @@ -552,13 +556,16 @@ class FlutterEngine extends CachedArtifact { return result; } - void _makeFilesExecutable(Directory dir) { - for (FileSystemEntity entity in dir.listSync()) { + os.chmod(dir, 'a+r,a+x'); + for (FileSystemEntity entity in dir.listSync(recursive: true)) { if (entity is File) { - final String name = fs.path.basename(entity.path); - if (name == 'flutter_tester') - os.makeExecutable(entity); + final FileStat stat = entity.statSync(); + final bool isUserExecutable = ((stat.mode >> 6) & 0x1) == 1; + if (entity.basename == 'flutter_tester' || isUserExecutable) { + // Make the file readable and executable by all users. + os.chmod(entity, 'a+r,a+x'); + } } } }