1
0

Compare commits

..

No commits in common. "ef4a9364a1bb27cae7209e21d5d91deac1825645" and "4e3313b6db54ff6c6a43df41a1afdf082628320b" have entirely different histories.

3 changed files with 75 additions and 89 deletions

View File

@ -125,7 +125,7 @@ jobs:
echo 'distro = { id = "${{ matrix.os.distro }}", release = "${{ matrix.os.release }}" }' >> examples/kernel-module/.out-of-tree.toml echo 'distro = { id = "${{ matrix.os.distro }}", release = "${{ matrix.os.release }}" }' >> examples/kernel-module/.out-of-tree.toml
echo 'kernel = { regex = ".*" }' >> examples/kernel-module/.out-of-tree.toml echo 'kernel = { regex = ".*" }' >> examples/kernel-module/.out-of-tree.toml
echo '[qemu]' >> examples/kernel-module/.out-of-tree.toml echo '[qemu]' >> examples/kernel-module/.out-of-tree.toml
echo 'timeout = "3m"' >> examples/kernel-module/.out-of-tree.toml echo 'timeout = "10m"' >> examples/kernel-module/.out-of-tree.toml
echo 'after_start_timeout = "10s"' >> examples/kernel-module/.out-of-tree.toml echo 'after_start_timeout = "10s"' >> examples/kernel-module/.out-of-tree.toml
echo 'modprobe uio || modprobe 9p || modprobe xfs' >> examples/kernel-module/test.sh echo 'modprobe uio || modprobe 9p || modprobe xfs' >> examples/kernel-module/test.sh
@ -142,7 +142,7 @@ jobs:
echo 'WorkingDirectory=/root/test' >> test.service echo 'WorkingDirectory=/root/test' >> test.service
echo 'TimeoutStopSec=1' >> test.service echo 'TimeoutStopSec=1' >> test.service
echo 'ExecStart=/usr/local/bin/out-of-tree kernel --no-prebuilt-containers autogen --threads=8 --max=64 --shuffle' >> test.service echo 'ExecStart=/usr/local/bin/out-of-tree kernel --no-prebuilt-containers autogen --threads=8 --max=64 --shuffle' >> test.service
echo 'ExecStart=/usr/local/bin/out-of-tree pew --threads=4 --include-internal-errors' >> test.service echo 'ExecStart=/usr/local/bin/out-of-tree pew --qemu-timeout=10m --threads=4 --include-internal-errors' >> test.service
scp test.service root@$IP:/etc/systemd/system/test.service scp test.service root@$IP:/etc/systemd/system/test.service

View File

@ -8,6 +8,8 @@
*out-of-tree* was created to reduce the complexity of the environment for developing, testing and debugging Linux kernel exploits and out-of-tree kernel modules (hence the name "out-of-tree"). *out-of-tree* was created to reduce the complexity of the environment for developing, testing and debugging Linux kernel exploits and out-of-tree kernel modules (hence the name "out-of-tree").
![Screenshot](https://cloudflare-ipfs.com/ipfs/Qmb88fgdDjbWkxz91sWsgmoZZNfVThnCtj37u3mF2s3T3T)
## Installation ## Installation
### GNU/Linux (with [Nix](https://nixos.org/nix/)) ### GNU/Linux (with [Nix](https://nixos.org/nix/))
@ -40,9 +42,9 @@ Read [documentation](https://out-of-tree.readthedocs.io) for further info.
## Examples ## Examples
Download all Ubuntu 24.04 kernels: Generate all Ubuntu 22.04 kernels:
$ out-of-tree kernel genall --distro-id=Ubuntu --distro-release=24.04 $ out-of-tree kernel genall --distro=Ubuntu --ver=22.04
Run tests based on .out-of-tree.toml definitions: Run tests based on .out-of-tree.toml definitions:
@ -50,8 +52,8 @@ Run tests based on .out-of-tree.toml definitions:
Test with a specific kernel: Test with a specific kernel:
$ out-of-tree pew --realtime-output --distro-id=ubuntu --kernel-regex=6.8.0-41-generic $ out-of-tree pew --kernel='Ubuntu:5.4.0-29-generic'
Run debug environment: Run debug environment:
$ out-of-tree debug --distro-id=ubuntu --distro-release=24.04 --kernel-regex=6.8.0-41-generic $ out-of-tree debug --kernel='Ubuntu:5.4.0-29-generic'

View File

@ -87,7 +87,6 @@ type PewCmd struct {
Threshold float64 `help:"reliablity threshold for exit code" default:"1.00"` Threshold float64 `help:"reliablity threshold for exit code" default:"1.00"`
IncludeInternalErrors bool `help:"count internal errors as part of the success rate"` IncludeInternalErrors bool `help:"count internal errors as part of the success rate"`
InternalErrorsRetries int `help:"amount of retries on internal errors" default:"3"`
OutputOnSuccess bool `help:"show output on success"` OutputOnSuccess bool `help:"show output on success"`
RealtimeOutput bool `help:"show realtime output"` RealtimeOutput bool `help:"show realtime output"`
@ -467,33 +466,12 @@ func (cmd PewCmd) testArtifact(swg *sizedwaitgroup.SizedWaitGroup,
Str("kernel", ki.KernelRelease). Str("kernel", ki.KernelRelease).
Logger() Logger()
retriesLeft := cmd.InternalErrorsRetries ka.Process(slog, ki, cmd.OutputOnSuccess, cmd.RealtimeOutput,
var stop bool cmd.Endless, cmd.Binary, cmd.EndlessStress, cmd.EndlessTimeout,
for !stop { func(q *qemu.System, ka artifact.Artifact, ki distro.KernelInfo, result *artifact.Result) {
ka.Process(slog, ki, cmd.OutputOnSuccess, cmd.RealtimeOutput, dumpResult(q, ka, ki, result, cmd.Dist, cmd.Tag, cmd.Binary, cmd.DB)
cmd.Endless, cmd.Binary, cmd.EndlessStress, cmd.EndlessTimeout, },
func(q *qemu.System, ka artifact.Artifact, ki distro.KernelInfo, res *artifact.Result) { )
if res.InternalError == nil {
cmd.dumpResult(q, ka, ki, res)
stop = true
return
}
q.Log.Warn().Err(res.InternalError).
Str("panic", fmt.Sprintf("%v", q.KernelPanic)).
Str("timeout", fmt.Sprintf("%v", q.KilledByTimeout)).
Int("retries_left", retriesLeft).
Msg("internal")
if retriesLeft == 0 {
state.InternalErrors += 1
stop = true
return
}
retriesLeft -= 1
},
)
}
} }
func shuffleKernels(a []distro.KernelInfo) []distro.KernelInfo { func shuffleKernels(a []distro.KernelInfo) []distro.KernelInfo {
@ -589,70 +567,76 @@ func genOkFail(name string, ok bool) (aurv aurora.Value) {
return return
} }
func (cmd PewCmd) dumpResult(q *qemu.System, ka artifact.Artifact, ki distro.KernelInfo, res *artifact.Result) { func dumpResult(q *qemu.System, ka artifact.Artifact, ki distro.KernelInfo,
state.Overall += 1 res *artifact.Result, dist, tag, binary string, db *sql.DB) {
if res.Test.Ok { // TODO refactor
state.Success += 1
}
colored := "" if res.InternalError != nil {
switch ka.Type { q.Log.Warn().Err(res.InternalError).
case artifact.KernelExploit: Str("panic", fmt.Sprintf("%v", q.KernelPanic)).
colored = aurora.Sprintf("%s %s", Str("timeout", fmt.Sprintf("%v", q.KilledByTimeout)).
genOkFail("BUILD", res.Build.Ok), Msg("internal")
genOkFail("LPE", res.Test.Ok)) res.InternalErrorString = res.InternalError.Error()
case artifact.KernelModule: state.InternalErrors += 1
colored = aurora.Sprintf("%s %s %s",
genOkFail("BUILD", res.Build.Ok),
genOkFail("INSMOD", res.Run.Ok),
genOkFail("TEST", res.Test.Ok))
case artifact.Script:
colored = aurora.Sprintf("%s",
genOkFail("", res.Test.Ok))
}
additional := ""
if q.KernelPanic {
additional = "(panic)"
} else if q.KilledByTimeout {
additional = "(timeout)"
}
if additional != "" {
q.Log.Info().Msgf("%v %v", colored, additional)
} else { } else {
q.Log.Info().Msgf("%v", colored) colored := ""
state.Overall += 1
if res.Test.Ok {
state.Success += 1
}
switch ka.Type {
case artifact.KernelExploit:
colored = aurora.Sprintf("%s %s",
genOkFail("BUILD", res.Build.Ok),
genOkFail("LPE", res.Test.Ok))
case artifact.KernelModule:
colored = aurora.Sprintf("%s %s %s",
genOkFail("BUILD", res.Build.Ok),
genOkFail("INSMOD", res.Run.Ok),
genOkFail("TEST", res.Test.Ok))
case artifact.Script:
colored = aurora.Sprintf("%s",
genOkFail("", res.Test.Ok))
}
additional := ""
if q.KernelPanic {
additional = "(panic)"
} else if q.KilledByTimeout {
additional = "(timeout)"
}
if additional != "" {
q.Log.Info().Msgf("%v %v", colored, additional)
} else {
q.Log.Info().Msgf("%v", colored)
}
} }
err := addToLog(cmd.DB, q, ka, ki, res, cmd.Tag) err := addToLog(db, q, ka, ki, res, tag)
if err != nil { if err != nil {
q.Log.Error().Err(err).Msgf("[db] addToLog (%v)", ka) q.Log.Warn().Err(err).Msgf("[db] addToLog (%v)", ka)
} }
if cmd.Binary != "" { if binary == "" && dist != pathDevNull {
return err = os.MkdirAll(dist, os.ModePerm)
} if err != nil {
log.Warn().Err(err).Msgf("os.MkdirAll (%v)", ka)
}
if cmd.Dist == pathDevNull { // why? path := fmt.Sprintf("%s/%s-%s-%s", dist, ki.Distro.ID,
return ki.Distro.Release, ki.KernelRelease)
} if ka.Type != artifact.KernelExploit {
path += ".ko"
}
err = os.MkdirAll(cmd.Dist, os.ModePerm) err = artifact.CopyFile(res.BuildArtifact, path)
if err != nil { if err != nil {
log.Error().Err(err).Msgf("os.MkdirAll (%v)", ka) log.Warn().Err(err).Msgf("copy file (%v)", ka)
return }
}
path := fmt.Sprintf("%s/%s-%s-%s", cmd.Dist, ki.Distro.ID,
ki.Distro.Release, ki.KernelRelease)
if ka.Type != artifact.KernelExploit {
path += ".ko"
}
err = artifact.CopyFile(res.BuildArtifact, path)
if err != nil {
log.Error().Err(err).Msgf("copy file (%v)", ka)
return
} }
} }