internal/worker: fix readAfterWrite bug
When triaging GHSAs, make a list of all GHSAs that need to
be created or updated and do the database writes all at once.
We need to do this to avoid a readAfterWrite bug in which
we attempt to read CVE records after writing GHSA records.
Change-Id: Ib5745e19f3eb9460178d02f7a7e3bc6aa024a848
Reviewed-on: https://go-review.googlesource.com/c/vulndb/+/432995
Run-TryBot: Tatiana Bradley <tatiana@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Tatiana Bradley <tatiana@golang.org>
diff --git a/internal/worker/update.go b/internal/worker/update.go
index 1bfbdff..d0fb7fa 100644
--- a/internal/worker/update.go
+++ b/internal/worker/update.go
@@ -484,6 +484,8 @@
}
// Determine what needs to be added and modified.
+ var toAdd []*store.GHSARecord
+ var toUpdate []*store.GHSARecord
for _, sa := range sas {
old := ghsaIDToRecord[sa.ID]
if old == nil {
@@ -493,14 +495,10 @@
if err != nil {
return err
}
- r := &store.GHSARecord{
+ toAdd = append(toAdd, &store.GHSARecord{
GHSA: sa,
TriageState: triageState,
- }
- if err := tx.CreateGHSARecord(r); err != nil {
- return err
- }
- numAdded++
+ })
} else if !old.GHSA.UpdatedAt.Equal(sa.UpdatedAt) {
// Modify record.
mod := *old
@@ -514,12 +512,23 @@
default:
// Don't change the TriageState.
}
- if err := tx.SetGHSARecord(&mod); err != nil {
- return err
- }
- numModified++
+ toUpdate = append(toUpdate, &mod)
}
}
+
+ for _, r := range toAdd {
+ if err := tx.CreateGHSARecord(r); err != nil {
+ return err
+ }
+ numAdded++
+ }
+ for _, r := range toUpdate {
+ if err := tx.SetGHSARecord(r); err != nil {
+ return err
+ }
+ numModified++
+ }
+
return nil
})
stats.NumAdded = numAdded