Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge 'db: hints: add checksum to sync_point encoding' from Patryk Ję…
…drzejczak Fixes #9405 `sync_point` API provided with incorrect sync point id might allocate crazy amount of memory and fail with `std::bad_alloc`. To fix this, we can check if the encoded sync point has been modified before decoding. We can achieve this by calculating a checksum before encoding, appending it to the encoded sync point, and compering it with a checksum calculated in `db::hints::decode` before decoding. Closes #14534 * github.com:scylladb/scylladb: db: hints: add checksum to sync point encoding db: hints: add the version_size constant
- Loading branch information
Showing
2 changed files
with
71 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import requests | ||
import urllib.parse | ||
import base64 | ||
|
||
def test_sync_point_checksum(rest_api): | ||
resp = rest_api.send('POST', "hinted_handoff/sync_point") | ||
sync_point = resp.json() | ||
# Decode the sync_point to bytes to ensure that every modification changes the data | ||
# (multiple base64 encoded strings may represent a single binary value) | ||
sync_point_b = base64.b64decode(sync_point.encode('ascii')) | ||
|
||
resp = rest_api.send('GET', "hinted_handoff/sync_point", { "id": urllib.parse.quote(sync_point) }) | ||
assert resp.ok | ||
|
||
# Modify each sync_point's byte (except the first one) and send an incorrect request | ||
# The first byte representing version is omitted, because changing it causes a different error | ||
for i in range(1, len(sync_point_b)): | ||
bad_sync_point_b = sync_point_b[:i] + bytes([(sync_point_b[i] + 1) % 255]) + sync_point_b[i + 1:] | ||
bad_sync_point = base64.b64encode(bad_sync_point_b).decode('ascii') | ||
|
||
# Expect that checksum is different | ||
resp = rest_api.send('GET', "hinted_handoff/sync_point", { "id": urllib.parse.quote(bad_sync_point) }) | ||
assert resp.status_code == requests.codes.bad_request | ||
assert "wrong checksum" in resp.json()['message'] |