1// Copyright 2018 Google Inc. All rights reserved.
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//     http://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 paths
16
17import "runtime"
18
19type PathConfig struct {
20	// Whether to create the symlink in the new PATH for this tool.
21	Symlink bool
22
23	// Whether to log about usages of this tool to the soong.log
24	Log bool
25
26	// Whether to exit with an error instead of invoking the underlying tool.
27	Error bool
28
29	// Whether we use a linux-specific prebuilt for this tool. On Darwin,
30	// we'll allow the host executable instead.
31	LinuxOnlyPrebuilt bool
32}
33
34// These binaries can be run from $PATH, nonhermetically. There should be as
35// few as possible of these, since this means that the build depends on tools
36// that are not shipped in the source tree and whose behavior is therefore
37// unpredictable.
38var Allowed = PathConfig{
39	Symlink: true,
40	Log:     false,
41	Error:   false,
42}
43
44// This tool is specifically disallowed and calling it will result in an
45// "executable no found" error.
46var Forbidden = PathConfig{
47	Symlink: false,
48	Log:     true,
49	Error:   true,
50}
51
52// This tool is allowed, but access to it will be logged.
53var Log = PathConfig{
54	Symlink: true,
55	Log:     true,
56	Error:   false,
57}
58
59// The configuration used if the tool is not listed in the config below.
60// Currently this will create the symlink, but log and error when it's used. In
61// the future, I expect the symlink to be removed, and this will be equivalent
62// to Forbidden. This applies to every tool not specifically mentioned in the
63// configuration.
64var Missing = PathConfig{
65	Symlink: true,
66	Log:     true,
67	Error:   true,
68}
69
70// This is used for binaries for which we have prebuilt versions, but only for
71// Linux. Thus, their execution from $PATH is only allowed on Mac OS.
72var LinuxOnlyPrebuilt = PathConfig{
73	Symlink:           false,
74	Log:               true,
75	Error:             true,
76	LinuxOnlyPrebuilt: true,
77}
78
79func GetConfig(name string) PathConfig {
80	if config, ok := Configuration[name]; ok {
81		return config
82	}
83	return Missing
84}
85
86// This list specifies whether a particular binary from $PATH is allowed to be
87// run during the build. For more documentation, see path_interposer.go .
88var Configuration = map[string]PathConfig{
89	"bash":           Allowed,
90	"diff":           Allowed,
91	"dlv":            Allowed,
92	"expr":           Allowed,
93	"fuser":          Allowed,
94	"gcert":          Allowed,
95	"gcertstatus":    Allowed,
96	"gcloud":         Allowed,
97	"git":            Allowed,
98	"hexdump":        Allowed,
99	"jar":            Allowed,
100	"java":           Allowed,
101	"javap":          Allowed,
102	"lsof":           Allowed,
103	"openssl":        Allowed,
104	"pstree":         Allowed,
105	"rsync":          Allowed,
106	"sh":             Allowed,
107	"stubby":         Allowed,
108	"tr":             Allowed,
109	"unzip":          Allowed,
110	"zip":            Allowed,
111
112	// Host toolchain is removed. In-tree toolchain should be used instead.
113	// GCC also can't find cc1 with this implementation.
114	"ar":         Forbidden,
115	"as":         Forbidden,
116	"cc":         Forbidden,
117	"clang":      Forbidden,
118	"clang++":    Forbidden,
119	"gcc":        Forbidden,
120	"g++":        Forbidden,
121	"ld":         Forbidden,
122	"ld.bfd":     Forbidden,
123	"ld.gold":    Forbidden,
124	"pkg-config": Forbidden,
125
126	// These are toybox tools that only work on Linux.
127	"pgrep": LinuxOnlyPrebuilt,
128	"pkill": LinuxOnlyPrebuilt,
129	"ps":    LinuxOnlyPrebuilt,
130}
131
132func init() {
133	if runtime.GOOS == "darwin" {
134		Configuration["sw_vers"] = Allowed
135		Configuration["xcrun"] = Allowed
136
137		// We don't have darwin prebuilts for some tools,
138		// so allow the host versions.
139		for name, config := range Configuration {
140			if config.LinuxOnlyPrebuilt {
141				Configuration[name] = Allowed
142			}
143		}
144	}
145}
146