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

Per-checksum score submission locks to prevent score duplicates #557

Merged
merged 1 commit into from
Feb 3, 2024

Conversation

cmyui
Copy link
Member

@cmyui cmyui commented Feb 3, 2024

Describe your changes

There is an ongoing issue due to this TOCTOU bug where scores (with identical checksums) may submit more than a single time (and award duplicate pp/score/etc.) if multiple get between the start and end conditions simultaneously.

This change adds a concurrency lock around the affected area to ensure only one runs at a time.

Related Issues / Projects

Checklist

  • I've manually tested my code

@cmyui
Copy link
Member Author

cmyui commented Feb 3, 2024

cc @minisbett

@cmyui cmyui changed the title per-checksum score submission locks to prevent score duplicates Per-checksum score submission locks to prevent score duplicates Feb 3, 2024
@cmyui cmyui self-assigned this Feb 3, 2024
@cmyui cmyui added the bug Something isn't working label Feb 3, 2024
score.acc = score.calculate_accuracy()
# hold a lock around (check if submitted, submission) to ensure no duplicates
# are submitted to the database, and potentially award duplicate score/pp/etc.
async with app.state.score_submission_locks[score.client_checksum]:
Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm I wonder if I could put a lifespan on the lock objects -- like a timeout in redis, to avoid holding the memory until shutdown

Copy link
Member Author

@cmyui cmyui Feb 3, 2024

Choose a reason for hiding this comment

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

Doesn't seem like a release blocker imo given

$ python3
Python 3.11.7 (main, Dec  8 2023, 18:56:58) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> import asyncio
>>> sys.getsizeof(asyncio.Lock())
56

Assuming 100,000 scores that means 56 * 100_000 / 1024 ** 2 = 5.34 MB

@cmyui cmyui merged commit 9918bc8 into master Feb 3, 2024
4 of 8 checks passed
@cmyui cmyui deleted the per-checksum-score-sub-locks branch February 3, 2024 22:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants