Compare commits
4 Commits
4e3313b6db
...
ef4a9364a1
Author | SHA1 | Date | |
---|---|---|---|
ef4a9364a1 | |||
0bc66ec025 | |||
1814fe1144 | |||
77442a31b1 |
4
.github/workflows/e2e.yml
vendored
4
.github/workflows/e2e.yml
vendored
@ -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 = "10m"' >> examples/kernel-module/.out-of-tree.toml
|
echo 'timeout = "3m"' >> 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 --qemu-timeout=10m --threads=4 --include-internal-errors' >> test.service
|
echo 'ExecStart=/usr/local/bin/out-of-tree pew --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
|
||||||
|
|
||||||
|
10
README.md
10
README.md
@ -8,8 +8,6 @@
|
|||||||
|
|
||||||
*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/))
|
||||||
@ -42,9 +40,9 @@ Read [documentation](https://out-of-tree.readthedocs.io) for further info.
|
|||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
Generate all Ubuntu 22.04 kernels:
|
Download all Ubuntu 24.04 kernels:
|
||||||
|
|
||||||
$ out-of-tree kernel genall --distro=Ubuntu --ver=22.04
|
$ out-of-tree kernel genall --distro-id=Ubuntu --distro-release=24.04
|
||||||
|
|
||||||
Run tests based on .out-of-tree.toml definitions:
|
Run tests based on .out-of-tree.toml definitions:
|
||||||
|
|
||||||
@ -52,8 +50,8 @@ Run tests based on .out-of-tree.toml definitions:
|
|||||||
|
|
||||||
Test with a specific kernel:
|
Test with a specific kernel:
|
||||||
|
|
||||||
$ out-of-tree pew --kernel='Ubuntu:5.4.0-29-generic'
|
$ out-of-tree pew --realtime-output --distro-id=ubuntu --kernel-regex=6.8.0-41-generic
|
||||||
|
|
||||||
Run debug environment:
|
Run debug environment:
|
||||||
|
|
||||||
$ out-of-tree debug --kernel='Ubuntu:5.4.0-29-generic'
|
$ out-of-tree debug --distro-id=ubuntu --distro-release=24.04 --kernel-regex=6.8.0-41-generic
|
||||||
|
150
cmd/pew.go
150
cmd/pew.go
@ -87,6 +87,7 @@ 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"`
|
||||||
@ -466,12 +467,33 @@ func (cmd PewCmd) testArtifact(swg *sizedwaitgroup.SizedWaitGroup,
|
|||||||
Str("kernel", ki.KernelRelease).
|
Str("kernel", ki.KernelRelease).
|
||||||
Logger()
|
Logger()
|
||||||
|
|
||||||
ka.Process(slog, ki, cmd.OutputOnSuccess, cmd.RealtimeOutput,
|
retriesLeft := cmd.InternalErrorsRetries
|
||||||
cmd.Endless, cmd.Binary, cmd.EndlessStress, cmd.EndlessTimeout,
|
var stop bool
|
||||||
func(q *qemu.System, ka artifact.Artifact, ki distro.KernelInfo, result *artifact.Result) {
|
for !stop {
|
||||||
dumpResult(q, ka, ki, result, cmd.Dist, cmd.Tag, cmd.Binary, cmd.DB)
|
ka.Process(slog, ki, cmd.OutputOnSuccess, cmd.RealtimeOutput,
|
||||||
},
|
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 {
|
||||||
@ -567,76 +589,70 @@ func genOkFail(name string, ok bool) (aurv aurora.Value) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func dumpResult(q *qemu.System, ka artifact.Artifact, ki distro.KernelInfo,
|
func (cmd PewCmd) dumpResult(q *qemu.System, ka artifact.Artifact, ki distro.KernelInfo, res *artifact.Result) {
|
||||||
res *artifact.Result, dist, tag, binary string, db *sql.DB) {
|
state.Overall += 1
|
||||||
|
|
||||||
// TODO refactor
|
if res.Test.Ok {
|
||||||
|
state.Success += 1
|
||||||
|
}
|
||||||
|
|
||||||
if res.InternalError != nil {
|
colored := ""
|
||||||
q.Log.Warn().Err(res.InternalError).
|
switch ka.Type {
|
||||||
Str("panic", fmt.Sprintf("%v", q.KernelPanic)).
|
case artifact.KernelExploit:
|
||||||
Str("timeout", fmt.Sprintf("%v", q.KilledByTimeout)).
|
colored = aurora.Sprintf("%s %s",
|
||||||
Msg("internal")
|
genOkFail("BUILD", res.Build.Ok),
|
||||||
res.InternalErrorString = res.InternalError.Error()
|
genOkFail("LPE", res.Test.Ok))
|
||||||
state.InternalErrors += 1
|
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 {
|
} else {
|
||||||
colored := ""
|
q.Log.Info().Msgf("%v", 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(db, q, ka, ki, res, tag)
|
err := addToLog(cmd.DB, q, ka, ki, res, cmd.Tag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
q.Log.Warn().Err(err).Msgf("[db] addToLog (%v)", ka)
|
q.Log.Error().Err(err).Msgf("[db] addToLog (%v)", ka)
|
||||||
}
|
}
|
||||||
|
|
||||||
if binary == "" && dist != pathDevNull {
|
if cmd.Binary != "" {
|
||||||
err = os.MkdirAll(dist, os.ModePerm)
|
return
|
||||||
if err != nil {
|
}
|
||||||
log.Warn().Err(err).Msgf("os.MkdirAll (%v)", ka)
|
|
||||||
}
|
|
||||||
|
|
||||||
path := fmt.Sprintf("%s/%s-%s-%s", dist, ki.Distro.ID,
|
if cmd.Dist == pathDevNull { // why?
|
||||||
ki.Distro.Release, ki.KernelRelease)
|
return
|
||||||
if ka.Type != artifact.KernelExploit {
|
}
|
||||||
path += ".ko"
|
|
||||||
}
|
|
||||||
|
|
||||||
err = artifact.CopyFile(res.BuildArtifact, path)
|
err = os.MkdirAll(cmd.Dist, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn().Err(err).Msgf("copy file (%v)", ka)
|
log.Error().Err(err).Msgf("os.MkdirAll (%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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user