Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new(pkg/driver): fixed some kernel version related issues. #364

Merged
merged 2 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions pkg/driver/distro/debian.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,13 @@ func (d *debian) FixupKernel(kr kernelrelease.KernelRelease) kernelrelease.Kerne
archExtra = fmt.Sprintf("-%s%s", matches[1], matches[2])
}
if debianKernelVersionRegex.MatchString(kr.KernelVersion) {
newKV := debianKernelVersionRegex.FindStringSubmatch(kr.KernelVersion)[0]
FedeDP marked this conversation as resolved.
Show resolved Hide resolved
// Real kernel release becomes: "5.10.178-3-rt-amd64"
realKernelReleaseStr := fmt.Sprintf("%s%s", kr.KernelVersion, archExtra)
realKernelReleaseStr := fmt.Sprintf("%s%s", newKV, archExtra)
// Parse it once again to a KernelRelease struct
kr, _ = driverkernel.FetchInfo(realKernelReleaseStr, "1")
return kr
}
return kr
// No substitutions needed; call generic FixupKernel.
return d.generic.FixupKernel(kr)
}
34 changes: 24 additions & 10 deletions pkg/driver/distro/debian_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,37 +92,50 @@ func TestDistroDebianFixup(t *testing.T) {
krInput string
kvInput string
krExpected string
kvExpected string
}
testCases := []testCase{
{
// Substitution needed since kernelversion contains the real kernelrelease
// Substitution needed since kernelversion contains the real kernelrelease (-rt)
krInput: "5.10.0-0.deb10.22-rt-amd64",
kvInput: "5.10.178-3",
kvInput: "#1 SMP PREEMPT_DYNAMIC Debian 5.10.178-3",
krExpected: "5.10.178-3-rt-amd64",
kvExpected: "1",
},
{
// Substitution needed since kernelversion contains the real kernelrelease
krInput: "5.10.0-0.deb10.22-amd64",
kvInput: "5.10.178-3",
krExpected: "5.10.178-3-amd64",
// Substitution needed since kernelversion contains the real kernelrelease (generic flavor)
krInput: "6.1.0-13-amd64",
kvInput: "#1 SMP PREEMPT_DYNAMIC Debian 6.1.55-1 (2023-09-29)",
krExpected: "6.1.55-1-amd64",
kvExpected: "1",
},
{
// Substitution NOT needed
krInput: "5.10.0-0.deb10.22-amd64",
kvInput: "1",
kvInput: "#1 SMP PREEMPT_DYNAMIC",
krExpected: "5.10.0-0.deb10.22-amd64",
kvExpected: "1",
},
{
// Substitution NOT needed
// Substitution NOT needed; kernelversion is 39
krInput: "5.10.0-0",
kvInput: "1",
kvInput: "#39 SMP PREEMPT_DYNAMIC",
krExpected: "5.10.0-0",
kvExpected: "39",
},
{
// Substitution NOT needed
krInput: "6.5.3-1~bpo12+1-rt-amd64",
kvInput: "#1 SMP PREEMPT_DYNAMIC",
krExpected: "6.5.3-1~bpo12+1-rt-amd64",
kvExpected: "1",
},
{
// Substitution NOT needed
krInput: "6.5.3-1~bpo12+1-rt-amd64",
kvInput: "1",
kvInput: "malformed",
krExpected: "6.5.3-1~bpo12+1-rt-amd64",
kvExpected: "malformed",
},
}
for _, tCase := range testCases {
Expand All @@ -131,5 +144,6 @@ func TestDistroDebianFixup(t *testing.T) {
kr.KernelVersion = tCase.kvInput
fixedKr := deb.FixupKernel(kr)
assert.Equal(t, tCase.krExpected, fixedKr.String())
assert.Equal(t, tCase.kvExpected, fixedKr.KernelVersion)
}
}
32 changes: 24 additions & 8 deletions pkg/driver/distro/distro.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"fmt"
"io"
"net/http"
"net/url"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -125,7 +126,7 @@ func getOSReleaseDistro(kr *kernelrelease.KernelRelease) (Distro, error) {
}

func toURL(repo, driverVer, fileName, arch string) string {
return fmt.Sprintf("%s/%s/%s/%s", repo, driverVer, arch, fileName)
return fmt.Sprintf("%s/%s/%s/%s", repo, url.QueryEscape(driverVer), arch, fileName)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, properly escape the driverVersion that contains a +driver.

}

func toLocalPath(driverVer, fileName, arch string) string {
Expand All @@ -138,7 +139,10 @@ func toFilename(d Distro, kr *kernelrelease.KernelRelease, driverName string, dr
return fmt.Sprintf("%s_%s_%s_%s%s", driverName, d, fixedKR.String(), fixedKR.KernelVersion, driverType.Extension())
}

func copyDataToLocalPath(destination string, src io.Reader) error {
// copyDataToLocalPath will copy a src Reader to a destination file, creating it and its paths if needed.
// Moreover, it will also take care of closing the reader.
func copyDataToLocalPath(destination string, src io.ReadCloser) error {
defer src.Close()
err := os.MkdirAll(filepath.Dir(destination), 0o750)
if err != nil {
return err
Expand All @@ -162,6 +166,13 @@ func Build(ctx context.Context,
driverType drivertype.DriverType,
driverVer string,
) (string, error) {
driverFileName := toFilename(d, &kr, driverName, driverType)
destination := toLocalPath(driverVer, driverFileName, kr.Architecture.ToNonDeb())
if exist, _ := utils.FileExists(destination); exist {
printer.Logger.Info("Skipping build, driver already present.", printer.Logger.Args("path", destination))
return destination, nil
}

env, err := d.customizeBuild(ctx, printer, driverType, kr)
if err != nil {
return "", err
Expand All @@ -173,15 +184,16 @@ func Build(ctx context.Context,
// Copy the path to the expected location.
// NOTE: for kmod, this is not useful since the driver will
// be loaded directly by dkms.
driverFileName := toFilename(d, &kr, driverName, driverType)
filePath := toLocalPath(driverVer, driverFileName, kr.Architecture.ToNonDeb())
printer.Logger.Info("Copying built driver to its destination.", printer.Logger.Args("src", path, "dst", filePath))
printer.Logger.Info("Copying built driver to its destination.", printer.Logger.Args("src", path, "dst", destination))
f, err := os.Open(filepath.Clean(path))
if err != nil {
return "", err
}
defer f.Close()
return filePath, copyDataToLocalPath(filePath, f)
err = copyDataToLocalPath(destination, f)
if err == nil {
printer.Logger.Info("Driver built.", printer.Logger.Args("path", destination))
}
return destination, err
}

// Download will try to download drivers for a distro trying specified repos.
Expand Down Expand Up @@ -224,7 +236,11 @@ func Download(ctx context.Context,
}
continue
}
return destination, copyDataToLocalPath(destination, resp.Body)
err = copyDataToLocalPath(destination, resp.Body)
if err == nil {
printer.Logger.Info("Driver downloaded.", printer.Logger.Args("path", destination))
}
return destination, err
}
return destination, fmt.Errorf("unable to find a prebuilt driver")
}
Expand Down
6 changes: 6 additions & 0 deletions pkg/driver/distro/generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package driverdistro

import (
"strings"

"github.com/blang/semver"
"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"golang.org/x/net/context"
Expand All @@ -41,6 +43,10 @@ func (g *generic) String() string {

//nolint:gocritic // the method shall not be able to modify kr
func (g *generic) FixupKernel(kr kernelrelease.KernelRelease) kernelrelease.KernelRelease {
// Take eg: "#1 SMP PREEMPT_DYNAMIC Tue, 10 Oct 2023 21:10:21 +0000" and return "1".
kv := strings.TrimLeft(kr.KernelVersion, "#")
kv = strings.Split(kv, " ")[0]
kr.KernelVersion = kv
return kr
}

Expand Down
2 changes: 2 additions & 0 deletions pkg/driver/distro/ubuntu.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ func (u *ubuntu) FixupKernel(kr kernelrelease.KernelRelease) kernelrelease.Kerne
// and everything starting from the first whitespace,
// so that eg: we receive "26~22.04.1-Ubuntu",
// therefore we only need to drop "-Ubuntu" suffix
// Take eg: "#1 SMP PREEMPT_DYNAMIC Tue, 10 Oct 2023 21:10:21 +0000" and return "1".
kr = u.generic.FixupKernel(kr)
kr.KernelVersion = strings.TrimSuffix(kr.KernelVersion, "-Ubuntu")
return kr
}
14 changes: 7 additions & 7 deletions pkg/driver/distro/ubuntu_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,43 +32,43 @@ func TestDistroUbuntuInitFixup(t *testing.T) {
testCases := []testCase{
{
krInput: "5.0.0-1028-aws-5.0",
kvInput: "26~22.04.1-Ubuntu",
kvInput: "#26~22.04.1-Ubuntu SMP Mon Apr 24 01:58:15 UTC 2023",
flavorExpected: "ubuntu-aws",
kvExpected: "26~22.04.1",
},
{
krInput: "5.0.0-1028-aws-5.0",
kvInput: "26",
kvInput: "#26",
flavorExpected: "ubuntu-aws",
kvExpected: "26",
},
{
krInput: "5.0.0-1028-aws-5.0",
kvInput: "26-Ubuntu",
kvInput: "#26-Ubuntu",
flavorExpected: "ubuntu-aws",
kvExpected: "26",
},
{
krInput: "5.0.0",
kvInput: "26",
kvInput: "#26",
flavorExpected: "ubuntu-generic",
kvExpected: "26",
},
{
krInput: "6.5.0-9-lowlatency",
kvInput: "9.1",
kvInput: "#9.1",
flavorExpected: "ubuntu-lowlatency",
kvExpected: "9.1",
},
{
krInput: "6.5.0-1008-gcp",
kvInput: "8",
kvInput: "#8",
flavorExpected: "ubuntu-gcp",
kvExpected: "8",
},
{
krInput: "6.5.0-1008-aws",
kvInput: "8~22.04.1",
kvInput: "#8~22.04.1",
flavorExpected: "ubuntu-aws",
kvExpected: "8~22.04.1",
},
Expand Down
14 changes: 1 addition & 13 deletions pkg/driver/kernel/kernel.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package driverkernel
import (
"bytes"
"runtime"
"strings"

"github.com/falcosecurity/driverkit/pkg/kernelrelease"
"golang.org/x/sys/unix"
Expand All @@ -44,21 +43,10 @@ func FetchInfo(enforcedKR, enforcedKV string) (kernelrelease.KernelRelease, erro
kv = enforcedKV
}
kernelRel := kernelrelease.FromString(kr)
kernelRel.KernelVersion = formatVersion(kv)
kernelRel.KernelVersion = kv
kernelRel.Architecture = kernelrelease.Architecture(runtime.GOARCH)
// we don't use this, it is used by bpf build to customize the kernel config LOCALVERSION.
// Expected value is empty.
kernelRel.Extraversion = ""
return kernelRel, nil
}

// formatVersion takes a kernelversion string (as taken from `uname -v`
// and extracts the first part of the string.
// Eg: '#1 SMP PREEMPT_DYNAMIC Tue, 10 Oct 2023 21:10:21 +0000' -> '1'.
// Eg: '#26~22.04.1-Ubuntu SMP Mon Apr 24 01:58:15 UTC 2023' -> '26~22.04.1-Ubuntu'.
func formatVersion(kv string) string {
// Take eg: "#1 SMP PREEMPT_DYNAMIC Tue, 10 Oct 2023 21:10:21 +0000" and return "1".
kv = strings.Trim(kv, "#")
kv = strings.Split(kv, " ")[0]
return kv
}