diff --git a/shell/platform/fuchsia/dart_runner/examples/goodbye_dart/meta/goodbye_dart_aot.cmx b/shell/platform/fuchsia/dart_runner/examples/goodbye_dart/meta/goodbye_dart_aot.cmx index e041f24109f72..c6705a70ac564 100644 --- a/shell/platform/fuchsia/dart_runner/examples/goodbye_dart/meta/goodbye_dart_aot.cmx +++ b/shell/platform/fuchsia/dart_runner/examples/goodbye_dart/meta/goodbye_dart_aot.cmx @@ -3,6 +3,9 @@ "data": "data/goodbye_dart_aot" }, "sandbox": { + "features": [ + "deprecated-ambient-replace-as-executable" + ], "services": [ "fuchsia.intl.PropertyProvider", "fuchsia.sys.Environment" diff --git a/shell/platform/fuchsia/dart_runner/meta/dart_aot_product_runner.cmx b/shell/platform/fuchsia/dart_runner/meta/dart_aot_product_runner.cmx index 26c6db097e343..629c352e01ae3 100644 --- a/shell/platform/fuchsia/dart_runner/meta/dart_aot_product_runner.cmx +++ b/shell/platform/fuchsia/dart_runner/meta/dart_aot_product_runner.cmx @@ -5,6 +5,7 @@ "sandbox": { "features": [ "config-data", + "deprecated-ambient-replace-as-executable", "root-ssl-certificates" ], "services": [ diff --git a/shell/platform/fuchsia/dart_runner/meta/dart_aot_runner.cmx b/shell/platform/fuchsia/dart_runner/meta/dart_aot_runner.cmx index 26c6db097e343..629c352e01ae3 100644 --- a/shell/platform/fuchsia/dart_runner/meta/dart_aot_runner.cmx +++ b/shell/platform/fuchsia/dart_runner/meta/dart_aot_runner.cmx @@ -5,6 +5,7 @@ "sandbox": { "features": [ "config-data", + "deprecated-ambient-replace-as-executable", "root-ssl-certificates" ], "services": [ diff --git a/shell/platform/fuchsia/flutter/component.cc b/shell/platform/fuchsia/flutter/component.cc index e0d58f3e80330..9f6bc6f91596c 100644 --- a/shell/platform/fuchsia/flutter/component.cc +++ b/shell/platform/fuchsia/flutter/component.cc @@ -431,8 +431,7 @@ class FileInNamespaceBuffer final : public fml::Mapping { FileInNamespaceBuffer(int namespace_fd, const char* path, bool executable) : address_(nullptr), size_(0) { fuchsia::mem::Buffer buffer; - if (!dart_utils::VmoFromFilenameAt(namespace_fd, path, executable, - &buffer)) { + if (!dart_utils::VmoFromFilenameAt(namespace_fd, path, &buffer)) { return; } if (buffer.size == 0) { @@ -442,6 +441,17 @@ class FileInNamespaceBuffer final : public fml::Mapping { uint32_t flags = ZX_VM_PERM_READ; if (executable) { flags |= ZX_VM_PERM_EXECUTE; + + // VmoFromFilenameAt will return VMOs without ZX_RIGHT_EXECUTE, + // so we need replace_as_executable to be able to map them as + // ZX_VM_PERM_EXECUTE. + // TODO(mdempsky): Update comment once SEC-42 is fixed. + zx_status_t status = + buffer.vmo.replace_as_executable(zx::handle(), &buffer.vmo); + if (status != ZX_OK) { + FML_LOG(FATAL) << "Failed to make VMO executable: " + << zx_status_get_string(status); + } } uintptr_t addr; zx_status_t status = diff --git a/shell/platform/fuchsia/flutter/meta/flutter_aot_product_runner.cmx b/shell/platform/fuchsia/flutter/meta/flutter_aot_product_runner.cmx index 914c22b6f2dbb..019dc11340d84 100644 --- a/shell/platform/fuchsia/flutter/meta/flutter_aot_product_runner.cmx +++ b/shell/platform/fuchsia/flutter/meta/flutter_aot_product_runner.cmx @@ -5,6 +5,7 @@ "sandbox": { "features": [ "config-data", + "deprecated-ambient-replace-as-executable", "root-ssl-certificates", "vulkan" ], diff --git a/shell/platform/fuchsia/flutter/meta/flutter_aot_runner.cmx b/shell/platform/fuchsia/flutter/meta/flutter_aot_runner.cmx index 11ba40d7870f2..af0c724590652 100644 --- a/shell/platform/fuchsia/flutter/meta/flutter_aot_runner.cmx +++ b/shell/platform/fuchsia/flutter/meta/flutter_aot_runner.cmx @@ -5,6 +5,7 @@ "sandbox": { "features": [ "config-data", + "deprecated-ambient-replace-as-executable", "root-ssl-certificates", "vulkan" ], diff --git a/shell/platform/fuchsia/flutter/runner.cc b/shell/platform/fuchsia/flutter/runner.cc index 6459236730e16..2fe0b5626ada6 100644 --- a/shell/platform/fuchsia/flutter/runner.cc +++ b/shell/platform/fuchsia/flutter/runner.cc @@ -87,7 +87,7 @@ bool InitializeICU() { const char* data_path = kIcuDataPath; fuchsia::mem::Buffer icu_data; - if (!dart_utils::VmoFromFilename(data_path, false, &icu_data)) { + if (!dart_utils::VmoFromFilename(data_path, &icu_data)) { return false; } diff --git a/shell/platform/fuchsia/runtime/dart/utils/mapped_resource.cc b/shell/platform/fuchsia/runtime/dart/utils/mapped_resource.cc index b14571ffbf9a9..d8837e6fbc27f 100644 --- a/shell/platform/fuchsia/runtime/dart/utils/mapped_resource.cc +++ b/shell/platform/fuchsia/runtime/dart/utils/mapped_resource.cc @@ -36,7 +36,7 @@ static bool OpenVmo(fuchsia::mem::Buffer* resource_vmo, dart_utils::Check(path[0] != '/', LOG_TAG); if (namespc == nullptr) { - if (!VmoFromFilename(path, executable, resource_vmo)) { + if (!VmoFromFilename(path, resource_vmo)) { return false; } } else { @@ -46,14 +46,27 @@ static bool OpenVmo(fuchsia::mem::Buffer* resource_vmo, return false; } - bool result = - dart_utils::VmoFromFilenameAt(root_dir, path, executable, resource_vmo); + bool result = dart_utils::VmoFromFilenameAt(root_dir, path, resource_vmo); close(root_dir); if (!result) { return result; } } + if (executable) { + // VmoFromFilenameAt will return VMOs without ZX_RIGHT_EXECUTE, + // so we need replace_as_executable to be able to map them as + // ZX_VM_PERM_EXECUTE. + // TODO(mdempsky): Update comment once SEC-42 is fixed. + zx_status_t status = resource_vmo->vmo.replace_as_executable( + zx::handle(), &resource_vmo->vmo); + if (status != ZX_OK) { + FX_LOGF(ERROR, LOG_TAG, "Failed to make VMO executable: %s", + zx_status_get_string(status)); + return false; + } + } + return true; } diff --git a/shell/platform/fuchsia/runtime/dart/utils/vmo.cc b/shell/platform/fuchsia/runtime/dart/utils/vmo.cc index 87f181e38b49c..130181c777bce 100644 --- a/shell/platform/fuchsia/runtime/dart/utils/vmo.cc +++ b/shell/platform/fuchsia/runtime/dart/utils/vmo.cc @@ -7,18 +7,15 @@ #include #include -#include #include -#include #include #include -#include #include "runtime/dart/utils/logging.h" namespace { -bool VmoFromFd(int fd, bool executable, fuchsia::mem::Buffer* buffer) { +bool VmoFromFd(int fd, fuchsia::mem::Buffer* buffer) { if (!buffer) { FX_LOG(FATAL, LOG_TAG, "Invalid buffer pointer"); } @@ -30,14 +27,7 @@ bool VmoFromFd(int fd, bool executable, fuchsia::mem::Buffer* buffer) { } zx_handle_t result = ZX_HANDLE_INVALID; - zx_status_t status; - if (executable) { - status = fdio_get_vmo_exec(fd, &result); - } else { - status = fdio_get_vmo_copy(fd, &result); - } - - if (status != ZX_OK) { + if (fdio_get_vmo_copy(fd, &result) != ZX_OK) { return false; } @@ -52,42 +42,20 @@ bool VmoFromFd(int fd, bool executable, fuchsia::mem::Buffer* buffer) { namespace dart_utils { bool VmoFromFilename(const std::string& filename, - bool executable, fuchsia::mem::Buffer* buffer) { - // Note: the implementation here cannot be shared with VmoFromFilenameAt - // because fdio_open_fd_at does not aim to provide POSIX compatibility, and - // thus does not handle AT_FDCWD as dirfd. - uint32_t flags = fuchsia::io::OPEN_RIGHT_READABLE | - (executable ? fuchsia::io::OPEN_RIGHT_EXECUTABLE : 0); - zx_status_t status; - int fd; - - status = fdio_open_fd(filename.c_str(), flags, &fd); - if (status != ZX_OK) { - FX_LOGF(ERROR, LOG_TAG, "fdio_open_fd(\"%s\", %08x) failed: %s", - filename.c_str(), flags, zx_status_get_string(status)); - return false; - } - bool result = VmoFromFd(fd, executable, buffer); - close(fd); - return result; + return VmoFromFilenameAt(AT_FDCWD, filename, buffer); } bool VmoFromFilenameAt(int dirfd, const std::string& filename, - bool executable, fuchsia::mem::Buffer* buffer) { - uint32_t flags = fuchsia::io::OPEN_RIGHT_READABLE | - (executable ? fuchsia::io::OPEN_RIGHT_EXECUTABLE : 0); - zx_status_t status; - int fd; - status = fdio_open_fd_at(dirfd, filename.c_str(), flags, &fd); - if (status != ZX_OK) { - FX_LOGF(ERROR, LOG_TAG, "fdio_open_fd_at(%d, \"%s\", %08x) failed: %s", - dirfd, filename.c_str(), flags, zx_status_get_string(status)); + int fd = openat(dirfd, filename.c_str(), O_RDONLY); + if (fd == -1) { + FX_LOGF(ERROR, LOG_TAG, "openat(\"%s\") failed: %s", filename.c_str(), + strerror(errno)); return false; } - bool result = VmoFromFd(fd, executable, buffer); + bool result = VmoFromFd(fd, buffer); close(fd); return result; } diff --git a/shell/platform/fuchsia/runtime/dart/utils/vmo.h b/shell/platform/fuchsia/runtime/dart/utils/vmo.h index 52871d2e32751..bc4065eb815e4 100644 --- a/shell/platform/fuchsia/runtime/dart/utils/vmo.h +++ b/shell/platform/fuchsia/runtime/dart/utils/vmo.h @@ -11,13 +11,10 @@ namespace dart_utils { -bool VmoFromFilename(const std::string& filename, - bool executable, - fuchsia::mem::Buffer* buffer); +bool VmoFromFilename(const std::string& filename, fuchsia::mem::Buffer* buffer); bool VmoFromFilenameAt(int dirfd, const std::string& filename, - bool executable, fuchsia::mem::Buffer* buffer); zx_status_t IsSizeValid(const fuchsia::mem::Buffer& buffer, bool* is_valid);