Insert one CVE per CPE when there are multiple matches (#4297)
* Insert one CVE per CPE when there are multiple matches * Remove comment * No need to do sqlx.In
This commit is contained in:
@@ -509,18 +509,30 @@ func (ds *Datastore) AllCPEs(ctx context.Context) ([]string, error) {
|
||||
// provided cpes. It returns the number of new rows inserted or an error. If
|
||||
// the CVE already existed for all CPEs, it would return 0, nil.
|
||||
func (ds *Datastore) InsertCVEForCPE(ctx context.Context, cve string, cpes []string) (int64, error) {
|
||||
values := strings.TrimSuffix(strings.Repeat("((SELECT id FROM software_cpe WHERE cpe=?),?),", len(cpes)), ",")
|
||||
sql := fmt.Sprintf(`INSERT IGNORE INTO software_cve (cpe_id, cve) VALUES %s`, values)
|
||||
var args []interface{}
|
||||
var totalCount int64
|
||||
for _, cpe := range cpes {
|
||||
args = append(args, cpe, cve)
|
||||
var ids []uint
|
||||
err := sqlx.Select(ds.writer, &ids, `SELECT id FROM software_cpe WHERE cpe=?`, cpe)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
values := strings.TrimSuffix(strings.Repeat("(?,?),", len(ids)), ",")
|
||||
sql := fmt.Sprintf(`INSERT IGNORE INTO software_cve (cpe_id, cve) VALUES %s`, values)
|
||||
|
||||
var args []interface{}
|
||||
for _, id := range ids {
|
||||
args = append(args, id, cve)
|
||||
}
|
||||
res, err := ds.writer.ExecContext(ctx, sql, args...)
|
||||
if err != nil {
|
||||
return 0, ctxerr.Wrap(ctx, err, "insert software cve")
|
||||
}
|
||||
count, _ := res.RowsAffected()
|
||||
totalCount += count
|
||||
}
|
||||
res, err := ds.writer.ExecContext(ctx, sql, args...)
|
||||
if err != nil {
|
||||
return 0, ctxerr.Wrap(ctx, err, "insert software cve")
|
||||
}
|
||||
count, _ := res.RowsAffected()
|
||||
return count, nil
|
||||
|
||||
return totalCount, nil
|
||||
}
|
||||
|
||||
func (ds *Datastore) ListSoftware(ctx context.Context, opt fleet.SoftwareListOptions) ([]fleet.Software, error) {
|
||||
|
||||
@@ -197,16 +197,19 @@ func testSoftwareInsertCVEs(t *testing.T, ds *Datastore) {
|
||||
host := test.NewHost(t, ds, "host1", "", "host1key", "host1uuid", time.Now())
|
||||
|
||||
software := []fleet.Software{
|
||||
{Name: "foo", Version: "0.0.1", Source: "chrome_extensions"},
|
||||
{Name: "foo", Version: "0.0.1", Source: "deb_packages", Release: "1"},
|
||||
{Name: "foo", Version: "0.0.1", Source: "deb_packages", Release: "2"},
|
||||
{Name: "foo", Version: "0.0.3", Source: "chrome_extensions"},
|
||||
}
|
||||
require.NoError(t, ds.UpdateHostSoftware(context.Background(), host.ID, software))
|
||||
require.NoError(t, ds.LoadHostSoftware(context.Background(), host))
|
||||
|
||||
require.NoError(t, ds.AddCPEForSoftware(context.Background(), host.Software[0], "somecpe"))
|
||||
require.NoError(t, ds.AddCPEForSoftware(context.Background(), host.Software[1], "somecpe"))
|
||||
count, err := ds.InsertCVEForCPE(context.Background(), "cve-123-123-132", []string{"somecpe"})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(1), count)
|
||||
// inserts one per release
|
||||
assert.Equal(t, int64(2), count)
|
||||
|
||||
// run again for the same CPE, should not create any new row
|
||||
count, err = ds.InsertCVEForCPE(context.Background(), "cve-123-123-132", []string{"somecpe"})
|
||||
|
||||
Reference in New Issue
Block a user