From 8430eea47fee26e1cd88a7a1c273aacafb3e5bda Mon Sep 17 00:00:00 2001 From: Mikhail Klementev Date: Wed, 14 Aug 2019 17:36:36 +0000 Subject: [PATCH] Implements saving build output Resolves #9 --- go.mod | 1 + go.sum | 2 ++ main.go | 7 ++++-- pew.go | 70 ++++++++++++++++++++++++++++++++++++++++++++------------- 4 files changed, 63 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index 1087f89..b930bc5 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ replace code.dumpstack.io/tools/out-of-tree/config => ./config require ( github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect + github.com/mattn/go-sqlite3 v1.11.0 github.com/naoina/go-stringutil v0.1.0 // indirect github.com/naoina/toml v0.1.1 github.com/otiai10/copy v1.0.1 diff --git a/go.sum b/go.sum index 1ef71c7..e4405b8 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5Vpd github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= +github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= github.com/naoina/toml v0.1.1 h1:PT/lllxVVN0gzzSqSlHEmP8MJB4MY2U7STGxiouV4X8= diff --git a/main.go b/main.go index c3d864a..1eade9b 100644 --- a/main.go +++ b/main.go @@ -66,7 +66,7 @@ func checkRequiredUtils() (err error) { func checkDockerPermissions() (err error) { output, err := exec.Command("docker", "ps").CombinedOutput() if err != nil { - err = fmt.Errorf(string(output)) + err = fmt.Errorf("%s", output) } return } @@ -125,6 +125,9 @@ func main() { pewTestFlag := pewCommand.Flag("test", "Override path test") pewTest := pewTestFlag.String() + pewDistFlag := pewCommand.Flag("dist", "Build result path") + pewDist := pewDistFlag.Default(PATH_DEV_NULL).String() + kernelCommand := app.Command("kernel", "Manipulate kernels") kernelListCommand := kernelCommand.Command("list", "List kernels") kernelAutogenCommand := kernelCommand.Command("autogen", @@ -230,7 +233,7 @@ func main() { case pewCommand.FullCommand(): err = pewHandler(kcfg, *path, *pewKernel, *pewBinary, *pewTest, *pewGuess, *qemuTimeout, *dockerTimeout, - *pewMax, db) + *pewMax, *pewDist, db) case kernelListCommand.FullCommand(): err = kernelListHandler(kcfg) case kernelAutogenCommand.FullCommand(): diff --git a/pew.go b/pew.go index 83076a6..7964da8 100644 --- a/pew.go +++ b/pew.go @@ -8,6 +8,7 @@ import ( "database/sql" "errors" "fmt" + "io" "io/ioutil" "log" "math/rand" @@ -27,6 +28,8 @@ import ( var somethingFailed = false +const PATH_DEV_NULL = "/dev/null" + func dockerRun(timeout time.Duration, container, workdir, command string) ( output string, err error) { @@ -141,14 +144,33 @@ func genOkFail(name string, ok bool) (aurv aurora.Value) { } type phasesResult struct { + BuildArtifact string Build, Run, Test struct { Output string Ok bool } } +func copyFile(sourcePath, destinationPath string) (err error) { + sourceFile, err := os.Open(sourcePath) + if err != nil { + return + } + defer sourceFile.Close() + + destinationFile, err := os.Create(destinationPath) + if err != nil { + return err + } + if _, err := io.Copy(destinationFile, sourceFile); err != nil { + destinationFile.Close() + return err + } + return destinationFile.Close() +} + func dumpResult(q *qemu.QemuSystem, ka config.Artifact, ki config.KernelInfo, - res *phasesResult, db *sql.DB) { + res *phasesResult, dist, binary string, db *sql.DB) { // TODO merge (problem is it's not 100% same) with log.go:logLogEntry @@ -184,11 +206,29 @@ func dumpResult(q *qemu.QemuSystem, ka config.Artifact, ki config.KernelInfo, if err != nil { log.Println("[db] addToLog (", ka, ") error:", err) } + + if binary == "" && dist != PATH_DEV_NULL { + err = os.MkdirAll(dist, os.ModePerm) + if err != nil { + log.Println("os.MkdirAll (", ka, ") error:", err) + } + + path := fmt.Sprintf("%s/%s-%s-%s", dist, ki.DistroType, + ki.DistroRelease, ki.KernelRelease) + if ka.Type != config.KernelExploit { + path += ".ko" + } + + err = copyFile(res.BuildArtifact, path) + if err != nil { + log.Println("copyFile (", ka, ") error:", err) + } + } } func whatever(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact, ki config.KernelInfo, binaryPath, testPath string, - qemuTimeout, dockerTimeout time.Duration, db *sql.DB) { + qemuTimeout, dockerTimeout time.Duration, dist string, db *sql.DB) { defer swg.Done() @@ -215,18 +255,18 @@ func whatever(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact, defer os.RemoveAll(tmp) result := phasesResult{} - defer dumpResult(q, ka, ki, &result, db) + defer dumpResult(q, ka, ki, &result, dist, binaryPath, db) - var outFile, output string if binaryPath == "" { - outFile, result.Build.Output, err = build(tmp, ka, ki, dockerTimeout) + result.BuildArtifact, result.Build.Output, err = build(tmp, ka, + ki, dockerTimeout) if err != nil { - log.Println(output) + log.Println(result.Build.Output) return } result.Build.Ok = true } else { - outFile = binaryPath + result.BuildArtifact = binaryPath result.Build.Ok = true } @@ -236,7 +276,7 @@ func whatever(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact, } if testPath == "" { - testPath = outFile + "_test" + testPath = result.BuildArtifact + "_test" } remoteTest := fmt.Sprintf("/tmp/test_%d", rand.Int()) @@ -262,7 +302,7 @@ func whatever(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact, switch ka.Type { case config.KernelModule: - result.Run.Output, err = q.CopyAndInsmod(outFile) + result.Run.Output, err = q.CopyAndInsmod(result.BuildArtifact) if err != nil { log.Println(result.Run.Output, err) return @@ -271,13 +311,13 @@ func whatever(swg *sizedwaitgroup.SizedWaitGroup, ka config.Artifact, result.Test.Output, err = testKernelModule(q, ka, remoteTest) if err != nil { - log.Println(output, err) + log.Println(result.Test.Output, err) return } result.Test.Ok = true case config.KernelExploit: remoteExploit := fmt.Sprintf("/tmp/exploit_%d", rand.Int()) - err = q.CopyFile("user", outFile, remoteExploit) + err = q.CopyFile("user", result.BuildArtifact, remoteExploit) if err != nil { return } @@ -306,7 +346,7 @@ func shuffleKernels(a []config.KernelInfo) []config.KernelInfo { func performCI(ka config.Artifact, kcfg config.KernelConfig, binaryPath, testPath string, qemuTimeout, dockerTimeout time.Duration, - max int64, db *sql.DB) (err error) { + max int64, dist string, db *sql.DB) (err error) { found := false @@ -327,7 +367,7 @@ func performCI(ka config.Artifact, kcfg config.KernelConfig, binaryPath, max -= 1 swg.Add() go whatever(&swg, ka, kernel, binaryPath, testPath, - qemuTimeout, dockerTimeout, db) + qemuTimeout, dockerTimeout, dist, db) } } swg.Wait() @@ -381,7 +421,7 @@ func genAllKernels() (sk []config.KernelMask, err error) { func pewHandler(kcfg config.KernelConfig, workPath, ovrrdKrnl, binary, test string, guess bool, qemuTimeout, dockerTimeout time.Duration, - max int64, db *sql.DB) (err error) { + max int64, dist string, db *sql.DB) (err error) { ka, err := config.ReadArtifactConfig(workPath + "/.out-of-tree.toml") if err != nil { @@ -410,7 +450,7 @@ func pewHandler(kcfg config.KernelConfig, } err = performCI(ka, kcfg, binary, test, qemuTimeout, dockerTimeout, - max, db) + max, dist, db) if err != nil { return }