mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
resolved: use strv_extend_with_size() to avoid slow parsing of /etc/hosts
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=43942 is a simple case where a repeated entry generates a timeout. I didn't import that case, but generated a simpler one by hand. $ time build/fuzz-etc-hosts test/fuzz/fuzz-etc-hosts/timeout-many-entries test/fuzz/fuzz-etc-hosts/timeout-many-entries... ok build/fuzz-etc-hosts test/fuzz/fuzz-etc-hosts/timeout-many-entries 3.17s (old) ↓ build/fuzz-etc-hosts test/fuzz/fuzz-etc-hosts/timeout-many-entries 0.11s (new) I considered simply disallowing too many aliases. E.g. microsoft appearently sometimes ignores entries after the ninth [1], and other systems set stringent limits [2,3], but the recommended way to get around that is to simply use more lines (as is done in the sample), so this wouldn't change anything. Even if we cannot put all those names in a reply packet, the resolution from the alias to the address should work. I think cases where people define lots and lots of aliases through some programmatic interface is realistic, for example for a blocklist, and such a file shouldn't bring resolved down to its knees. [1] https://superuser.com/questions/932112/is-there-a-maximum-number-of-hostname-aliases-per-line-in-a-windows-hosts-file [2] https://library.netapp.com/ecmdocs/ECMP1516135/html/GUID-C6F3B6D1-232D-44BB-A76C-3304C19607A3.html [3] https://www.ibm.com/docs/en/zos/2.1.0?topic=optional-creating-etchosts
This commit is contained in:
parent
3ec3ae68d2
commit
eb164c51ea
@ -127,7 +127,7 @@ static int parse_line(EtcHosts *hosts, unsigned nr, const char *line) {
|
||||
continue;
|
||||
}
|
||||
|
||||
r = strv_extend(&item->names, name);
|
||||
r = strv_extend_with_size(&item->names, &item->n_names, name);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
@ -391,7 +391,7 @@ int manager_etc_hosts_lookup(Manager *m, DnsQuestion* q, DnsAnswer **answer) {
|
||||
}
|
||||
|
||||
if (found_ptr) {
|
||||
r = dns_answer_reserve(answer, strv_length(item->names));
|
||||
r = dns_answer_reserve(answer, item->n_names);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -9,6 +9,7 @@ typedef struct EtcHostsItem {
|
||||
struct in_addr_data address;
|
||||
|
||||
char **names;
|
||||
size_t n_names;
|
||||
} EtcHostsItem;
|
||||
|
||||
typedef struct EtcHostsItemByName {
|
||||
|
1000
test/fuzz/fuzz-etc-hosts/timeout-strv
Normal file
1000
test/fuzz/fuzz-etc-hosts/timeout-strv
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user