MEDIUM: server: Don't load server-state file if a line is corrupted

This change is not huge but may have a visible impact for users. Now, if a
line of a server-state file is corrupted, the whole file is ignored. A
warning is emitted with the corrupted line number.

In fact, there is no way to recover from a corrupted line. A line is
considered as corrupted if it is too long (truncated line) or if it contains
the wrong number of arguments. In both cases, it means the file was forged
(or at least manually edited). It is safer to ignore it.

Note for now, memory allocation errors are not reported and the
corresponding line is silently ignored.
This commit is contained in:
Christopher Faulet 2021-02-16 11:51:12 +01:00
parent d0a5e84c8d
commit a67c6bf333

View File

@ -3333,7 +3333,7 @@ void apply_server_state(void)
FILE *f;
char mybuf[SRV_STATE_LINE_MAXLEN];
char file[MAXPATHLEN];
int local_vsn, global_vsn, len;
int local_vsn, global_vsn, len, linenum;
global_vsn = 0; /* no global file */
if (!global.server_state_file)
@ -3359,8 +3359,17 @@ void apply_server_state(void)
goto close_globalfile;
}
while (fgets(mybuf, SRV_STATE_LINE_MAXLEN, f))
srv_state_parse_and_store_line(mybuf, global_vsn, &global_state_tree, NULL);
for (linenum = 0; fgets(mybuf, SRV_STATE_LINE_MAXLEN, f); linenum++) {
int ret;
ret = srv_state_parse_and_store_line(mybuf, global_vsn, &global_state_tree, NULL);
if (ret == -1) {
ha_warning("config: corrupted global server state file '%s' at line %d.\n",
file, linenum);
global_vsn = 0;
break;
}
}
close_globalfile:
fclose(f);
@ -3419,8 +3428,17 @@ void apply_server_state(void)
}
/* First, parse lines of the local server-state file and store them in a eb-tree */
while (fgets(mybuf, SRV_STATE_LINE_MAXLEN, f))
srv_state_parse_and_store_line(mybuf, local_vsn, &local_state_tree, curproxy);
for (linenum = 0; fgets(mybuf, SRV_STATE_LINE_MAXLEN, f); linenum++) {
int ret;
ret = srv_state_parse_and_store_line(mybuf, local_vsn, &local_state_tree, curproxy);
if (ret == -1) {
ha_warning("Proxy '%s': corrupted server state file '%s' at line %d.\n",
curproxy->id, file, linenum);
local_vsn = 0;
break;
}
}
if (local_vsn)
srv_state_px_update(curproxy, local_vsn, &local_state_tree);
@ -3432,11 +3450,13 @@ void apply_server_state(void)
next_node = eb64_next(node);
eb64_delete(node);
/* if no server found, then warn */
ha_warning("Proxy '%s': can't find server '%s' in backend '%s'\n",
curproxy->id, st_line->params[3], curproxy->id);
send_log(curproxy, LOG_NOTICE, "can't find server '%s' in backend '%s'\n",
st_line->params[3], curproxy->id);
if (local_vsn) {
/* if no server found, then warn */
ha_warning("Proxy '%s': can't find server '%s' in backend '%s'\n",
curproxy->id, st_line->params[3], curproxy->id);
send_log(curproxy, LOG_NOTICE, "can't find server '%s' in backend '%s'\n",
st_line->params[3], curproxy->id);
}
free(st_line->line);
free(st_line);