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