diff --git a/server/datastore/mysql/operating_system_vulnerabilities.go b/server/datastore/mysql/operating_system_vulnerabilities.go index eee50e6b8d..af3f6dbb09 100644 --- a/server/datastore/mysql/operating_system_vulnerabilities.go +++ b/server/datastore/mysql/operating_system_vulnerabilities.go @@ -228,7 +228,10 @@ FROM LEFT JOIN software_cve ON software.id = software_cve.software_id JOIN kernel_host_counts ON kernel_host_counts.software_id = software.id WHERE - kernel_host_counts.os_version_id = ? %s GROUP BY id, cve, version + kernel_host_counts.os_version_id = ? + AND kernel_host_counts.hosts_count > 0 + %s +GROUP BY id, cve, version ` var tmID uint diff --git a/server/datastore/mysql/operating_system_vulnerabilities_test.go b/server/datastore/mysql/operating_system_vulnerabilities_test.go index 9c5db33dcd..61e0f51732 100644 --- a/server/datastore/mysql/operating_system_vulnerabilities_test.go +++ b/server/datastore/mysql/operating_system_vulnerabilities_test.go @@ -592,11 +592,15 @@ func testKernelVulnsHostCount(t *testing.T, ds *Datastore) { require.NoError(t, ds.LoadHostSoftware(ctx, h, false)) } - require.NoError(t, ds.UpdateOSVersions(ctx)) - require.NoError(t, ds.SyncHostsSoftware(ctx, time.Now())) - require.NoError(t, ds.ReconcileSoftwareTitles(ctx)) - require.NoError(t, ds.SyncHostsSoftwareTitles(ctx, time.Now())) - require.NoError(t, ds.InsertKernelSoftwareMapping(ctx)) + updateMappings := func() { + require.NoError(t, ds.UpdateOSVersions(ctx)) + require.NoError(t, ds.SyncHostsSoftware(ctx, time.Now())) + require.NoError(t, ds.ReconcileSoftwareTitles(ctx)) + require.NoError(t, ds.SyncHostsSoftwareTitles(ctx, time.Now())) + require.NoError(t, ds.InsertKernelSoftwareMapping(ctx)) + } + + updateMappings() expectedCVEs := []string{"CVE-2025-0001", "CVE-2025-0002"} @@ -639,11 +643,7 @@ func testKernelVulnsHostCount(t *testing.T, ds *Datastore) { require.NoError(t, ds.UpdateHostOperatingSystem(ctx, host5.ID, *os2)) addKernelToHost(host5) - require.NoError(t, ds.UpdateOSVersions(ctx)) - require.NoError(t, ds.SyncHostsSoftware(ctx, time.Now())) - require.NoError(t, ds.ReconcileSoftwareTitles(ctx)) - require.NoError(t, ds.SyncHostsSoftwareTitles(ctx, time.Now())) - require.NoError(t, ds.InsertKernelSoftwareMapping(ctx)) + updateMappings() kernels, err = ds.ListKernelsByOS(ctx, os2.OSVersionID, &team1.ID) require.NoError(t, err) @@ -659,4 +659,21 @@ func testKernelVulnsHostCount(t *testing.T, ds *Datastore) { assert.ElementsMatchf(t, expectedCVEs, kernels[0].Vulnerabilities, "unexpected vulnerabilities for kernel %s", kernels[0].Version) assert.Equal(t, uint(4), kernels[0].HostsCount) + // Delete host 1. We should see the count for the kernel go down to 0. + require.NoError(t, ds.DeleteHost(ctx, host1.ID)) + + updateMappings() + + ExecAdhocSQL(t, ds, func(q sqlx.ExtContext) error { + var count uint + err := sqlx.GetContext(ctx, q, &count, "SELECT hosts_count FROM kernel_host_counts WHERE os_version_id = ?", os1.OSVersionID) + require.NoError(t, err) + assert.Zero(t, count) + return nil + }) + + kernels, err = ds.ListKernelsByOS(ctx, os1.OSVersionID, nil) + require.NoError(t, err) + require.Empty(t, kernels) + }