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

statedb: Fix termination of string and IP keys #29368

Merged
merged 2 commits into from Nov 28, 2023

Conversation

joamaki
Copy link
Contributor

@joamaki joamaki commented Nov 24, 2023

Due to missing zero byte termination in the keys returned by index.String and
index.Stringer the Get() method returned wrong results, e.g. Get("foo") would've returned both "foo" and "foobar" for a unique index. Fix by adding the termination.

Similar issue also existed for index.NetIP and index.NetIPAddr since they returned variable-sized keys (e.g. 4 bytes for IPv4 and 16 bytes for IPv6). Fix this by changing them to fixed-size keys.

While at it, make the construction of keys a bit more explicit by making index.Key a newtype over []byte and fix usages. Add documentation about the need for termination for variable sized keys to index.Key.

I did think about alternative ways to fix this. We can't just add "\x00" to keys since that may be a valid byte (e.g. in net.IP) and thus would not serve as termination. A more complex marker or adding e.g. length to beginning or end has the same issues (and breaks prefix searching). The only working alternative I can think of is to have a special iterator for Get() which does full key comparison, but that would be quite expensive for large keys, thus I opted for making the index functions carry the responsibility of properly either terminating the key or using fixed sizes.

@maintainer-s-little-helper maintainer-s-little-helper bot added the dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. label Nov 24, 2023
@joamaki joamaki added kind/bug This is a bug in the Cilium logic. release-note/bug This PR fixes an issue in a previous release of Cilium. and removed kind/bug This is a bug in the Cilium logic. labels Nov 24, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot removed the dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. label Nov 24, 2023
@joamaki joamaki marked this pull request as ready for review November 24, 2023 14:06
@joamaki joamaki requested review from a team as code owners November 24, 2023 14:06
@joamaki joamaki requested review from rgo3, aspsk and bimmlerd and removed request for rgo3 November 24, 2023 14:06
Copy link
Member

@bimmlerd bimmlerd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this fixes the issue 🚀
When I briefly looked into fixing this, all I could come up with was the expensive check during iteration - happy to see you found another way!

pkg/statedb/index/keyset.go Outdated Show resolved Hide resolved
pkg/statedb/txn.go Show resolved Hide resolved
@joamaki joamaki force-pushed the pr/joamaki/statedb-fix-key-termination branch 3 times, most recently from fc573ee to d088c33 Compare November 27, 2023 13:59
… key)

Signed-off-by: Jussi Maki <jussi@isovalent.com>
Due to missing zero byte termination in the keys returned by index.String and
index.Stringer the Get() method returned wrong results, e.g. Get("foo") would've
returned both "foo" and "foobar" for a unique index. Fix by adding the termination.

Similar issue also existed for index.NetIP and index.NetIPAddr since they returned
variable-sized keys (e.g. 4 bytes for IPv4 and 16 bytes for IPv6). Fix this by changing
them to fixed-size keys.

While at it, make the construction of keys a bit more explicit by making index.Key
a newtype over []byte and fix usages. Add documentation about the need for termination
for variable sized keys to index.Key.

I did think about alternative ways to fix this. We can't just add "\x00" to keys since
that may be a valid byte (e.g. in net.IP) and thus would not serve as termination.
A more complex marker or adding e.g. length to beginning or end has the same issues.
The only working alternative I can think of is to have a special iterator for Get()
which does full key comparison, but that would be quite expensive for large keys,
thus I opted for making the index functions carry the responsibility of properly
either terminating the key or using fixed sizes.

Fixes: cilium#29324
Fixes: 23b0492 ("statedb2: StateDB v2.0 with per-table locks and deletion tracking")
Signed-off-by: Jussi Maki <jussi@isovalent.com>
@joamaki joamaki force-pushed the pr/joamaki/statedb-fix-key-termination branch from d088c33 to ca6924c Compare November 27, 2023 15:06
@joamaki
Copy link
Contributor Author

joamaki commented Nov 28, 2023

/test

@joamaki joamaki requested review from dylandreimerink and removed request for aspsk November 28, 2023 09:12
@maintainer-s-little-helper maintainer-s-little-helper bot added the ready-to-merge This PR has passed all tests and received consensus from code owners to merge. label Nov 28, 2023
@joamaki joamaki added this pull request to the merge queue Nov 28, 2023
Merged via the queue into cilium:main with commit 1d69288 Nov 28, 2023
62 checks passed
@joamaki joamaki deleted the pr/joamaki/statedb-fix-key-termination branch November 28, 2023 11:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready-to-merge This PR has passed all tests and received consensus from code owners to merge. release-note/bug This PR fixes an issue in a previous release of Cilium.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants