CWE-362
Allowed-with-ReviewConcurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')
Abstraction: Class · Status: Draft
The product contains a concurrent code sequence that requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence operating concurrently.
2925 vulnerabilities reference this CWE, most recent first.
GHSA-9Q24-HWMC-797X
Vulnerability from github – Published: 2024-02-22 12:30 – Updated: 2024-12-11 21:10Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition') vulnerability in Apache Answer. This issue affects Apache Answer through 1.2.1.
Repeated submission during registration resulted in the registration of the same user. When users register, if they rapidly submit multiple registrations using scripts, it can result in the creation of multiple user accounts simultaneously with the same name.
Users are recommended to upgrade to version 1.2.5, which fixes the issue.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/apache/incubator-answer"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.2.5"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-26578"
],
"database_specific": {
"cwe_ids": [
"CWE-362"
],
"github_reviewed": true,
"github_reviewed_at": "2024-02-22T21:35:15Z",
"nvd_published_at": "2024-02-22T10:15:08Z",
"severity": "MODERATE"
},
"details": "Concurrent Execution using Shared Resource with Improper Synchronization (\u0027Race Condition\u0027) vulnerability in Apache Answer. This issue affects Apache Answer through 1.2.1.\n\nRepeated submission during registration resulted in the registration of the same user. When users register, if they rapidly submit multiple registrations using scripts, it can result in the creation of multiple user accounts simultaneously with the same name.\n\nUsers are recommended to upgrade to version 1.2.5, which fixes the issue.",
"id": "GHSA-9q24-hwmc-797x",
"modified": "2024-12-11T21:10:47Z",
"published": "2024-02-22T12:30:56Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-26578"
},
{
"type": "PACKAGE",
"url": "https://github.com/apache/incubator-answer"
},
{
"type": "WEB",
"url": "https://lists.apache.org/thread/ko0ksnznt2484lxt0zts2ygr82ldkhcb"
},
{
"type": "WEB",
"url": "http://www.openwall.com/lists/oss-security/2024/02/22/3"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Apache Answer Race Condition vulnerability"
}
GHSA-9Q4W-JMGX-6765
Vulnerability from github – Published: 2022-05-17 05:24 – Updated: 2024-03-21 03:33** DISPUTED ** Race condition in F-Secure Internet Security 2010 10.00 build 246 on Windows XP allows local users to bypass kernel-mode hook handlers, and execute dangerous code that would otherwise be blocked by a handler but not blocked by signature-based malware detection, via certain user-space memory changes during hook-handler execution, aka an argument-switch attack or a KHOBE attack. NOTE: this issue is disputed by some third parties because it is a flaw in a protection mechanism for situations where a crafted program has already begun to execute.
{
"affected": [],
"aliases": [
"CVE-2010-5161"
],
"database_specific": {
"cwe_ids": [
"CWE-362"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2012-08-25T21:55:00Z",
"severity": "MODERATE"
},
"details": "** DISPUTED ** Race condition in F-Secure Internet Security 2010 10.00 build 246 on Windows XP allows local users to bypass kernel-mode hook handlers, and execute dangerous code that would otherwise be blocked by a handler but not blocked by signature-based malware detection, via certain user-space memory changes during hook-handler execution, aka an argument-switch attack or a KHOBE attack. NOTE: this issue is disputed by some third parties because it is a flaw in a protection mechanism for situations where a crafted program has already begun to execute.",
"id": "GHSA-9q4w-jmgx-6765",
"modified": "2024-03-21T03:33:10Z",
"published": "2022-05-17T05:24:22Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2010-5161"
},
{
"type": "WEB",
"url": "http://archives.neohapsis.com/archives/bugtraq/2010-05/0026.html"
},
{
"type": "WEB",
"url": "http://archives.neohapsis.com/archives/fulldisclosure/2010-05/0066.html"
},
{
"type": "WEB",
"url": "http://countermeasures.trendmicro.eu/you-just-cant-trust-a-drunk"
},
{
"type": "WEB",
"url": "http://matousec.com/info/advisories/khobe-8.0-earthquake-for-windows-desktop-security-software.php"
},
{
"type": "WEB",
"url": "http://matousec.com/info/articles/khobe-8.0-earthquake-for-windows-desktop-security-software.php"
},
{
"type": "WEB",
"url": "http://www.f-secure.com/weblog/archives/00001949.html"
},
{
"type": "WEB",
"url": "http://www.osvdb.org/67660"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/39924"
},
{
"type": "WEB",
"url": "http://www.theregister.co.uk/2010/05/07/argument_switch_av_bypass"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-9Q5M-JFC4-WC92
Vulnerability from github – Published: 2026-04-01 19:52 – Updated: 2026-04-06 17:18Summary
All three OAuth service implementations (GenericOAuthService, GithubOAuthService, GoogleOAuthService) store PKCE verifiers and access tokens as mutable struct fields on singleton instances shared across all concurrent requests. When two users initiate OAuth login for the same provider concurrently, a race condition between VerifyCode() and Userinfo() causes one user to receive a session with the other user's identity.
Details
The OAuthBrokerService.GetService() returns a single shared instance per provider for every request. The OAuth flow stores intermediate state as struct fields on this singleton:
Token storage — generic_oauth_service.go line 96:
generic.token = token // Shared mutable field on singleton
Verifier storage — generic_oauth_service.go line 81:
generic.verifier = verifier // Shared mutable field on singleton
In the callback handler oauth_controller.go lines 136–143, the code calls:
err = service.VerifyCode(code) // line 136 — stores token on singleton
// ... race window ...
user, err := controller.broker.GetUser(req.Provider) // line 143 — reads token from singleton
Between these two calls, a concurrent request's VerifyCode() can overwrite the token field, causing GetUser() → Userinfo() to fetch the wrong user's identity claims.
The same pattern exists in all three implementations:
- github_oauth_service.go lines 34–39, 77, 86–99
- google_oauth_service.go lines 22–27, 65, 73–87
PoC
Race scenario (two concurrent OAuth callbacks):
- User A and User B both click "Login with GitHub" on the same tinyauth instance
- Both are redirected to GitHub, authorize, and GitHub redirects both back with authorization codes
- Both callbacks arrive at tinyauth nearly simultaneously:
Timeline:
t0: Request A → service.VerifyCode(codeA) → singleton.token = tokenA
t1: Request B → service.VerifyCode(codeB) → singleton.token = tokenB (overwrites tokenA)
t2: Request A → broker.GetUser("github") → Userinfo() reads singleton.token = tokenB
t3: Request A receives User B's identity (email, name, groups)
User A now has a tinyauth session with User B's email, gaining access to all resources User B is authorized for via tinyauth's ACL.
PKCE verifier DoS variant: Even with PKCE, concurrent oauthURLHandler calls overwrite the verifier field, causing VerifyCode() to send the wrong verifier to the OAuth provider, which rejects the exchange.
Static verification: Run Go's race detector on a test that calls VerifyCode and Userinfo concurrently on the same service instance — the -race flag will flag data races on the token and verifier fields.
Go race detector confirmation: Running a concurrent test with go test -race on the singleton service detects 4 data races on the token and verifier fields. Without the race detector, measured token overwrite rate is 99.9% (9,985/10,000 iterations).
Test environment: tinyauth v5.0.4, commit 592b7ded, Go race detector + source code analysis
Impact
An attacker who times their OAuth callback to race with a victim's callback can obtain a tinyauth session with the victim's identity. This grants unauthorized access to all resources the victim is permitted to access through tinyauth's ACL system. The probability of collision increases with concurrent OAuth traffic.
The PKCE verifier overwrite additionally causes a denial-of-service: concurrent OAuth logins for the same provider reliably fail.
Suggested Fix
Pass verifier and token through method parameters or return values instead of storing them on the singleton:
func (generic *GenericOAuthService) VerifyCode(code string, verifier string) (*oauth2.Token, error) {
return generic.config.Exchange(generic.context, code, oauth2.VerifierOption(verifier))
}
func (generic *GenericOAuthService) Userinfo(token *oauth2.Token) (config.Claims, error) {
client := generic.config.Client(generic.context, token)
// ...
}
Store the PKCE verifier in the session/cookie associated with the OAuth state parameter, not on the service struct.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/steveiliop56/tinyauth"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.0.1-0.20260401140714-fc1d4f2082a5"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-33544"
],
"database_specific": {
"cwe_ids": [
"CWE-362"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-01T19:52:04Z",
"nvd_published_at": "2026-04-02T15:16:39Z",
"severity": "HIGH"
},
"details": "### Summary\n\nAll three OAuth service implementations (`GenericOAuthService`, `GithubOAuthService`, `GoogleOAuthService`) store PKCE verifiers and access tokens as mutable struct fields on singleton instances shared across all concurrent requests. When two users initiate OAuth login for the same provider concurrently, a race condition between `VerifyCode()` and `Userinfo()` causes one user to receive a session with the other user\u0027s identity.\n\n### Details\n\nThe [`OAuthBrokerService.GetService()`](https://github.com/steveiliop56/tinyauth/blob/592b7ded24959013f8af63ab9930254c752c8c8e/internal/service/oauth_broker_service.go#L70-L72) returns a single shared instance per provider for every request. The OAuth flow stores intermediate state as struct fields on this singleton:\n\n**Token storage** \u2014 [`generic_oauth_service.go` line 96](https://github.com/steveiliop56/tinyauth/blob/592b7ded24959013f8af63ab9930254c752c8c8e/internal/service/generic_oauth_service.go#L96):\n```go\ngeneric.token = token // Shared mutable field on singleton\n```\n\n**Verifier storage** \u2014 [`generic_oauth_service.go` line 81](https://github.com/steveiliop56/tinyauth/blob/592b7ded24959013f8af63ab9930254c752c8c8e/internal/service/generic_oauth_service.go#L81):\n```go\ngeneric.verifier = verifier // Shared mutable field on singleton\n```\n\nIn the callback handler [`oauth_controller.go` lines 136\u2013143](https://github.com/steveiliop56/tinyauth/blob/592b7ded24959013f8af63ab9930254c752c8c8e/internal/controller/oauth_controller.go#L136-L143), the code calls:\n```go\nerr = service.VerifyCode(code) // line 136 \u2014 stores token on singleton\n// ... race window ...\nuser, err := controller.broker.GetUser(req.Provider) // line 143 \u2014 reads token from singleton\n```\n\nBetween these two calls, a concurrent request\u0027s `VerifyCode()` can overwrite the `token` field, causing `GetUser()` \u2192 `Userinfo()` to fetch the **wrong user\u0027s** identity claims.\n\nThe same pattern exists in all three implementations:\n- [`github_oauth_service.go` lines 34\u201339, 77, 86\u201399](https://github.com/steveiliop56/tinyauth/blob/592b7ded24959013f8af63ab9930254c752c8c8e/internal/service/github_oauth_service.go#L34-L39)\n- [`google_oauth_service.go` lines 22\u201327, 65, 73\u201387](https://github.com/steveiliop56/tinyauth/blob/592b7ded24959013f8af63ab9930254c752c8c8e/internal/service/google_oauth_service.go#L22-L27)\n\n### PoC\n\n**Race scenario** (two concurrent OAuth callbacks):\n\n1. User A and User B both click \"Login with GitHub\" on the same tinyauth instance\n2. Both are redirected to GitHub, authorize, and GitHub redirects both back with authorization codes\n3. Both callbacks arrive at tinyauth nearly simultaneously:\n\n```\nTimeline:\n t0: Request A \u2192 service.VerifyCode(codeA) \u2192 singleton.token = tokenA\n t1: Request B \u2192 service.VerifyCode(codeB) \u2192 singleton.token = tokenB (overwrites tokenA)\n t2: Request A \u2192 broker.GetUser(\"github\") \u2192 Userinfo() reads singleton.token = tokenB\n t3: Request A receives User B\u0027s identity (email, name, groups)\n```\n\nUser A now has a tinyauth session with User B\u0027s email, gaining access to all resources User B is authorized for via tinyauth\u0027s ACL.\n\n**PKCE verifier DoS variant**: Even with PKCE, concurrent `oauthURLHandler` calls overwrite the `verifier` field, causing `VerifyCode()` to send the wrong verifier to the OAuth provider, which rejects the exchange.\n\n**Static verification**: Run Go\u0027s race detector on a test that calls `VerifyCode` and `Userinfo` concurrently on the same service instance \u2014 the `-race` flag will flag data races on the `token` and `verifier` fields.\n\n**Go race detector confirmation**: Running a concurrent test with `go test -race` on the singleton service detects **4 data races** on the `token` and `verifier` fields. Without the race detector, measured token overwrite rate is 99.9% (9,985/10,000 iterations).\n\n**Test environment**: tinyauth v5.0.4, commit `592b7ded`, Go race detector + source code analysis\n\n### Impact\n\nAn attacker who times their OAuth callback to race with a victim\u0027s callback can obtain a tinyauth session with the victim\u0027s identity. This grants unauthorized access to all resources the victim is permitted to access through tinyauth\u0027s ACL system. The probability of collision increases with concurrent OAuth traffic.\n\nThe PKCE verifier overwrite additionally causes a denial-of-service: concurrent OAuth logins for the same provider reliably fail.\n\n### Suggested Fix\n\nPass verifier and token through method parameters or return values instead of storing them on the singleton:\n\n```go\nfunc (generic *GenericOAuthService) VerifyCode(code string, verifier string) (*oauth2.Token, error) {\n return generic.config.Exchange(generic.context, code, oauth2.VerifierOption(verifier))\n}\n\nfunc (generic *GenericOAuthService) Userinfo(token *oauth2.Token) (config.Claims, error) {\n client := generic.config.Client(generic.context, token)\n // ...\n}\n```\n\nStore the PKCE verifier in the session/cookie associated with the OAuth `state` parameter, not on the service struct.",
"id": "GHSA-9q5m-jfc4-wc92",
"modified": "2026-04-06T17:18:24Z",
"published": "2026-04-01T19:52:04Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/steveiliop56/tinyauth/security/advisories/GHSA-9q5m-jfc4-wc92"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-33544"
},
{
"type": "WEB",
"url": "https://github.com/steveiliop56/tinyauth/commit/f26c2171610d5c2dfbba2edb6ccd39490e349803"
},
{
"type": "PACKAGE",
"url": "https://github.com/steveiliop56/tinyauth"
},
{
"type": "WEB",
"url": "https://github.com/steveiliop56/tinyauth/releases/tag/v5.0.5"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Tinyauth has OAuth account confusion via shared mutable state on singleton service instances"
}
GHSA-9Q85-MV98-F8HX
Vulnerability from github – Published: 2023-07-12 09:30 – Updated: 2024-04-04 06:02In bluetooth service, there is a possible out of bounds write due to race condition. This could lead to local denial of service with System execution privileges needed.
{
"affected": [],
"aliases": [
"CVE-2022-48451"
],
"database_specific": {
"cwe_ids": [
"CWE-362"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-07-12T09:15:10Z",
"severity": "MODERATE"
},
"details": "In bluetooth service, there is a possible out of bounds write due to race condition. This could lead to local denial of service with System execution privileges needed.",
"id": "GHSA-9q85-mv98-f8hx",
"modified": "2024-04-04T06:02:21Z",
"published": "2023-07-12T09:30:53Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-48451"
},
{
"type": "WEB",
"url": "https://www.unisoc.com/en_us/secy/announcementDetail/1676902764208259073"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-9QCJ-GPQG-C7CW
Vulnerability from github – Published: 2022-05-01 23:55 – Updated: 2022-05-01 23:55Race condition in (1) checkinstall 1.6.1 and (2) installwatch allows local users to overwrite arbitrary files and have other impacts via symlink and possibly other attacks on temporary working directories.
{
"affected": [],
"aliases": [
"CVE-2008-2958"
],
"database_specific": {
"cwe_ids": [
"CWE-362"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2008-07-01T22:41:00Z",
"severity": "MODERATE"
},
"details": "Race condition in (1) checkinstall 1.6.1 and (2) installwatch allows local users to overwrite arbitrary files and have other impacts via symlink and possibly other attacks on temporary working directories.",
"id": "GHSA-9qcj-gpqg-c7cw",
"modified": "2022-05-01T23:55:07Z",
"published": "2022-05-01T23:55:07Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2008-2958"
},
{
"type": "WEB",
"url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/43440"
},
{
"type": "WEB",
"url": "http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=488140"
},
{
"type": "WEB",
"url": "http://lists.alioth.debian.org/pipermail/secure-testing-team/2008-June/001672.html"
},
{
"type": "WEB",
"url": "http://secunia.com/advisories/30873"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-9QJG-WX3M-W8J2
Vulnerability from github – Published: 2025-12-09 18:30 – Updated: 2025-12-09 18:30Concurrent execution using shared resource with improper synchronization ('race condition') in Windows Shell allows an authorized attacker to elevate privileges locally.
{
"affected": [],
"aliases": [
"CVE-2025-64661"
],
"database_specific": {
"cwe_ids": [
"CWE-362"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-12-09T18:16:05Z",
"severity": "HIGH"
},
"details": "Concurrent execution using shared resource with improper synchronization (\u0027race condition\u0027) in Windows Shell allows an authorized attacker to elevate privileges locally.",
"id": "GHSA-9qjg-wx3m-w8j2",
"modified": "2025-12-09T18:30:47Z",
"published": "2025-12-09T18:30:47Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-64661"
},
{
"type": "WEB",
"url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-64661"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-9QV2-Q963-RPQ5
Vulnerability from github – Published: 2022-11-25 06:30 – Updated: 2025-11-04 00:30An issue was discovered in the Linux kernel through 6.0.9. drivers/char/xillybus/xillyusb.c has a race condition and use-after-free during physical removal of a USB device.
{
"affected": [],
"aliases": [
"CVE-2022-45888"
],
"database_specific": {
"cwe_ids": [
"CWE-362"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-11-25T04:15:00Z",
"severity": "MODERATE"
},
"details": "An issue was discovered in the Linux kernel through 6.0.9. drivers/char/xillybus/xillyusb.c has a race condition and use-after-free during physical removal of a USB device.",
"id": "GHSA-9qv2-q963-rpq5",
"modified": "2025-11-04T00:30:33Z",
"published": "2022-11-25T06:30:22Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-45888"
},
{
"type": "WEB",
"url": "https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=282a4b71816b6076029017a7bab3a9dcee12a920"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2025/01/msg00001.html"
},
{
"type": "WEB",
"url": "https://lore.kernel.org/all/20221022175404.GA375335%40ubuntu"
},
{
"type": "WEB",
"url": "https://lore.kernel.org/all/20221022175404.GA375335@ubuntu"
},
{
"type": "WEB",
"url": "https://security.netapp.com/advisory/ntap-20230113-0006"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:P/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-9R53-65FP-9GR6
Vulnerability from github – Published: 2022-05-14 01:05 – Updated: 2022-05-14 01:05Race condition in the grant table code in Xen 4.6.x through 4.9.x allows local guest OS administrators to cause a denial of service (free list corruption and host crash) or gain privileges on the host via vectors involving maptrack free list handling.
{
"affected": [],
"aliases": [
"CVE-2017-12136"
],
"database_specific": {
"cwe_ids": [
"CWE-362"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2017-08-24T14:29:00Z",
"severity": "HIGH"
},
"details": "Race condition in the grant table code in Xen 4.6.x through 4.9.x allows local guest OS administrators to cause a denial of service (free list corruption and host crash) or gain privileges on the host via vectors involving maptrack free list handling.",
"id": "GHSA-9r53-65fp-9gr6",
"modified": "2022-05-14T01:05:33Z",
"published": "2022-05-14T01:05:33Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2017-12136"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=1477651"
},
{
"type": "WEB",
"url": "https://security.gentoo.org/glsa/201801-14"
},
{
"type": "WEB",
"url": "https://support.citrix.com/article/CTX225941"
},
{
"type": "WEB",
"url": "http://www.debian.org/security/2017/dsa-3969"
},
{
"type": "WEB",
"url": "http://www.openwall.com/lists/oss-security/2017/08/15/3"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/100346"
},
{
"type": "WEB",
"url": "http://www.securitytracker.com/id/1039175"
},
{
"type": "WEB",
"url": "http://xenbits.xen.org/xsa/advisory-228.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-9R8Q-3PMV-VR2F
Vulnerability from github – Published: 2024-06-25 15:31 – Updated: 2025-09-17 18:31In the Linux kernel, the following vulnerability has been resolved:
btrfs: protect folio::private when attaching extent buffer folios
[BUG] Since v6.8 there are rare kernel crashes reported by various people, the common factor is bad page status error messages like this:
BUG: Bad page state in process kswapd0 pfn:d6e840 page: refcount:0 mapcount:0 mapping:000000007512f4f2 index:0x2796c2c7c pfn:0xd6e840 aops:btree_aops ino:1 flags: 0x17ffffe0000008(uptodate|node=0|zone=2|lastcpupid=0x3fffff) page_type: 0xffffffff() raw: 0017ffffe0000008 dead000000000100 dead000000000122 ffff88826d0be4c0 raw: 00000002796c2c7c 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: non-NULL mapping
[CAUSE] Commit 09e6cef19c9f ("btrfs: refactor alloc_extent_buffer() to allocate-then-attach method") changes the sequence when allocating a new extent buffer.
Previously we always called grab_extent_buffer() under mapping->i_private_lock, to ensure the safety on modification on folio::private (which is a pointer to extent buffer for regular sectorsize).
This can lead to the following race:
Thread A is trying to allocate an extent buffer at bytenr X, with 4 4K pages, meanwhile thread B is trying to release the page at X + 4K (the second page of the extent buffer at X).
Thread A | Thread B
-----------------------------------+------------------------------------- | btree_release_folio() | | This is for the page at X + 4K, | | Not page X. | | alloc_extent_buffer() | |- release_extent_buffer() |- filemap_add_folio() for the | | |- atomic_dec_and_test(eb->refs) | page at bytenr X (the first | | | | page). | | | | Which returned -EEXIST. | | | | | | | |- filemap_lock_folio() | | | | Returned the first page locked. | | | | | | | |- grab_extent_buffer() | | | | |- atomic_inc_not_zero() | | | | | Returned false | | | | |- folio_detach_private() | | |- folio_detach_private() for X | |- folio_test_private() | | |- folio_test_private() | Returned true | | | Returned true |- folio_put() | |- folio_put()
Now there are two puts on the same folio at folio X, leading to refcount underflow of the folio X, and eventually causing the BUG_ON() on the page->mapping.
The condition is not that easy to hit:
-
The release must be triggered for the middle page of an eb If the release is on the same first page of an eb, page lock would kick in and prevent the race.
-
folio_detach_private() has a very small race window It's only between folio_test_private() and folio_clear_private().
That's exactly when mapping->i_private_lock is used to prevent such race, and commit 09e6cef19c9f ("btrfs: refactor alloc_extent_buffer() to allocate-then-attach method") screwed that up.
At that time, I thought the page lock would kick in as filemap_release_folio() also requires the page to be locked, but forgot the filemap_release_folio() only locks one page, not all pages of an extent buffer.
[FIX] Move all the code requiring i_private_lock into attach_eb_folio_to_filemap(), so that everything is done with proper lock protection.
Furthermore to prevent future problems, add an extra lockdep_assert_locked() to ensure we're holding the proper lock.
To reproducer that is able to hit the race (takes a few minutes with instrumented code inserting delays to alloc_extent_buffer()):
#!/bin/sh drop_caches () { while(true); do echo 3 > /proc/sys/vm/drop_caches echo 1 > /proc/sys/vm/compact_memory done }
run_tar () {
while(true); do
for x in seq 1 80 ; do
tar cf /dev/zero /mnt > /dev/null &
done
wait
done
}
mkfs.btrfs -f -d single -m single ---truncated---
{
"affected": [],
"aliases": [
"CVE-2024-38306"
],
"database_specific": {
"cwe_ids": [
"CWE-362"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-06-25T15:15:13Z",
"severity": "MODERATE"
},
"details": "In the Linux kernel, the following vulnerability has been resolved:\n\nbtrfs: protect folio::private when attaching extent buffer folios\n\n[BUG]\nSince v6.8 there are rare kernel crashes reported by various people,\nthe common factor is bad page status error messages like this:\n\n BUG: Bad page state in process kswapd0 pfn:d6e840\n page: refcount:0 mapcount:0 mapping:000000007512f4f2 index:0x2796c2c7c\n pfn:0xd6e840\n aops:btree_aops ino:1\n flags: 0x17ffffe0000008(uptodate|node=0|zone=2|lastcpupid=0x3fffff)\n page_type: 0xffffffff()\n raw: 0017ffffe0000008 dead000000000100 dead000000000122 ffff88826d0be4c0\n raw: 00000002796c2c7c 0000000000000000 00000000ffffffff 0000000000000000\n page dumped because: non-NULL mapping\n\n[CAUSE]\nCommit 09e6cef19c9f (\"btrfs: refactor alloc_extent_buffer() to\nallocate-then-attach method\") changes the sequence when allocating a new\nextent buffer.\n\nPreviously we always called grab_extent_buffer() under\nmapping-\u003ei_private_lock, to ensure the safety on modification on\nfolio::private (which is a pointer to extent buffer for regular\nsectorsize).\n\nThis can lead to the following race:\n\nThread A is trying to allocate an extent buffer at bytenr X, with 4\n4K pages, meanwhile thread B is trying to release the page at X + 4K\n(the second page of the extent buffer at X).\n\n Thread A | Thread B\n-----------------------------------+-------------------------------------\n | btree_release_folio()\n\t\t\t\t | | This is for the page at X + 4K,\n\t\t\t\t | | Not page X.\n\t\t\t\t | |\nalloc_extent_buffer() | |- release_extent_buffer()\n|- filemap_add_folio() for the | | |- atomic_dec_and_test(eb-\u003erefs)\n| page at bytenr X (the first | | |\n| page). | | |\n| Which returned -EEXIST. | | |\n| | | |\n|- filemap_lock_folio() | | |\n| Returned the first page locked. | | |\n| | | |\n|- grab_extent_buffer() | | |\n| |- atomic_inc_not_zero() | | |\n| | Returned false | | |\n| |- folio_detach_private() | | |- folio_detach_private() for X\n| |- folio_test_private() | | |- folio_test_private()\n | Returned true | | | Returned true\n |- folio_put() | |- folio_put()\n\nNow there are two puts on the same folio at folio X, leading to refcount\nunderflow of the folio X, and eventually causing the BUG_ON() on the\npage-\u003emapping.\n\nThe condition is not that easy to hit:\n\n- The release must be triggered for the middle page of an eb\n If the release is on the same first page of an eb, page lock would kick\n in and prevent the race.\n\n- folio_detach_private() has a very small race window\n It\u0027s only between folio_test_private() and folio_clear_private().\n\nThat\u0027s exactly when mapping-\u003ei_private_lock is used to prevent such race,\nand commit 09e6cef19c9f (\"btrfs: refactor alloc_extent_buffer() to\nallocate-then-attach method\") screwed that up.\n\nAt that time, I thought the page lock would kick in as\nfilemap_release_folio() also requires the page to be locked, but forgot\nthe filemap_release_folio() only locks one page, not all pages of an\nextent buffer.\n\n[FIX]\nMove all the code requiring i_private_lock into\nattach_eb_folio_to_filemap(), so that everything is done with proper\nlock protection.\n\nFurthermore to prevent future problems, add an extra\nlockdep_assert_locked() to ensure we\u0027re holding the proper lock.\n\nTo reproducer that is able to hit the race (takes a few minutes with\ninstrumented code inserting delays to alloc_extent_buffer()):\n\n #!/bin/sh\n drop_caches () {\n\t while(true); do\n\t\t echo 3 \u003e /proc/sys/vm/drop_caches\n\t\t echo 1 \u003e /proc/sys/vm/compact_memory\n\t done\n }\n\n run_tar () {\n\t while(true); do\n\t\t for x in `seq 1 80` ; do\n\t\t\t tar cf /dev/zero /mnt \u003e /dev/null \u0026\n\t\t done\n\t\t wait\n\t done\n }\n\n mkfs.btrfs -f -d single -m single\n---truncated---",
"id": "GHSA-9r8q-3pmv-vr2f",
"modified": "2025-09-17T18:31:15Z",
"published": "2024-06-25T15:31:09Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-38306"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/952f048eb901881a7cc6f7c1368b53cd386ead7b"
},
{
"type": "WEB",
"url": "https://git.kernel.org/stable/c/f3a5367c679d31473d3fbb391675055b4792c309"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-9RH9-HF3W-9FGG
Vulnerability from github – Published: 2026-05-18 16:37 – Updated: 2026-06-08 20:07Impact
CreateOrderFromCartAction::execute previously created the Order row before checking and incrementing the discount's total_use counter. Under concurrent checkout pressure (Black Friday, flash sale, viral coupon), the global usage_limit was silently exceeded: orders were committed with the discount fully applied to price_amount while the counter blocked at usage_limit. The merchant had no signal that an over-redemption had occurred.
A second related bug: usage_limit_per_user was effectively a no-op because the counter it relied on (DiscountDetail.total_use) was never incremented anywhere in the codebase. The per-user check therefore always saw 0 uses and validation passed regardless of how many times the same customer had previously redeemed the coupon. For eligibility = Everyone the per-user limit could not fire at all because the underlying DiscountDetail row only exists for eligibility = Customers.
Direct financial loss: each over-redemption is a discount the merchant did not intend to grant.
Patches
Fixed in v2.8.0. CreateOrderFromCartAction now:
- Reserves the discount slot atomically before the order row is created, inside the same
DB::transactionwithlockForUpdateand a compare-and-swap ontotal_use. - Throws
DiscountLimitReachedException::globaland rolls back the transaction when the global limit was exhausted between cart validation and commit. No order is committed. - Throws
DiscountLimitReachedException::perUserand rolls back when the discount is restricted to one use per customer and the customer has already redeemed it. - Snapshots
discount_id,discount_code,discount_type,discount_value_at_applyanddiscount_currency_codeonto theorderstable for resilience against later discount edits or deletions.
DiscountValidator was updated to perform the same Order-based per-user check at cart-apply time so the rejection is surfaced before checkout.
Upgrade via:
composer require shopper/cart:^2.8 shopper/core:^2.8
php artisan migrate
Workarounds
None. Upgrade to v2.8.0.
Resources
- Issue: https://github.com/shopperlabs/shopper/issues/510
- Pull request: https://github.com/shopperlabs/shopper/pull/511
- CWE-362 Concurrent Execution using Shared Resource with Improper Synchronization
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "shopper/cart"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.8.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-47741"
],
"database_specific": {
"cwe_ids": [
"CWE-362"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-18T16:37:20Z",
"nvd_published_at": "2026-05-29T19:16:25Z",
"severity": "MODERATE"
},
"details": "## Impact\n\n`CreateOrderFromCartAction::execute` previously created the `Order` row before checking and incrementing the discount\u0027s `total_use` counter. Under concurrent checkout pressure (Black Friday, flash sale, viral coupon), the global `usage_limit` was silently exceeded: orders were committed with the discount fully applied to `price_amount` while the counter blocked at `usage_limit`. The merchant had no signal that an over-redemption had occurred.\n\nA second related bug: `usage_limit_per_user` was effectively a no-op because the counter it relied on (`DiscountDetail.total_use`) was never incremented anywhere in the codebase. The per-user check therefore always saw `0` uses and validation passed regardless of how many times the same customer had previously redeemed the coupon. For `eligibility = Everyone` the per-user limit could not fire at all because the underlying `DiscountDetail` row only exists for `eligibility = Customers`.\n\nDirect financial loss: each over-redemption is a discount the merchant did not intend to grant.\n\n## Patches\n\nFixed in `v2.8.0`. `CreateOrderFromCartAction` now:\n\n- Reserves the discount slot atomically before the order row is created, inside the same `DB::transaction` with `lockForUpdate` and a compare-and-swap on `total_use`.\n- Throws `DiscountLimitReachedException::global` and rolls back the transaction when the global limit was exhausted between cart validation and commit. No order is committed.\n- Throws `DiscountLimitReachedException::perUser` and rolls back when the discount is restricted to one use per customer and the customer has already redeemed it.\n- Snapshots `discount_id`, `discount_code`, `discount_type`, `discount_value_at_apply` and `discount_currency_code` onto the `orders` table for resilience against later discount edits or deletions.\n\n`DiscountValidator` was updated to perform the same Order-based per-user check at cart-apply time so the rejection is surfaced before checkout.\n\nUpgrade via:\n\n`composer require shopper/cart:^2.8 shopper/core:^2.8`\n`php artisan migrate`\n\n## Workarounds\n\nNone. Upgrade to `v2.8.0`.\n\n## Resources\n\n- Issue: https://github.com/shopperlabs/shopper/issues/510\n- Pull request: https://github.com/shopperlabs/shopper/pull/511\n- CWE-362 Concurrent Execution using Shared Resource with Improper Synchronization",
"id": "GHSA-9rh9-hf3w-9fgg",
"modified": "2026-06-08T20:07:26Z",
"published": "2026-05-18T16:37:20Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/shopperlabs/shopper/security/advisories/GHSA-9rh9-hf3w-9fgg"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-47741"
},
{
"type": "WEB",
"url": "https://github.com/shopperlabs/shopper/issues/510"
},
{
"type": "WEB",
"url": "https://github.com/shopperlabs/shopper/pull/511"
},
{
"type": "WEB",
"url": "https://github.com/shopperlabs/shopper/commit/fcd0c5920588702df5b874f432b1042abd77a50b"
},
{
"type": "PACKAGE",
"url": "https://github.com/shopperlabs/shopper"
},
{
"type": "WEB",
"url": "https://github.com/shopperlabs/shopper/releases/tag/v2.8.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "shopper/framework: Race condition on Discount.usage_limit allows silent over-redemption"
}
Mitigation
In languages that support it, use synchronization primitives. Only wrap these around critical code to minimize the impact on performance.
Mitigation
Use thread-safe capabilities such as the data access abstraction in Spring.
Mitigation
- Minimize the usage of shared resources in order to remove as much complexity as possible from the control flow and to reduce the likelihood of unexpected conditions occurring.
- Additionally, this will minimize the amount of synchronization necessary and may even help to reduce the likelihood of a denial of service where an attacker may be able to repeatedly trigger a critical section (CWE-400).
Mitigation
When using multithreading and operating on shared variables, only use thread-safe functions.
Mitigation
Use atomic operations on shared variables. Be wary of innocent-looking constructs such as "x++". This may appear atomic at the code layer, but it is actually non-atomic at the instruction layer, since it involves a read, followed by a computation, followed by a write.
Mitigation
Use a mutex if available, but be sure to avoid related weaknesses such as CWE-412.
Mitigation
Avoid double-checked locking (CWE-609) and other implementation errors that arise when trying to avoid the overhead of synchronization.
Mitigation
Disable interrupts or signals over critical parts of the code, but also make sure that the code does not go into a large or infinite loop.
Mitigation
Use the volatile type modifier for critical variables to avoid unexpected compiler optimization or reordering. This does not necessarily solve the synchronization problem, but it can help.
Mitigation MIT-17
Strategy: Environment Hardening
Run your code using the lowest privileges that are required to accomplish the necessary tasks [REF-76]. If possible, create isolated accounts with limited privileges that are only used for a single task. That way, a successful attack will not immediately give the attacker access to the rest of the software or its environment. For example, database applications rarely need to run as the database administrator, especially in day-to-day operations.
CAPEC-26: Leveraging Race Conditions
The adversary targets a race condition occurring when multiple processes access and manipulate the same resource concurrently, and the outcome of the execution depends on the particular order in which the access takes place. The adversary can leverage a race condition by "running the race", modifying the resource and modifying the normal execution flow. For instance, a race condition can occur while accessing a file: the adversary can trick the system by replacing the original file with their version and cause the system to read the malicious file.
CAPEC-29: Leveraging Time-of-Check and Time-of-Use (TOCTOU) Race Conditions
This attack targets a race condition occurring between the time of check (state) for a resource and the time of use of a resource. A typical example is file access. The adversary can leverage a file access race condition by "running the race", meaning that they would modify the resource between the first time the target program accesses the file and the time the target program uses the file. During that period of time, the adversary could replace or modify the file, causing the application to behave unexpectedly.