1// Copyright 2020 Google LLC 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package bind 16 17import ( 18 "fmt" 19 "path/filepath" 20 "syscall" 21 22 "android.googlesource.com/platform/tools/treble.git/hacksaw/mount" 23) 24 25//localBinder executes PathBinder calls locally 26type localBinder struct { 27 mounter mount.Mounter 28} 29 30func NewLocalPathBinder() PathBinder { 31 var p localBinder 32 p.mounter = mount.NewSystemMounter() 33 return &p 34} 35 36func NewFakePathBinder() PathBinder { 37 var p localBinder 38 p.mounter = mount.NewFakeMounter() 39 return &p 40} 41 42func (p localBinder) checkValidPath(inPath string) error { 43 for dir := filepath.Dir(inPath); dir != "." && dir != "/"; dir = filepath.Dir(dir) { 44 // Only allow mounts in hacksaw path 45 if filepath.Base(dir) == "hacksaw" { 46 return nil 47 } 48 } 49 return fmt.Errorf("Not allowed to bind mount path %s because it's outside a hacksaw workspace", inPath) 50} 51 52func (p localBinder) BindReadOnly(source string, destination string) error { 53 // TODO: check valid path considering sym links 54 source, err := filepath.EvalSymlinks(source) 55 if err != nil { 56 return err 57 } 58 destination, err = filepath.EvalSymlinks(destination) 59 if err != nil { 60 return err 61 } 62 err = p.mounter.Mount(source, destination, 63 "bind", syscall.MS_BIND, "") 64 if err != nil { 65 return err 66 } 67 err = p.mounter.Mount(source, destination, 68 "bind", syscall.MS_REMOUNT|syscall.MS_BIND|syscall.MS_RDONLY, "") 69 return err 70} 71 72func (p localBinder) BindReadWrite(source string, destination string) error { 73 // TODO: check valid path considering sym links 74 source, err := filepath.EvalSymlinks(source) 75 if err != nil { 76 return err 77 } 78 destination, err = filepath.EvalSymlinks(destination) 79 if err != nil { 80 return err 81 } 82 err = p.mounter.Mount(source, destination, 83 "bind", syscall.MS_BIND, "") 84 return err 85} 86 87func (p localBinder) Unbind(destination string) error { 88 // TODO: check valid path considering sym links 89 destination, err := filepath.EvalSymlinks(destination) 90 if err != nil { 91 return err 92 } 93 err = p.mounter.Unmount(destination, syscall.MNT_DETACH) 94 return err 95} 96 97func (p localBinder) List() ([]string, error) { 98 return p.mounter.List() 99} 100