Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

config_file: fix quadratic behaviour when adding config multivars #4799

Merged
merged 1 commit into from
Sep 6, 2018

Conversation

pks-t
Copy link
Member

@pks-t pks-t commented Sep 6, 2018

In case where we add multiple configuration entries with the same key to
a diskfile backend, we always need to iterate the list of this key to
find the last entry due to the list being a singly-linked list. This
is obviously quadratic behaviour, and this has sure enough been found by
oss-fuzz by generating a configuration file with 50k lines, where most
of them have the same key. While the issue will not arise with "sane"
configuration files, an adversary may trigger it by providing a crafted
".gitmodules" file, which is delivered as part of the repo and also
parsed by the configuration parser.

The fix is trivial: store a pointer to the last entry of the list in its
head. As there are only two locations now where we append to this data
structure, mainting this pointer is trivial, too. We can also optimize
retrieval of a single value via config_get, where we previously had to
chase the next pointer to find the last entry that was added.

Using our configuration file fozzur with a corpus that has a single file
with 50000 "-=" lines previously took around 21s. With this optimization
the same file scans in about 0.053s, which is a nearly 400-fold
improvement. But in most cases with a "normal" amount of same-named keys
it's not going to matter anyway.

In case where we add multiple configuration entries with the same key to
a diskfile backend, we always need to iterate the list of this key to
find the last entry due to the list being a singly-linked list. This
is obviously quadratic behaviour, and this has sure enough been found by
oss-fuzz by generating a configuration file with 50k lines, where most
of them have the same key. While the issue will not arise with "sane"
configuration files, an adversary may trigger it by providing a crafted
".gitmodules" file, which is delivered as part of the repo and also
parsed by the configuration parser.

The fix is trivial: store a pointer to the last entry of the list in its
head. As there are only two locations now where we append to this data
structure, mainting this pointer is trivial, too. We can also optimize
retrieval of a single value via `config_get`, where we previously had to
chase the `next` pointer to find the last entry that was added.

Using our configuration file fozzur with a corpus that has a single file
with 50000 "-=" lines previously took around 21s. With this optimization
the same file scans in about 0.053s, which is a nearly 400-fold
improvement. But in most cases with a "normal" amount of same-named keys
it's not going to matter anyway.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants