Skip to content

Commit

Permalink
new(pkg/driver): initial work towards kernel headers download leverag…
Browse files Browse the repository at this point in the history
…ing driverkit library when building drivers.

Signed-off-by: Federico Di Pierro <[email protected]>
  • Loading branch information
FedeDP committed Mar 25, 2024
1 parent c2dead3 commit abb4fe3
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 10 deletions.
13 changes: 13 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ require (
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-chi/chi v4.1.2+incompatible // indirect
Expand Down Expand Up @@ -193,6 +194,7 @@ require (
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/klauspost/compress v1.17.4 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
Expand Down Expand Up @@ -224,6 +226,7 @@ require (
github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 // indirect
github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 // indirect
github.com/redis/go-redis/v9 v9.3.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
Expand Down Expand Up @@ -298,6 +301,16 @@ require (
k8s.io/api v0.29.3 // indirect
k8s.io/klog/v2 v2.110.1 // indirect
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
lukechampine.com/uint128 v1.3.0 // indirect
modernc.org/cc/v3 v3.41.0 // indirect
modernc.org/ccgo/v3 v3.16.15 // indirect
modernc.org/libc v1.24.1 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.7.1 // indirect
modernc.org/opt v0.1.3 // indirect
modernc.org/sqlite v1.25.0 // indirect
modernc.org/strutil v1.2.0 // indirect
modernc.org/token v1.1.0 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/release-utils v0.7.7 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
Expand Down
18 changes: 18 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
Expand Down Expand Up @@ -511,6 +513,8 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
Expand Down Expand Up @@ -552,6 +556,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
Expand Down Expand Up @@ -662,6 +668,8 @@ github.com/redis/go-redis/extra/redisotel/v9 v9.0.5/go.mod h1:WZjPDy7VNzn77AAfnA
github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk=
github.com/redis/go-redis/v9 v9.3.0 h1:RiVDjmig62jIWp7Kk4XVLs0hzV6pI3PyTnnL0cnn0u0=
github.com/redis/go-redis/v9 v9.3.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
Expand Down Expand Up @@ -1148,6 +1156,16 @@ k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/A
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y=
modernc.org/ccgo/v3 v3.16.15/go.mod h1:yT7B+/E2m43tmMOT51GMoM98/MtHIcQQSleGnddkUNI=
modernc.org/libc v1.24.1/go.mod h1:FmfO1RLrU3MHJfyi9eYYmZBfi/R+tqZ6+hQ3yQQUkak=
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
modernc.org/memory v1.7.1/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/sqlite v1.25.0/go.mod h1:FL3pVXie73rg3Rii6V/u5BoHlSoyeZeIgKZEgHARyCU=
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
oras.land/oras-go/v2 v2.5.0 h1:o8Me9kLY74Vp5uw07QXPiitjsw7qNXi8Twd+19Zf02c=
oras.land/oras-go/v2 v2.5.0/go.mod h1:z4eisnLP530vwIOUOJeBIj0aGI0L1C3d53atvCBqZHg=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
Expand Down
4 changes: 2 additions & 2 deletions pkg/driver/distro/cos.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (c *cos) customizeBuild(ctx context.Context,
return nil, err
}

currKernelDir := env[kernelDirEnv]
currKernelDir := env[drivertype.KernelDirEnv]

cosKernelDir := filepath.Join(currKernelDir, "usr", "src")
entries, err := os.ReadDir(cosKernelDir)
Expand All @@ -87,7 +87,7 @@ func (c *cos) customizeBuild(ctx context.Context,
}
cosKernelDir = filepath.Join(cosKernelDir, entries[0].Name())
// Override env key
env[kernelDirEnv] = cosKernelDir
env[drivertype.KernelDirEnv] = cosKernelDir

clangCompilerHeader := fmt.Sprintf("%s/include/linux/compiler-clang.h", cosKernelDir)
err = utils.ReplaceLineInFile(clangCompilerHeader, "#define randomized_struct_fields_start", "", 1)
Expand Down
64 changes: 59 additions & 5 deletions pkg/driver/distro/distro.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"strings"

"github.com/docker/docker/pkg/homedir"
"github.com/falcosecurity/driverkit/pkg/driverbuilder/builder"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"golang.org/x/net/context"
"gopkg.in/ini.v1"
Expand All @@ -39,7 +40,6 @@ import (
)

const (
kernelDirEnv = "KERNELDIR"
kernelSrcDownloadFolder = "kernel-sources"
// UndeterminedDistro is the string used for the generic distro object returned when we cannot determine the distro.
UndeterminedDistro = "undetermined"
Expand Down Expand Up @@ -128,6 +128,46 @@ func getOSReleaseDistro(kr *kernelrelease.KernelRelease) (Distro, error) {
return distro, nil
}

//nolint:gocritic // the method shall not be able to modify kr
func loadKernelHeadersFromDk(distro string, kr kernelrelease.KernelRelease) ([]string, error) {
// Try to load kernel headers from driverkit. Don't error out if unable to.
b, err := builder.Factory(builder.Type(distro))
if err != nil {
return nil, nil
}

// Load minimum urls for the builder
minimumURLs := 1
if bb, ok := b.(builder.MinimumURLsBuilder); ok {
minimumURLs = bb.MinimumURLs()
}

// Fetch URLs
kernelheaders, err := b.URLs(kr)
if err != nil {
return nil, err
}

// Check actually resolving URLs
kernelheaders, err = builder.GetResolvingURLs(kernelheaders)
if err != nil {
return nil, err
}
if len(kernelheaders) < minimumURLs {
return nil, fmt.Errorf("not enough headers packages found; expected %d, found %d", minimumURLs, len(kernelheaders))
}
return kernelheaders, nil
}

func downloadKernelHeaders(headers []string) (string, error) {
// TODO download all and mv everything under /tmp/kernel/usr/{lib,src}
// change driverkit?
for _, h := range headers {
fmt.Println(h)
}
return "", nil
}

func toURL(repo, driverVer, fileName, arch string) string {
return fmt.Sprintf("%s/%s/%s/%s", repo, url.QueryEscape(driverVer), arch, fileName)
}
Expand Down Expand Up @@ -179,6 +219,20 @@ func Build(ctx context.Context,
if err != nil {
return "", err
}

// If customizeBuild did not set any KERNELDIR env variable,
// try to load kernel headers urls from driverkit.
if _, found := env[drivertype.KernelDirEnv]; !found {
headers, _ := loadKernelHeadersFromDk(d.String(), kr)
if headers != nil {
// We found the headers! Download them to `/tmp/kernel`.
path, err := downloadKernelHeaders(headers)
if err != nil {
env[drivertype.KernelDirEnv] = path
}
}
}

path, err := driverType.Build(ctx, printer, kr, driverName, driverVer, env)
if err != nil {
return "", err
Expand Down Expand Up @@ -216,10 +270,10 @@ func Download(ctx context.Context,
// Try to download from any specified repository,
// stopping at first successful http GET.
for _, repo := range repos {
url := toURL(repo, driverVer, driverFileName, kr.Architecture.ToNonDeb())
printer.Logger.Info("Trying to download a driver.", printer.Logger.Args("url", url))
driverURL := toURL(repo, driverVer, driverFileName, kr.Architecture.ToNonDeb())
printer.Logger.Info("Trying to download a driver.", printer.Logger.Args("url", driverURL))

req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, driverURL, nil)
if err != nil {
printer.Logger.Warn("Error creating http request.", printer.Logger.Args("err", err))
continue
Expand Down Expand Up @@ -368,6 +422,6 @@ func downloadKernelSrc(ctx context.Context,
if err != nil {
return nil, err
}
env[kernelDirEnv] = fullKernelDir
env[drivertype.KernelDirEnv] = fullKernelDir
return env, nil
}
12 changes: 9 additions & 3 deletions pkg/driver/type/kmod.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func (k *kmod) Build(ctx context.Context,
printer *output.Printer,
kr kernelrelease.KernelRelease,
driverName, driverVersion string,
_ map[string]string,
env map[string]string,
) (string, error) {
// Skip dkms on UEK hosts because it will always fail
if strings.Contains(kr.String(), "uek") {
Expand Down Expand Up @@ -223,8 +223,14 @@ func (k *kmod) Build(ctx context.Context,
printer.Logger.Warn("Could not fill /tmp/falco-dkms-make content.")
continue
}
dkmsCmdArgs := fmt.Sprintf(`dkms install --directive="MAKE='/tmp/falco-dkms-make'" -m %q -v %q -k %q --verbose`,
driverName, driverVersion, kr.String())
var dkmsCmdArgs string
if kernelDir, found := env[KernelDirEnv]; found {
dkmsCmdArgs = fmt.Sprintf(`dkms install --kernelsourcedir %q --directive="MAKE='/tmp/falco-dkms-make'" -m %q -v %q -k %q --verbose`,
kernelDir, driverName, driverVersion, kr.String())
} else {
dkmsCmdArgs = fmt.Sprintf(`dkms install --directive="MAKE='/tmp/falco-dkms-make'" -m %q -v %q -k %q --verbose`,
driverName, driverVersion, kr.String())
}

// Try the build through dkms
out, err = exec.CommandContext(ctx, "bash", "-c", dkmsCmdArgs).CombinedOutput() //nolint:gosec // false positive
Expand Down
3 changes: 3 additions & 0 deletions pkg/driver/type/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ import (
"github.com/falcosecurity/falcoctl/pkg/output"
)

// KernelDirEnv is the env variable set to kernel headers extraction paths.
const KernelDirEnv = "KERNELDIR"

var driverTypes = map[string]DriverType{}

// DriverType is the interface that wraps driver types.
Expand Down

0 comments on commit abb4fe3

Please sign in to comment.