From d035e4f8ad9455dc3a859e44a364771f9743bafd Mon Sep 17 00:00:00 2001 From: Mikhail Klementev Date: Fri, 16 Aug 2019 05:05:26 +0000 Subject: [PATCH] Implements build on host and support for custom kernels Resolves #6 --- config/config.go | 1 + kernel.go | 83 +++++++++++++++++++++++++++++++++++++++++------- main.go | 7 ++-- pew.go | 29 +++++++++++++++-- 4 files changed, 102 insertions(+), 18 deletions(-) diff --git a/config/config.go b/config/config.go index 439e1fd..38ba07d 100644 --- a/config/config.go +++ b/config/config.go @@ -163,6 +163,7 @@ type KernelInfo struct { KernelRelease string // Build-time information + KernelSource string // module/exploit will be build on host ContainerName string // Runtime information diff --git a/kernel.go b/kernel.go index 6fb09df..f45c389 100644 --- a/kernel.go +++ b/kernel.go @@ -18,8 +18,10 @@ import ( "strings" "time" - "code.dumpstack.io/tools/out-of-tree/config" "github.com/naoina/toml" + "github.com/zcalusic/sysinfo" + + "code.dumpstack.io/tools/out-of-tree/config" ) var KERNELS_ALL int64 = math.MaxInt64 @@ -304,16 +306,73 @@ func listDockerImages() (diis []dockerImageInfo, err error) { return } -func updateKernelsCfg() (err error) { +func genHostKernels() (kcfg config.KernelConfig, err error) { + si := sysinfo.SysInfo{} + si.GetSysInfo() + + distroType, err := config.NewDistroType(si.OS.Vendor) + if err != nil { + return + } + + cmd := exec.Command("ls", "/lib/modules") + rawOutput, err := cmd.CombinedOutput() + if err != nil { + log.Println(string(rawOutput), err) + return + } + + kernelsBase := "/boot/" + files, err := ioutil.ReadDir(kernelsBase) + if err != nil { + return + } + + // only for compatibility, docker is not really used + dii := dockerImageInfo{ + ContainerName: config.KernelMask{ + DistroType: distroType, + DistroRelease: si.OS.Version, + }.DockerName(), + } + + for _, k := range strings.Fields(string(rawOutput)) { + ki := config.KernelInfo{ + DistroType: distroType, + DistroRelease: si.OS.Version, + KernelRelease: k, + + KernelSource: "/lib/modules/" + k + "/build", + + KernelPath: kernelsBase + genKernelPath(files, k), + InitrdPath: kernelsBase + genInitrdPath(files, k), + RootFS: genRootfsImage(dii), + } + kcfg.Kernels = append(kcfg.Kernels, ki) + } + + return +} + +func updateKernelsCfg(host bool) (err error) { + newkcfg := config.KernelConfig{} + + if host { + // Get host kernels + newkcfg, err = genHostKernels() + if err != nil { + return + } + } + + // Get docker kernels dockerImages, err := listDockerImages() if err != nil { return } - newkcfg := config.KernelConfig{} - for _, d := range dockerImages { - err = genKernels(d, &newkcfg) + err = genDockerKernels(d, &newkcfg) if err != nil { log.Println("gen kernels", d.ContainerName, ":", err) continue @@ -350,7 +409,7 @@ func updateKernelsCfg() (err error) { return } -func genKernels(dii dockerImageInfo, newkcfg *config.KernelConfig) ( +func genDockerKernels(dii dockerImageInfo, newkcfg *config.KernelConfig) ( err error) { name := dii.ContainerName @@ -450,7 +509,7 @@ func generateKernels(km config.KernelMask, max int64) (err error) { return } -func kernelAutogenHandler(workPath string, max int64) (err error) { +func kernelAutogenHandler(workPath string, max int64, host bool) (err error) { ka, err := config.ReadArtifactConfig(workPath + "/.out-of-tree.toml") if err != nil { return @@ -468,11 +527,11 @@ func kernelAutogenHandler(workPath string, max int64) (err error) { } } - err = updateKernelsCfg() + err = updateKernelsCfg(host) return } -func kernelDockerRegenHandler() (err error) { +func kernelDockerRegenHandler(host bool) (err error) { dockerImages, err := listDockerImages() if err != nil { return @@ -510,10 +569,10 @@ func kernelDockerRegenHandler() (err error) { } } - return updateKernelsCfg() + return updateKernelsCfg(host) } -func kernelGenallHandler(distro, version string) (err error) { +func kernelGenallHandler(distro, version string, host bool) (err error) { distroType, err := config.NewDistroType(distro) if err != nil { return @@ -529,5 +588,5 @@ func kernelGenallHandler(distro, version string) (err error) { return } - return updateKernelsCfg() + return updateKernelsCfg(host) } diff --git a/main.go b/main.go index fb92912..e9065db 100644 --- a/main.go +++ b/main.go @@ -131,6 +131,7 @@ func main() { pewDist := pewDistFlag.Default(PATH_DEV_NULL).String() kernelCommand := app.Command("kernel", "Manipulate kernels") + kernelUseHost := kernelCommand.Flag("host", "Use also host kernels").Bool() kernelListCommand := kernelCommand.Command("list", "List kernels") kernelAutogenCommand := kernelCommand.Command("autogen", "Generate kernels based on a current config") @@ -239,11 +240,11 @@ func main() { case kernelListCommand.FullCommand(): err = kernelListHandler(kcfg) case kernelAutogenCommand.FullCommand(): - err = kernelAutogenHandler(*path, *kernelAutogenMax) + err = kernelAutogenHandler(*path, *kernelAutogenMax, *kernelUseHost) case kernelDockerRegenCommand.FullCommand(): - err = kernelDockerRegenHandler() + err = kernelDockerRegenHandler(*kernelUseHost) case kernelGenallCommand.FullCommand(): - err = kernelGenallHandler(*distro, *version) + err = kernelGenallHandler(*distro, *version, *kernelUseHost) case genModuleCommand.FullCommand(): err = genConfig(config.KernelModule) case genExploitCommand.FullCommand(): diff --git a/pew.go b/pew.go index 7643616..924ebf9 100644 --- a/pew.go +++ b/pew.go @@ -72,10 +72,33 @@ func build(tmp string, ka config.Artifact, ki config.KernelInfo, } kernel := "/lib/modules/" + ki.KernelRelease + "/build" + if ki.KernelSource != "" { + kernel = ki.KernelSource + } - output, err = dockerRun(dockerTimeout, ki.ContainerName, - tmpSourcePath, "make KERNEL="+kernel+" TARGET="+target+ - " && chmod -R 777 /work") + if ki.ContainerName != "" { + output, err = dockerRun(dockerTimeout, ki.ContainerName, + tmpSourcePath, "make KERNEL="+kernel+" TARGET="+target+ + " && chmod -R 777 /work") + } else { + command := "make KERNEL=" + kernel + " TARGET=" + target + cmd := exec.Command("bash", "-c", "cd "+tmpSourcePath+" && "+command) + timer := time.AfterFunc(dockerTimeout, func() { + cmd.Process.Kill() + }) + defer timer.Stop() + + var raw []byte + raw, err = cmd.CombinedOutput() + if err != nil { + e := fmt.Sprintf("error `%v` for cmd `%v` with output `%v`", + err, command, string(raw)) + err = errors.New(e) + return + } + + output = string(raw) + } return }