Support deterministic output for bootimg/filesystem
Adding salt to bootimg/filesystem so that avbtool can produce the same output with same input. Adding timestamp/uuid to filesystem so that resulting image can be deterministic. Bug: 229784558 Test: m com.android.virt # remove intermediates and touch some sources m com.android.virt # compare two built artifacts Change-Id: I4e4668fd0ac42a35bea5a33ec3ae8c362b6a6bd2
This commit is contained in:
parent
e3db7f6d38
commit
65f402b780
2 changed files with 40 additions and 1 deletions
|
@ -228,6 +228,15 @@ func (b *bootimg) signImage(ctx android.ModuleContext, unsignedImage android.Out
|
|||
return output
|
||||
}
|
||||
|
||||
// Calculates avb_salt from some input for deterministic output.
|
||||
func (b *bootimg) salt() string {
|
||||
var input []string
|
||||
input = append(input, b.properties.Cmdline...)
|
||||
input = append(input, proptools.StringDefault(b.properties.Partition_name, b.Name()))
|
||||
input = append(input, proptools.String(b.properties.Header_version))
|
||||
return sha1sum(input)
|
||||
}
|
||||
|
||||
func (b *bootimg) buildPropFile(ctx android.ModuleContext) (propFile android.OutputPath, toolDeps android.Paths) {
|
||||
var sb strings.Builder
|
||||
var deps android.Paths
|
||||
|
@ -248,6 +257,7 @@ func (b *bootimg) buildPropFile(ctx android.ModuleContext) (propFile android.Out
|
|||
addStr("avb_add_hash_footer_args", "") // TODO(jiyong): add --rollback_index
|
||||
partitionName := proptools.StringDefault(b.properties.Partition_name, b.Name())
|
||||
addStr("partition_name", partitionName)
|
||||
addStr("avb_salt", b.salt())
|
||||
|
||||
propFile = android.PathForModuleOut(ctx, "prop").OutputPath
|
||||
android.WriteFileRule(ctx, propFile, sb.String())
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
package filesystem
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
|
@ -88,6 +90,13 @@ type filesystemProperties struct {
|
|||
|
||||
// Symbolic links to be created under root with "ln -sf <target> <name>".
|
||||
Symlinks []symlinkDefinition
|
||||
|
||||
// Seconds since unix epoch to override timestamps of file entries
|
||||
Fake_timestamp *string
|
||||
|
||||
// When set, passed to mkuserimg_mke2fs --mke2fs_uuid & --mke2fs_hash_seed.
|
||||
// Otherwise, they'll be set as random which might cause indeterministic build output.
|
||||
Uuid *string
|
||||
}
|
||||
|
||||
// android_filesystem packages a set of modules and their transitive dependencies into a filesystem
|
||||
|
@ -276,6 +285,11 @@ func (f *filesystem) buildFileContexts(ctx android.ModuleContext) android.Output
|
|||
return fcBin.OutputPath
|
||||
}
|
||||
|
||||
// Calculates avb_salt from entry list (sorted) for deterministic output.
|
||||
func (f *filesystem) salt() string {
|
||||
return sha1sum(f.entries)
|
||||
}
|
||||
|
||||
func (f *filesystem) buildPropFile(ctx android.ModuleContext) (propFile android.OutputPath, toolDeps android.Paths) {
|
||||
type prop struct {
|
||||
name string
|
||||
|
@ -321,12 +335,19 @@ func (f *filesystem) buildPropFile(ctx android.ModuleContext) (propFile android.
|
|||
addStr("avb_add_hashtree_footer_args", "--do_not_generate_fec")
|
||||
partitionName := proptools.StringDefault(f.properties.Partition_name, f.Name())
|
||||
addStr("partition_name", partitionName)
|
||||
addStr("avb_salt", f.salt())
|
||||
}
|
||||
|
||||
if proptools.String(f.properties.File_contexts) != "" {
|
||||
addPath("selinux_fc", f.buildFileContexts(ctx))
|
||||
}
|
||||
|
||||
if timestamp := proptools.String(f.properties.Fake_timestamp); timestamp != "" {
|
||||
addStr("timestamp", timestamp)
|
||||
}
|
||||
if uuid := proptools.String(f.properties.Uuid); uuid != "" {
|
||||
addStr("uuid", uuid)
|
||||
addStr("hash_seed", uuid)
|
||||
}
|
||||
propFile = android.PathForModuleOut(ctx, "prop").OutputPath
|
||||
builder := android.NewRuleBuilder(pctx, ctx)
|
||||
builder.Command().Text("rm").Flag("-rf").Output(propFile)
|
||||
|
@ -451,3 +472,11 @@ func (f *filesystem) gatherFilteredPackagingSpecs(ctx android.ModuleContext) map
|
|||
}
|
||||
return specs
|
||||
}
|
||||
|
||||
func sha1sum(values []string) string {
|
||||
h := sha256.New()
|
||||
for _, value := range values {
|
||||
io.WriteString(h, value)
|
||||
}
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue