mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 09:28:54 +00:00
Ubuntu Kernel Vulns Part 1: Generate OVAL JSON (#19210)
This commit is contained in:
parent
84a1c84244
commit
14fa3e2cbe
13 changed files with 288 additions and 19 deletions
|
|
@ -7,5 +7,10 @@ type UbuntuResultXML struct {
|
||||||
DpkgInfoTests []DpkgInfoTestXML
|
DpkgInfoTests []DpkgInfoTestXML
|
||||||
DpkgInfoStates []DpkgInfoStateXML
|
DpkgInfoStates []DpkgInfoStateXML
|
||||||
DpkgInfoObjects []PackageInfoTestObjectXML
|
DpkgInfoObjects []PackageInfoTestObjectXML
|
||||||
|
UnameTests []UnixUnameTestXML
|
||||||
|
UnameStates []UnixUnameStateXML
|
||||||
|
VariableTests []VariableTestXML
|
||||||
|
VariableObjects map[int]VariableObjectXML
|
||||||
|
VariableStates []VariableStateXML
|
||||||
Variables map[string]ConstantVariableXML
|
Variables map[string]ConstantVariableXML
|
||||||
}
|
}
|
||||||
|
|
|
||||||
7
server/vulnerabilities/oval/input/unix_uname_state.go
Normal file
7
server/vulnerabilities/oval/input/unix_uname_state.go
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
package oval_input
|
||||||
|
|
||||||
|
// UnixUnameStateXML see https://oval.mitre.org/language/version5.10.1/ovaldefinition/documentation/unix-definitions-schema.html#uname_state
|
||||||
|
type UnixUnameStateXML struct {
|
||||||
|
Id string `xml:"id,attr"`
|
||||||
|
OSRelease *SimpleTypeXML `xml:"os_release"`
|
||||||
|
}
|
||||||
11
server/vulnerabilities/oval/input/unix_uname_test_object.go
Normal file
11
server/vulnerabilities/oval/input/unix_uname_test_object.go
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
package oval_input
|
||||||
|
|
||||||
|
type unixUnameTestStateXML struct {
|
||||||
|
Id string `xml:"state_ref,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://oval.mitre.org/language/version5.10.1/ovaldefinition/documentation/unix-definitions-schema.html#uname_state
|
||||||
|
type UnixUnameTestXML struct {
|
||||||
|
Id string `xml:"id,attr"`
|
||||||
|
States []unixUnameTestStateXML `xml:"state"`
|
||||||
|
}
|
||||||
7
server/vulnerabilities/oval/input/variable_object.go
Normal file
7
server/vulnerabilities/oval/input/variable_object.go
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
package oval_input
|
||||||
|
|
||||||
|
// https://oval.mitre.org/language/version5.10.1/ovaldefinition/documentation/independent-definitions-schema.html#variable_object
|
||||||
|
type VariableObjectXML struct {
|
||||||
|
Id string `xml:"id,attr"`
|
||||||
|
RefID string `xml:"var_ref"`
|
||||||
|
}
|
||||||
7
server/vulnerabilities/oval/input/variable_state.go
Normal file
7
server/vulnerabilities/oval/input/variable_state.go
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
package oval_input
|
||||||
|
|
||||||
|
// https://oval.mitre.org/language/version5.10.1/ovaldefinition/documentation/independent-definitions-schema.html#variable_state
|
||||||
|
type VariableStateXML struct {
|
||||||
|
Id string `xml:"id,attr"`
|
||||||
|
Value SimpleTypeXML `xml:"value"`
|
||||||
|
}
|
||||||
16
server/vulnerabilities/oval/input/variable_test_object.go
Normal file
16
server/vulnerabilities/oval/input/variable_test_object.go
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
package oval_input
|
||||||
|
|
||||||
|
type variableObjectXML struct {
|
||||||
|
Id string `xml:"object_ref"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type variableStateXML struct {
|
||||||
|
Id string `xml:"state_ref,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://oval.mitre.org/language/version5.10.1/ovaldefinition/documentation/independent-definitions-schema.html#variable_test
|
||||||
|
type VariableTestXML struct {
|
||||||
|
Id string `xml:"id,attr"`
|
||||||
|
Object variableObjectXML `xml:"object"`
|
||||||
|
States []variableStateXML `xml:"state"`
|
||||||
|
}
|
||||||
|
|
@ -277,6 +277,17 @@ func mapDpkgInfoTest(i oval_input.DpkgInfoTestXML) (int, *oval_parsed.DpkgInfoTe
|
||||||
return id, &tst, nil
|
return id, &tst, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mapUnixUnameTest(i oval_input.UnixUnameTestXML) (int, *oval_parsed.UnixUnameTest, error) {
|
||||||
|
id, err := extractId(i.Id)
|
||||||
|
if err != nil {
|
||||||
|
return 0, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tst := oval_parsed.UnixUnameTest{}
|
||||||
|
|
||||||
|
return id, &tst, nil
|
||||||
|
}
|
||||||
|
|
||||||
// mapDpkgInfoState maps a DpkgInfoStateXML into an EVR string. The state of an object defines
|
// mapDpkgInfoState maps a DpkgInfoStateXML into an EVR string. The state of an object defines
|
||||||
// the different information that can be used to evaluate the specified DPKG package. All Ubuntu
|
// the different information that can be used to evaluate the specified DPKG package. All Ubuntu
|
||||||
// OVAL definitions seem to only use Evr strings to define object state, that's why only Evr support
|
// OVAL definitions seem to only use Evr strings to define object state, that's why only Evr support
|
||||||
|
|
@ -296,3 +307,24 @@ func mapDpkgInfoState(sta oval_input.DpkgInfoStateXML) (*oval_parsed.ObjectState
|
||||||
r := oval_parsed.NewObjectStateEvrString(sta.Evr.Op, sta.Evr.Value)
|
r := oval_parsed.NewObjectStateEvrString(sta.Evr.Op, sta.Evr.Value)
|
||||||
return &r, nil
|
return &r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mapUnameState(sta oval_input.UnixUnameStateXML) *oval_parsed.ObjectStateString {
|
||||||
|
r := oval_parsed.NewObjectStateString(sta.OSRelease.Op, sta.OSRelease.Value)
|
||||||
|
return &r
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapVariableTest(i oval_input.VariableTestXML) (int, *oval_parsed.UnixUnameTest, error) {
|
||||||
|
id, err := extractId(i.Id)
|
||||||
|
if err != nil {
|
||||||
|
return 0, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tst := oval_parsed.UnixUnameTest{}
|
||||||
|
|
||||||
|
return id, &tst, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapVariableState(sta oval_input.VariableStateXML) *oval_parsed.ObjectStateString {
|
||||||
|
r := oval_parsed.NewObjectStateString(sta.Value.Op, sta.Value.Value)
|
||||||
|
return &r
|
||||||
|
}
|
||||||
|
|
|
||||||
9
server/vulnerabilities/oval/parsed/ind_variabletest.go
Normal file
9
server/vulnerabilities/oval/parsed/ind_variabletest.go
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
package oval_parsed
|
||||||
|
|
||||||
|
type VariableTest struct {
|
||||||
|
Objects []string
|
||||||
|
States []ObjectStateEvrString
|
||||||
|
StateOperator OperatorType
|
||||||
|
ObjectMatch ObjectMatchType
|
||||||
|
StateMatch StateMatchType
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
type UbuntuResult struct {
|
type UbuntuResult struct {
|
||||||
Definitions []Definition
|
Definitions []Definition
|
||||||
PackageTests map[int]*DpkgInfoTest
|
PackageTests map[int]*DpkgInfoTest
|
||||||
|
UnameTests map[int]*UnixUnameTest
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewUbuntuResult is the result of parsing an OVAL file that targets an Ubuntu distro.
|
// NewUbuntuResult is the result of parsing an OVAL file that targets an Ubuntu distro.
|
||||||
|
|
@ -14,6 +15,7 @@ type UbuntuResult struct {
|
||||||
func NewUbuntuResult() *UbuntuResult {
|
func NewUbuntuResult() *UbuntuResult {
|
||||||
return &UbuntuResult{
|
return &UbuntuResult{
|
||||||
PackageTests: make(map[int]*DpkgInfoTest),
|
PackageTests: make(map[int]*DpkgInfoTest),
|
||||||
|
UnameTests: make(map[int]*UnixUnameTest),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,6 +29,10 @@ func (r *UbuntuResult) AddPackageTest(id int, tst *DpkgInfoTest) {
|
||||||
r.PackageTests[id] = tst
|
r.PackageTests[id] = tst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *UbuntuResult) AddUnameTest(id int, tst *UnixUnameTest) {
|
||||||
|
r.UnameTests[id] = tst
|
||||||
|
}
|
||||||
|
|
||||||
func (r UbuntuResult) Eval(ver fleet.OSVersion, software []fleet.Software) ([]fleet.SoftwareVulnerability, error) {
|
func (r UbuntuResult) Eval(ver fleet.OSVersion, software []fleet.Software) ([]fleet.SoftwareVulnerability, error) {
|
||||||
// Test Id => Matching software
|
// Test Id => Matching software
|
||||||
pkgTstResults := make(map[int][]fleet.Software)
|
pkgTstResults := make(map[int][]fleet.Software)
|
||||||
|
|
|
||||||
6
server/vulnerabilities/oval/parsed/unix_unameState.go
Normal file
6
server/vulnerabilities/oval/parsed/unix_unameState.go
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
package oval_parsed
|
||||||
|
|
||||||
|
type UnixUnameState struct {
|
||||||
|
States []ObjectStateString
|
||||||
|
StateMatch StateMatchType
|
||||||
|
}
|
||||||
5
server/vulnerabilities/oval/parsed/unix_unameTest.go
Normal file
5
server/vulnerabilities/oval/parsed/unix_unameTest.go
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
package oval_parsed
|
||||||
|
|
||||||
|
type UnixUnameTest struct {
|
||||||
|
States []ObjectStateString
|
||||||
|
}
|
||||||
|
|
@ -254,17 +254,17 @@ func mapToRhelResult(xmlResult *oval_input.RhelResultXML) (*oval_parsed.RhelResu
|
||||||
func processUbuntuDef(r io.Reader) ([]byte, error) {
|
func processUbuntuDef(r io.Reader) ([]byte, error) {
|
||||||
xmlResult, err := parseUbuntuXML(r)
|
xmlResult, err := parseUbuntuXML(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("parsing ubuntu xml: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := mapToUbuntuResult(xmlResult)
|
result, err := mapToUbuntuResult(xmlResult)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("mapping ubuntu result: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
payload, err := json.Marshal(result)
|
payload, err := json.Marshal(result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("marshalling ubuntu result: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return payload, nil
|
return payload, nil
|
||||||
|
|
@ -272,7 +272,8 @@ func processUbuntuDef(r io.Reader) ([]byte, error) {
|
||||||
|
|
||||||
func parseUbuntuXML(reader io.Reader) (*oval_input.UbuntuResultXML, error) {
|
func parseUbuntuXML(reader io.Reader) (*oval_input.UbuntuResultXML, error) {
|
||||||
r := &oval_input.UbuntuResultXML{
|
r := &oval_input.UbuntuResultXML{
|
||||||
Variables: make(map[string]oval_input.ConstantVariableXML),
|
Variables: make(map[string]oval_input.ConstantVariableXML),
|
||||||
|
VariableObjects: make(map[int]oval_input.VariableObjectXML),
|
||||||
}
|
}
|
||||||
d := xml.NewDecoder(reader)
|
d := xml.NewDecoder(reader)
|
||||||
|
|
||||||
|
|
@ -290,35 +291,76 @@ func parseUbuntuXML(reader io.Reader) (*oval_input.UbuntuResultXML, error) {
|
||||||
if t.Name.Local == "definition" {
|
if t.Name.Local == "definition" {
|
||||||
def := oval_input.DefinitionXML{}
|
def := oval_input.DefinitionXML{}
|
||||||
if err = d.DecodeElement(&def, &t); err != nil {
|
if err = d.DecodeElement(&def, &t); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("decoding definition: %w", err)
|
||||||
}
|
}
|
||||||
r.Definitions = append(r.Definitions, def)
|
r.Definitions = append(r.Definitions, def)
|
||||||
}
|
}
|
||||||
if t.Name.Local == "dpkginfo_test" {
|
if t.Name.Local == "dpkginfo_test" {
|
||||||
tst := oval_input.DpkgInfoTestXML{}
|
tst := oval_input.DpkgInfoTestXML{}
|
||||||
if err = d.DecodeElement(&tst, &t); err != nil {
|
if err = d.DecodeElement(&tst, &t); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("decoding dpkginfo_test: %w", err)
|
||||||
}
|
}
|
||||||
r.DpkgInfoTests = append(r.DpkgInfoTests, tst)
|
r.DpkgInfoTests = append(r.DpkgInfoTests, tst)
|
||||||
}
|
}
|
||||||
if t.Name.Local == "dpkginfo_state" {
|
if t.Name.Local == "dpkginfo_state" {
|
||||||
sta := oval_input.DpkgInfoStateXML{}
|
sta := oval_input.DpkgInfoStateXML{}
|
||||||
if err = d.DecodeElement(&sta, &t); err != nil {
|
if err = d.DecodeElement(&sta, &t); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("decoding dpkginfo_state: %w", err)
|
||||||
}
|
}
|
||||||
r.DpkgInfoStates = append(r.DpkgInfoStates, sta)
|
r.DpkgInfoStates = append(r.DpkgInfoStates, sta)
|
||||||
}
|
}
|
||||||
if t.Name.Local == "dpkginfo_object" {
|
if t.Name.Local == "dpkginfo_object" {
|
||||||
obj := oval_input.PackageInfoTestObjectXML{}
|
obj := oval_input.PackageInfoTestObjectXML{}
|
||||||
if err = d.DecodeElement(&obj, &t); err != nil {
|
if err = d.DecodeElement(&obj, &t); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("decoding dpkginfo_object: %w", err)
|
||||||
}
|
}
|
||||||
r.DpkgInfoObjects = append(r.DpkgInfoObjects, obj)
|
r.DpkgInfoObjects = append(r.DpkgInfoObjects, obj)
|
||||||
}
|
}
|
||||||
|
if t.Name.Local == "uname_test" {
|
||||||
|
tst := oval_input.UnixUnameTestXML{}
|
||||||
|
if err = d.DecodeElement(&tst, &t); err != nil {
|
||||||
|
return nil, fmt.Errorf("decoding uname_test: %w", err)
|
||||||
|
}
|
||||||
|
r.UnameTests = append(r.UnameTests, tst)
|
||||||
|
}
|
||||||
|
if t.Name.Local == "uname_state" {
|
||||||
|
sta := oval_input.UnixUnameStateXML{}
|
||||||
|
if err = d.DecodeElement(&sta, &t); err != nil {
|
||||||
|
return nil, fmt.Errorf("decoding uname_state: %w", err)
|
||||||
|
}
|
||||||
|
r.UnameStates = append(r.UnameStates, sta)
|
||||||
|
}
|
||||||
|
if t.Name.Local == "variable_test" {
|
||||||
|
tst := oval_input.VariableTestXML{}
|
||||||
|
if err = d.DecodeElement(&tst, &t); err != nil {
|
||||||
|
return nil, fmt.Errorf("decoding variable_test: %w", err)
|
||||||
|
}
|
||||||
|
r.VariableTests = append(r.VariableTests, tst)
|
||||||
|
}
|
||||||
|
if t.Name.Local == "variable_object" {
|
||||||
|
obj := oval_input.VariableObjectXML{}
|
||||||
|
if err = d.DecodeElement(&obj, &t); err != nil {
|
||||||
|
return nil, fmt.Errorf("decoding variable_object: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := extractId(obj.Id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("extracting id: %w", err)
|
||||||
|
}
|
||||||
|
r.VariableObjects[id] = obj
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.Name.Local == "variable_state" {
|
||||||
|
sta := oval_input.VariableStateXML{}
|
||||||
|
if err = d.DecodeElement(&sta, &t); err != nil {
|
||||||
|
return nil, fmt.Errorf("decoding variable_state: %w", err)
|
||||||
|
}
|
||||||
|
r.VariableStates = append(r.VariableStates, sta)
|
||||||
|
}
|
||||||
if t.Name.Local == "constant_variable" {
|
if t.Name.Local == "constant_variable" {
|
||||||
cVar := oval_input.ConstantVariableXML{}
|
cVar := oval_input.ConstantVariableXML{}
|
||||||
if err = d.DecodeElement(&cVar, &t); err != nil {
|
if err = d.DecodeElement(&cVar, &t); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("decoding constant_variable: %w", err)
|
||||||
}
|
}
|
||||||
r.Variables[cVar.Id] = cVar
|
r.Variables[cVar.Id] = cVar
|
||||||
}
|
}
|
||||||
|
|
@ -331,12 +373,14 @@ func mapToUbuntuResult(xmlResult *oval_input.UbuntuResultXML) (*oval_parsed.Ubun
|
||||||
|
|
||||||
staToTst := make(map[string][]int)
|
staToTst := make(map[string][]int)
|
||||||
objToTst := make(map[string][]int)
|
objToTst := make(map[string][]int)
|
||||||
|
ustaToTst := make(map[string][]int)
|
||||||
|
vstaToTst := make(map[string][]int)
|
||||||
|
|
||||||
for _, d := range xmlResult.Definitions {
|
for _, d := range xmlResult.Definitions {
|
||||||
if len(d.Vulnerabilities) > 0 {
|
if len(d.Vulnerabilities) > 0 {
|
||||||
def, err := mapDefinition(d)
|
def, err := mapDefinition(d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("mapping definition: %w", err)
|
||||||
}
|
}
|
||||||
r.AddDefinition(*def)
|
r.AddDefinition(*def)
|
||||||
}
|
}
|
||||||
|
|
@ -345,7 +389,7 @@ func mapToUbuntuResult(xmlResult *oval_input.UbuntuResultXML) (*oval_parsed.Ubun
|
||||||
for _, t := range xmlResult.DpkgInfoTests {
|
for _, t := range xmlResult.DpkgInfoTests {
|
||||||
id, tst, err := mapDpkgInfoTest(t)
|
id, tst, err := mapDpkgInfoTest(t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("mapping dpkg info test: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
objToTst[t.Object.Id] = append(objToTst[t.Object.Id], id)
|
objToTst[t.Object.Id] = append(objToTst[t.Object.Id], id)
|
||||||
|
|
@ -358,7 +402,7 @@ func mapToUbuntuResult(xmlResult *oval_input.UbuntuResultXML) (*oval_parsed.Ubun
|
||||||
for _, o := range xmlResult.DpkgInfoObjects {
|
for _, o := range xmlResult.DpkgInfoObjects {
|
||||||
obj, err := mapPackageInfoTestObject(o, xmlResult.Variables)
|
obj, err := mapPackageInfoTestObject(o, xmlResult.Variables)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("mapping dpkg info object: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tId := range objToTst[o.Id] {
|
for _, tId := range objToTst[o.Id] {
|
||||||
|
|
@ -374,7 +418,7 @@ func mapToUbuntuResult(xmlResult *oval_input.UbuntuResultXML) (*oval_parsed.Ubun
|
||||||
for _, s := range xmlResult.DpkgInfoStates {
|
for _, s := range xmlResult.DpkgInfoStates {
|
||||||
sta, err := mapDpkgInfoState(s)
|
sta, err := mapDpkgInfoState(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("mapping dpkg info state: %w", err)
|
||||||
}
|
}
|
||||||
for _, tId := range staToTst[s.Id] {
|
for _, tId := range staToTst[s.Id] {
|
||||||
t, ok := r.PackageTests[tId]
|
t, ok := r.PackageTests[tId]
|
||||||
|
|
@ -385,5 +429,66 @@ func mapToUbuntuResult(xmlResult *oval_input.UbuntuResultXML) (*oval_parsed.Ubun
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, t := range xmlResult.UnameTests {
|
||||||
|
id, tst, err := mapUnixUnameTest(t)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("mapping uname test: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sta := range t.States {
|
||||||
|
ustaToTst[sta.Id] = append(ustaToTst[sta.Id], id)
|
||||||
|
}
|
||||||
|
r.AddUnameTest(id, tst)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range xmlResult.UnameStates {
|
||||||
|
sta := mapUnameState(s)
|
||||||
|
for _, tId := range ustaToTst[s.Id] {
|
||||||
|
t, ok := r.UnameTests[tId]
|
||||||
|
if ok {
|
||||||
|
t.States = append(t.States, *sta)
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("test not found: %d", tId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, t := range xmlResult.VariableTests {
|
||||||
|
id, tst, err := mapVariableTest(t)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("mapping variable test: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip tests that are not used in any uname test
|
||||||
|
// (there should be none)
|
||||||
|
if obj, ok := xmlResult.VariableObjects[id]; ok {
|
||||||
|
id, err := extractId(obj.RefID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("extracting variable object id: %w", err)
|
||||||
|
}
|
||||||
|
if _, ok := r.UnameTests[id]; !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sta := range t.States {
|
||||||
|
vstaToTst[sta.Id] = append(vstaToTst[sta.Id], id)
|
||||||
|
}
|
||||||
|
r.AddUnameTest(id, tst)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range xmlResult.VariableStates {
|
||||||
|
sta := mapVariableState(s)
|
||||||
|
for _, tId := range vstaToTst[s.Id] {
|
||||||
|
t, ok := r.UnameTests[tId]
|
||||||
|
if ok {
|
||||||
|
t.States = append(t.States, *sta)
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("test not found: %d", tId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,38 @@ func TestOvalParser(t *testing.T) {
|
||||||
</criteria>
|
</criteria>
|
||||||
</definition>
|
</definition>
|
||||||
</definitions>
|
</definitions>
|
||||||
|
<definition id="oval:com.ubuntu.jammy:def:55441000000" version="1" class="patch">
|
||||||
|
<metadata>
|
||||||
|
<title>USN-5544-1 -- Linux kernel vulnerabilities</title>
|
||||||
|
<affected family="unix">
|
||||||
|
<platform>Ubuntu 22.04 LTS</platform>
|
||||||
|
</affected>
|
||||||
|
<reference source="USN" ref_id="USN-5544-1" ref_url="https://ubuntu.com/security/notices/USN-5544-1"/>
|
||||||
|
<reference source="CVE" ref_id="CVE-2022-1652" ref_url="https://ubuntu.com/security/CVE-2022-1652"/>
|
||||||
|
<reference source="CVE" ref_id="CVE-2022-1679" ref_url="https://ubuntu.com/security/CVE-2022-1679"/>
|
||||||
|
<reference source="CVE" ref_id="CVE-2022-28893" ref_url="https://ubuntu.com/security/CVE-2022-28893"/>
|
||||||
|
<reference source="CVE" ref_id="CVE-2022-34918" ref_url="https://ubuntu.com/security/CVE-2022-34918"/>
|
||||||
|
<description>Some long description</description>
|
||||||
|
<advisory from="security@ubuntu.com">
|
||||||
|
<severity>High</severity>
|
||||||
|
<issued date="2022-08-02"/>
|
||||||
|
<cve href="https://ubuntu.com/security/CVE-2022-1652" priority="medium" public="20220602" cvss_score="7.8" cvss_vector="CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H" cvss_severity="high" usns="5500-1,5505-1,5513-1,5529-1,5544-1,5560-1,5560-2,5562-1,5564-1,5566-1,5582-1">CVE-2022-1652</cve>
|
||||||
|
<cve href="https://ubuntu.com/security/CVE-2022-1679" priority="medium" public="20220516" cvss_score="7.8" cvss_vector="CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H" cvss_severity="high" usns="5500-1,5505-1,5513-1,5529-1,5517-1,5544-1,5560-1,5560-2,5562-1,5564-1,5566-1,5582-1">CVE-2022-1679</cve>
|
||||||
|
<cve href="https://ubuntu.com/security/CVE-2022-28893" priority="medium" public="20220411" cvss_score="7.8" cvss_vector="CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H" cvss_severity="high" usns="5544-1,5562-1,5564-1,5566-1,5582-1">CVE-2022-28893</cve>
|
||||||
|
<cve href="https://ubuntu.com/security/CVE-2022-34918" priority="high" public="20220704" cvss_score="7.8" cvss_vector="CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H" cvss_severity="high" usns="5540-1,5544-1,5545-1,5560-1,5560-2,5562-1,5564-1,5566-1,5582-1">CVE-2022-34918</cve>
|
||||||
|
|
||||||
|
</advisory>
|
||||||
|
</metadata>
|
||||||
|
<criteria>
|
||||||
|
<extend_definition definition_ref="oval:com.ubuntu.jammy:def:100" comment="Ubuntu 22.04 LTS (jammy) is installed." applicability_check="true" />
|
||||||
|
<criteria operator="OR">
|
||||||
|
<criteria operator="AND">
|
||||||
|
<criterion test_ref="oval:com.ubuntu.jammy:tst:554410000000" comment="Long Term Support" />
|
||||||
|
<criterion test_ref="oval:com.ubuntu.jammy:tst:554410000010" comment="Long Term Support" />
|
||||||
|
</criteria>
|
||||||
|
</criteria>
|
||||||
|
</criteria>
|
||||||
|
</definition>
|
||||||
<tests>
|
<tests>
|
||||||
<linux:dpkginfo_test id="oval:com.ubuntu.jammy:tst:540210000000" version="1" check_existence="at_least_one_exists" check="at least one" comment="Long Term Support">
|
<linux:dpkginfo_test id="oval:com.ubuntu.jammy:tst:540210000000" version="1" check_existence="at_least_one_exists" check="at least one" comment="Long Term Support">
|
||||||
<linux:object object_ref="oval:com.ubuntu.jammy:obj:540210000000"/>
|
<linux:object object_ref="oval:com.ubuntu.jammy:obj:540210000000"/>
|
||||||
|
|
@ -68,7 +100,15 @@ func TestOvalParser(t *testing.T) {
|
||||||
<linux:object object_ref="oval:com.ubuntu.jammy:obj:542910000000"/>
|
<linux:object object_ref="oval:com.ubuntu.jammy:obj:542910000000"/>
|
||||||
<linux:state state_ref="oval:com.ubuntu.jammy:ste:542910000000"/>
|
<linux:state state_ref="oval:com.ubuntu.jammy:ste:542910000000"/>
|
||||||
</linux:dpkginfo_test>
|
</linux:dpkginfo_test>
|
||||||
|
<ind:variable_test id="oval:com.ubuntu.jammy:tst:554410000010" version="1" check="all" check_existence="all_exist" comment="kernel version comparison">
|
||||||
|
<ind:object object_ref="oval:com.ubuntu.jammy:obj:554410000010"/>
|
||||||
|
<ind:state state_ref="oval:com.ubuntu.jammy:ste:554410000010"/>
|
||||||
|
</ind:variable_test>
|
||||||
</tests>
|
</tests>
|
||||||
|
<unix:uname_test check="at least one" comment="Is kernel 5.15.0-\d+(-generic|-generic-64k|-generic-lpae|-lowlatency|-lowlatency-64k) currently running?" id="oval:com.ubuntu.jammy:tst:554410000000" version="1">
|
||||||
|
<unix:object object_ref="oval:com.ubuntu.jammy:obj:554410000000"/>
|
||||||
|
<unix:state state_ref="oval:com.ubuntu.jammy:ste:554410000000"/>
|
||||||
|
</unix:uname_test>
|
||||||
<objects>
|
<objects>
|
||||||
<linux:dpkginfo_object id="oval:com.ubuntu.jammy:obj:540210000000" version="1" comment="Long Term Support">
|
<linux:dpkginfo_object id="oval:com.ubuntu.jammy:obj:540210000000" version="1" comment="Long Term Support">
|
||||||
<linux:name var_ref="oval:com.ubuntu.jammy:var:540210000000" var_check="at least one" />
|
<linux:name var_ref="oval:com.ubuntu.jammy:var:540210000000" var_check="at least one" />
|
||||||
|
|
@ -76,6 +116,10 @@ func TestOvalParser(t *testing.T) {
|
||||||
<linux:dpkginfo_object id="oval:com.ubuntu.jammy:obj:542910000000" version="1" comment="Long Term Support">
|
<linux:dpkginfo_object id="oval:com.ubuntu.jammy:obj:542910000000" version="1" comment="Long Term Support">
|
||||||
<linux:name var_ref="oval:com.ubuntu.jammy:var:542910000000" var_check="at least one" />
|
<linux:name var_ref="oval:com.ubuntu.jammy:var:542910000000" var_check="at least one" />
|
||||||
</linux:dpkginfo_object>
|
</linux:dpkginfo_object>
|
||||||
|
<unix:uname_object id="oval:com.ubuntu.jammy:obj:554410000000" version="1"/>
|
||||||
|
<ind:variable_object id="oval:com.ubuntu.jammy:obj:554410000010" version="1">
|
||||||
|
<ind:var_ref>oval:com.ubuntu.jammy:var:554410000000</ind:var_ref>
|
||||||
|
</ind:variable_object>
|
||||||
</objects>
|
</objects>
|
||||||
<states>
|
<states>
|
||||||
<linux:dpkginfo_state id="oval:com.ubuntu.jammy:ste:540210000000" version="1" comment="Long Term Support">
|
<linux:dpkginfo_state id="oval:com.ubuntu.jammy:ste:540210000000" version="1" comment="Long Term Support">
|
||||||
|
|
@ -84,6 +128,12 @@ func TestOvalParser(t *testing.T) {
|
||||||
<linux:dpkginfo_state id="oval:com.ubuntu.jammy:ste:542910000000" version="1" comment="Long Term Support">
|
<linux:dpkginfo_state id="oval:com.ubuntu.jammy:ste:542910000000" version="1" comment="Long Term Support">
|
||||||
<linux:evr datatype="evr_string" operation="less than">1:9.18.1-1ubuntu1.1</linux:evr>
|
<linux:evr datatype="evr_string" operation="less than">1:9.18.1-1ubuntu1.1</linux:evr>
|
||||||
</linux:dpkginfo_state>
|
</linux:dpkginfo_state>
|
||||||
|
<unix:uname_state id="oval:com.ubuntu.jammy:ste:554410000000" version="1">
|
||||||
|
<unix:os_release operation="pattern match">5.15.0-\d+(-generic|-generic-64k|-generic-lpae|-lowlatency|-lowlatency-64k)</unix:os_release>
|
||||||
|
</unix:uname_state>
|
||||||
|
<ind:variable_state id="oval:com.ubuntu.jammy:ste:554410000010" version="1">
|
||||||
|
<ind:value datatype="debian_evr_string" operation="less than">0:5.15.0-43</ind:value>
|
||||||
|
</ind:variable_state>
|
||||||
</states>
|
</states>
|
||||||
<variables>
|
<variables>
|
||||||
<constant_variable id="oval:com.ubuntu.jammy:var:540210000000" version="1" datatype="string" comment="Long Term Support">
|
<constant_variable id="oval:com.ubuntu.jammy:var:540210000000" version="1" datatype="string" comment="Long Term Support">
|
||||||
|
|
@ -351,14 +401,8 @@ func TestOvalParser(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var expectedVulns []string
|
var expectedVulns []string
|
||||||
var expectedTestIds []int
|
|
||||||
|
|
||||||
for _, d := range xmlResult.Definitions {
|
for _, d := range xmlResult.Definitions {
|
||||||
for _, c := range d.Criteria.Criteriums {
|
|
||||||
tstId, err := extractId(c.TestId)
|
|
||||||
require.NoError(t, err)
|
|
||||||
expectedTestIds = append(expectedTestIds, tstId)
|
|
||||||
}
|
|
||||||
for _, v := range d.Vulnerabilities {
|
for _, v := range d.Vulnerabilities {
|
||||||
expectedVulns = append(expectedVulns, v.Id)
|
expectedVulns = append(expectedVulns, v.Id)
|
||||||
}
|
}
|
||||||
|
|
@ -373,6 +417,8 @@ func TestOvalParser(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
require.Equal(t, expectedVulns, actualVulns)
|
require.Equal(t, expectedVulns, actualVulns)
|
||||||
|
|
||||||
|
expectedTestIds := []int{540210000000, 542910000000, 554410000000, 554410000010}
|
||||||
require.ElementsMatch(t, expectedTestIds, actualTestIds)
|
require.ElementsMatch(t, expectedTestIds, actualTestIds)
|
||||||
|
|
||||||
require.Len(t, result.PackageTests, 2)
|
require.Len(t, result.PackageTests, 2)
|
||||||
|
|
@ -399,6 +445,13 @@ func TestOvalParser(t *testing.T) {
|
||||||
"bind9-dnsutils",
|
"bind9-dnsutils",
|
||||||
"bind9-host",
|
"bind9-host",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
require.Len(t, result.UnameTests, 2)
|
||||||
|
matchState := []oval_parsed.ObjectStateString{"pattern match|5.15.0-\\d+(-generic|-generic-64k|-generic-lpae|-lowlatency|-lowlatency-64k)"}
|
||||||
|
require.ElementsMatch(t, result.UnameTests[554410000000].States, matchState)
|
||||||
|
|
||||||
|
variableState := []oval_parsed.ObjectStateString{"less than|0:5.15.0-43"}
|
||||||
|
require.ElementsMatch(t, result.UnameTests[554410000010].States, variableState)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("#parseRhelXML", func(t *testing.T) {
|
t.Run("#parseRhelXML", func(t *testing.T) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue