Do not randomize kernels installation/test order by default
This commit is contained in:
parent
f399390c2c
commit
fc0c76f114
13
kernel.go
13
kernel.go
@ -29,6 +29,7 @@ type KernelCmd struct {
|
|||||||
UseHost bool `help:"also use host kernels"`
|
UseHost bool `help:"also use host kernels"`
|
||||||
Force bool `help:"force reinstall kernel"`
|
Force bool `help:"force reinstall kernel"`
|
||||||
NoHeaders bool `help:"do not install kernel headers"`
|
NoHeaders bool `help:"do not install kernel headers"`
|
||||||
|
Shuffle bool `help:"randomize kernels installation order"`
|
||||||
|
|
||||||
List KernelListCmd `cmd:"" help:"list kernels"`
|
List KernelListCmd `cmd:"" help:"list kernels"`
|
||||||
Autogen KernelAutogenCmd `cmd:"" help:"generate kernels based on the current config"`
|
Autogen KernelAutogenCmd `cmd:"" help:"generate kernels based on the current config"`
|
||||||
@ -79,6 +80,7 @@ func (cmd KernelAutogenCmd) Run(kernelCmd *KernelCmd, g *Globals) (err error) {
|
|||||||
!kernelCmd.NoDownload,
|
!kernelCmd.NoDownload,
|
||||||
kernelCmd.Force,
|
kernelCmd.Force,
|
||||||
!kernelCmd.NoHeaders,
|
!kernelCmd.NoHeaders,
|
||||||
|
kernelCmd.Shuffle,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -111,6 +113,7 @@ func (cmd *KernelGenallCmd) Run(kernelCmd *KernelCmd, g *Globals) (err error) {
|
|||||||
!kernelCmd.NoDownload,
|
!kernelCmd.NoDownload,
|
||||||
kernelCmd.Force,
|
kernelCmd.Force,
|
||||||
!kernelCmd.NoHeaders,
|
!kernelCmd.NoHeaders,
|
||||||
|
kernelCmd.Shuffle,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -143,6 +146,7 @@ func (cmd *KernelInstallCmd) Run(kernelCmd *KernelCmd, g *Globals) (err error) {
|
|||||||
!kernelCmd.NoDownload,
|
!kernelCmd.NoDownload,
|
||||||
kernelCmd.Force,
|
kernelCmd.Force,
|
||||||
!kernelCmd.NoHeaders,
|
!kernelCmd.NoHeaders,
|
||||||
|
kernelCmd.Shuffle,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -670,7 +674,7 @@ func hasKernel(ki config.KernelInfo, kcfg config.KernelConfig) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func shuffle(a []string) []string {
|
func shuffleStrings(a []string) []string {
|
||||||
// Fisher–Yates shuffle
|
// Fisher–Yates shuffle
|
||||||
for i := len(a) - 1; i > 0; i-- {
|
for i := len(a) - 1; i > 0; i-- {
|
||||||
j := rand.Intn(i + 1)
|
j := rand.Intn(i + 1)
|
||||||
@ -681,7 +685,7 @@ func shuffle(a []string) []string {
|
|||||||
|
|
||||||
func generateKernels(km config.KernelMask, registry string,
|
func generateKernels(km config.KernelMask, registry string,
|
||||||
commands []config.DockerCommand, max int64,
|
commands []config.DockerCommand, max int64,
|
||||||
download, force, headers bool) (err error) {
|
download, force, headers, shuffle bool) (err error) {
|
||||||
|
|
||||||
log.Info().Msgf("Generating for kernel mask %v", km)
|
log.Info().Msgf("Generating for kernel mask %v", km)
|
||||||
|
|
||||||
@ -711,7 +715,10 @@ func generateKernels(km config.KernelMask, registry string,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, pkg := range shuffle(pkgs) {
|
if shuffle {
|
||||||
|
pkgs = shuffleStrings(pkgs)
|
||||||
|
}
|
||||||
|
for i, pkg := range pkgs {
|
||||||
if max <= 0 {
|
if max <= 0 {
|
||||||
log.Print("Max is reached")
|
log.Print("Max is reached")
|
||||||
break
|
break
|
||||||
|
6
pack.go
6
pack.go
@ -63,7 +63,7 @@ func (cmd *PackCmd) Run(g *Globals) (err error) {
|
|||||||
|
|
||||||
log.Print(f.Name())
|
log.Print(f.Name())
|
||||||
|
|
||||||
PewCmd{
|
pew := PewCmd{
|
||||||
Max: cmd.KernelRuns,
|
Max: cmd.KernelRuns,
|
||||||
Runs: cmd.ExploitRuns,
|
Runs: cmd.ExploitRuns,
|
||||||
Threads: cmd.Threads,
|
Threads: cmd.Threads,
|
||||||
@ -72,7 +72,9 @@ func (cmd *PackCmd) Run(g *Globals) (err error) {
|
|||||||
QemuTimeout: cmd.QemuTimeout,
|
QemuTimeout: cmd.QemuTimeout,
|
||||||
DockerTimeout: cmd.DockerTimeout,
|
DockerTimeout: cmd.DockerTimeout,
|
||||||
Dist: pathDevNull,
|
Dist: pathDevNull,
|
||||||
}.Run(&Globals{
|
}
|
||||||
|
|
||||||
|
pew.Run(&Globals{
|
||||||
Config: g.Config,
|
Config: g.Config,
|
||||||
WorkDir: workPath,
|
WorkDir: workPath,
|
||||||
})
|
})
|
||||||
|
90
pew.go
90
pew.go
@ -32,6 +32,7 @@ type PewCmd struct {
|
|||||||
Runs int64 `help:"runs per each kernel" default:"1"`
|
Runs int64 `help:"runs per each kernel" default:"1"`
|
||||||
Kernel string `help:"override kernel regex"`
|
Kernel string `help:"override kernel regex"`
|
||||||
Guess bool `help:"try all defined kernels"`
|
Guess bool `help:"try all defined kernels"`
|
||||||
|
Shuffle bool `help:"randomize kernels test order"`
|
||||||
Binary string `help:"use binary, do not build"`
|
Binary string `help:"use binary, do not build"`
|
||||||
Test string `help:"override path for test"`
|
Test string `help:"override path for test"`
|
||||||
Dist string `help:"build result path" default:"/dev/null"`
|
Dist string `help:"build result path" default:"/dev/null"`
|
||||||
@ -45,26 +46,29 @@ type PewCmd struct {
|
|||||||
DockerTimeout time.Duration `help:"timeout for docker"`
|
DockerTimeout time.Duration `help:"timeout for docker"`
|
||||||
|
|
||||||
Threshold float64 `help:"reliablity threshold for exit code" default:"1.00"`
|
Threshold float64 `help:"reliablity threshold for exit code" default:"1.00"`
|
||||||
|
|
||||||
|
db *sql.DB
|
||||||
|
kcfg config.KernelConfig
|
||||||
|
timeoutDeadline time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd PewCmd) Run(g *Globals) (err error) {
|
func (cmd *PewCmd) Run(g *Globals) (err error) {
|
||||||
kcfg, err := config.ReadKernelConfig(g.Config.Kernels)
|
cmd.kcfg, err = config.ReadKernelConfig(g.Config.Kernels)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug().Err(err).Msg("read kernels config")
|
log.Fatal().Err(err).Msg("read kernels config")
|
||||||
}
|
}
|
||||||
|
|
||||||
stop := time.Time{} // never stop
|
|
||||||
if cmd.Timeout != 0 {
|
if cmd.Timeout != 0 {
|
||||||
log.Info().Msgf("Set global timeout to %s", cmd.Timeout)
|
log.Info().Msgf("Set global timeout to %s", cmd.Timeout)
|
||||||
stop = time.Now().Add(cmd.Timeout)
|
cmd.timeoutDeadline = time.Now().Add(cmd.Timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
db, err := openDatabase(g.Config.Database)
|
cmd.db, err = openDatabase(g.Config.Database)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal().Err(err).
|
log.Fatal().Err(err).
|
||||||
Msgf("Cannot open database %s", g.Config.Database)
|
Msgf("Cannot open database %s", g.Config.Database)
|
||||||
}
|
}
|
||||||
defer db.Close()
|
defer cmd.db.Close()
|
||||||
|
|
||||||
var configPath string
|
var configPath string
|
||||||
if cmd.ArtifactConfig == "" {
|
if cmd.ArtifactConfig == "" {
|
||||||
@ -98,16 +102,16 @@ func (cmd PewCmd) Run(g *Globals) (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qemuTimeout := g.Config.Qemu.Timeout.Duration
|
|
||||||
if cmd.QemuTimeout != 0 {
|
if cmd.QemuTimeout != 0 {
|
||||||
log.Info().Msgf("Set qemu timeout to %s", cmd.QemuTimeout)
|
log.Info().Msgf("Set qemu timeout to %s", cmd.QemuTimeout)
|
||||||
qemuTimeout = cmd.QemuTimeout
|
} else {
|
||||||
|
cmd.QemuTimeout = g.Config.Qemu.Timeout.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
dockerTimeout := g.Config.Docker.Timeout.Duration
|
|
||||||
if cmd.DockerTimeout != 0 {
|
if cmd.DockerTimeout != 0 {
|
||||||
log.Info().Msgf("Set docker timeout to %s", cmd.DockerTimeout)
|
log.Info().Msgf("Set docker timeout to %s", cmd.DockerTimeout)
|
||||||
dockerTimeout = cmd.DockerTimeout
|
} else {
|
||||||
|
cmd.DockerTimeout = g.Config.Docker.Timeout.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.Tag == "" {
|
if cmd.Tag == "" {
|
||||||
@ -115,10 +119,7 @@ func (cmd PewCmd) Run(g *Globals) (err error) {
|
|||||||
}
|
}
|
||||||
log.Info().Str("tag", cmd.Tag).Msg("log")
|
log.Info().Str("tag", cmd.Tag).Msg("log")
|
||||||
|
|
||||||
err = performCI(ka, kcfg, cmd.Binary, cmd.Test, stop,
|
err = cmd.performCI(ka)
|
||||||
qemuTimeout, dockerTimeout,
|
|
||||||
cmd.Max, cmd.Runs, cmd.Dist, cmd.Tag,
|
|
||||||
cmd.Threads, db)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -518,10 +519,8 @@ func copyStandardModules(q *qemu.System, ki config.KernelInfo) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func testArtifact(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact,
|
func (cmd PewCmd) testArtifact(swg *sizedwaitgroup.SizedWaitGroup,
|
||||||
ki config.KernelInfo, binaryPath, testPath string,
|
ka config.Artifact, ki config.KernelInfo) {
|
||||||
qemuTimeout, dockerTimeout time.Duration, dist, tag string,
|
|
||||||
db *sql.DB) {
|
|
||||||
|
|
||||||
defer swg.Done()
|
defer swg.Done()
|
||||||
|
|
||||||
@ -539,7 +538,7 @@ func testArtifact(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact,
|
|||||||
slog.Error().Err(err).Msg("qemu init")
|
slog.Error().Err(err).Msg("qemu init")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
q.Timeout = qemuTimeout
|
q.Timeout = cmd.QemuTimeout
|
||||||
|
|
||||||
if ka.Qemu.Timeout.Duration != 0 {
|
if ka.Qemu.Timeout.Duration != 0 {
|
||||||
q.Timeout = ka.Qemu.Timeout.Duration
|
q.Timeout = ka.Qemu.Timeout.Duration
|
||||||
@ -552,7 +551,7 @@ func testArtifact(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ka.Docker.Timeout.Duration != 0 {
|
if ka.Docker.Timeout.Duration != 0 {
|
||||||
dockerTimeout = ka.Docker.Timeout.Duration
|
cmd.DockerTimeout = ka.Docker.Timeout.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
q.SetKASLR(!ka.Mitigations.DisableKaslr)
|
q.SetKASLR(!ka.Mitigations.DisableKaslr)
|
||||||
@ -589,16 +588,16 @@ func testArtifact(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact,
|
|||||||
defer os.RemoveAll(tmp)
|
defer os.RemoveAll(tmp)
|
||||||
|
|
||||||
result := phasesResult{}
|
result := phasesResult{}
|
||||||
defer dumpResult(q, ka, ki, &result, dist, tag, binaryPath, db)
|
defer dumpResult(q, ka, ki, &result, cmd.Dist, cmd.Tag, cmd.Binary, cmd.db)
|
||||||
|
|
||||||
if ka.Type == config.Script {
|
if ka.Type == config.Script {
|
||||||
result.Build.Ok = true
|
result.Build.Ok = true
|
||||||
testPath = ka.Script
|
cmd.Test = ka.Script
|
||||||
} else if binaryPath == "" {
|
} else if cmd.Binary == "" {
|
||||||
// TODO: build should return structure
|
// TODO: build should return structure
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
result.BuildDir, result.BuildArtifact, result.Build.Output, err =
|
result.BuildDir, result.BuildArtifact, result.Build.Output, err =
|
||||||
build(tmp, ka, ki, dockerTimeout)
|
build(tmp, ka, ki, cmd.DockerTimeout)
|
||||||
slog.Debug().Str("duration", time.Now().Sub(start).String()).
|
slog.Debug().Str("duration", time.Now().Sub(start).String()).
|
||||||
Msg("build done")
|
Msg("build done")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -607,23 +606,23 @@ func testArtifact(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact,
|
|||||||
}
|
}
|
||||||
result.Build.Ok = true
|
result.Build.Ok = true
|
||||||
} else {
|
} else {
|
||||||
result.BuildArtifact = binaryPath
|
result.BuildArtifact = cmd.Binary
|
||||||
result.Build.Ok = true
|
result.Build.Ok = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if testPath == "" {
|
if cmd.Test == "" {
|
||||||
testPath = result.BuildArtifact + "_test"
|
cmd.Test = result.BuildArtifact + "_test"
|
||||||
if !exists(testPath) {
|
if !exists(cmd.Test) {
|
||||||
testPath = tmp + "/source/" + "test.sh"
|
cmd.Test = tmp + "/source/" + "test.sh"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = q.WaitForSSH(qemuTimeout)
|
err = q.WaitForSSH(cmd.QemuTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteTest, err := copyTest(q, testPath, ka)
|
remoteTest, err := copyTest(q, cmd.Test, ka)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -640,7 +639,7 @@ func testArtifact(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact,
|
|||||||
Msg("copy standard modules")
|
Msg("copy standard modules")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = preloadModules(q, ka, ki, dockerTimeout)
|
err = preloadModules(q, ka, ki, cmd.DockerTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error().Err(err).Msg("preload modules")
|
slog.Error().Err(err).Msg("preload modules")
|
||||||
return
|
return
|
||||||
@ -661,16 +660,15 @@ func shuffleKernels(a []config.KernelInfo) []config.KernelInfo {
|
|||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
func performCI(ka config.Artifact, kcfg config.KernelConfig, binaryPath,
|
func (cmd PewCmd) performCI(ka config.Artifact) (err error) {
|
||||||
testPath string, stop time.Time,
|
|
||||||
qemuTimeout, dockerTimeout time.Duration,
|
|
||||||
max, runs int64, dist, tag string, threads int,
|
|
||||||
db *sql.DB) (err error) {
|
|
||||||
|
|
||||||
found := false
|
found := false
|
||||||
|
max := cmd.Max
|
||||||
|
|
||||||
swg := sizedwaitgroup.New(threads)
|
swg := sizedwaitgroup.New(cmd.Threads)
|
||||||
for _, kernel := range shuffleKernels(kcfg.Kernels) {
|
if cmd.Shuffle {
|
||||||
|
cmd.kcfg.Kernels = shuffleKernels(cmd.kcfg.Kernels)
|
||||||
|
}
|
||||||
|
for _, kernel := range cmd.kcfg.Kernels {
|
||||||
if max <= 0 {
|
if max <= 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -684,14 +682,14 @@ func performCI(ka config.Artifact, kcfg config.KernelConfig, binaryPath,
|
|||||||
if supported {
|
if supported {
|
||||||
found = true
|
found = true
|
||||||
max--
|
max--
|
||||||
for i := int64(0); i < runs; i++ {
|
for i := int64(0); i < cmd.Runs; i++ {
|
||||||
if !stop.IsZero() && time.Now().After(stop) {
|
if !cmd.timeoutDeadline.IsZero() &&
|
||||||
|
time.Now().After(cmd.timeoutDeadline) {
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
swg.Add()
|
swg.Add()
|
||||||
go testArtifact(&swg, ka, kernel, binaryPath,
|
go cmd.testArtifact(&swg, ka, kernel)
|
||||||
testPath, qemuTimeout, dockerTimeout,
|
|
||||||
dist, tag, db)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user