Strengthen metalava sandbox support using sbox
Run sandbox metalava rules inside sbox, which copies only the expected inputs into a separate directory tree. This ensures it can't read any extra inputs. Test: m hwbinder.stubs Test: TestDroidstubs Test: TestDroidstubsSandboxed Change-Id: I71a83e3af6a385cc23f895397c2c883a2ac5fa22
This commit is contained in:
@@ -383,32 +383,42 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi
|
|||||||
|
|
||||||
if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_METALAVA") {
|
if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_METALAVA") {
|
||||||
rule.Remoteable(android.RemoteRuleSupports{RBE: true})
|
rule.Remoteable(android.RemoteRuleSupports{RBE: true})
|
||||||
pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "metalava")
|
if sandbox {
|
||||||
execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
|
execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
|
||||||
labels := map[string]string{"type": "compile", "lang": "java", "compiler": "metalava"}
|
labels := map[string]string{"type": "tool", "name": "metalava"}
|
||||||
if !sandbox {
|
// TODO: metalava pool rejects these jobs
|
||||||
execStrategy = remoteexec.LocalExecStrategy
|
pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "java16")
|
||||||
labels["shallow"] = "true"
|
rule.Rewrapper(&remoteexec.REParams{
|
||||||
|
Labels: labels,
|
||||||
|
ExecStrategy: execStrategy,
|
||||||
|
ToolchainInputs: []string{config.JavaCmd(ctx).String()},
|
||||||
|
Platform: map[string]string{remoteexec.PoolKey: pool},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
execStrategy := remoteexec.LocalExecStrategy
|
||||||
|
labels := map[string]string{"type": "compile", "lang": "java", "compiler": "metalava", "shallow": "true"}
|
||||||
|
pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "metalava")
|
||||||
|
|
||||||
|
inputs := []string{
|
||||||
|
ctx.Config().HostJavaToolPath(ctx, "metalava").String(),
|
||||||
|
homeDir.String(),
|
||||||
|
}
|
||||||
|
if v := ctx.Config().Getenv("RBE_METALAVA_INPUTS"); v != "" {
|
||||||
|
inputs = append(inputs, strings.Split(v, ",")...)
|
||||||
|
}
|
||||||
|
cmd.Text((&remoteexec.REParams{
|
||||||
|
Labels: labels,
|
||||||
|
ExecStrategy: execStrategy,
|
||||||
|
Inputs: inputs,
|
||||||
|
RSPFiles: []string{implicitsRsp.String()},
|
||||||
|
ToolchainInputs: []string{config.JavaCmd(ctx).String()},
|
||||||
|
Platform: map[string]string{remoteexec.PoolKey: pool},
|
||||||
|
EnvironmentVariables: []string{"ANDROID_PREFS_ROOT"},
|
||||||
|
}).NoVarTemplate(ctx.Config().RBEWrapper()))
|
||||||
}
|
}
|
||||||
inputs := []string{
|
|
||||||
ctx.Config().HostJavaToolPath(ctx, "metalava").String(),
|
|
||||||
homeDir.String(),
|
|
||||||
}
|
|
||||||
if v := ctx.Config().Getenv("RBE_METALAVA_INPUTS"); v != "" {
|
|
||||||
inputs = append(inputs, strings.Split(v, ",")...)
|
|
||||||
}
|
|
||||||
cmd.Text((&remoteexec.REParams{
|
|
||||||
Labels: labels,
|
|
||||||
ExecStrategy: execStrategy,
|
|
||||||
Inputs: inputs,
|
|
||||||
RSPFiles: []string{implicitsRsp.String()},
|
|
||||||
ToolchainInputs: []string{config.JavaCmd(ctx).String()},
|
|
||||||
Platform: map[string]string{remoteexec.PoolKey: pool},
|
|
||||||
EnvironmentVariables: []string{"ANDROID_PREFS_ROOT"},
|
|
||||||
}).NoVarTemplate(ctx.Config().RBEWrapper()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.BuiltTool("metalava").
|
cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")).
|
||||||
Flag(config.JavacVmFlags).
|
Flag(config.JavacVmFlags).
|
||||||
Flag("-J--add-opens=java.base/java.util=ALL-UNNAMED").
|
Flag("-J--add-opens=java.base/java.util=ALL-UNNAMED").
|
||||||
FlagWithArg("-encoding ", "UTF-8").
|
FlagWithArg("-encoding ", "UTF-8").
|
||||||
@@ -416,18 +426,16 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi
|
|||||||
FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "metalava.rsp"), srcs).
|
FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "metalava.rsp"), srcs).
|
||||||
FlagWithInput("@", srcJarList)
|
FlagWithInput("@", srcJarList)
|
||||||
|
|
||||||
if javaHome := ctx.Config().Getenv("ANDROID_JAVA_HOME"); javaHome != "" {
|
if !sandbox {
|
||||||
cmd.Implicit(android.PathForSource(ctx, javaHome))
|
if javaHome := ctx.Config().Getenv("ANDROID_JAVA_HOME"); javaHome != "" {
|
||||||
}
|
cmd.Implicit(android.PathForSource(ctx, javaHome))
|
||||||
|
}
|
||||||
|
|
||||||
if sandbox {
|
|
||||||
cmd.FlagWithOutput("--strict-input-files ", android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"violations.txt"))
|
|
||||||
} else {
|
|
||||||
cmd.FlagWithOutput("--strict-input-files:warn ", android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"violations.txt"))
|
cmd.FlagWithOutput("--strict-input-files:warn ", android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"violations.txt"))
|
||||||
}
|
|
||||||
|
|
||||||
if implicitsRsp != nil {
|
if implicitsRsp != nil {
|
||||||
cmd.FlagWithArg("--strict-input-files-exempt ", "@"+implicitsRsp.String())
|
cmd.FlagWithArg("--strict-input-files-exempt ", "@"+implicitsRsp.String())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(bootclasspath) > 0 {
|
if len(bootclasspath) > 0 {
|
||||||
@@ -465,6 +473,13 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
|
|
||||||
rule := android.NewRuleBuilder(pctx, ctx)
|
rule := android.NewRuleBuilder(pctx, ctx)
|
||||||
|
|
||||||
|
sandbox := proptools.Bool(d.Javadoc.properties.Sandbox)
|
||||||
|
if sandbox {
|
||||||
|
rule.Sbox(android.PathForModuleOut(ctx, "metalava"),
|
||||||
|
android.PathForModuleOut(ctx, "metalava.sbox.textproto")).
|
||||||
|
SandboxInputs()
|
||||||
|
}
|
||||||
|
|
||||||
if BoolDefault(d.properties.High_mem, false) {
|
if BoolDefault(d.properties.High_mem, false) {
|
||||||
// This metalava run uses lots of memory, restrict the number of metalava jobs that can run in parallel.
|
// This metalava run uses lots of memory, restrict the number of metalava jobs that can run in parallel.
|
||||||
rule.HighMem()
|
rule.HighMem()
|
||||||
@@ -485,7 +500,7 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
homeDir := android.PathForModuleOut(ctx, "metalava", "home")
|
homeDir := android.PathForModuleOut(ctx, "metalava", "home")
|
||||||
cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
|
cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
|
||||||
deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths, implicitsRsp, homeDir,
|
deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths, implicitsRsp, homeDir,
|
||||||
Bool(d.Javadoc.properties.Sandbox))
|
sandbox)
|
||||||
cmd.Implicits(d.Javadoc.implicits)
|
cmd.Implicits(d.Javadoc.implicits)
|
||||||
|
|
||||||
d.stubsFlags(ctx, cmd, stubsDir)
|
d.stubsFlags(ctx, cmd, stubsDir)
|
||||||
@@ -610,17 +625,21 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
cmd.FlagWithArg("--error-message:compatibility:released ", msg)
|
cmd.FlagWithArg("--error-message:compatibility:released ", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
impRule := android.NewRuleBuilder(pctx, ctx)
|
if !sandbox {
|
||||||
impCmd := impRule.Command()
|
// When sandboxing is enabled RuleBuilder tracks all the inputs needed for remote execution.
|
||||||
// An action that copies the ninja generated rsp file to a new location. This allows us to
|
// Without it we have to do it manually.
|
||||||
// add a large number of inputs to a file without exceeding bash command length limits (which
|
impRule := android.NewRuleBuilder(pctx, ctx)
|
||||||
// would happen if we use the WriteFile rule). The cp is needed because RuleBuilder sets the
|
impCmd := impRule.Command()
|
||||||
// rsp file to be ${output}.rsp.
|
// An action that copies the ninja generated rsp file to a new location. This allows us to
|
||||||
impCmd.Text("cp").
|
// add a large number of inputs to a file without exceeding bash command length limits (which
|
||||||
FlagWithRspFileInputList("", android.PathForModuleOut(ctx, "metalava-implicits.rsp"), cmd.GetImplicits()).
|
// would happen if we use the WriteFile rule). The cp is needed because RuleBuilder sets the
|
||||||
Output(implicitsRsp)
|
// rsp file to be ${output}.rsp.
|
||||||
impRule.Build("implicitsGen", "implicits generation")
|
impCmd.Text("cp").
|
||||||
cmd.Implicit(implicitsRsp)
|
FlagWithRspFileInputList("", android.PathForModuleOut(ctx, "metalava-implicits.rsp"), cmd.GetImplicits()).
|
||||||
|
Output(implicitsRsp)
|
||||||
|
impRule.Build("implicitsGen", "implicits generation")
|
||||||
|
cmd.Implicit(implicitsRsp)
|
||||||
|
}
|
||||||
|
|
||||||
if generateStubs {
|
if generateStubs {
|
||||||
rule.Command().
|
rule.Command().
|
||||||
@@ -652,7 +671,10 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
rule.Command().Text("touch").Output(d.checkLastReleasedApiTimestamp)
|
rule.Command().Text("touch").Output(d.checkLastReleasedApiTimestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
rule.Restat()
|
// TODO(b/183630617): rewrapper doesn't support restat rules
|
||||||
|
if !sandbox {
|
||||||
|
rule.Restat()
|
||||||
|
}
|
||||||
|
|
||||||
zipSyncCleanupCmd(rule, srcJarDir)
|
zipSyncCleanupCmd(rule, srcJarDir)
|
||||||
|
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
package java
|
package java
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -78,6 +79,25 @@ func TestDroidstubs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDroidstubsSandbox(t *testing.T) {
|
||||||
|
ctx, _ := testJavaWithFS(t, `
|
||||||
|
droidstubs {
|
||||||
|
name: "bar-stubs",
|
||||||
|
srcs: ["bar-doc/a.java"],
|
||||||
|
sandbox: true,
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
map[string][]byte{
|
||||||
|
"bar-doc/a.java": nil,
|
||||||
|
})
|
||||||
|
|
||||||
|
m := ctx.ModuleForTests("bar-stubs", "android_common")
|
||||||
|
metalava := m.Rule("metalava")
|
||||||
|
if g, w := metalava.Inputs.Strings(), []string{"bar-doc/a.java"}; !reflect.DeepEqual(w, g) {
|
||||||
|
t.Errorf("Expected inputs %q, got %q", w, g)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDroidstubsWithSystemModules(t *testing.T) {
|
func TestDroidstubsWithSystemModules(t *testing.T) {
|
||||||
ctx, _ := testJava(t, `
|
ctx, _ := testJava(t, `
|
||||||
droidstubs {
|
droidstubs {
|
||||||
|
Reference in New Issue
Block a user