1
0
Fork 0
out-of-tree/config/config.go

270 lines
5.3 KiB
Go
Raw Normal View History

2018-11-17 20:20:59 +00:00
// Copyright 2018 Mikhail Klementev. All rights reserved.
// Use of this source code is governed by a AGPLv3 license
// (or later) that can be found in the LICENSE file.
package config
import (
"fmt"
"io/ioutil"
"os"
"regexp"
"strings"
"time"
2018-11-17 20:20:59 +00:00
"code.dumpstack.io/tools/out-of-tree/distro"
2018-11-17 20:20:59 +00:00
"github.com/naoina/toml"
)
type Kernel struct {
// TODO
// Version string
// From string
// To string
// prev. ReleaseMask
Regex string
}
// Target defines the kernel
type Target struct {
Distro distro.Distro
Kernel Kernel
2018-11-17 20:20:59 +00:00
}
2019-08-17 08:51:42 +00:00
// DockerName is returns stable name for docker container
func (km Target) DockerName() string {
distro := strings.ToLower(km.Distro.ID.String())
release := strings.Replace(km.Distro.Release, ".", "__", -1)
return fmt.Sprintf("out_of_tree_%s_%s", distro, release)
}
2019-08-17 08:51:42 +00:00
// ArtifactType is the kernel module or exploit
2018-11-17 20:20:59 +00:00
type ArtifactType int
const (
2019-08-17 09:35:36 +00:00
// KernelModule is any kind of kernel module
2018-11-17 20:20:59 +00:00
KernelModule ArtifactType = iota
2019-08-17 09:47:13 +00:00
// KernelExploit is the privilege escalation exploit
2018-11-17 20:20:59 +00:00
KernelExploit
2023-03-22 20:56:44 +00:00
// Script for information gathering or automation
Script
2018-11-17 20:20:59 +00:00
)
func (at ArtifactType) String() string {
2023-03-22 20:56:44 +00:00
return [...]string{"module", "exploit", "script"}[at]
2018-11-17 20:20:59 +00:00
}
2019-08-17 08:51:42 +00:00
// UnmarshalTOML is for support github.com/naoina/toml
2018-11-17 20:20:59 +00:00
func (at *ArtifactType) UnmarshalTOML(data []byte) (err error) {
stype := strings.Trim(string(data), `"`)
stypelower := strings.ToLower(stype)
if strings.Contains(stypelower, "module") {
*at = KernelModule
} else if strings.Contains(stypelower, "exploit") {
*at = KernelExploit
2023-03-22 20:56:44 +00:00
} else if strings.Contains(stypelower, "script") {
*at = Script
2018-11-17 20:20:59 +00:00
} else {
2018-12-10 02:45:17 +00:00
err = fmt.Errorf("Type %s is unsupported", stype)
2018-11-17 20:20:59 +00:00
}
return
}
2019-08-17 08:51:42 +00:00
// MarshalTOML is for support github.com/naoina/toml
2018-11-23 09:00:30 +00:00
func (at ArtifactType) MarshalTOML() (data []byte, err error) {
s := ""
switch at {
case KernelModule:
s = "module"
case KernelExploit:
s = "exploit"
2023-03-22 20:56:44 +00:00
case Script:
s = "script"
2018-11-23 09:00:30 +00:00
default:
2018-12-10 02:45:17 +00:00
err = fmt.Errorf("Cannot marshal %d", at)
2018-11-23 09:00:30 +00:00
}
data = []byte(`"` + s + `"`)
return
}
// Duration type with toml unmarshalling support
type Duration struct {
time.Duration
}
// UnmarshalTOML for Duration
func (d *Duration) UnmarshalTOML(data []byte) (err error) {
duration := strings.Replace(string(data), "\"", "", -1)
d.Duration, err = time.ParseDuration(duration)
return
}
2019-08-19 19:01:29 +00:00
// MarshalTOML for Duration
func (d Duration) MarshalTOML() (data []byte, err error) {
data = []byte(`"` + d.Duration.String() + `"`)
return
}
2020-06-14 20:14:59 +00:00
type PreloadModule struct {
Repo string
Path string
TimeoutAfterLoad Duration
}
// Extra test files to copy over
type FileTransfer struct {
2023-01-30 20:15:17 +00:00
User string
Local string
Remote string
}
2023-02-16 10:21:44 +00:00
type Patch struct {
Path string
Source string
Script string
}
2019-08-17 08:51:42 +00:00
// Artifact is for .out-of-tree.toml
2018-11-17 20:20:59 +00:00
type Artifact struct {
Name string
Type ArtifactType
TestFiles []FileTransfer
SourcePath string
Targets []Target
2023-03-22 20:56:44 +00:00
Script string
Qemu struct {
2019-08-19 19:03:59 +00:00
Cpus int
Memory int
Timeout Duration
}
Docker struct {
Timeout Duration
}
Mitigations struct {
2019-08-19 19:03:59 +00:00
DisableSmep bool
DisableSmap bool
DisableKaslr bool
2019-08-20 00:05:19 +00:00
DisableKpti bool
}
2020-06-14 20:14:59 +00:00
2023-02-16 10:21:44 +00:00
Patches []Patch
2023-02-15 16:54:46 +00:00
Make struct {
Target string
}
2023-02-15 11:48:25 +00:00
StandardModules bool
2020-06-14 20:14:59 +00:00
Preload []PreloadModule
2018-11-17 20:20:59 +00:00
}
func (ka Artifact) checkSupport(ki KernelInfo, km Target) (
2018-11-17 20:20:59 +00:00
supported bool, err error) {
if ki.Distro.ID != km.Distro.ID {
2018-11-17 20:20:59 +00:00
supported = false
return
}
// DistroRelease is optional
if km.Distro.Release != "" && ki.Distro.Release != km.Distro.Release {
2018-11-17 20:20:59 +00:00
supported = false
return
}
supported, err = regexp.MatchString(km.Kernel.Regex, ki.KernelRelease)
2018-11-17 20:20:59 +00:00
return
}
2019-08-17 08:51:42 +00:00
// Supported returns true if given kernel is supported by artifact
2018-11-17 20:20:59 +00:00
func (ka Artifact) Supported(ki KernelInfo) (supported bool, err error) {
for _, km := range ka.Targets {
2018-11-17 20:20:59 +00:00
supported, err = ka.checkSupport(ki, km)
if supported {
break
}
}
return
}
2019-08-17 09:35:36 +00:00
// ByRootFS is sorting by .RootFS lexicographically
type ByRootFS []KernelInfo
func (a ByRootFS) Len() int { return len(a) }
func (a ByRootFS) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByRootFS) Less(i, j int) bool { return a[i].RootFS < a[j].RootFS }
2019-08-17 09:35:36 +00:00
// KernelInfo defines kernels.toml entries
2018-11-17 20:20:59 +00:00
type KernelInfo struct {
Distro distro.Distro
2018-11-17 20:20:59 +00:00
// Must be *exactly* same as in `uname -r`
2023-05-14 22:00:29 +00:00
KernelVersion string
2018-11-17 20:20:59 +00:00
KernelRelease string
// Build-time information
KernelSource string // module/exploit will be build on host
2018-11-17 20:20:59 +00:00
ContainerName string
// Runtime information
2023-02-15 10:52:36 +00:00
KernelPath string
InitrdPath string
ModulesPath string
RootFS string
// Debug symbols
VmlinuxPath string
2018-11-17 20:20:59 +00:00
}
2019-08-17 08:51:42 +00:00
// KernelConfig is the ~/.out-of-tree/kernels.toml configuration description
2018-11-17 20:20:59 +00:00
type KernelConfig struct {
Kernels []KernelInfo
}
func readFileAll(path string) (buf []byte, err error) {
f, err := os.Open(path)
if err != nil {
return
}
defer f.Close()
buf, err = ioutil.ReadAll(f)
return
}
2019-08-17 08:51:42 +00:00
// ReadKernelConfig is for read kernels.toml
2018-11-17 20:20:59 +00:00
func ReadKernelConfig(path string) (kernelCfg KernelConfig, err error) {
buf, err := readFileAll(path)
if err != nil {
return
}
err = toml.Unmarshal(buf, &kernelCfg)
if err != nil {
return
}
return
}
2019-08-17 08:51:42 +00:00
// ReadArtifactConfig is for read .out-of-tree.toml
func ReadArtifactConfig(path string) (ka Artifact, err error) {
2018-11-17 20:20:59 +00:00
buf, err := readFileAll(path)
if err != nil {
return
}
err = toml.Unmarshal(buf, &ka)
2018-11-17 20:20:59 +00:00
return
}