diff --git a/.gitignore b/.gitignore index 227cf37..1667872 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,7 @@ bin/ # Internally used sqlite DB data/internal.sqlite + +# test code coverage +coverage.out +coverage.html diff --git a/.gitmodules b/.gitmodules index c9b875b..c9da501 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "submodules/cvelistV5"] path = submodules/cvelistV5 url = https://github.com/CVEProject/cvelistV5.git +[submodule "submodules/debian-security-tracker"] + path = submodules/debian-security-tracker + url = https://salsa.debian.org/security-tracker-team/security-tracker.git diff --git a/.golangci.yaml b/.golangci.yaml index eae8e35..b9452a3 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -7,7 +7,10 @@ issues: linters: default: all + enable: + - gomodguard_v2 disable: + - gomodguard - gocognit - gocyclo - cyclop @@ -113,7 +116,7 @@ linters: tagliatelle: case: rules: - json: camel + json: snake yaml: camel xml: camel toml: camel @@ -132,7 +135,7 @@ linters: - CVSSV2_0 exhaustruct: include: - - "github.com/github.com/gardenlinux/glvd2" + - "github.com/github.com/gardenlinux/glvd2" formatters: enable: diff --git a/Makefile b/Makefile index 6dd6084..4431b69 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ build: .PHONY: format format: - gofmt -l -s -w . + golangci-lint fmt .PHONY: lint lint: @@ -18,6 +18,11 @@ lint: test: clean_test go test -v ./... +.PHONY: test-coverage-html +test-coverage-html: clean_test + go test --covermode=atomic --coverprofile=coverage.out -v ./... + go tool cover -html=coverage.out + .PHONY: db_code_generate db_code_generate: sqlc generate @@ -41,4 +46,4 @@ clean_test: .PHONY: clean clean: clean_test - $(RM) $(BINARY) \ No newline at end of file + $(RM) $(BINARY) diff --git a/cmd/glvd2/main.go b/cmd/glvd2/main.go index 1a62e0b..78de1a4 100644 --- a/cmd/glvd2/main.go +++ b/cmd/glvd2/main.go @@ -12,6 +12,8 @@ import ( "github.com/gardenlinux/glvd2/internal/gardenlinux/packages" "github.com/gardenlinux/glvd2/internal/git" "github.com/gardenlinux/glvd2/internal/ingestion" + "github.com/gardenlinux/glvd2/internal/ingestion/debsectracker" + "github.com/gardenlinux/glvd2/internal/repository" "github.com/spf13/cobra" _ "modernc.org/sqlite" ) @@ -33,10 +35,8 @@ func setLogLevel(logLevelStr string) error { return nil } -func ingestCve(cfg *config.AppConfig) error { - var err error - - db, err := database.Open() +func ingestCVEs(cfg *config.AppConfig) error { + db, err := database.Regenerate(cfg.InternalSqliteDBPath) if err != nil { slog.Error("could not open database", slog.Any("error", err)) return err @@ -53,9 +53,11 @@ func ingestCve(cfg *config.AppConfig) error { return err } - // TODO: clean DB and apply migrations + queries := repository.New(db) + ctx := context.Background() + // CVEListV5 and the Debian Security Tracker are currently added as git submodules submoduleService, err := git.NewSubmoduleService(cfg) if err != nil { slog.Error("Could not initialize the submodule service", slog.Any("error", err)) @@ -67,6 +69,13 @@ func ingestCve(cfg *config.AppConfig) error { return err } + debSecTrackerIngestion := debsectracker.NewService(db, queries, cfg) + err = debSecTrackerIngestion.IngestTriage(ctx) + if err != nil { + slog.Error("Ingestion from Debian Security Tracker: %w", slog.Any("error", err)) + return err + } + cveV5Ingestion := ingestion.NewCVEV5IngestionService(cfg) resCh, errCh := cveV5Ingestion.ReceiveCVEs() tmp := "" @@ -116,7 +125,7 @@ func cmd(cfg *config.AppConfig) *cobra.Command { return err } - return ingestCve(cfg) + return ingestCVEs(cfg) }, } rootCmd.PersistentFlags().String("log-level", "error", "specify log-level") diff --git a/config/default.yaml b/config/default.yaml index b6af871..815e64f 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -1 +1,3 @@ +internal_sqlite_db_path: "./data/internal.sqlite" cve_list_v5_sub_repo_path: "./submodules/cvelistV5" +deb_sec_tracker_sub_repo_path: "./submodules/debian-security-tracker" diff --git a/go.mod b/go.mod index 8c692e5..1565625 100644 --- a/go.mod +++ b/go.mod @@ -11,16 +11,17 @@ require ( ) require ( - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/golang-migrate/migrate/v4 v4.19.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/ncruces/go-strftime v1.0.0 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/sagikazarmark/locafero v0.11.0 // indirect diff --git a/go.sum b/go.sum index 8f20b15..69e419e 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -9,6 +11,8 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/golang-migrate/migrate/v4 v4.19.1 h1:OCyb44lFuQfYXYLx1SCxPZQGU7mcaZ7gH9yH4jSFbBA= +github.com/golang-migrate/migrate/v4 v4.19.1/go.mod h1:CTcgfjxhaUtsLipnLoQRWCrjYXycRz/g5+RWDuYgPrE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= @@ -34,6 +38,8 @@ github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0 github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 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/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= diff --git a/internal/config/config.go b/internal/config/config.go index 5b6b12a..ceec828 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -8,7 +8,9 @@ import ( // AppConfig contains different configuration options for the application. type AppConfig struct { - CVEListV5SubRepoPath string `mapstructure:"cve_list_v5_sub_repo_path"` + CVEListV5SubRepoPath string `mapstructure:"cve_list_v5_sub_repo_path"` + DebSecTrackerSubRepoPath string `mapstructure:"deb_sec_tracker_sub_repo_path"` + InternalSqliteDBPath string `mapstructure:"internal_sqlite_db_path"` } // LoadAppConfig loads the configuration from disk. diff --git a/internal/db/database.go b/internal/db/database.go index a4e8bf0..bc6a2b8 100644 --- a/internal/db/database.go +++ b/internal/db/database.go @@ -2,12 +2,47 @@ package db import ( "database/sql" + "os" + + "github.com/golang-migrate/migrate/v4" + _ "github.com/golang-migrate/migrate/v4/database/sqlite" // blank import like lib proposes + _ "github.com/golang-migrate/migrate/v4/source/file" ) +const sqliteConnectionStringSuffix = "?journal_mode=WAL&busy_timeout=3000&secure_delete=true" + + "&foreign_keys=true&cache=shared&x-no-tx-wrap=true" + +// Regenerate clears the DB file, recreates the structure via migration, and returns a DB connection. +func Regenerate(fp string) (*sql.DB, error) { + // ensure that the file exists + f, err := os.OpenFile(fp, os.O_CREATE, 0o644) //nolint:gosec,mnd // no user input and fil + if err != nil { + return nil, err + } + if err = f.Close(); err != nil { + return nil, err + } + + // clear the file content + if err = os.Truncate(fp, 0); err != nil { + return nil, err + } + + if err = Migrate(fp); err != nil { + return nil, err + } + + db, err := Open(fp) + if err != nil { + return nil, err + } + + return db, nil +} + // Open a sqlite db from file. -func Open() (*sql.DB, error) { - db, err := sql.Open("sqlite", - "data/internal.sqlite?journal_mode=WAL&busy_timeout=3000&secure_delete=true&foreign_keys=true&cache=shared") +func Open(fp string) (*sql.DB, error) { + db, err := sql.Open("sqlite", fp+sqliteConnectionStringSuffix) if err != nil { return nil, err } @@ -17,3 +52,19 @@ func Open() (*sql.DB, error) { return db, nil } + +func Migrate(fp string) error { + m, err := migrate.New( + "file://internal/db/migrations/", + "sqlite://"+fp+sqliteConnectionStringSuffix) + if err != nil { + return err + } + + err = m.Up() + if err != nil { + return err + } + + return nil +} diff --git a/internal/db/migrations/000001_init.down.sql b/internal/db/migrations/000001_init.down.sql index 8e3f3d9..6948c88 100644 --- a/internal/db/migrations/000001_init.down.sql +++ b/internal/db/migrations/000001_init.down.sql @@ -5,4 +5,10 @@ DROP TABLE IF EXISTS product; DROP TABLE IF EXISTS affect; DROP TABLE IF EXISTS cvss_metric; +DROP TABLE IF EXISTS debian_triage; +DROP TABLE IF EXISTS debian_package; +DROP TABLE IF EXISTS debian_triage_affected_package; +DROP TABLE IF EXISTS debian_release; +DROP TABLE IF EXISTS debian_triage_affected_release; + END; diff --git a/internal/db/migrations/000001_init.up.sql b/internal/db/migrations/000001_init.up.sql index 1cad32a..648884a 100644 --- a/internal/db/migrations/000001_init.up.sql +++ b/internal/db/migrations/000001_init.up.sql @@ -4,8 +4,8 @@ CREATE TABLE IF NOT EXISTS cve( id TEXT PRIMARY KEY, title TEXT, description TEXT, - serial INT NOT NULL DEFAULT 1, - is_rejected INT NOT NULL DEFAULT 0, + serial INTEGER NOT NULL DEFAULT 1, + is_rejected INTEGER NOT NULL DEFAULT 0, assigner_org_id TEXT, assigner_short_name TEXT, date_reserved TEXT, @@ -16,20 +16,21 @@ CREATE TABLE IF NOT EXISTS cve( ); CREATE TABLE IF NOT EXISTS product( - id INT PRIMARY KEY, + id INTEGER PRIMARY KEY, title TEXT, cpe TEXT ); CREATE TABLE IF NOT EXISTS affect( - id INT PRIMARY KEY, + id INTEGER PRIMARY KEY, cve_id TEXT, + product_id INTEGER, FOREIGN KEY(cve_id) REFERENCES cve(id), FOREIGN KEY(product_id) REFERENCES product(id) ); CREATE TABLE IF NOT EXISTS cvss_metric( - id INT PRIMARY KEY, + id INTEGER PRIMARY KEY, cve_id TEXT, issuer TEXT, version TEXT, @@ -39,4 +40,41 @@ CREATE TABLE IF NOT EXISTS cvss_metric( FOREIGN KEY(cve_id) REFERENCES cve(id) ); +CREATE TABLE IF NOT EXISTS debian_triage( + cve_id TEXT PRIMARY KEY, + status TEXT CHECK( status IN ('UNKNOWN', 'TODO', 'REJECTED', 'NOT-FOR-US', 'PROCESSED', 'RESERVED') ) NOT NULL, + not_for_us TEXT NOT NULL, + notes TEXT NOT NULL, + to_dos TEXT NOT NULL +); + +CREATE TABLE IF NOT EXISTS debian_package( + name TEXT PRIMARY KEY +); + +CREATE TABLE IF NOT EXISTS debian_triage_affected_package( + id INTEGER PRIMARY KEY, + cve_id TEXT NOT NULL, + package_name TEXT NOT NULL, + version TEXT NOT NULL, + info TEXT, + FOREIGN KEY(cve_id) REFERENCES debian_triage(cve_id), + FOREIGN KEY(package_name) REFERENCES debian_package(name) +); + +CREATE TABLE IF NOT EXISTS debian_release( + name TEXT PRIMARY KEY +); + +CREATE TABLE IF NOT EXISTS debian_triage_affected_release( + id INTEGER PRIMARY KEY, + cve_id TEXT NOT NULL, + release_name TEXT NOT NULL, + package_name TEXT NOT NULL, + action TEXT NOT NULL, + info TEXT, + FOREIGN KEY(cve_id) REFERENCES debian_triage(cve_id), + FOREIGN KEY(release_name) REFERENCES debian_release(name) +); + END; diff --git a/internal/db/queries/cve.sql b/internal/db/queries/cve.sql index 73b2c89..43075c1 100644 --- a/internal/db/queries/cve.sql +++ b/internal/db/queries/cve.sql @@ -1,2 +1,2 @@ --- name: ListCves :many -SELECT sqlc.embed(c) FROM cve As c ORDER BY c.name DESC; +-- name: ListCVEs :many +SELECT * FROM cve ORDER BY name DESC; diff --git a/internal/db/queries/debiantriage.sql b/internal/db/queries/debiantriage.sql new file mode 100644 index 0000000..5c1861b --- /dev/null +++ b/internal/db/queries/debiantriage.sql @@ -0,0 +1,26 @@ +-- name: GetDebianTriage :one +SELECT * FROM debian_triage WHERE cve_id = ? LIMIT 1; + +-- name: ListDebianTriages :many +SELECT * FROM debian_triage ORDER BY cve_id DESC; + +-- name: ListAffectedPackagesForDebianTriage :many +SELECT * FROM debian_triage_affected_package WHERE cve_id = ? ORDER BY id ASC; + +-- name: ListAffectedReleasesForDebianTriage :many +SELECT * FROM debian_triage_affected_release WHERE cve_id = ? ORDER BY id ASC; + +-- name: InsertDebianPackageOrIgnore :one +INSERT OR IGNORE INTO debian_package(name) VALUES (?) RETURNING *; + +-- name: InsertDebianReleaseOrIgnore :one +INSERT OR IGNORE INTO debian_release(name) VALUES (?) RETURNING *; + +-- name: InsertDebianTriage :one +INSERT INTO debian_triage(cve_id, status, not_for_us, notes, to_dos) VALUES (?, ?, ?, ?, ?) RETURNING *; + +-- name: InsertDebianTriageAffectedPackage :one +INSERT INTO debian_triage_affected_package(cve_id, package_name, version, info) VALUES (?, ?, ?, ?) RETURNING *; + +-- name: InsertDebianTriageAffectedRelease :one +INSERT INTO debian_triage_affected_release(cve_id, release_name, package_name, action, info) VALUES (?, ?, ?, ?, ?) RETURNING *; diff --git a/internal/gardenlinux/glrd/glrd.go b/internal/gardenlinux/glrd/glrd.go index 4562573..ef1e8a0 100644 --- a/internal/gardenlinux/glrd/glrd.go +++ b/internal/gardenlinux/glrd/glrd.go @@ -13,7 +13,7 @@ const glrdReleasesMinorURL = "https://gardenlinux-glrd.s3.eu-central-1.amazonaws type Git struct { Commit string `json:"commit"` - CommitShort string `json:"commit_short"` //nolint:tagliatelle // json field is defined with underscore + CommitShort string `json:"commit_short"` } type GitHub struct { @@ -37,7 +37,7 @@ type LifeCycle struct { } type Attributes struct { - SourceRepo bool `json:"source_repo"` //nolint:tagliatelle // json field is defined with underscore + SourceRepo bool `json:"source_repo"` } type Release struct { diff --git a/internal/gardenlinux/packages/packages.go b/internal/gardenlinux/packages/packages.go index 82e1c57..3078b20 100644 --- a/internal/gardenlinux/packages/packages.go +++ b/internal/gardenlinux/packages/packages.go @@ -299,7 +299,12 @@ func Cmd() (*cobra.Command, error) { } for _, pkg := range packages { - fmt.Printf("%s (%s) %s\n", pkg.Name, pkg.Architecture, pkg.Version) //nolint:revive,nolintlint,forbidigo,golines,lll // printing output for debugging + fmt.Printf( //nolint:revive,forbidigo // printing output for debugging + "%s (%s) %s\n", + pkg.Name, + pkg.Architecture, + pkg.Version, + ) } return nil }, diff --git a/internal/git/git_repo_service.go b/internal/git/git_repo_service.go index 545fb14..1dbc734 100644 --- a/internal/git/git_repo_service.go +++ b/internal/git/git_repo_service.go @@ -72,6 +72,8 @@ func fixDateIssues() error { } func (r *SubmoduleService) GetLatest(ctx context.Context) error { + slog.Info("Updating the git submodules") + err := setup(ctx) if err != nil { return err @@ -90,5 +92,7 @@ func (r *SubmoduleService) GetLatest(ctx context.Context) error { return err } + slog.Info("Finished updating the git submodules") + return nil } diff --git a/internal/ingestion/cve_list_v5_ingestion.go b/internal/ingestion/cve_list_v5_ingestion.go index 6ad6187..1566b39 100644 --- a/internal/ingestion/cve_list_v5_ingestion.go +++ b/internal/ingestion/cve_list_v5_ingestion.go @@ -30,7 +30,7 @@ func (s CVEV5IngestionService) parseJSONFile(fp string) (*cve_v5.CVEV5, error) { fp = filepath.Clean(fp) if !strings.HasPrefix(fp, filepath.Clean(s.cfg.CVEListV5SubRepoPath)) { slog.Error("Prefix does not match", - slog.String("filepath", fp), slog.String("prefix", s.cfg.CVEListV5SubRepoPath)) + slog.String("filepath", fp), slog.String("expectedPrefix", s.cfg.CVEListV5SubRepoPath)) return nil, errors.New("unsafe file path used") } jsonFile, err := os.Open(fp) diff --git a/internal/ingestion/debsectracker/debsectracker.go b/internal/ingestion/debsectracker/debsectracker.go new file mode 100644 index 0000000..2ade3d2 --- /dev/null +++ b/internal/ingestion/debsectracker/debsectracker.go @@ -0,0 +1,361 @@ +package debsectracker + +import ( + "bufio" + "context" + "database/sql" + "errors" + "fmt" + "io" + "log/slog" + "os" + "path/filepath" + "regexp" + "strings" + + "github.com/gardenlinux/glvd2/internal/config" + "github.com/gardenlinux/glvd2/internal/model/debtriage" + "github.com/gardenlinux/glvd2/internal/repository" +) + +var ( + ErrMissingHeaderLine = errors.New("missing triage entry header") + ErrUnknownHeaderLineFormat = errors.New("unknown format for a triage entry header line") + ErrUnknownFormat = errors.New("unknown format for a triage entry") +) + +type Service struct { + db *sql.DB + queries *repository.Queries + cfg *config.AppConfig +} + +func NewService(db *sql.DB, queries *repository.Queries, cfg *config.AppConfig) *Service { + return &Service{ + db: db, + queries: queries, + cfg: cfg, + } +} + +type TriageEntry struct { + Triage repository.DebianTriage `json:"debian_triage"` + AffectedPackages []repository.DebianTriageAffectedPackage `json:"affected_package"` + AffectedReleases []repository.DebianTriageAffectedRelease `json:"affected_release"` +} + +// processTriage is called by processLine once a complete triage entry is read and +// after all lines have been read to not miss the last entry. +func (s Service) processTriage(ctx context.Context, qtx *repository.Queries, entry *TriageEntry) error { + if strings.HasSuffix(entry.Triage.CVEID, "-XXXX") { + // Skipping entry, since there is no official CVE ID for it. + return nil + } + + if entry.Triage.Status == debtriage.StatusReserved || + entry.Triage.Status == debtriage.StatusRejected { + // Skipping entry, since it is not disclosed yet or was rejected. + return nil + } + + _, err := qtx.InsertDebianTriage(ctx, repository.InsertDebianTriageParams(entry.Triage)) + if err != nil { + return err + } + + for _, pkg := range entry.AffectedPackages { + _, pErr := qtx.InsertDebianPackageOrIgnore(ctx, pkg.PackageName) + if pErr != nil && !errors.Is(pErr, sql.ErrNoRows) { + return pErr + } + + _, pErr = qtx.InsertDebianTriageAffectedPackage(ctx, + repository.InsertDebianTriageAffectedPackageParams{ + // id is automatically set + CVEID: pkg.CVEID, + PackageName: pkg.PackageName, + Version: pkg.Version, + Info: pkg.Info, + }) + if pErr != nil { + return pErr + } + } + + for _, rl := range entry.AffectedReleases { + _, rErr := qtx.InsertDebianReleaseOrIgnore(ctx, rl.ReleaseName) + if rErr != nil && !errors.Is(rErr, sql.ErrNoRows) { + return rErr + } + + _, rErr = qtx.InsertDebianTriageAffectedRelease(ctx, + repository.InsertDebianTriageAffectedReleaseParams{ + CVEID: rl.CVEID, + ReleaseName: rl.ReleaseName, + PackageName: rl.PackageName, + Action: rl.Action, + Info: rl.Info, + }) + if rErr != nil { + return rErr + } + } + + return nil +} + +// CVE-YEAR-XXXX can be used, if there is not an official CVE ID yet. +var headerLineRegex = regexp.MustCompile(`^CVE-(?P\d+)-(?P\d+|XXXX).*\n$`) + +var toDoCheckRegex = regexp.MustCompile(`^\tTODO: check\n$`) + +var toDoNoteRegex = regexp.MustCompile(`^\tTODO: (?P.*)\n$`) + +var notForUsRegex = regexp.MustCompile(`^\tNOT-FOR-US: (?P.*)\n$`) + +var noteRegex = regexp.MustCompile(`^\tNOTE: (?P.*)\n$`) + +var rejectedRegex = regexp.MustCompile(`^\tREJECTED\n$`) + +var reservedRegex = regexp.MustCompile(`^\tRESERVED\n$`) + +var packageRegex = regexp.MustCompile(`^\t- (?P[^ ]+) (?P[^ ]+)( \((?P.+)\))?\n$`) + +var releaseRegex = regexp.MustCompile( + `^\t\[(?P.*)\] - (?P[^ ]+) ` + + `(?P[^ ]+)( \((?P.+)\))?\n$`) + +var advisoryRegex = regexp.MustCompile(`^\t{.*}\n$`) + +// processLine is called consecutively for all lines of the data/CVE file and calls itself processTriage once +// a triage entry has been read completely (a valid entry spans multiple lines). +func (s Service) processLine(ctx context.Context, qtx *repository.Queries, + entry *TriageEntry, line string, +) (*TriageEntry, error) { + // triage entries start with a header line like "CVE-2021-1222" + headerMatches := headerLineRegex.FindStringSubmatch(line) + if len(headerMatches) > 0 { + if entry != nil { + // process the previous triage entry, since a new one is started + err := s.processTriage(ctx, qtx, entry) + if err != nil { + return nil, err + } + } + + cveID := fmt.Sprintf("CVE-%s-%s", headerMatches[1], headerMatches[2]) + entry = &TriageEntry{ + Triage: repository.DebianTriage{ + CVEID: cveID, + Status: debtriage.StatusUnknown, + NotForUs: "", + Notes: "", + ToDos: "", + }, + AffectedPackages: []repository.DebianTriageAffectedPackage{}, + AffectedReleases: []repository.DebianTriageAffectedRelease{}, + } + + return entry, nil + } + if entry == nil { + return nil, ErrMissingHeaderLine + } + + if !strings.HasPrefix(line, "\t") { + slog.Error("Unknown format for a triage entry header line", + slog.String("ingestion", "Debian Security Tracker"), + slog.String("input", line)) + + return nil, ErrUnknownHeaderLineFormat + } + + // must now be content for a previously opened triage entry + + notForUsMatch := notForUsRegex.FindStringSubmatch(line) + if len(notForUsMatch) > 0 { + entry.Triage.Status = debtriage.StatusNotForUs + entry.Triage.NotForUs = notForUsMatch[1] + + return entry, nil + } + + packageMatch := packageRegex.FindStringSubmatch(line) + if len(packageMatch) > 0 { + entry.Triage.Status = debtriage.StatusProcessed + ap := repository.DebianTriageAffectedPackage{ + ID: -1, // ignored while insertion + CVEID: entry.Triage.CVEID, + PackageName: packageMatch[1], + Version: packageMatch[2], + Info: &packageMatch[4], + } + entry.AffectedPackages = append(entry.AffectedPackages, ap) + + return entry, nil + } + + releaseMatch := releaseRegex.FindStringSubmatch(line) + if len(releaseMatch) > 0 { + entry.Triage.Status = debtriage.StatusProcessed + ri := repository.DebianTriageAffectedRelease{ + ID: -1, // ignored while insertion + CVEID: entry.Triage.CVEID, + ReleaseName: releaseMatch[1], + PackageName: releaseMatch[2], + Action: releaseMatch[3], + Info: &releaseMatch[5], + } + entry.AffectedReleases = append(entry.AffectedReleases, ri) + + return entry, nil + } + + advisoryMatch := advisoryRegex.FindStringSubmatch(line) + if len(advisoryMatch) > 0 { + return entry, nil // not used for now + } + + toDoCheckMatch := toDoCheckRegex.FindStringSubmatch(line) + if len(toDoCheckMatch) > 0 { + entry.Triage.Status = debtriage.StatusToDo + + return entry, nil + } + + toDoNoteMatch := toDoNoteRegex.FindStringSubmatch(line) + if len(toDoNoteMatch) > 0 { + entry.Triage.ToDos += toDoNoteMatch[1] + "\n" + + return entry, nil + } + + noteMatch := noteRegex.FindStringSubmatch(line) + if len(noteMatch) > 0 { + entry.Triage.Notes += noteMatch[1] + "\n" + + return entry, nil + } + + rejectedMatch := rejectedRegex.FindStringSubmatch(line) + if len(rejectedMatch) > 0 { + entry.Triage.Status = debtriage.StatusRejected + + return entry, nil + } + + reservedMatch := reservedRegex.FindStringSubmatch(line) + if len(reservedMatch) > 0 { + entry.Triage.Status = debtriage.StatusReserved + + return entry, nil + } + + slog.Error("Unknown format for a triage entry", + slog.String("ingestion", "Debian Security Tracker"), + slog.String("input", line)) + + return nil, ErrUnknownFormat +} + +func (s Service) parseTriageList(ctx context.Context, fp string) error { + fp = filepath.Clean(fp) + if !strings.HasPrefix(fp, filepath.Clean(s.cfg.DebSecTrackerSubRepoPath)) { + slog.Error("Prefix does not match", + slog.String("filepath", fp), slog.String("expectedPrefix", s.cfg.DebSecTrackerSubRepoPath)) + return errors.New("unsafe file path used") + } + f, err := os.Open(fp) + if err != nil { + return err + } + defer func() { + if closeErr := f.Close(); closeErr != nil { + slog.Error("Error while closing file", + slog.Any("error", err)) + } + }() + + // commit all changes in one transaction to speed up the insertion + tx, err := s.db.BeginTx(ctx, &sql.TxOptions{ + Isolation: sql.LevelSerializable, + ReadOnly: false, + }) + if err != nil { + return err + } + defer func() { + if txErr := tx.Rollback(); txErr != nil && !errors.Is(txErr, sql.ErrTxDone) { + slog.Error("Error while rolling back transaction", + slog.Any("error", txErr)) + } + }() + qtx := s.queries.WithTx(tx) + + entry := (*TriageEntry)(nil) + scanner := bufio.NewReader(f) + for { + line, lErr := scanner.ReadString('\n') + if lErr == io.EOF { + if len(line) > 0 { + var lpErr error + entry, lpErr = s.processLine(ctx, qtx, entry, line) + if lpErr != nil { + return fmt.Errorf("error reading line from 'data/CVE/list': %w", lpErr) + } + } + tErr := s.processTriage(ctx, qtx, entry) // ensures that also the last entry is processed + if tErr != nil { + return tErr + } + + break + } + if lErr != nil { + return fmt.Errorf("error reading line from 'data/CVE/list': %w", lErr) + } + var lpErr error + entry, lpErr = s.processLine(ctx, qtx, entry, line) + if lpErr != nil { + return fmt.Errorf("error reading line from 'data/CVE/list': %w", lpErr) + } + } + + return tx.Commit() +} + +func (s Service) IngestTriage(ctx context.Context) error { + slog.Info("Ingesting from Debian Security Tracker") + + err := s.parseTriageList(ctx, s.cfg.DebSecTrackerSubRepoPath+"/data/CVE/list") + if err != nil { + return err + } + + slog.Info("Finished ingestion from Debian Security Tracker") + + return nil +} + +func (s Service) getTriageEntryFromDB(ctx context.Context, cveID string) (*TriageEntry, error) { + debTriage, err := s.queries.GetDebianTriage(ctx, cveID) + if err != nil { + return nil, err + } + + affectedPackages, pErr := s.queries.ListAffectedPackagesForDebianTriage(ctx, debTriage.CVEID) + if pErr != nil { + return nil, pErr + } + + affectedReleases, rErr := s.queries.ListAffectedReleasesForDebianTriage(ctx, debTriage.CVEID) + if rErr != nil { + return nil, rErr + } + + return &TriageEntry{ + Triage: debTriage, + AffectedPackages: affectedPackages, + AffectedReleases: affectedReleases, + }, nil +} diff --git a/internal/ingestion/debsectracker/debsectracker_test.go b/internal/ingestion/debsectracker/debsectracker_test.go new file mode 100644 index 0000000..b3b9673 --- /dev/null +++ b/internal/ingestion/debsectracker/debsectracker_test.go @@ -0,0 +1,210 @@ +package debsectracker_test + +import ( + "bytes" + "context" + "database/sql" + "encoding/json" + "errors" + "os" + "testing" + + "github.com/gardenlinux/glvd2/internal/config" + "github.com/gardenlinux/glvd2/internal/ingestion/debsectracker" + "github.com/gardenlinux/glvd2/internal/repository" + "github.com/golang-migrate/migrate/v4" + "github.com/golang-migrate/migrate/v4/database/sqlite" + _ "github.com/golang-migrate/migrate/v4/source/file" +) + +const sqliteConnectionStringSuffix = "?journal_mode=WAL&busy_timeout=3000&secure_delete=true" + + "&foreign_keys=true&cache=shared&x-no-tx-wrap=true" + +// getAllTriageEntriesWithRelationsFromDB: Fetches all entries in a simple way, +// so with the current implementation only recommended for tests with a limited amount of data. +func getAllTriageEntriesWithRelationsFromDB( + ctx context.Context, + queries *repository.Queries, +) ([]debsectracker.TriageEntry, error) { + entries := []debsectracker.TriageEntry{} + + debTriages, err := queries.ListDebianTriages(ctx) + if err != nil { + return nil, err + } + + for _, dt := range debTriages { + affectedPackages, pErr := queries.ListAffectedPackagesForDebianTriage(ctx, dt.CVEID) + if pErr != nil { + return nil, pErr + } + + affectedReleases, rErr := queries.ListAffectedReleasesForDebianTriage(ctx, dt.CVEID) + if rErr != nil { + return nil, rErr + } + + entries = append(entries, debsectracker.TriageEntry{ + Triage: dt, + AffectedPackages: affectedPackages, + AffectedReleases: affectedReleases, + }) + } + + return entries, nil +} + +func minifyJSON(i []byte) ([]byte, error) { + var d []any + + err := json.Unmarshal(i, &d) + if err != nil { + return nil, err + } + + o, err := json.Marshal(d) + if err != nil { + return nil, err + } + + return o, nil +} + +type IngestTriageTestCase struct { + name string // description of this test case + // Named input parameters for receiver constructor. + cfg *config.AppConfig + expectedEntriesJSONPath string + expectedError error // nil if no error is expected +} + +func genIngestTriageTestCase(name, folderName string, expectedError error) IngestTriageTestCase { + return IngestTriageTestCase{ + name: name, + cfg: &config.AppConfig{ + CVEListV5SubRepoPath: "", + DebSecTrackerSubRepoPath: "./testdata/" + folderName + "/debsectracker", + InternalSqliteDBPath: "", + }, + expectedEntriesJSONPath: "./testdata/" + folderName + "/expected_entries.json", + expectedError: expectedError, + } +} + +func TestService_IngestTriage(t *testing.T) { + t.Parallel() + tests := []IngestTriageTestCase{ + genIngestTriageTestCase("valid triage entry", "validentrytest", nil), + genIngestTriageTestCase("valid triage entry with advisory (DSA + DLA)", "validentrywithadvisorytest", nil), + genIngestTriageTestCase("valid entry with multiple packages", "multiplepackagesentrytest", nil), + genIngestTriageTestCase("valid TODO triage entry", "todotest", nil), + genIngestTriageTestCase("valid triage entry with note in TODO", "todonotetest", nil), + genIngestTriageTestCase("valid REJECTED triage entry", "rejectedtest", nil), + genIngestTriageTestCase("valid RESERVED triage entry", "reservedtest", nil), + genIngestTriageTestCase("valid NOT-FOR-US triage entry", "notforustest", nil), + genIngestTriageTestCase("not disclosed (-XXXX) entry skipped", "notdisclosedskiptest", nil), + genIngestTriageTestCase("multiple valid entries", "multipleentriestest", nil), // XXX check result + genIngestTriageTestCase( + "missing header line at start", + "missingheaderlineatstarttest", + debsectracker.ErrMissingHeaderLine, + ), + genIngestTriageTestCase( + "wrong header line format", + "wrongheaderlinetest", + debsectracker.ErrUnknownHeaderLineFormat, + ), + genIngestTriageTestCase("unknown format", "unknownformattest", debsectracker.ErrUnknownFormat), + genIngestTriageTestCase("empty input", "emptyinputtest", debsectracker.ErrMissingHeaderLine), + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + th := "IngestTriage() - " + tt.name + // in-memory test DB setup + db, err := sql.Open("sqlite", ":memory:"+sqliteConnectionStringSuffix) + if err != nil { + t.Errorf("%s: setup failed - in-memory DB creation: %v", th, err) + return + } + defer func() { + if err = db.Close(); err != nil { + t.Errorf("%s: clean up failed: %v", th, err) + } + }() + driver, err := sqlite.WithInstance( + db, + &sqlite.Config{MigrationsTable: "", DatabaseName: "", NoTxWrap: true}, + ) + if err != nil { + t.Errorf("%s: setup failed - DB driver setup for migration: %v", th, err) + return + } + m, err := migrate.NewWithDatabaseInstance( + "file://../../db/migrations/", + "sqlite", driver) + if err != nil { + t.Errorf("%s: setup failed - DB migration setup: %v", th, err) + return + } + if err = m.Up(); err != nil { + t.Errorf("%s: setup failed - DB migration: %v", th, err) + return + } + queries := repository.New(db) + + s := debsectracker.NewService(db, queries, tt.cfg) + gotErr := s.IngestTriage(context.Background()) // TODO: right context during a test? + if gotErr != nil { + if tt.expectedError != nil { + if !errors.Is(gotErr, tt.expectedError) { // XXX use specific errors + t.Errorf("%s failed with: \"%v\"; expected: \"%v\"", th, gotErr, tt.expectedError) + } + } else { + t.Errorf("%s failed with: '%v'", th, gotErr) + } + return + } + if tt.expectedError != nil { + t.Fatalf("%s succeeded unexpectedly", th) + } + + entries, err := getAllTriageEntriesWithRelationsFromDB(context.Background(), queries) + if err != nil { + t.Fatalf("%s failed: could not get the data from the DB: %v", th, err) + } + + actualJSON, err := json.Marshal(entries) + if err != nil { + t.Fatalf( + "%s failed: unexcepted problem while marshalling json the processed entries: %v", + th, + err, + ) + } + actualJSON, err = minifyJSON(actualJSON) + if err != nil { + t.Fatalf("%s failed: could not minify JSON of processed entries: %v", th, err) + } + + jb, err := os.ReadFile(tt.expectedEntriesJSONPath) + if err != nil { + t.Fatalf("%s failed: could not read JSON file with expected entries: %v", th, err) + } + + expectedJSON, err := minifyJSON(jb) + if err != nil { + t.Fatalf("%s failed: could not minify read JSON file: %v", th, err) + } + + if !bytes.Equal(actualJSON, expectedJSON) { + t.Errorf( + "%s failed: actual entries does not match the expected ones: '%s' != '%s'", + th, + actualJSON, + expectedJSON, + ) + } + }) + } +} diff --git a/internal/ingestion/debsectracker/testdata/emptyinputtest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/emptyinputtest/debsectracker/data/CVE/list new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/emptyinputtest/debsectracker/data/CVE/list @@ -0,0 +1 @@ + diff --git a/internal/ingestion/debsectracker/testdata/emptyinputtest/expected_entries.json b/internal/ingestion/debsectracker/testdata/emptyinputtest/expected_entries.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/emptyinputtest/expected_entries.json @@ -0,0 +1 @@ +[] diff --git a/internal/ingestion/debsectracker/testdata/missingheaderlineatstarttest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/missingheaderlineatstarttest/debsectracker/data/CVE/list new file mode 100644 index 0000000..68f21c9 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/missingheaderlineatstarttest/debsectracker/data/CVE/list @@ -0,0 +1,19 @@ + - grub2 2.14~git20250718.0e36779-2 (bug #1105108) + [trixie] - grub2 (Minor issue) + [bookworm] - grub2 (Minor issue) + NOTE: Fixed by: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=c448f511e74cb7c776b314fcb7943f98d3f22b6d (grub-2.14-rc1) + NOTE: Additional hardening via: + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=ed691c0e0e20d9d0e8d8305a120e8c61d6be3d38 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=7a584fbde0c339816a57d55fc165a854039cf0b2 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=10d778c4b4d56cc36836d86a9698bc5272b12101 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=23ec4535f40dc53f68d2709f8fb44af571431ca7 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=301b4ef25a8fafaeba48498e97efd28bd2809f97 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=dbc0eb5bd1f40de9b394e3a86e84f46c39a23e40 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=73d1c959ea3417e9309ba8c6102d7d6dc7c94259 + NOTE: Option to block command line interface at build time introduced with: + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=bb65d81fe320e4b20d0a9b32232a7546eb275ecc + TODO: double check if vulnerability only considered present after grub_is_cli_disabled is introduced +CVE-2023-2311 (Insufficient policy enforcement in File System API in Google Chrome pr ...) + {DSA-5386-1} + - chromium 112.0.5615.49-1 + [buster] - chromium (see DSA 5046) diff --git a/internal/ingestion/debsectracker/testdata/missingheaderlineatstarttest/expected_entries.json b/internal/ingestion/debsectracker/testdata/missingheaderlineatstarttest/expected_entries.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/missingheaderlineatstarttest/expected_entries.json @@ -0,0 +1 @@ +[] diff --git a/internal/ingestion/debsectracker/testdata/multipleentriestest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/multipleentriestest/debsectracker/data/CVE/list new file mode 100644 index 0000000..fb812e2 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/multipleentriestest/debsectracker/data/CVE/list @@ -0,0 +1,81 @@ +CVE-2026-40937 (RustFS is a distributed object storage system built in Rust. Prior to ...) + NOT-FOR-US: RustFS +CVE-2026-40517 (radare2 prior to 6.1.4 contains a command injection vulnerability in t ...) + - radare2 + NOTE: https://github.com/radareorg/radare2/issues/25730 + NOTE: https://github.com/radareorg/radare2/pull/25731 + NOTE: Fixed by: https://github.com/radareorg/radare2/commit/0e38152560e689327a74d2944fa45ba7afd4cb33 (6.1.4) +CVE-2026-6862 (A flaw was found in libefiboot, a component of efivar. The device path ...) + - efivar (bug #1134691) + NOTE: https://bugzilla.redhat.com/show_bug.cgi?id=2459982 +CVE-2026-6515 (GitLab has remediated an issue in GitLab CE/EE affecting all versions ...) + - gitlab (Only affects 18.x) +CVE-2026-35371 (The id utility in uutils coreutils exhibits incorrect behavior in its ...) + - rust-coreutils + [trixie] - rust-coreutils (Minor issue) + [bookworm] - rust-coreutils (Minor issue) + NOTE: https://github.com/uutils/coreutils/issues/10006 +CVE-2010-20110 + REJECTED +CVE-2026-40448 (Potential Integer overflow in tensor allocation size calculation could ...) + NOT-FOR-US: Samsung +CVE-2025-XXXX [OSSN-0094] + - nova 2:31.0.0-7 (bug #1111689) + [trixie] - nova 2:31.0.0-6+deb13u1 + [bookworm] - nova (Will be fixed via point release) + [bullseye] - nova (minor issue need admin right) + - watcher 14.0.0-3 (bug #1111692) + [trixie] - watcher 14.0.0-1+deb13u1 + [bookworm] - watcher (Will be fixed via point release) + NOTE: https://wiki.openstack.org/wiki/OSSN/OSSN-0094 + NOTE: https://bugs.launchpad.net/nova/+bug/2112187 + NOTE: The swap volume, live migration and all Watcher APIs are admin only so with + NOTE: default policy is only possible to create the inconsistent state described in + NOTE: the OSSN-0094 if one has admin rights on the relevant OpenStack project. +CVE-2025-38513 (In the Linux kernel, the following vulnerability has been resolved: w ...) + {DLA-4328-1 DLA-4327-1} + - linux 6.16.3-1 + [trixie] - linux 6.12.41-1 + [bookworm] - linux 6.1.147-1 + NOTE: https://git.kernel.org/linus/74b1ec9f5d627d2bdd5e5b6f3f81c23317657023 (6.16-rc6) +CVE-2025-24975 (Firebird is a relational database. Prior to snapshot versions 4.0.6.31 ...) + {DSA-5992-1} + - firebird3.0 (Vulnerable code introduced later) + - firebird4.0 4.0.6.3221.ds6-1 (bug #1111322) + NOTE: https://github.com/FirebirdSQL/firebird/security/advisories/GHSA-fx9r-rj68-7p69 + NOTE: https://github.com/FirebirdSQL/firebird/issues/8429 + NOTE: https://github.com/FirebirdSQL/firebird/commit/658abd20449f72097fbbce57e8e6ae42ff837fb6 +CVE-2023-31288 + RESERVED +CVE-2023-2311 (Insufficient policy enforcement in File System API in Google Chrome pr ...) + {DSA-5386-1} + - chromium 112.0.5615.49-1 + [buster] - chromium (see DSA 5046) +CVE-2023-31022 (NVIDIA GPU Display Driver for Windows and Linux contains a vulnerabili ...) + - nvidia-graphics-drivers 525.147.05-1 (bug #1055136) + [bookworm] - nvidia-graphics-drivers 525.147.05-1~deb12u1 + [bullseye] - nvidia-graphics-drivers 470.223.02-1 + [buster] - nvidia-graphics-drivers (Non-free not supported) + - nvidia-open-gpu-kernel-modules 525.147.05-1 (bug #1055144) + [bookworm] - nvidia-open-gpu-kernel-modules 525.147.05-1~deb12u1 + - nvidia-graphics-drivers-tesla 525.147.05-1 (bug #1055143) + [bookworm] - nvidia-graphics-drivers-tesla 525.147.05-3~deb12u1 + - nvidia-graphics-drivers-tesla-470 470.223.02-1 (bug #1055142) + [bookworm] - nvidia-graphics-drivers-tesla-470 470.223.02-1~deb12u1 + [bullseye] - nvidia-graphics-drivers-tesla-470 470.223.02-1~deb11u1 + - nvidia-graphics-drivers-tesla-460 460.106.00-3 (bug #1055141) + [bullseye] - nvidia-graphics-drivers-tesla-460 (Non-free not supported) + NOTE: 460.106.00-3 turned the package into a metapackage to aid switching to nvidia-graphics-drivers-tesla-470 + - nvidia-graphics-drivers-tesla-450 450.248.02-4 (bug #1055140) + NOTE: 450.248.02-4 turned the package into a metapackage to aid switching to nvidia-graphics-drivers-tesla-470 + [bullseye] - nvidia-graphics-drivers-tesla-450 (Non-free not supported) + - nvidia-graphics-drivers-tesla-418 (bug #1055139) + [bullseye] - nvidia-graphics-drivers-tesla-418 (Non-free not supported) + - nvidia-graphics-drivers-legacy-390xx (bug #1055138) + [bullseye] - nvidia-graphics-drivers-legacy-390xx (Non-free not supported) + [buster] - nvidia-graphics-drivers-legacy-390xx (Non-free not supported) + - nvidia-graphics-drivers-legacy-340xx (bug #1055137) + [buster] - nvidia-graphics-drivers-legacy-340xx (Non-free not supported) + NOTE: https://nvidia.custhelp.com/app/answers/detail/a_id/5491 +CVE-1999-0020 + REJECTED diff --git a/internal/ingestion/debsectracker/testdata/multipleentriestest/expected_entries.json b/internal/ingestion/debsectracker/testdata/multipleentriestest/expected_entries.json new file mode 100644 index 0000000..44b52e6 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/multipleentriestest/expected_entries.json @@ -0,0 +1,387 @@ +[ + { + "affected_package": [ + { + "cve_id": "CVE-2026-6862", + "id": 2, + "info": "bug #1134691", + "package_name": "efivar", + "version": "" + } + ], + "affected_release": null, + "debian_triage": { + "cve_id": "CVE-2026-6862", + "not_for_us": "", + "notes": "https://bugzilla.redhat.com/show_bug.cgi?id=2459982\n", + "status": "PROCESSED", + "to_dos": "" + } + }, + { + "affected_package": [ + { + "cve_id": "CVE-2026-6515", + "id": 3, + "info": "Only affects 18.x", + "package_name": "gitlab", + "version": "" + } + ], + "affected_release": null, + "debian_triage": { + "cve_id": "CVE-2026-6515", + "not_for_us": "", + "notes": "", + "status": "PROCESSED", + "to_dos": "" + } + }, + { + "affected_package": null, + "affected_release": null, + "debian_triage": { + "cve_id": "CVE-2026-40937", + "not_for_us": "RustFS", + "notes": "", + "status": "NOT-FOR-US", + "to_dos": "" + } + }, + { + "affected_package": [ + { + "cve_id": "CVE-2026-40517", + "id": 1, + "info": "", + "package_name": "radare2", + "version": "" + } + ], + "affected_release": null, + "debian_triage": { + "cve_id": "CVE-2026-40517", + "not_for_us": "", + "notes": "https://github.com/radareorg/radare2/issues/25730\nhttps://github.com/radareorg/radare2/pull/25731\nFixed by: https://github.com/radareorg/radare2/commit/0e38152560e689327a74d2944fa45ba7afd4cb33 (6.1.4)\n", + "status": "PROCESSED", + "to_dos": "" + } + }, + { + "affected_package": null, + "affected_release": null, + "debian_triage": { + "cve_id": "CVE-2026-40448", + "not_for_us": "Samsung", + "notes": "", + "status": "NOT-FOR-US", + "to_dos": "" + } + }, + { + "affected_package": [ + { + "cve_id": "CVE-2026-35371", + "id": 4, + "info": "", + "package_name": "rust-coreutils", + "version": "" + } + ], + "affected_release": [ + { + "action": "", + "cve_id": "CVE-2026-35371", + "id": 1, + "info": "Minor issue", + "package_name": "rust-coreutils", + "release_name": "trixie" + }, + { + "action": "", + "cve_id": "CVE-2026-35371", + "id": 2, + "info": "Minor issue", + "package_name": "rust-coreutils", + "release_name": "bookworm" + } + ], + "debian_triage": { + "cve_id": "CVE-2026-35371", + "not_for_us": "", + "notes": "https://github.com/uutils/coreutils/issues/10006\n", + "status": "PROCESSED", + "to_dos": "" + } + }, + { + "affected_package": [ + { + "cve_id": "CVE-2025-38513", + "id": 5, + "info": "", + "package_name": "linux", + "version": "6.16.3-1" + } + ], + "affected_release": [ + { + "action": "6.12.41-1", + "cve_id": "CVE-2025-38513", + "id": 3, + "info": "", + "package_name": "linux", + "release_name": "trixie" + }, + { + "action": "6.1.147-1", + "cve_id": "CVE-2025-38513", + "id": 4, + "info": "", + "package_name": "linux", + "release_name": "bookworm" + } + ], + "debian_triage": { + "cve_id": "CVE-2025-38513", + "not_for_us": "", + "notes": "https://git.kernel.org/linus/74b1ec9f5d627d2bdd5e5b6f3f81c23317657023 (6.16-rc6)\n", + "status": "PROCESSED", + "to_dos": "" + } + }, + { + "affected_package": [ + { + "cve_id": "CVE-2025-24975", + "id": 6, + "info": "Vulnerable code introduced later", + "package_name": "firebird3.0", + "version": "" + }, + { + "cve_id": "CVE-2025-24975", + "id": 7, + "info": "bug #1111322", + "package_name": "firebird4.0", + "version": "4.0.6.3221.ds6-1" + } + ], + "affected_release": null, + "debian_triage": { + "cve_id": "CVE-2025-24975", + "not_for_us": "", + "notes": "https://github.com/FirebirdSQL/firebird/security/advisories/GHSA-fx9r-rj68-7p69\nhttps://github.com/FirebirdSQL/firebird/issues/8429\nhttps://github.com/FirebirdSQL/firebird/commit/658abd20449f72097fbbce57e8e6ae42ff837fb6\n", + "status": "PROCESSED", + "to_dos": "" + } + }, + { + "affected_package": [ + { + "cve_id": "CVE-2023-31022", + "id": 9, + "info": "bug #1055136", + "package_name": "nvidia-graphics-drivers", + "version": "525.147.05-1" + }, + { + "cve_id": "CVE-2023-31022", + "id": 10, + "info": "bug #1055144", + "package_name": "nvidia-open-gpu-kernel-modules", + "version": "525.147.05-1" + }, + { + "cve_id": "CVE-2023-31022", + "id": 11, + "info": "bug #1055143", + "package_name": "nvidia-graphics-drivers-tesla", + "version": "525.147.05-1" + }, + { + "cve_id": "CVE-2023-31022", + "id": 12, + "info": "bug #1055142", + "package_name": "nvidia-graphics-drivers-tesla-470", + "version": "470.223.02-1" + }, + { + "cve_id": "CVE-2023-31022", + "id": 13, + "info": "bug #1055141", + "package_name": "nvidia-graphics-drivers-tesla-460", + "version": "460.106.00-3" + }, + { + "cve_id": "CVE-2023-31022", + "id": 14, + "info": "bug #1055140", + "package_name": "nvidia-graphics-drivers-tesla-450", + "version": "450.248.02-4" + }, + { + "cve_id": "CVE-2023-31022", + "id": 15, + "info": "bug #1055139", + "package_name": "nvidia-graphics-drivers-tesla-418", + "version": "" + }, + { + "cve_id": "CVE-2023-31022", + "id": 16, + "info": "bug #1055138", + "package_name": "nvidia-graphics-drivers-legacy-390xx", + "version": "" + }, + { + "cve_id": "CVE-2023-31022", + "id": 17, + "info": "bug #1055137", + "package_name": "nvidia-graphics-drivers-legacy-340xx", + "version": "" + } + ], + "affected_release": [ + { + "action": "525.147.05-1~deb12u1", + "cve_id": "CVE-2023-31022", + "id": 6, + "info": "", + "package_name": "nvidia-graphics-drivers", + "release_name": "bookworm" + }, + { + "action": "470.223.02-1", + "cve_id": "CVE-2023-31022", + "id": 7, + "info": "", + "package_name": "nvidia-graphics-drivers", + "release_name": "bullseye" + }, + { + "action": "", + "cve_id": "CVE-2023-31022", + "id": 8, + "info": "Non-free not supported", + "package_name": "nvidia-graphics-drivers", + "release_name": "buster" + }, + { + "action": "525.147.05-1~deb12u1", + "cve_id": "CVE-2023-31022", + "id": 9, + "info": "", + "package_name": "nvidia-open-gpu-kernel-modules", + "release_name": "bookworm" + }, + { + "action": "525.147.05-3~deb12u1", + "cve_id": "CVE-2023-31022", + "id": 10, + "info": "", + "package_name": "nvidia-graphics-drivers-tesla", + "release_name": "bookworm" + }, + { + "action": "470.223.02-1~deb12u1", + "cve_id": "CVE-2023-31022", + "id": 11, + "info": "", + "package_name": "nvidia-graphics-drivers-tesla-470", + "release_name": "bookworm" + }, + { + "action": "470.223.02-1~deb11u1", + "cve_id": "CVE-2023-31022", + "id": 12, + "info": "", + "package_name": "nvidia-graphics-drivers-tesla-470", + "release_name": "bullseye" + }, + { + "action": "", + "cve_id": "CVE-2023-31022", + "id": 13, + "info": "Non-free not supported", + "package_name": "nvidia-graphics-drivers-tesla-460", + "release_name": "bullseye" + }, + { + "action": "", + "cve_id": "CVE-2023-31022", + "id": 14, + "info": "Non-free not supported", + "package_name": "nvidia-graphics-drivers-tesla-450", + "release_name": "bullseye" + }, + { + "action": "", + "cve_id": "CVE-2023-31022", + "id": 15, + "info": "Non-free not supported", + "package_name": "nvidia-graphics-drivers-tesla-418", + "release_name": "bullseye" + }, + { + "action": "", + "cve_id": "CVE-2023-31022", + "id": 16, + "info": "Non-free not supported", + "package_name": "nvidia-graphics-drivers-legacy-390xx", + "release_name": "bullseye" + }, + { + "action": "", + "cve_id": "CVE-2023-31022", + "id": 17, + "info": "Non-free not supported", + "package_name": "nvidia-graphics-drivers-legacy-390xx", + "release_name": "buster" + }, + { + "action": "", + "cve_id": "CVE-2023-31022", + "id": 18, + "info": "Non-free not supported", + "package_name": "nvidia-graphics-drivers-legacy-340xx", + "release_name": "buster" + } + ], + "debian_triage": { + "cve_id": "CVE-2023-31022", + "not_for_us": "", + "notes": "460.106.00-3 turned the package into a metapackage to aid switching to nvidia-graphics-drivers-tesla-470\n450.248.02-4 turned the package into a metapackage to aid switching to nvidia-graphics-drivers-tesla-470\nhttps://nvidia.custhelp.com/app/answers/detail/a_id/5491\n", + "status": "PROCESSED", + "to_dos": "" + } + }, + { + "affected_package": [ + { + "cve_id": "CVE-2023-2311", + "id": 8, + "info": "", + "package_name": "chromium", + "version": "112.0.5615.49-1" + } + ], + "affected_release": [ + { + "action": "", + "cve_id": "CVE-2023-2311", + "id": 5, + "info": "see DSA 5046", + "package_name": "chromium", + "release_name": "buster" + } + ], + "debian_triage": { + "cve_id": "CVE-2023-2311", + "not_for_us": "", + "notes": "", + "status": "PROCESSED", + "to_dos": "" + } + } +] diff --git a/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/debsectracker/data/CVE/list new file mode 100644 index 0000000..8c2fbef --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/debsectracker/data/CVE/list @@ -0,0 +1,11 @@ +CVE-2022-48468 (protobuf-c before 1.4.1 has an unsigned integer overflow in parse_requ ...) + - protobuf-c 1.4.1-1 + [bullseye] - protobuf-c (Minor issue) + [buster] - protobuf-c (Minor issue) + - libsignal-protocol-c 2.3.3-3 + [bullseye] - libsignal-protocol-c (Minor issue) + [buster] - libsignal-protocol-c (Minor issue) + NOTE: https://github.com/protobuf-c/protobuf-c/commit/289f5c18b195aa43d46a619d1188709abbfa9c82 (v1.4.1) + NOTE: https://github.com/protobuf-c/protobuf-c/commit/0d1fd124a4e0a07b524989f6e64410ff648fba61 (v1.4.1) + NOTE: https://github.com/protobuf-c/protobuf-c/pull/513 + NOTE: https://github.com/protobuf-c/protobuf-c/issues/499 diff --git a/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/expected_entries.json b/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/expected_entries.json new file mode 100644 index 0000000..91f08cc --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/expected_entries.json @@ -0,0 +1,61 @@ +[ + { + "debian_triage": { + "cve_id": "CVE-2022-48468", + "not_for_us": "", + "notes": "https://github.com/protobuf-c/protobuf-c/commit/289f5c18b195aa43d46a619d1188709abbfa9c82 (v1.4.1)\nhttps://github.com/protobuf-c/protobuf-c/commit/0d1fd124a4e0a07b524989f6e64410ff648fba61 (v1.4.1)\nhttps://github.com/protobuf-c/protobuf-c/pull/513\nhttps://github.com/protobuf-c/protobuf-c/issues/499\n", + "status": "PROCESSED", + "to_dos": "" + }, + "affected_package": [ + { + "cve_id": "CVE-2022-48468", + "id": 1, + "info": "", + "package_name": "protobuf-c", + "version": "1.4.1-1" + }, + { + "cve_id": "CVE-2022-48468", + "id": 2, + "info": "", + "package_name": "libsignal-protocol-c", + "version": "2.3.3-3" + } + ], + "affected_release": [ + { + "action": "", + "cve_id": "CVE-2022-48468", + "id": 1, + "info": "Minor issue", + "package_name": "protobuf-c", + "release_name": "bullseye" + }, + { + "action": "", + "cve_id": "CVE-2022-48468", + "id": 2, + "info": "Minor issue", + "package_name": "protobuf-c", + "release_name": "buster" + }, + { + "action": "", + "cve_id": "CVE-2022-48468", + "id": 3, + "info": "Minor issue", + "package_name": "libsignal-protocol-c", + "release_name": "bullseye" + }, + { + "action": "", + "cve_id": "CVE-2022-48468", + "id": 4, + "info": "Minor issue", + "package_name": "libsignal-protocol-c", + "release_name": "buster" + } + ] + } +] diff --git a/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/todotest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/todotest/debsectracker/data/CVE/list new file mode 100644 index 0000000..f932350 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/todotest/debsectracker/data/CVE/list @@ -0,0 +1,16 @@ +CVE-2025-4382 (A flaw was found in systems utilizing LUKS-encrypted disks with GRUB c ...) + - grub2 2.14~git20250718.0e36779-2 (bug #1105108) + [trixie] - grub2 (Minor issue) + [bookworm] - grub2 (Minor issue) + NOTE: Fixed by: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=c448f511e74cb7c776b314fcb7943f98d3f22b6d (grub-2.14-rc1) + NOTE: Additional hardening via: + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=ed691c0e0e20d9d0e8d8305a120e8c61d6be3d38 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=7a584fbde0c339816a57d55fc165a854039cf0b2 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=10d778c4b4d56cc36836d86a9698bc5272b12101 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=23ec4535f40dc53f68d2709f8fb44af571431ca7 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=301b4ef25a8fafaeba48498e97efd28bd2809f97 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=dbc0eb5bd1f40de9b394e3a86e84f46c39a23e40 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=73d1c959ea3417e9309ba8c6102d7d6dc7c94259 + NOTE: Option to block command line interface at build time introduced with: + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=bb65d81fe320e4b20d0a9b32232a7546eb275ecc + TODO: double check if vulnerability only considered present after grub_is_cli_disabled is introduced diff --git a/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/todotest/expected_entries.json b/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/todotest/expected_entries.json new file mode 100644 index 0000000..7bd0195 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/multiplepackagesentrytest/todotest/expected_entries.json @@ -0,0 +1,38 @@ +[ + { + "debian_triage": { + "cve_id": "CVE-2025-4382", + "not_for_us": "", + "notes": "Fixed by: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=c448f511e74cb7c776b314fcb7943f98d3f22b6d (grub-2.14-rc1)\nAdditional hardening via:\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=ed691c0e0e20d9d0e8d8305a120e8c61d6be3d38\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=7a584fbde0c339816a57d55fc165a854039cf0b2\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=10d778c4b4d56cc36836d86a9698bc5272b12101\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=23ec4535f40dc53f68d2709f8fb44af571431ca7\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=301b4ef25a8fafaeba48498e97efd28bd2809f97\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=dbc0eb5bd1f40de9b394e3a86e84f46c39a23e40\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=73d1c959ea3417e9309ba8c6102d7d6dc7c94259\nOption to block command line interface at build time introduced with:\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=bb65d81fe320e4b20d0a9b32232a7546eb275ecc\n", + "status": "PROCESSED", + "to_dos": "double check if vulnerability only considered present after grub_is_cli_disabled is introduced\n" + }, + "affected_package": [ + { + "cve_id": "CVE-2025-4382", + "id": 1, + "info": "bug #1105108", + "package_name": "grub2", + "version": "2.14~git20250718.0e36779-2" + } + ], + "affected_release": [ + { + "action": "", + "cve_id": "CVE-2025-4382", + "id": 1, + "info": "Minor issue", + "package_name": "grub2", + "release_name": "trixie" + }, + { + "action": "", + "cve_id": "CVE-2025-4382", + "id": 2, + "info": "Minor issue", + "package_name": "grub2", + "release_name": "bookworm" + } + ] + } +] diff --git a/internal/ingestion/debsectracker/testdata/notdisclosedskiptest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/notdisclosedskiptest/debsectracker/data/CVE/list new file mode 100644 index 0000000..c3248cf --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/notdisclosedskiptest/debsectracker/data/CVE/list @@ -0,0 +1,5 @@ +CVE-2025-XXXX [RUSTSEC-2025-0020] + - rust-pyo3 0.22.6-3 (bug #1103894) + [bookworm] - rust-pyo3 (Minor issue) + NOTE: https://rustsec.org/advisories/RUSTSEC-2025-0020.html + NOTE: https://github.com/PyO3/pyo3/issues/5005 diff --git a/internal/ingestion/debsectracker/testdata/notdisclosedskiptest/expected_entries.json b/internal/ingestion/debsectracker/testdata/notdisclosedskiptest/expected_entries.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/notdisclosedskiptest/expected_entries.json @@ -0,0 +1 @@ +[] diff --git a/internal/ingestion/debsectracker/testdata/notforustest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/notforustest/debsectracker/data/CVE/list new file mode 100644 index 0000000..7284233 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/notforustest/debsectracker/data/CVE/list @@ -0,0 +1,2 @@ +CVE-2026-34261 (Due to a missing authorization check in SAP Business Analytics and SAP ...) + NOT-FOR-US: SAP diff --git a/internal/ingestion/debsectracker/testdata/notforustest/expected_entries.json b/internal/ingestion/debsectracker/testdata/notforustest/expected_entries.json new file mode 100644 index 0000000..2387742 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/notforustest/expected_entries.json @@ -0,0 +1,13 @@ +[ + { + "debian_triage": { + "cve_id": "CVE-2026-34261", + "status": "NOT-FOR-US", + "not_for_us": "SAP", + "notes": "", + "to_dos": "" + }, + "affected_package": null, + "affected_release": null + } +] diff --git a/internal/ingestion/debsectracker/testdata/rejectedtest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/rejectedtest/debsectracker/data/CVE/list new file mode 100644 index 0000000..8be3f5f --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/rejectedtest/debsectracker/data/CVE/list @@ -0,0 +1,2 @@ +CVE-2025-31523 + REJECTED diff --git a/internal/ingestion/debsectracker/testdata/rejectedtest/expected_entries.json b/internal/ingestion/debsectracker/testdata/rejectedtest/expected_entries.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/rejectedtest/expected_entries.json @@ -0,0 +1 @@ +[] diff --git a/internal/ingestion/debsectracker/testdata/reservedtest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/reservedtest/debsectracker/data/CVE/list new file mode 100644 index 0000000..8964f40 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/reservedtest/debsectracker/data/CVE/list @@ -0,0 +1,2 @@ +CVE-2002-1246 + RESERVED diff --git a/internal/ingestion/debsectracker/testdata/reservedtest/expected_entries.json b/internal/ingestion/debsectracker/testdata/reservedtest/expected_entries.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/reservedtest/expected_entries.json @@ -0,0 +1 @@ +[] diff --git a/internal/ingestion/debsectracker/testdata/todonotetest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/todonotetest/debsectracker/data/CVE/list new file mode 100644 index 0000000..e64808d --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/todonotetest/debsectracker/data/CVE/list @@ -0,0 +1,2 @@ +CVE-2026-41179 (Rclone is a command-line program to sync files and directories to and ...) + TODO: check diff --git a/internal/ingestion/debsectracker/testdata/todonotetest/expected_entries.json b/internal/ingestion/debsectracker/testdata/todonotetest/expected_entries.json new file mode 100644 index 0000000..27dd481 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/todonotetest/expected_entries.json @@ -0,0 +1,13 @@ +[ + { + "debian_triage": { + "cve_id": "CVE-2026-41179", + "status": "TODO", + "not_for_us": "", + "notes": "", + "to_dos": "" + }, + "affected_package": null, + "affected_release": null + } +] diff --git a/internal/ingestion/debsectracker/testdata/todotest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/todotest/debsectracker/data/CVE/list new file mode 100644 index 0000000..f932350 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/todotest/debsectracker/data/CVE/list @@ -0,0 +1,16 @@ +CVE-2025-4382 (A flaw was found in systems utilizing LUKS-encrypted disks with GRUB c ...) + - grub2 2.14~git20250718.0e36779-2 (bug #1105108) + [trixie] - grub2 (Minor issue) + [bookworm] - grub2 (Minor issue) + NOTE: Fixed by: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=c448f511e74cb7c776b314fcb7943f98d3f22b6d (grub-2.14-rc1) + NOTE: Additional hardening via: + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=ed691c0e0e20d9d0e8d8305a120e8c61d6be3d38 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=7a584fbde0c339816a57d55fc165a854039cf0b2 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=10d778c4b4d56cc36836d86a9698bc5272b12101 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=23ec4535f40dc53f68d2709f8fb44af571431ca7 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=301b4ef25a8fafaeba48498e97efd28bd2809f97 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=dbc0eb5bd1f40de9b394e3a86e84f46c39a23e40 + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=73d1c959ea3417e9309ba8c6102d7d6dc7c94259 + NOTE: Option to block command line interface at build time introduced with: + NOTE: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=bb65d81fe320e4b20d0a9b32232a7546eb275ecc + TODO: double check if vulnerability only considered present after grub_is_cli_disabled is introduced diff --git a/internal/ingestion/debsectracker/testdata/todotest/expected_entries.json b/internal/ingestion/debsectracker/testdata/todotest/expected_entries.json new file mode 100644 index 0000000..7bd0195 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/todotest/expected_entries.json @@ -0,0 +1,38 @@ +[ + { + "debian_triage": { + "cve_id": "CVE-2025-4382", + "not_for_us": "", + "notes": "Fixed by: https://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=c448f511e74cb7c776b314fcb7943f98d3f22b6d (grub-2.14-rc1)\nAdditional hardening via:\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=ed691c0e0e20d9d0e8d8305a120e8c61d6be3d38\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=7a584fbde0c339816a57d55fc165a854039cf0b2\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=10d778c4b4d56cc36836d86a9698bc5272b12101\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=23ec4535f40dc53f68d2709f8fb44af571431ca7\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=301b4ef25a8fafaeba48498e97efd28bd2809f97\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=dbc0eb5bd1f40de9b394e3a86e84f46c39a23e40\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=73d1c959ea3417e9309ba8c6102d7d6dc7c94259\nOption to block command line interface at build time introduced with:\nhttps://git.savannah.gnu.org/gitweb/?p=grub.git;a=commit;h=bb65d81fe320e4b20d0a9b32232a7546eb275ecc\n", + "status": "PROCESSED", + "to_dos": "double check if vulnerability only considered present after grub_is_cli_disabled is introduced\n" + }, + "affected_package": [ + { + "cve_id": "CVE-2025-4382", + "id": 1, + "info": "bug #1105108", + "package_name": "grub2", + "version": "2.14~git20250718.0e36779-2" + } + ], + "affected_release": [ + { + "action": "", + "cve_id": "CVE-2025-4382", + "id": 1, + "info": "Minor issue", + "package_name": "grub2", + "release_name": "trixie" + }, + { + "action": "", + "cve_id": "CVE-2025-4382", + "id": 2, + "info": "Minor issue", + "package_name": "grub2", + "release_name": "bookworm" + } + ] + } +] diff --git a/internal/ingestion/debsectracker/testdata/unknownformattest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/unknownformattest/debsectracker/data/CVE/list new file mode 100644 index 0000000..47eb614 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/unknownformattest/debsectracker/data/CVE/list @@ -0,0 +1,13 @@ +CVE-2026-31447 (In the Linux kernel, the following vulnerability has been resolved: e ...) + - linux 6.19.11-1 + NOTE: https://git.kernel.org/linus/3822743dc20386d9897e999dbb990befa3a5b3f8 (7.0-rc6) +CVE-2026-31446 (In the Linux kernel, the following vulnerability has been resolved: e ...) + - linux 6.19.11-1 + NOTE: https://git.kernel.org/linus/d15e4b0a418537aafa56b2cb80d44add83e83697 (7.0-rc6) +CVE-2026-31445 (In the Linux kernel, the following vulnerability has been resolved: m ...) + - linux 6.19.11-1 + [trixie] - linux (Vulnerable code not present) + [bookworm] - linux (Vulnerable code not present) + [bullseye] - linux (Vulnerable code not present) + SEVERITY: HIGH + NOTE: https://git.kernel.org/linus/26f775a054c3cda86ad465a64141894a90a9e145 (7.0-rc6) diff --git a/internal/ingestion/debsectracker/testdata/unknownformattest/expected_entries.json b/internal/ingestion/debsectracker/testdata/unknownformattest/expected_entries.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/unknownformattest/expected_entries.json @@ -0,0 +1 @@ +[] diff --git a/internal/ingestion/debsectracker/testdata/validentrytest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/validentrytest/debsectracker/data/CVE/list new file mode 100644 index 0000000..9d1bf99 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/validentrytest/debsectracker/data/CVE/list @@ -0,0 +1,8 @@ +CVE-2025-15281 (Calling wordexp with WRDE_REUSE in conjunction with WRDE_APPEND in the ...) + - glibc 2.42-11 (bug #1126266) + [trixie] - glibc 2.41-12+deb13u2 + [bookworm] - glibc (Minor issue) + [bullseye] - glibc (Minor issue, unlikely scenario) + NOTE: https://www.openwall.com/lists/oss-security/2026/01/20/3 + NOTE: Introduced with: https://sourceware.org/git/?p=glibc.git;a=commit;h=8f2ece695d8822e9ecc63ecd157e90bf17a6fe65 (glibc-2.0.92) + NOTE: Fixed by: https://sourceware.org/git/?p=glibc.git;a=commit;h=80cc58ea2de214f85b0a1d902a3b668ad2ecb302 (glibc-2.43) diff --git a/internal/ingestion/debsectracker/testdata/validentrytest/expected_entries.json b/internal/ingestion/debsectracker/testdata/validentrytest/expected_entries.json new file mode 100644 index 0000000..354e2e1 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/validentrytest/expected_entries.json @@ -0,0 +1,46 @@ +[ + { + "debian_triage": { + "cve_id": "CVE-2025-15281", + "not_for_us": "", + "notes": "https://www.openwall.com/lists/oss-security/2026/01/20/3\nIntroduced with: https://sourceware.org/git/?p=glibc.git;a=commit;h=8f2ece695d8822e9ecc63ecd157e90bf17a6fe65 (glibc-2.0.92)\nFixed by: https://sourceware.org/git/?p=glibc.git;a=commit;h=80cc58ea2de214f85b0a1d902a3b668ad2ecb302 (glibc-2.43)\n", + "status": "PROCESSED", + "to_dos": "" + }, + "affected_package": [ + { + "cve_id": "CVE-2025-15281", + "id": 1, + "info": "bug #1126266", + "package_name": "glibc", + "version": "2.42-11" + } + ], + "affected_release": [ + { + "action": "2.41-12+deb13u2", + "cve_id": "CVE-2025-15281", + "id": 1, + "info": "", + "package_name": "glibc", + "release_name": "trixie" + }, + { + "action": "", + "cve_id": "CVE-2025-15281", + "id": 2, + "info": "Minor issue", + "package_name": "glibc", + "release_name": "bookworm" + }, + { + "action": "", + "cve_id": "CVE-2025-15281", + "id": 3, + "info": "Minor issue, unlikely scenario", + "package_name": "glibc", + "release_name": "bullseye" + } + ] + } +] diff --git a/internal/ingestion/debsectracker/testdata/validentrywithadvisorytest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/validentrywithadvisorytest/debsectracker/data/CVE/list new file mode 100644 index 0000000..74478ed --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/validentrywithadvisorytest/debsectracker/data/CVE/list @@ -0,0 +1,6 @@ +CVE-2026-23952 (ImageMagick is free and open-source software used for editing and mani ...) + {DSA-6111-1 DLA-4448-1} + - imagemagick 8:7.1.2.13+dfsg1-1 (bug #1126077) + NOTE: https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-5vx3-wx4q-6cj8 + NOTE: Fixed by: https://github.com/ImageMagick/ImageMagick/commit/1eefab41bc0ab1c6c2c1fd3e4a49e3ee1849751d (7.1.2-13) + NOTE: Fixed by: https://github.com/ImageMagick/ImageMagick6/commit/0e4023775c8859d2b802e8b459a27b599ca8403a (6.9.13-38) diff --git a/internal/ingestion/debsectracker/testdata/validentrywithadvisorytest/expected_entries.json b/internal/ingestion/debsectracker/testdata/validentrywithadvisorytest/expected_entries.json new file mode 100644 index 0000000..c1a5cac --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/validentrywithadvisorytest/expected_entries.json @@ -0,0 +1,21 @@ +[ + { + "debian_triage": { + "cve_id": "CVE-2026-23952", + "not_for_us": "", + "notes": "https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-5vx3-wx4q-6cj8\nFixed by: https://github.com/ImageMagick/ImageMagick/commit/1eefab41bc0ab1c6c2c1fd3e4a49e3ee1849751d (7.1.2-13)\nFixed by: https://github.com/ImageMagick/ImageMagick6/commit/0e4023775c8859d2b802e8b459a27b599ca8403a (6.9.13-38)\n", + "status": "PROCESSED", + "to_dos": "" + }, + "affected_package": [ + { + "cve_id": "CVE-2026-23952", + "id": 1, + "info": "bug #1126077", + "package_name": "imagemagick", + "version": "8:7.1.2.13+dfsg1-1" + } + ], + "affected_release": null + } +] diff --git a/internal/ingestion/debsectracker/testdata/wrongheaderlinetest/debsectracker/data/CVE/list b/internal/ingestion/debsectracker/testdata/wrongheaderlinetest/debsectracker/data/CVE/list new file mode 100644 index 0000000..fd69f20 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/wrongheaderlinetest/debsectracker/data/CVE/list @@ -0,0 +1,9 @@ +CVE-2023-2311 (Insufficient policy enforcement in File System API in Google Chrome pr ...) + {DSA-5386-1} + - chromium 112.0.5615.49-1 + [buster] - chromium (see DSA 5046) +GH-123-456 + - packetX 42.0 + [trixie] - grub2 (Minor issue) + [bookworm] - grub2 (Minor issue) + TODO: double check diff --git a/internal/ingestion/debsectracker/testdata/wrongheaderlinetest/expected_entries.json b/internal/ingestion/debsectracker/testdata/wrongheaderlinetest/expected_entries.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/internal/ingestion/debsectracker/testdata/wrongheaderlinetest/expected_entries.json @@ -0,0 +1 @@ +[] diff --git a/internal/model/cve_v5/cve_v5.go b/internal/model/cve_v5/cve_v5.go index 6e72a72..480ed2a 100644 --- a/internal/model/cve_v5/cve_v5.go +++ b/internal/model/cve_v5/cve_v5.go @@ -1,3 +1,4 @@ +//nolint:tagliatelle // schema not defined by us package cve_v5 import ( diff --git a/internal/model/cvss_v2_0/cvss_v2_0.go b/internal/model/cvss_v2_0/cvss_v2_0.go index f647368..db84575 100644 --- a/internal/model/cvss_v2_0/cvss_v2_0.go +++ b/internal/model/cvss_v2_0/cvss_v2_0.go @@ -1,3 +1,4 @@ +//nolint:tagliatelle // schema not defined by us package cvss_v2_0 type CVSSV2_0 struct { diff --git a/internal/model/cvss_v3_x/cvss_v3_x.go b/internal/model/cvss_v3_x/cvss_v3_x.go index 64a84ef..16b8a2c 100644 --- a/internal/model/cvss_v3_x/cvss_v3_x.go +++ b/internal/model/cvss_v3_x/cvss_v3_x.go @@ -1,3 +1,4 @@ +//nolint:tagliatelle // schema not defined by us package cvss_v3_x // CVSSV3_x: 3.0 and 3.1 share the same structure, but a scored differently. diff --git a/internal/model/cvss_v4_0/cvss_v4_0.go b/internal/model/cvss_v4_0/cvss_v4_0.go index e78e434..9af938f 100644 --- a/internal/model/cvss_v4_0/cvss_v4_0.go +++ b/internal/model/cvss_v4_0/cvss_v4_0.go @@ -1,3 +1,4 @@ +//nolint:tagliatelle // schema not defined by us package cvss_v4_0 type CVSSV4_0 struct { diff --git a/internal/model/debtriage/debtriage.go b/internal/model/debtriage/debtriage.go new file mode 100644 index 0000000..10dc074 --- /dev/null +++ b/internal/model/debtriage/debtriage.go @@ -0,0 +1,12 @@ +package debtriage + +type StatusType string + +const ( + StatusUnknown StatusType = "UNKNOWN" + StatusToDo StatusType = "TODO" + StatusRejected StatusType = "REJECTED" + StatusNotForUs StatusType = "NOT-FOR-US" + StatusProcessed StatusType = "PROCESSED" + StatusReserved StatusType = "RESERVED" +) diff --git a/internal/repository/cve.sql.go b/internal/repository/cve.sql.go index 6c91134..29231a6 100644 --- a/internal/repository/cve.sql.go +++ b/internal/repository/cve.sql.go @@ -9,36 +9,32 @@ import ( "context" ) -const listCves = `-- name: ListCves :many -SELECT c.id, c.title, c.description, c.serial, c.is_rejected, c.assigner_org_id, c.assigner_short_name, c.date_reserved, c.date_published, c.date_updated, c.date_assigned, c.date_public FROM cve As c ORDER BY c.name DESC +const listCVEs = `-- name: ListCVEs :many +SELECT id, title, description, serial, is_rejected, assigner_org_id, assigner_short_name, date_reserved, date_published, date_updated, date_assigned, date_public FROM cve ORDER BY name DESC ` -type ListCvesRow struct { - Cve Cve `json:"cve"` -} - -func (q *Queries) ListCves(ctx context.Context) ([]ListCvesRow, error) { - rows, err := q.db.QueryContext(ctx, listCves) +func (q *Queries) ListCVEs(ctx context.Context) ([]Cve, error) { + rows, err := q.db.QueryContext(ctx, listCVEs) if err != nil { return nil, err } defer rows.Close() - var items []ListCvesRow + var items []Cve for rows.Next() { - var i ListCvesRow + var i Cve if err := rows.Scan( - &i.Cve.ID, - &i.Cve.Title, - &i.Cve.Description, - &i.Cve.Serial, - &i.Cve.IsRejected, - &i.Cve.AssignerOrgID, - &i.Cve.AssignerShortName, - &i.Cve.DateReserved, - &i.Cve.DatePublished, - &i.Cve.DateUpdated, - &i.Cve.DateAssigned, - &i.Cve.DatePublic, + &i.ID, + &i.Title, + &i.Description, + &i.Serial, + &i.IsRejected, + &i.AssignerOrgID, + &i.AssignerShortName, + &i.DateReserved, + &i.DatePublished, + &i.DateUpdated, + &i.DateAssigned, + &i.DatePublic, ); err != nil { return nil, err } diff --git a/internal/repository/debiantriage.sql.go b/internal/repository/debiantriage.sql.go new file mode 100644 index 0000000..28f181e --- /dev/null +++ b/internal/repository/debiantriage.sql.go @@ -0,0 +1,241 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 +// source: debiantriage.sql + +package repository + +import ( + "context" + + debtriage "github.com/gardenlinux/glvd2/internal/model/debtriage" +) + +const getDebianTriage = `-- name: GetDebianTriage :one +SELECT cve_id, status, not_for_us, notes, to_dos FROM debian_triage WHERE cve_id = ? LIMIT 1 +` + +func (q *Queries) GetDebianTriage(ctx context.Context, cveID string) (DebianTriage, error) { + row := q.db.QueryRowContext(ctx, getDebianTriage, cveID) + var i DebianTriage + err := row.Scan( + &i.CVEID, + &i.Status, + &i.NotForUs, + &i.Notes, + &i.ToDos, + ) + return i, err +} + +const insertDebianPackageOrIgnore = `-- name: InsertDebianPackageOrIgnore :one +INSERT OR IGNORE INTO debian_package(name) VALUES (?) RETURNING name +` + +func (q *Queries) InsertDebianPackageOrIgnore(ctx context.Context, name string) (string, error) { + row := q.db.QueryRowContext(ctx, insertDebianPackageOrIgnore, name) + err := row.Scan(&name) + return name, err +} + +const insertDebianReleaseOrIgnore = `-- name: InsertDebianReleaseOrIgnore :one +INSERT OR IGNORE INTO debian_release(name) VALUES (?) RETURNING name +` + +func (q *Queries) InsertDebianReleaseOrIgnore(ctx context.Context, name string) (string, error) { + row := q.db.QueryRowContext(ctx, insertDebianReleaseOrIgnore, name) + err := row.Scan(&name) + return name, err +} + +const insertDebianTriage = `-- name: InsertDebianTriage :one +INSERT INTO debian_triage(cve_id, status, not_for_us, notes, to_dos) VALUES (?, ?, ?, ?, ?) RETURNING cve_id, status, not_for_us, notes, to_dos +` + +type InsertDebianTriageParams struct { + CVEID string `json:"cve_id"` + Status debtriage.StatusType `json:"status"` + NotForUs string `json:"not_for_us"` + Notes string `json:"notes"` + ToDos string `json:"to_dos"` +} + +func (q *Queries) InsertDebianTriage(ctx context.Context, arg InsertDebianTriageParams) (DebianTriage, error) { + row := q.db.QueryRowContext(ctx, insertDebianTriage, + arg.CVEID, + arg.Status, + arg.NotForUs, + arg.Notes, + arg.ToDos, + ) + var i DebianTriage + err := row.Scan( + &i.CVEID, + &i.Status, + &i.NotForUs, + &i.Notes, + &i.ToDos, + ) + return i, err +} + +const insertDebianTriageAffectedPackage = `-- name: InsertDebianTriageAffectedPackage :one +INSERT INTO debian_triage_affected_package(cve_id, package_name, version, info) VALUES (?, ?, ?, ?) RETURNING id, cve_id, package_name, version, info +` + +type InsertDebianTriageAffectedPackageParams struct { + CVEID string `json:"cve_id"` + PackageName string `json:"package_name"` + Version string `json:"version"` + Info *string `json:"info"` +} + +func (q *Queries) InsertDebianTriageAffectedPackage(ctx context.Context, arg InsertDebianTriageAffectedPackageParams) (DebianTriageAffectedPackage, error) { + row := q.db.QueryRowContext(ctx, insertDebianTriageAffectedPackage, + arg.CVEID, + arg.PackageName, + arg.Version, + arg.Info, + ) + var i DebianTriageAffectedPackage + err := row.Scan( + &i.ID, + &i.CVEID, + &i.PackageName, + &i.Version, + &i.Info, + ) + return i, err +} + +const insertDebianTriageAffectedRelease = `-- name: InsertDebianTriageAffectedRelease :one +INSERT INTO debian_triage_affected_release(cve_id, release_name, package_name, action, info) VALUES (?, ?, ?, ?, ?) RETURNING id, cve_id, release_name, package_name, "action", info +` + +type InsertDebianTriageAffectedReleaseParams struct { + CVEID string `json:"cve_id"` + ReleaseName string `json:"release_name"` + PackageName string `json:"package_name"` + Action string `json:"action"` + Info *string `json:"info"` +} + +func (q *Queries) InsertDebianTriageAffectedRelease(ctx context.Context, arg InsertDebianTriageAffectedReleaseParams) (DebianTriageAffectedRelease, error) { + row := q.db.QueryRowContext(ctx, insertDebianTriageAffectedRelease, + arg.CVEID, + arg.ReleaseName, + arg.PackageName, + arg.Action, + arg.Info, + ) + var i DebianTriageAffectedRelease + err := row.Scan( + &i.ID, + &i.CVEID, + &i.ReleaseName, + &i.PackageName, + &i.Action, + &i.Info, + ) + return i, err +} + +const listAffectedPackagesForDebianTriage = `-- name: ListAffectedPackagesForDebianTriage :many +SELECT id, cve_id, package_name, version, info FROM debian_triage_affected_package WHERE cve_id = ? ORDER BY id ASC +` + +func (q *Queries) ListAffectedPackagesForDebianTriage(ctx context.Context, cveID string) ([]DebianTriageAffectedPackage, error) { + rows, err := q.db.QueryContext(ctx, listAffectedPackagesForDebianTriage, cveID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []DebianTriageAffectedPackage + for rows.Next() { + var i DebianTriageAffectedPackage + if err := rows.Scan( + &i.ID, + &i.CVEID, + &i.PackageName, + &i.Version, + &i.Info, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listAffectedReleasesForDebianTriage = `-- name: ListAffectedReleasesForDebianTriage :many +SELECT id, cve_id, release_name, package_name, "action", info FROM debian_triage_affected_release WHERE cve_id = ? ORDER BY id ASC +` + +func (q *Queries) ListAffectedReleasesForDebianTriage(ctx context.Context, cveID string) ([]DebianTriageAffectedRelease, error) { + rows, err := q.db.QueryContext(ctx, listAffectedReleasesForDebianTriage, cveID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []DebianTriageAffectedRelease + for rows.Next() { + var i DebianTriageAffectedRelease + if err := rows.Scan( + &i.ID, + &i.CVEID, + &i.ReleaseName, + &i.PackageName, + &i.Action, + &i.Info, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const listDebianTriages = `-- name: ListDebianTriages :many +SELECT cve_id, status, not_for_us, notes, to_dos FROM debian_triage ORDER BY cve_id DESC +` + +func (q *Queries) ListDebianTriages(ctx context.Context) ([]DebianTriage, error) { + rows, err := q.db.QueryContext(ctx, listDebianTriages) + if err != nil { + return nil, err + } + defer rows.Close() + var items []DebianTriage + for rows.Next() { + var i DebianTriage + if err := rows.Scan( + &i.CVEID, + &i.Status, + &i.NotForUs, + &i.Notes, + &i.ToDos, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/repository/models.go b/internal/repository/models.go index 1dbd0e4..3006069 100644 --- a/internal/repository/models.go +++ b/internal/repository/models.go @@ -4,9 +4,14 @@ package repository +import ( + debtriage "github.com/gardenlinux/glvd2/internal/model/debtriage" +) + type Affect struct { - ID int64 `json:"id"` - CveID *string `json:"cve_id"` + ID int64 `json:"id"` + CVEID *string `json:"cve_id"` + ProductID *int64 `json:"product_id"` } type Cve struct { @@ -26,7 +31,7 @@ type Cve struct { type CvssMetric struct { ID int64 `json:"id"` - CveID *string `json:"cve_id"` + CVEID *string `json:"cve_id"` Issuer *string `json:"issuer"` Version *string `json:"version"` VectorString *string `json:"vector_string"` @@ -34,8 +39,41 @@ type CvssMetric struct { BaseSeverity *string `json:"base_severity"` } +type DebianPackage struct { + Name string `json:"name"` +} + +type DebianRelease struct { + Name string `json:"name"` +} + +type DebianTriage struct { + CVEID string `json:"cve_id"` + Status debtriage.StatusType `json:"status"` + NotForUs string `json:"not_for_us"` + Notes string `json:"notes"` + ToDos string `json:"to_dos"` +} + +type DebianTriageAffectedPackage struct { + ID int64 `json:"id"` + CVEID string `json:"cve_id"` + PackageName string `json:"package_name"` + Version string `json:"version"` + Info *string `json:"info"` +} + +type DebianTriageAffectedRelease struct { + ID int64 `json:"id"` + CVEID string `json:"cve_id"` + ReleaseName string `json:"release_name"` + PackageName string `json:"package_name"` + Action string `json:"action"` + Info *string `json:"info"` +} + type Product struct { ID int64 `json:"id"` Title *string `json:"title"` - Cpe *string `json:"cpe"` + CPE *string `json:"cpe"` } diff --git a/sqlc.yaml b/sqlc.yaml index d73cdd0..f036428 100644 --- a/sqlc.yaml +++ b/sqlc.yaml @@ -11,3 +11,12 @@ sql: emit_json_tags: true emit_enum_valid_method: true emit_all_enum_values: true + rename: + cve_id: "CVEID" + cpe: "CPE" + overrides: + - column: "debian_triage.status" + go_type: + import: "github.com/gardenlinux/glvd2/internal/model/debtriage" + package: "debtriage" + type: "StatusType" diff --git a/submodules/debian-security-tracker b/submodules/debian-security-tracker new file mode 160000 index 0000000..8788c5f --- /dev/null +++ b/submodules/debian-security-tracker @@ -0,0 +1 @@ +Subproject commit 8788c5fb8b6b1d17f0b6e519d575330fd4d8d349