• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "mapped_resource.h"
6 
7 #include <fcntl.h>
8 #include <lib/trace/event.h>
9 #include <sys/stat.h>
10 #include <sys/types.h>
11 #include <zircon/status.h>
12 
13 #include "flutter/fml/logging.h"
14 #include "logging.h"
15 #include "runtime/dart/utils/inlines.h"
16 #include "runtime/dart/utils/vmo.h"
17 
18 namespace dart_runner {
19 
LoadFromNamespace(fdio_ns_t * namespc,const std::string & path,MappedResource & resource,bool executable)20 bool MappedResource::LoadFromNamespace(fdio_ns_t* namespc,
21                                        const std::string& path,
22                                        MappedResource& resource,
23                                        bool executable) {
24   TRACE_DURATION("dart", "LoadFromNamespace", "path", path);
25 
26   // openat of a path with a leading '/' ignores the namespace fd.
27   dart_utils::Check(path[0] != '/', LOG_TAG);
28 
29   fuchsia::mem::Buffer resource_vmo;
30   if (namespc == nullptr) {
31     if (!dart_utils::VmoFromFilename(path, &resource_vmo)) {
32       return false;
33     }
34   } else {
35     auto root_dir = fdio_ns_opendir(namespc);
36     if (root_dir < 0) {
37       FML_LOG(ERROR) << "Failed to open namespace directory";
38       return false;
39     }
40 
41     bool result = dart_utils::VmoFromFilenameAt(root_dir, path, &resource_vmo);
42     close(root_dir);
43     if (!result) {
44       return result;
45     }
46   }
47 
48   if (executable) {
49     // VmoFromFilenameAt will return VMOs without ZX_RIGHT_EXECUTE,
50     // so we need replace_as_executable to be able to map them as
51     // ZX_VM_PERM_EXECUTE.
52     // TODO(mdempsky): Update comment once SEC-42 is fixed.
53     zx_status_t status =
54         resource_vmo.vmo.replace_as_executable(zx::handle(), &resource_vmo.vmo);
55     if (status != ZX_OK) {
56       FML_LOG(ERROR) << "Failed to make VMO executable: "
57                      << zx_status_get_string(status);
58       return false;
59     }
60   }
61 
62   return LoadFromVmo(path, std::move(resource_vmo), resource, executable);
63 }
64 
LoadFromVmo(const std::string & path,fuchsia::mem::Buffer resource_vmo,MappedResource & resource,bool executable)65 bool MappedResource::LoadFromVmo(const std::string& path,
66                                  fuchsia::mem::Buffer resource_vmo,
67                                  MappedResource& resource,
68                                  bool executable) {
69   if (resource_vmo.size == 0) {
70     return true;
71   }
72 
73   uint32_t flags = ZX_VM_PERM_READ;
74   if (executable) {
75     flags |= ZX_VM_PERM_EXECUTE;
76   }
77   uintptr_t addr;
78   zx_status_t status = zx::vmar::root_self()->map(
79       0, resource_vmo.vmo, 0, resource_vmo.size, flags, &addr);
80   if (status != ZX_OK) {
81     FML_LOG(ERROR) << "Failed to map " << path << ": "
82                    << zx_status_get_string(status);
83 
84     return false;
85   }
86 
87   resource.address_ = reinterpret_cast<void*>(addr);
88   resource.size_ = resource_vmo.size;
89   return true;
90 }
91 
~MappedResource()92 MappedResource::~MappedResource() {
93   if (address_ != nullptr) {
94     zx::vmar::root_self()->unmap(reinterpret_cast<uintptr_t>(address_), size_);
95     address_ = nullptr;
96     size_ = 0;
97   }
98 }
99 
100 }  // namespace dart_runner
101