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
Race condition can make MaxCreationLimit useless #5926
Comments
|
Thank you for a high quality report! |
|
Interesting issue, I would like to fix this. |
Thanks for expressing your interests! I think it is probably an overkill, given Gogs is a single binary monolith application, we can simply hold locks in memory. Something like (not a working solution): type createRepositoryLocker struct {
lock sync.Mutex
userIDs map[int64]sync.Mutex
}
func (l *createRepositoryLocker) Lock(userID int64) {
l.lock.Lock()
user := l.userIDs[userID]
l.lock.Unlock()
user.Lock()
}
func (l *createRepositoryLocker) Unlock(userID int64) {
l.lock.Lock()
user := l.userIDs[userID]
l.lock.Unlock()
user.Unlock()
} |
Does it really necessary to create a struct for every single counter? // Counters
NumFollowersLock sync.Mutex
NumFollowers int
NumFollowingLock sync.Mutex
NumFollowing int `xorm:"NOT NULL DEFAULT 0" gorm:"not null;default:0"`
NumStarsLock sync.Mutex
NumStars int
NumReposLock sync.Mutex
NumRepos intoption 2: // Counters
Counters *SafeCounters
type SafeCounters struct {
NumFollowersLock sync.Mutex
NumFollowers int
NumFollowingLock sync.Mutex
NumFollowing int `xorm:"NOT NULL DEFAULT 0" gorm:"not null;default:0"`
NumStarsLock sync.Mutex
NumStars int
NumReposLock sync.Mutex
NumRepos int
}What do you think? |
|
I don't fully understand where or how to achieve this, maybe I need to get more familiar with the code base so I will search for other open issues, If you have something to recommend I would like that :) |
Description
Users could potentially create more repos than specified in MaxCreationLimit as NumRepos field is not updated in a race-condition-safe cavalier (i.e. row is not locked). Such logic error could be fatal in some specific settings.
Reason
internal/db/repo.go:1108
PoC
Execute following script in the console of the user:
The resultant NumRepos is less than 10 (it is 2~4 in my settings) though 10 repos are created.
Solution
Indeed, some other fields also need locking but are not that crucial to the integrity of the system.
Or stop using fields in user table to save the value as it could be counted directly by using repository table.
The text was updated successfully, but these errors were encountered: