feat(gost/ubuntu): check kernel source package more strictly (#1599)
This commit is contained in:
		@@ -181,7 +181,7 @@ func (deb Debian) isKernelSourcePackage(pkgname string) bool {
 | 
			
		||||
	case 1:
 | 
			
		||||
		return pkgname == "linux"
 | 
			
		||||
	case 2:
 | 
			
		||||
		if ss[0] != "liunx" {
 | 
			
		||||
		if ss[0] != "linux" {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		switch ss[1] {
 | 
			
		||||
 
 | 
			
		||||
@@ -309,3 +309,38 @@ func TestDebian_detect(t *testing.T) {
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestDebian_isKernelSourcePackage(t *testing.T) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		pkgname string
 | 
			
		||||
		want    bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			pkgname: "linux",
 | 
			
		||||
			want:    true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pkgname: "apt",
 | 
			
		||||
			want:    false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pkgname: "linux-5.10",
 | 
			
		||||
			want:    true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pkgname: "linux-grsec",
 | 
			
		||||
			want:    true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pkgname: "linux-base",
 | 
			
		||||
			want:    false,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		t.Run(tt.pkgname, func(t *testing.T) {
 | 
			
		||||
			if got := (Debian{}).isKernelSourcePackage(tt.pkgname); got != tt.want {
 | 
			
		||||
				t.Errorf("Debian.isKernelSourcePackage() = %v, want %v", got, tt.want)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										124
									
								
								gost/ubuntu.go
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								gost/ubuntu.go
									
									
									
									
									
								
							@@ -6,7 +6,7 @@ package gost
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	debver "github.com/knqyf263/go-deb-version"
 | 
			
		||||
@@ -70,8 +70,6 @@ type cveContent struct {
 | 
			
		||||
	fixStatuses models.PackageFixStatuses
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var kernelSourceNamePattern = regexp.MustCompile(`^linux((-(ti-omap4|armadaxp|mako|manta|flo|goldfish|joule|raspi2?|snapdragon|aws|azure|bluefield|dell300x|gcp|gke(op)?|ibm|intel|lowlatency|kvm|oem|oracle|euclid|lts-xenial|hwe|riscv))?(-(edge|fde|iotg|hwe|osp1))?(-[\d\.]+)?)?$`)
 | 
			
		||||
 | 
			
		||||
// DetectCVEs fills cve information that has in Gost
 | 
			
		||||
func (ubu Ubuntu) DetectCVEs(r *models.ScanResult, _ bool) (nCVEs int, err error) {
 | 
			
		||||
	if !ubu.supported(strings.Replace(r.Release, ".", "", 1)) {
 | 
			
		||||
@@ -121,7 +119,7 @@ func (ubu Ubuntu) detectCVEsWithFixState(r *models.ScanResult, fixed bool) ([]st
 | 
			
		||||
 | 
			
		||||
			n := strings.NewReplacer("linux-signed", "linux", "linux-meta", "linux").Replace(res.request.packName)
 | 
			
		||||
 | 
			
		||||
			if kernelSourceNamePattern.MatchString(n) {
 | 
			
		||||
			if ubu.isKernelSourcePackage(n) {
 | 
			
		||||
				isRunning := false
 | 
			
		||||
				for _, bn := range r.SrcPackages[res.request.packName].BinaryNames {
 | 
			
		||||
					if bn == fmt.Sprintf("linux-image-%s", r.RunningKernel.Release) {
 | 
			
		||||
@@ -151,7 +149,7 @@ func (ubu Ubuntu) detectCVEsWithFixState(r *models.ScanResult, fixed bool) ([]st
 | 
			
		||||
		for _, p := range r.SrcPackages {
 | 
			
		||||
			n := strings.NewReplacer("linux-signed", "linux", "linux-meta", "linux").Replace(p.Name)
 | 
			
		||||
 | 
			
		||||
			if kernelSourceNamePattern.MatchString(n) {
 | 
			
		||||
			if ubu.isKernelSourcePackage(n) {
 | 
			
		||||
				isRunning := false
 | 
			
		||||
				for _, bn := range p.BinaryNames {
 | 
			
		||||
					if bn == fmt.Sprintf("linux-image-%s", r.RunningKernel.Release) {
 | 
			
		||||
@@ -225,7 +223,7 @@ func (ubu Ubuntu) detect(cves map[string]gostmodels.UbuntuCVE, fixed bool, srcPk
 | 
			
		||||
					patchedVersion := rp.Note
 | 
			
		||||
 | 
			
		||||
					// https://git.launchpad.net/ubuntu-cve-tracker/tree/scripts/generate-oval#n384
 | 
			
		||||
					if kernelSourceNamePattern.MatchString(n) && strings.HasPrefix(srcPkg.Name, "linux-meta") {
 | 
			
		||||
					if ubu.isKernelSourcePackage(n) && strings.HasPrefix(srcPkg.Name, "linux-meta") {
 | 
			
		||||
						// 5.15.0.1026.30~20.04.16 -> 5.15.0.1026
 | 
			
		||||
						ss := strings.Split(installedVersion, ".")
 | 
			
		||||
						if len(ss) >= 4 {
 | 
			
		||||
@@ -247,7 +245,7 @@ func (ubu Ubuntu) detect(cves map[string]gostmodels.UbuntuCVE, fixed bool, srcPk
 | 
			
		||||
 | 
			
		||||
					if affected {
 | 
			
		||||
						for _, bn := range srcPkg.BinaryNames {
 | 
			
		||||
							if kernelSourceNamePattern.MatchString(n) && bn != runningKernelBinaryPkgName {
 | 
			
		||||
							if ubu.isKernelSourcePackage(n) && bn != runningKernelBinaryPkgName {
 | 
			
		||||
								continue
 | 
			
		||||
							}
 | 
			
		||||
							c.fixStatuses = append(c.fixStatuses, models.PackageFixStatus{
 | 
			
		||||
@@ -260,7 +258,7 @@ func (ubu Ubuntu) detect(cves map[string]gostmodels.UbuntuCVE, fixed bool, srcPk
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			for _, bn := range srcPkg.BinaryNames {
 | 
			
		||||
				if kernelSourceNamePattern.MatchString(n) && bn != runningKernelBinaryPkgName {
 | 
			
		||||
				if ubu.isKernelSourcePackage(n) && bn != runningKernelBinaryPkgName {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				c.fixStatuses = append(c.fixStatuses, models.PackageFixStatus{
 | 
			
		||||
@@ -322,3 +320,113 @@ func (ubu Ubuntu) ConvertToModel(cve *gostmodels.UbuntuCVE) *models.CveContent {
 | 
			
		||||
		Published:     cve.PublicDate,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// https://git.launchpad.net/ubuntu-cve-tracker/tree/scripts/cve_lib.py#n931
 | 
			
		||||
func (ubu Ubuntu) isKernelSourcePackage(pkgname string) bool {
 | 
			
		||||
	switch ss := strings.Split(pkgname, "-"); len(ss) {
 | 
			
		||||
	case 1:
 | 
			
		||||
		return pkgname == "linux"
 | 
			
		||||
	case 2:
 | 
			
		||||
		if ss[0] != "linux" {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		switch ss[1] {
 | 
			
		||||
		case "armadaxp", "mako", "manta", "flo", "goldfish", "joule", "raspi", "raspi2", "snapdragon", "aws", "azure", "bluefield", "dell300x", "gcp", "gke", "gkeop", "ibm", "lowlatency", "kvm", "oem", "oracle", "euclid", "hwe", "riscv":
 | 
			
		||||
			return true
 | 
			
		||||
		default:
 | 
			
		||||
			_, err := strconv.ParseFloat(ss[1], 64)
 | 
			
		||||
			return err == nil
 | 
			
		||||
		}
 | 
			
		||||
	case 3:
 | 
			
		||||
		if ss[0] != "linux" {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		switch ss[1] {
 | 
			
		||||
		case "ti":
 | 
			
		||||
			return ss[2] == "omap4"
 | 
			
		||||
		case "raspi", "raspi2", "gke", "gkeop", "ibm", "oracle", "riscv":
 | 
			
		||||
			_, err := strconv.ParseFloat(ss[2], 64)
 | 
			
		||||
			return err == nil
 | 
			
		||||
		case "aws":
 | 
			
		||||
			switch ss[2] {
 | 
			
		||||
			case "hwe", "edge":
 | 
			
		||||
				return true
 | 
			
		||||
			default:
 | 
			
		||||
				_, err := strconv.ParseFloat(ss[2], 64)
 | 
			
		||||
				return err == nil
 | 
			
		||||
			}
 | 
			
		||||
		case "azure":
 | 
			
		||||
			switch ss[2] {
 | 
			
		||||
			case "fde", "edge":
 | 
			
		||||
				return true
 | 
			
		||||
			default:
 | 
			
		||||
				_, err := strconv.ParseFloat(ss[2], 64)
 | 
			
		||||
				return err == nil
 | 
			
		||||
			}
 | 
			
		||||
		case "gcp":
 | 
			
		||||
			switch ss[2] {
 | 
			
		||||
			case "edge":
 | 
			
		||||
				return true
 | 
			
		||||
			default:
 | 
			
		||||
				_, err := strconv.ParseFloat(ss[2], 64)
 | 
			
		||||
				return err == nil
 | 
			
		||||
			}
 | 
			
		||||
		case "intel":
 | 
			
		||||
			switch ss[2] {
 | 
			
		||||
			case "iotg":
 | 
			
		||||
				return true
 | 
			
		||||
			default:
 | 
			
		||||
				_, err := strconv.ParseFloat(ss[2], 64)
 | 
			
		||||
				return err == nil
 | 
			
		||||
			}
 | 
			
		||||
		case "oem":
 | 
			
		||||
			switch ss[2] {
 | 
			
		||||
			case "osp1":
 | 
			
		||||
				return true
 | 
			
		||||
			default:
 | 
			
		||||
				_, err := strconv.ParseFloat(ss[2], 64)
 | 
			
		||||
				return err == nil
 | 
			
		||||
			}
 | 
			
		||||
		case "lts":
 | 
			
		||||
			return ss[2] == "xenial"
 | 
			
		||||
		case "hwe":
 | 
			
		||||
			switch ss[2] {
 | 
			
		||||
			case "edge":
 | 
			
		||||
				return true
 | 
			
		||||
			default:
 | 
			
		||||
				_, err := strconv.ParseFloat(ss[2], 64)
 | 
			
		||||
				return err == nil
 | 
			
		||||
			}
 | 
			
		||||
		default:
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	case 4:
 | 
			
		||||
		if ss[0] != "linux" {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		switch ss[1] {
 | 
			
		||||
		case "azure":
 | 
			
		||||
			if ss[2] != "fde" {
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
			_, err := strconv.ParseFloat(ss[3], 64)
 | 
			
		||||
			return err == nil
 | 
			
		||||
		case "intel":
 | 
			
		||||
			if ss[2] != "iotg" {
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
			_, err := strconv.ParseFloat(ss[3], 64)
 | 
			
		||||
			return err == nil
 | 
			
		||||
		case "lowlatency":
 | 
			
		||||
			if ss[2] != "hwe" {
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
			_, err := strconv.ParseFloat(ss[3], 64)
 | 
			
		||||
			return err == nil
 | 
			
		||||
		default:
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -278,3 +278,54 @@ func Test_detect(t *testing.T) {
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestUbuntu_isKernelSourcePackage(t *testing.T) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		pkgname string
 | 
			
		||||
		want    bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			pkgname: "linux",
 | 
			
		||||
			want:    true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pkgname: "apt",
 | 
			
		||||
			want:    false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pkgname: "linux-aws",
 | 
			
		||||
			want:    true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pkgname: "linux-5.9",
 | 
			
		||||
			want:    true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pkgname: "linux-base",
 | 
			
		||||
			want:    false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pkgname: "apt-utils",
 | 
			
		||||
			want:    false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pkgname: "linux-aws-edge",
 | 
			
		||||
			want:    true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pkgname: "linux-aws-5.15",
 | 
			
		||||
			want:    true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pkgname: "linux-lowlatency-hwe-5.15",
 | 
			
		||||
			want:    true,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		t.Run(tt.pkgname, func(t *testing.T) {
 | 
			
		||||
			if got := (Ubuntu{}).isKernelSourcePackage(tt.pkgname); got != tt.want {
 | 
			
		||||
				t.Errorf("Ubuntu.isKernelSourcePackage() = %v, want %v", got, tt.want)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user