@@ -176,6 +176,21 @@ absl::Status Mounts::Remove(absl::string_view path) {
176176 return absl::OkStatus ();
177177}
178178
179+ absl::StatusOr<MountTree::Node> Mounts::GetNode (absl::string_view path) {
180+ std::vector<absl::string_view> parts =
181+ absl::StrSplit (absl::StripPrefix (path, " /" ), ' /' );
182+ MountTree* curtree = &mount_tree_;
183+ for (absl::string_view part : parts) {
184+ auto it = curtree->mutable_entries ()->find (std::string (part));
185+ if (it == curtree->mutable_entries ()->end ()) {
186+ return absl::NotFoundError (
187+ absl::StrCat (" Path does not exist in mounts: " , path));
188+ }
189+ curtree = &it->second ;
190+ }
191+ return curtree->node ();
192+ }
193+
179194absl::Status Mounts::Insert (absl::string_view path,
180195 const MountTree::Node& new_node) {
181196 // Some sandboxes allow the inside/outside paths to be partially
@@ -353,6 +368,16 @@ absl::Status Mounts::AddTmpfs(absl::string_view inside, size_t sz) {
353368 return Insert (inside, node);
354369}
355370
371+ absl::Status Mounts::AllowMountPropagation (absl::string_view inside) {
372+ SAPI_ASSIGN_OR_RETURN (MountTree::Node node, GetNode (inside));
373+ if (!node.has_dir_node ()) {
374+ return absl::InvalidArgumentError (
375+ absl::StrCat (" Path is not a directory: " , inside));
376+ }
377+ node.mutable_dir_node ()->set_allow_mount_propagation (true );
378+ return absl::OkStatus ();
379+ }
380+
356381namespace {
357382
358383uint64_t GetMountFlagsFor (const std::string& path) {
@@ -508,7 +533,8 @@ bool IsSymlink(const std::string& path) {
508533
509534// Traverses the MountTree to create all required files and perform the mounts.
510535void CreateMounts (const MountTree& tree, const std::string& root_path,
511- const std::string& path, bool create_backing_files) {
536+ const std::string& path, bool create_backing_files,
537+ bool allow_mount_propagation) {
512538 // First, create the backing files if needed.
513539 if (create_backing_files) {
514540 switch (tree.node ().node_case ()) {
@@ -549,8 +575,12 @@ void CreateMounts(const MountTree& tree, const std::string& root_path,
549575 create_backing_files = false ;
550576
551577 auto node = tree.node ().dir_node ();
552- MountWithDefaults (node.outside (), path, " " , MS_BIND , nullptr ,
553- !node.writable ());
578+ MountWithDefaults (
579+ node.outside (), path, " " ,
580+ MS_BIND | (node.allow_mount_propagation () || allow_mount_propagation
581+ ? MS_SHARED
582+ : MS_PRIVATE ),
583+ nullptr , !node.writable ());
554584 break ;
555585 }
556586 case MountTree::Node::kTmpfsNode : {
@@ -580,14 +610,17 @@ void CreateMounts(const MountTree& tree, const std::string& root_path,
580610 // Traverse the subtrees.
581611 for (const auto & [key, value] : GetSortedEntries (tree)) {
582612 std::string new_path = sapi::file::JoinPath (path, key);
583- CreateMounts (*value, root_path, new_path, create_backing_files);
613+ CreateMounts (*value, root_path, new_path, create_backing_files,
614+ allow_mount_propagation);
584615 }
585616}
586617
587618} // namespace
588619
589- void Mounts::CreateMounts (const std::string& root_path) const {
590- sandbox2::CreateMounts (mount_tree_, root_path, root_path, true );
620+ void Mounts::CreateMounts (const std::string& root_path,
621+ bool allow_mount_propagation) const {
622+ sandbox2::CreateMounts (mount_tree_, root_path, root_path, true ,
623+ allow_mount_propagation);
591624}
592625
593626namespace {
0 commit comments