xref: /aosp_15_r20/tools/treble/hacksaw/bind/local.go (revision 105f628577ac4ba0e277a494fbb614ed8c12a994)
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