Skip to content

Commit 1e26b31

Browse files
committed
Fix: Limit query size for affected products update
The update of the affected products is now limited to 1000 CVEs per SQL query. This number can be changed with the --affected-products-query-size option. Also, an index has been added to make the queries a little faster. This is meant to prevent the WAL from becoming very large during the affected products update.
1 parent 3229e9f commit 1e26b31

7 files changed

+127
-9
lines changed

doc/gvmd.8

+6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ It manages the storage of any vulnerability management configurations and of the
1313
\fB-h, --help\f1
1414
Show help options.
1515
.TP
16+
\fB--affected-products-query-size=\fINUMBER\fB\f1
17+
Sets the number of CVEs to process per query when updating the affected products. Defaults to 1000.
18+
.TP
19+
\fB--auth-timeout=\fITIMEOUT\fB\f1
20+
Sets the authentication timeout time for the cached authentication. Defaults to 15 minutes.
21+
.TP
1622
\fB--broker-address=\fIADDRESS\fB\f1
1723
Sets the address for the publish-subscribe message (MQTT) broker. Defaults to localhost:9138. Set to empty to disable.
1824
.TP

doc/gvmd.8.xml

+18
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
5252
<p>Show help options.</p>
5353
</optdesc>
5454
</option>
55+
<option>
56+
<p><opt>--affected-products-query-size=<arg>NUMBER</arg></opt></p>
57+
<optdesc>
58+
<p>
59+
Sets the number of CVEs to process per query when updating
60+
the affected products. Defaults to 1000.
61+
</p>
62+
</optdesc>
63+
</option>
64+
<option>
65+
<p><opt>--auth-timeout=<arg>TIMEOUT</arg></opt></p>
66+
<optdesc>
67+
<p>
68+
Sets the authentication timeout time for the cached authentication.
69+
Defaults to 15 minutes.
70+
</p>
71+
</optdesc>
72+
</option>
5573
<option>
5674
<p><opt>--broker-address=<arg>ADDRESS</arg></opt></p>
5775
<optdesc>

doc/gvmd.html

+14
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,20 @@ <h2>Options</h2>
3737

3838

3939

40+
<p><b>--affected-products-query-size=<em>NUMBER</em></b></p>
41+
42+
<p>Sets the number of CVEs to process per query when updating
43+
the affected products. Defaults to 1000.</p>
44+
45+
46+
47+
<p><b>--auth-timeout=<em>TIMEOUT</em></b></p>
48+
49+
<p>Sets the authentication timeout time for the cached authentication.
50+
Defaults to 15 minutes.</p>
51+
52+
53+
4054
<p><b>--broker-address=<em>ADDRESS</em></b></p>
4155

4256
<p>Sets the address for the publish-subscribe message (MQTT) broker.

src/gvmd.c

+10
Original file line numberDiff line numberDiff line change
@@ -1865,6 +1865,8 @@ gvmd (int argc, char** argv, char *env[])
18651865
static gchar *scanner_key_priv = NULL;
18661866
static int scanner_connection_retry = SCANNER_CONNECTION_RETRY_DEFAULT;
18671867
static int schedule_timeout = SCHEDULE_TIMEOUT_DEFAULT;
1868+
static int affected_products_query_size
1869+
= AFFECTED_PRODUCTS_QUERY_SIZE_DEFAULT;
18681870
static int secinfo_commit_size = SECINFO_COMMIT_SIZE_DEFAULT;
18691871
static gchar *delete_scanner = NULL;
18701872
static gchar *verify_scanner = NULL;
@@ -1911,6 +1913,12 @@ gvmd (int argc, char** argv, char *env[])
19111913
GOptionContext *option_context;
19121914
static GOptionEntry option_entries[]
19131915
= {
1916+
{ "affected-products-query-size", '\0', 0, G_OPTION_ARG_INT,
1917+
&affected_products_query_size,
1918+
"Sets the number of CVEs to process per query when updating"
1919+
" the affected products. Defaults to "
1920+
G_STRINGIFY (AFFECTED_PRODUCTS_QUERY_SIZE_DEFAULT) ".",
1921+
"<number>" },
19141922
{ "auth-timeout", '\0', 0, G_OPTION_ARG_INT,
19151923
&auth_timeout,
19161924
"Sets the authentication timeout time for the cached authentication."
@@ -2364,6 +2372,8 @@ gvmd (int argc, char** argv, char *env[])
23642372

23652373
/* Set SQL sizes */
23662374

2375+
set_affected_products_query_size (affected_products_query_size);
2376+
23672377
set_secinfo_commit_size (secinfo_commit_size);
23682378

23692379
set_vt_ref_insert_size (vt_ref_insert_size);

src/manage_pg.c

+2
Original file line numberDiff line numberDiff line change
@@ -3781,6 +3781,8 @@ manage_db_init_indexes (const gchar *name)
37813781
" ON scap2.cpes (severity);");
37823782
sql ("CREATE INDEX cpes_by_uuid"
37833783
" ON scap2.cpes (uuid);");
3784+
sql ("CREATE INDEX cpes_by_cpe_name_id"
3785+
" ON scap2.cpes(cpe_name_id);");
37843786

37853787
sql ("CREATE INDEX afp_cpe_idx"
37863788
" ON scap2.affected_products (cpe);");

src/manage_sql_secinfo.c

+69-9
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@
7171
*/
7272
#define CPE_MAX_CHUNK_SIZE 10000
7373

74+
/**
75+
* @brief Query size for affected products updates.
76+
*/
77+
static int affected_products_query_size = AFFECTED_PRODUCTS_QUERY_SIZE_DEFAULT;
78+
7479
/**
7580
* @brief Commit size for updates.
7681
*/
@@ -4055,6 +4060,24 @@ update_scap_cves ()
40554060
return 0;
40564061
}
40574062

4063+
static void
4064+
exec_affected_products_sql (const char *cve_ids_str)
4065+
{
4066+
sql ("INSERT INTO scap2.affected_products"
4067+
" SELECT DISTINCT scap2.cpe_match_nodes.cve_id, scap2.cpes.id"
4068+
" FROM scap2.cpe_match_nodes, scap2.cpe_nodes_match_criteria,"
4069+
" scap2.cpe_matches, scap2.cpes"
4070+
" WHERE scap2.cpe_match_nodes.cve_id IN (%s)"
4071+
" AND scap2.cpe_match_nodes.id ="
4072+
" scap2.cpe_nodes_match_criteria.node_id"
4073+
" AND scap2.cpe_nodes_match_criteria.vulnerable = 1"
4074+
" AND scap2.cpe_nodes_match_criteria.match_criteria_id ="
4075+
" scap2.cpe_matches.match_criteria_id"
4076+
" AND scap2.cpe_matches.cpe_name_id = scap2.cpes.cpe_name_id"
4077+
" ON CONFLICT DO NOTHING;",
4078+
cve_ids_str);
4079+
}
4080+
40584081
/**
40594082
* @brief Update SCAP affected products.
40604083
*
@@ -4063,17 +4086,40 @@ update_scap_cves ()
40634086
static void
40644087
update_scap_affected_products ()
40654088
{
4089+
iterator_t cves_iter;
4090+
GString *cve_ids_buffer;
40664091
g_info ("Updating affected products");
40674092

4068-
sql ("INSERT INTO scap2.affected_products"
4069-
" SELECT DISTINCT scap2.cpe_match_nodes.cve_id, scap2.cpes.id"
4070-
" FROM scap2.cpe_match_nodes, scap2.cpe_nodes_match_criteria,"
4071-
" scap2.cpe_matches, scap2.cpes"
4072-
" WHERE scap2.cpe_match_nodes.id = scap2.cpe_nodes_match_criteria.node_id"
4073-
" AND scap2.cpe_nodes_match_criteria.vulnerable = 1"
4074-
" AND scap2.cpe_nodes_match_criteria.match_criteria_id ="
4075-
" scap2.cpe_matches.match_criteria_id"
4076-
" AND scap2.cpe_matches.cpe_name_id = scap2.cpes.cpe_name_id;");
4093+
init_iterator(&cves_iter,
4094+
"SELECT DISTINCT cve_id FROM scap2.cpe_match_nodes");
4095+
4096+
int count = 0;
4097+
4098+
cve_ids_buffer = g_string_new("");
4099+
while (next (&cves_iter))
4100+
{
4101+
resource_t cve_id;
4102+
cve_id = iterator_int64 (&cves_iter, 0);
4103+
g_string_append_printf (cve_ids_buffer, "%s%llu",
4104+
cve_ids_buffer->len ? ", " : "",
4105+
cve_id);
4106+
count ++;
4107+
4108+
if (count % affected_products_query_size == 0)
4109+
{
4110+
exec_affected_products_sql (cve_ids_buffer->str);
4111+
g_string_truncate (cve_ids_buffer, 0);
4112+
g_message("%s: Products of %d CVEs processed", __func__, count);
4113+
}
4114+
}
4115+
4116+
if (cve_ids_buffer->len)
4117+
{
4118+
exec_affected_products_sql (cve_ids_buffer->str);
4119+
g_string_truncate (cve_ids_buffer, 0);
4120+
g_message("%s: Products of %d CVEs processed", __func__, count);
4121+
}
4122+
40774123
}
40784124

40794125
/**
@@ -5785,6 +5831,20 @@ manage_rebuild_scap (GSList *log_config, const db_conn_info_t *database)
57855831
return -1;
57865832
}
57875833

5834+
/**
5835+
* @brief Set the affected products query size.
5836+
*
5837+
* @param new_size The new affected products query size.
5838+
*/
5839+
void
5840+
set_affected_products_query_size (int new_size)
5841+
{
5842+
if (new_size <= 0)
5843+
affected_products_query_size = AFFECTED_PRODUCTS_QUERY_SIZE_DEFAULT;
5844+
else
5845+
secinfo_commit_size = new_size;
5846+
}
5847+
57885848
/**
57895849
* @brief Set the SecInfo update commit size.
57905850
*

src/manage_sql_secinfo.h

+8
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,11 @@
165165
{ NULL, NULL, KEYWORD_TYPE_UNKNOWN } \
166166
}
167167

168+
/**
169+
* @brief Default for affected_products_query_size.
170+
*/
171+
#define AFFECTED_PRODUCTS_QUERY_SIZE_DEFAULT 1000
172+
168173
/**
169174
* @brief Default for secinfo_commit_size.
170175
*/
@@ -191,6 +196,9 @@ check_cert_db_version ();
191196
int
192197
get_secinfo_commit_size ();
193198

199+
void
200+
set_affected_products_query_size (int);
201+
194202
void
195203
set_secinfo_commit_size (int);
196204

0 commit comments

Comments
 (0)