Skip to content

Commit

Permalink
[CWS] add ubuntu 18.04 with kernel 4.15 to CI + fix constants (#11010)
Browse files Browse the repository at this point in the history
* [CWS] add ubuntu 18.04 with kernel 4.15 to CI

* [CWS] fix constants on 4.15 kernel

* [CWS] fix `pid_numbers_offset` on Ubuntu kernel 5.0

* [CWS] compact CI functional tests

* [CWS] revert sizeof inode changes

* [CWS] add ubuntu kernel version specific parsing

* [CWS] fix net_ns_offset constant on 4.15 kernels

* [CWS] add missing documentation comment

* [CWS] minimal abi versions

* [CWS] remove upload from ubuntu kernel version

* [CWS] fix sizeof inode constant on ubuntu 4.15 kernels

* Fix sizeof inode on amazon linux
  • Loading branch information
paulcacheux authored Mar 30, 2022
1 parent 09b2187 commit d7e2c44
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .gitlab/functional_test/security_agent.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ kitchen_test_security_agent_x64:
- KITCHEN_PLATFORM: "centos"
KITCHEN_OSVERS: "centos-77,rhel-85"
- KITCHEN_PLATFORM: "ubuntu"
KITCHEN_OSVERS: "ubuntu-18-04,ubuntu-18-04-3"
KITCHEN_OSVERS: "ubuntu-18-04-0,ubuntu-18-04,ubuntu-18-04-3"
- KITCHEN_PLATFORM: "ubuntu"
KITCHEN_OSVERS: "ubuntu-20-04,ubuntu-20-04-2,ubuntu-21-10"
- KITCHEN_PLATFORM: "suse"
Expand Down
13 changes: 13 additions & 0 deletions pkg/security/ebpf/kernel/kernel.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,19 @@ func (k *Version) IsDebianKernel() bool {
return k.OsRelease["ID"] == "debian"
}

// UbuntuKernelVersion returns a parsed ubuntu kernel version or nil if not on ubuntu or if parsing failed
func (k *Version) UbuntuKernelVersion() *kernel.UbuntuKernelVersion {
if k.OsRelease["ID"] != "ubuntu" {
return nil
}

ukv, err := kernel.NewUbuntuKernelVersion(k.UnameRelease)
if err != nil {
return nil
}
return ukv
}

// IsRH7Kernel returns whether the kernel is a rh7 kernel
func (k *Version) IsRH7Kernel() bool {
return (k.OsRelease["ID"] == "centos" || k.OsRelease["ID"] == "rhel") && k.OsRelease["VERSION_ID"] == "7"
Expand Down
64 changes: 61 additions & 3 deletions pkg/security/probe/constantfetch/fallback.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,17 @@ func (f *FallbackConstantFetcher) FinishAndGetResults() (map[string]uint64, erro
func getSizeOfStructInode(kv *kernel.Version) uint64 {
sizeOf := uint64(600)

// see https://ubuntu.com/security/CVE-2019-10638
increaseSizeAbiMinVersion := map[string]int{
"generic": 99,
"generic-lpae": 99,
"lowlatency": 99,
"gke": 1058,
"gcp": 1093,
"aws": 1066,
"azure": 1082,
}

switch {
case kv.IsRH7Kernel():
sizeOf = 584
Expand All @@ -139,6 +150,12 @@ func getSizeOfStructInode(kv *kernel.Version) uint64 {
sizeOf = 584
case kv.IsAmazonLinuxKernel() && kv.IsInRangeCloseOpen(kernel.Kernel5_10, kernel.Kernel5_11):
sizeOf = 584
case kv.IsInRangeCloseOpen(kernel.Kernel4_15, kernel.Kernel4_16):
if ubuntuAbiVersionCheck(kv, increaseSizeAbiMinVersion) {
sizeOf = 608
} else {
sizeOf = 600
}
case kv.Code != 0 && kv.Code < kernel.Kernel4_16:
sizeOf = 608
case kv.IsInRangeCloseOpen(kernel.Kernel5_0, kernel.Kernel5_1):
Expand Down Expand Up @@ -184,7 +201,9 @@ func getSignalTTYOffset(kv *kernel.Version) uint64 {
ttyOffset = 368
case kv.IsAmazonLinuxKernel() && kv.IsInRangeCloseOpen(kernel.Kernel5_4, kernel.Kernel5_5):
ttyOffset = 400
case kv.IsInRangeCloseOpen(kernel.Kernel4_13, kernel.Kernel4_19):
case kv.IsInRangeCloseOpen(kernel.Kernel4_15, kernel.Kernel4_16):
ttyOffset = 368
case kv.IsInRangeCloseOpen(kernel.Kernel4_16, kernel.Kernel4_19):
ttyOffset = 376
case kv.IsInRangeCloseOpen(kernel.Kernel4_19, kernel.Kernel5_0):
ttyOffset = 400
Expand Down Expand Up @@ -279,6 +298,8 @@ func getBpfMapNameOffset(kv *kernel.Version) uint64 {
case kv.IsSLES12Kernel():
nameOffset = 176

case kv.IsInRangeCloseOpen(kernel.Kernel4_15, kernel.Kernel4_18):
nameOffset = 112
case kv.IsInRangeCloseOpen(kernel.Kernel4_18, kernel.Kernel5_1):
nameOffset = 176
case kv.IsInRangeCloseOpen(kernel.Kernel5_1, kernel.Kernel5_3):
Expand Down Expand Up @@ -316,6 +337,8 @@ func getBpfProgAuxOffset(kv *kernel.Version) uint64 {
switch {
case kv.IsAmazonLinuxKernel() && kv.IsInRangeCloseOpen(kernel.Kernel4_14, kernel.Kernel4_15):
auxOffset = 24
case kv.IsInRangeCloseOpen(kernel.Kernel4_15, kernel.Kernel4_16):
auxOffset = 24
case kv.Code >= kernel.Kernel5_13:
auxOffset = 56
}
Expand All @@ -328,7 +351,8 @@ func getBpfProgTagOffset(kv *kernel.Version) uint64 {
switch {
case kv.IsAmazonLinuxKernel() && kv.IsInRangeCloseOpen(kernel.Kernel4_14, kernel.Kernel4_15):
progTagOffset = 16
default:
case kv.IsInRangeCloseOpen(kernel.Kernel4_15, kernel.Kernel4_16):
progTagOffset = 16
}

return progTagOffset
Expand Down Expand Up @@ -357,7 +381,7 @@ func getBpfProgAuxIDOffset(kv *kernel.Version) uint64 {
case kv.IsAmazonLinuxKernel() && kv.IsInRangeCloseOpen(kernel.Kernel4_14, kernel.Kernel4_15):
idOffset = 16

case kv.IsInRangeCloseOpen(kernel.Kernel4_18, kernel.Kernel5_0):
case kv.IsInRangeCloseOpen(kernel.Kernel4_15, kernel.Kernel5_0):
idOffset = 16
case kv.IsInRangeCloseOpen(kernel.Kernel5_0, kernel.Kernel5_4):
idOffset = 20
Expand Down Expand Up @@ -387,6 +411,8 @@ func getBpfProgAuxNameOffset(kv *kernel.Version) uint64 {
case kv.IsCOSKernel() && kv.IsInRangeCloseOpen(kernel.Kernel5_10, kernel.Kernel5_11):
nameOffset = 544

case kv.IsInRangeCloseOpen(kernel.Kernel4_15, kernel.Kernel4_18):
nameOffset = 128
case kv.IsInRangeCloseOpen(kernel.Kernel4_18, kernel.Kernel4_19):
nameOffset = 152
case kv.IsInRangeCloseOpen(kernel.Kernel4_19, kernel.Kernel5_0):
Expand Down Expand Up @@ -435,6 +461,10 @@ func getPIDNumbersOffset(kv *kernel.Version) uint64 {

case kv.IsInRangeCloseOpen(kernel.Kernel4_15, kernel.Kernel5_0):
pidNumbersOffset = 48
case kv.IsInRangeCloseOpen(kernel.Kernel5_0, kernel.Kernel5_1):
pidNumbersOffset = 56
case kv.IsInRangeCloseOpen(kernel.Kernel5_1, kernel.Kernel5_3):
pidNumbersOffset = 48
case kv.IsInRangeCloseOpen(kernel.Kernel5_0, kernel.Kernel5_3):
pidNumbersOffset = 56
case kv.IsInRangeCloseOpen(kernel.Kernel5_3, kernel.Kernel5_7):
Expand Down Expand Up @@ -522,7 +552,21 @@ func getNetDeviceIfindexOffset(kv *kernel.Version) uint64 {
}

func getNetNSOffset(kv *kernel.Version) uint64 {
// see https://ubuntu.com/security/CVE-2019-10638
hashMixAbiMinVersion := map[string]int{
"generic": 60,
"generic-lpae": 60,
"lowlatency": 60,
"oracle": 1022,
"gke": 1041,
"gcp": 1042,
"aws": 1047,
"azure": 1018,
}

switch {
case kv.IsInRangeCloseOpen(kernel.Kernel4_15, kernel.Kernel4_16) && ubuntuAbiVersionCheck(kv, hashMixAbiMinVersion):
fallthrough
// Commit 355b98553789b646ed97ad801a619ff898471b92 introduces a hashmix field for security
// purposes. This commit was cherry-picked in stable releases 4.9.168, 4.14.111, 4.19.34 and 5.0.7
// and is part of master since 5.1
Expand Down Expand Up @@ -609,3 +653,17 @@ func getFlowi6SAddrOffset(kv *kernel.Version) uint64 {
func getFlowi6ULIOffset(kv *kernel.Version) uint64 {
return getFlowi6SAddrOffset(kv) + 20
}

func ubuntuAbiVersionCheck(kv *kernel.Version, minAbiPerFlavor map[string]int) bool {
ukv := kv.UbuntuKernelVersion()
if ukv == nil {
return false
}

minAbi, present := minAbiPerFlavor[ukv.Flavor]
if !present {
return false
}

return ukv.Abi >= minAbi
}
50 changes: 50 additions & 0 deletions pkg/util/kernel/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,53 @@ func parseDebianVersion(str string) (Version, error) {
}
return ParseReleaseString(match[1])
}

// UbuntuKernelVersion represents a version from an ubuntu kernel
// Please see: https://ubuntu.com/kernel for the documentation of this scheme
type UbuntuKernelVersion struct {
Major int
Minor int
Patch int // always 0
Abi int
Flavor string
}

var ubuntuKernelVersionRegex = regexp.MustCompile(`^(\d+)\.(\d+)\.(0)-(\d+)-([[:lower:]-]+)$`)

// NewUbuntuKernelVersion parses the ubuntu release string and returns a structure with each extracted fields
func NewUbuntuKernelVersion(unameRelease string) (*UbuntuKernelVersion, error) {
match := ubuntuKernelVersionRegex.FindStringSubmatch(unameRelease)
if len(match) == 0 {
return nil, fmt.Errorf("failed to parse ubuntu kernel version")
}

major, err := strconv.ParseInt(match[1], 10, 0)
if err != nil {
return nil, err
}

minor, err := strconv.ParseInt(match[2], 10, 0)
if err != nil {
return nil, err
}

patch, err := strconv.ParseInt(match[3], 10, 0)
if err != nil {
return nil, err
}

abi, err := strconv.ParseInt(match[4], 10, 0)
if err != nil {
return nil, err
}

flavor := match[5]

return &UbuntuKernelVersion{
Major: int(major),
Minor: int(minor),
Patch: int(patch),
Abi: int(abi),
Flavor: flavor,
}, nil
}
14 changes: 14 additions & 0 deletions pkg/util/kernel/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,17 @@ func TestLinuxKernelVersionCode(t *testing.T) {
assert.Equal(t, Version(197132).String(), "3.2.12")
assert.Equal(t, Version(263168).String(), "4.4.0")
}

func TestUbuntuKernelVersion(t *testing.T) {
ubuntuVersion := "5.13.0-35-generic-lpae"
ukv, err := NewUbuntuKernelVersion(ubuntuVersion)
if err != nil {
t.Fatal(err)
}

assert.Equal(t, ukv.Major, 5)
assert.Equal(t, ukv.Minor, 13)
assert.Equal(t, ukv.Patch, 0)
assert.Equal(t, ukv.Abi, 35)
assert.Equal(t, ukv.Flavor, "generic-lpae")
}
1 change: 1 addition & 0 deletions test/kitchen/platforms.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"x86_64": {
"ubuntu-14-04": "urn,Canonical:UbuntuServer:14.04.5-LTS:14.04.201905140",
"ubuntu-16-04": "urn,Canonical:UbuntuServer:16.04.0-LTS:16.04.202106110",
"ubuntu-18-04-0": "urn,Canonical:UbuntuServer:18.04-LTS:18.04.201809110",
"ubuntu-18-04": "urn,Canonical:UbuntuServer:18.04-LTS:18.04.201906040",
"ubuntu-18-04-3": "urn,Canonical:UbuntuServer:18.04-LTS:18.04.201912180",
"ubuntu-20-04": "urn,Canonical:0001-com-ubuntu-server-focal:20_04-lts:20.04.202004230",
Expand Down

0 comments on commit d7e2c44

Please sign in to comment.