Common Weakness Enumeration

CWE-362

Allowed-with-Review

Concurrent 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.

3216 vulnerabilities reference this CWE, most recent first.

GHSA-37XG-V5FF-WMH2

Vulnerability from github – Published: 2026-07-30 03:31 – Updated: 2026-07-30 18:31
VLAI
Details

Race in Downloads in Google Chrome on Mac prior to 151.0.7922.72 allowed a remote attacker who had compromised the renderer process to potentially perform a sandbox escape via a crafted HTML page. (Chromium security severity: High)

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-17711"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-362"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-07-30T01:16:33Z",
    "severity": "CRITICAL"
  },
  "details": "Race in Downloads in Google Chrome on Mac prior to 151.0.7922.72 allowed a remote attacker who had compromised the renderer process to potentially perform a sandbox escape via a crafted HTML page. (Chromium security severity: High)",
  "id": "GHSA-37xg-v5ff-wmh2",
  "modified": "2026-07-30T18:31:28Z",
  "published": "2026-07-30T03:31:10Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-17711"
    },
    {
      "type": "WEB",
      "url": "https://chromereleases.googleblog.com/2026/07/stable-channel-update-for-desktop_0887107924.html"
    },
    {
      "type": "WEB",
      "url": "https://issues.chromium.org/issues/519996040"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-37XV-HHG6-7Q67

Vulnerability from github – Published: 2022-07-07 00:00 – Updated: 2022-07-15 00:00
VLAI
Details

In TEEI driver, there is a possible use after free due to a race condition. This could lead to local escalation of privilege with System execution privileges needed. User interaction is not needed for exploitation. Patch ID: ALPS06641388; Issue ID: ALPS06641388.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-21773"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-362"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2022-07-06T14:15:00Z",
    "severity": "MODERATE"
  },
  "details": "In TEEI driver, there is a possible use after free due to a race condition. This could lead to local escalation of privilege with System execution privileges needed. User interaction is not needed for exploitation. Patch ID: ALPS06641388; Issue ID: ALPS06641388.",
  "id": "GHSA-37xv-hhg6-7q67",
  "modified": "2022-07-15T00:00:24Z",
  "published": "2022-07-07T00:00:25Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-21773"
    },
    {
      "type": "WEB",
      "url": "https://corp.mediatek.com/product-security-bulletin/July-2022"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-3854-FX7W-XM5R

Vulnerability from github – Published: 2026-09-08 21:34 – Updated: 2026-09-10 18:31
VLAI
Details

In multiple locations, there is a possible use after free due to a race condition. This could lead to remote code execution with no additional execution privileges needed. User interaction is not needed for exploitation.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-28604"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-362"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-09-08T19:17:52Z",
    "severity": "HIGH"
  },
  "details": "In multiple locations, there is a possible use after free due to a race condition. This could lead to remote code execution with no additional execution privileges needed. User interaction is not needed for exploitation.",
  "id": "GHSA-3854-fx7w-xm5r",
  "modified": "2026-09-10T18:31:32Z",
  "published": "2026-09-08T21:34:14Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-28604"
    },
    {
      "type": "WEB",
      "url": "https://source.android.com/docs/security/bulletin/2026/2026-09-01"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-38C9-7H78-X2JX

Vulnerability from github – Published: 2026-07-20 18:32 – Updated: 2026-07-27 06:30
VLAI
Details

In the Linux kernel, the following vulnerability has been resolved:

netfilter: ipset: fix race between dump and ip_set_list resize

The release path of ip_set_dump_do() and ip_set_dump_done() read inst->ip_set_list via ip_set_ref_netlink(), a plain rcu_dereference_raw() of the array pointer. These run from netlink_recvmsg() without the nfnl mutex and without an RCU read-side critical section.

A concurrent ip_set_create() can grow the array: it publishes the new array, calls synchronize_net() and then kvfree()s the old one. Since the dump paths read the array outside any RCU reader, synchronize_net() does not wait for them and the old array can be freed while they still index into it, causing a use-after-free.

The dumped set itself stays pinned via set->ref_netlink, so only the array load needs protecting. Take rcu_read_lock() around it, matching ip_set_get_byname() and __ip_set_put_byindex().

BUG: KASAN: slab-use-after-free in ip_set_dump_do (net/netfilter/ipset/ip_set_core.c:1697) Read of size 8 at addr ffff88800b5c4018 by task exploit/150 Call Trace: ... kasan_report (mm/kasan/report.c:595) ip_set_dump_do (net/netfilter/ipset/ip_set_core.c:1697) netlink_dump (net/netlink/af_netlink.c:2325) netlink_recvmsg (net/netlink/af_netlink.c:1976) sock_recvmsg (net/socket.c:1159) __sys_recvfrom (net/socket.c:2315) ... Oops: general protection fault, probably for non-canonical address ... KASAN NOPTI KASAN: maybe wild-memory-access in range [0x02d6...d0-0x02d6...d7] RIP: 0010:ip_set_dump_do (net/netfilter/ipset/ip_set_core.c:1698) Kernel panic - not syncing: Fatal exception

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-64189"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-362"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-07-20T17:18:21Z",
    "severity": "HIGH"
  },
  "details": "In the Linux kernel, the following vulnerability has been resolved:\n\nnetfilter: ipset: fix race between dump and ip_set_list resize\n\nThe release path of ip_set_dump_do() and ip_set_dump_done() read\ninst-\u003eip_set_list via ip_set_ref_netlink(), a plain rcu_dereference_raw()\nof the array pointer. These run from netlink_recvmsg() without the nfnl\nmutex and without an RCU read-side critical section.\n\nA concurrent ip_set_create() can grow the array: it publishes the new\narray, calls synchronize_net() and then kvfree()s the old one. Since the\ndump paths read the array outside any RCU reader, synchronize_net() does\nnot wait for them and the old array can be freed while they still index\ninto it, causing a use-after-free.\n\nThe dumped set itself stays pinned via set-\u003eref_netlink, so only the\narray load needs protecting. Take rcu_read_lock() around it, matching\nip_set_get_byname() and __ip_set_put_byindex().\n\n  BUG: KASAN: slab-use-after-free in ip_set_dump_do (net/netfilter/ipset/ip_set_core.c:1697)\n  Read of size 8 at addr ffff88800b5c4018 by task exploit/150\n  Call Trace:\n   ...\n   kasan_report (mm/kasan/report.c:595)\n   ip_set_dump_do (net/netfilter/ipset/ip_set_core.c:1697)\n   netlink_dump (net/netlink/af_netlink.c:2325)\n   netlink_recvmsg (net/netlink/af_netlink.c:1976)\n   sock_recvmsg (net/socket.c:1159)\n   __sys_recvfrom (net/socket.c:2315)\n   ...\n  Oops: general protection fault, probably for non-canonical address ... KASAN NOPTI\n  KASAN: maybe wild-memory-access in range [0x02d6...d0-0x02d6...d7]\n  RIP: 0010:ip_set_dump_do (net/netfilter/ipset/ip_set_core.c:1698)\n  Kernel panic - not syncing: Fatal exception",
  "id": "GHSA-38c9-7h78-x2jx",
  "modified": "2026-07-27T06:30:30Z",
  "published": "2026-07-20T18:32:33Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-64189"
    },
    {
      "type": "WEB",
      "url": "https://git.kernel.org/stable/c/1bc67c3fc98e9fc07032cc56afcdbc690c47d11e"
    },
    {
      "type": "WEB",
      "url": "https://git.kernel.org/stable/c/7cd9103283b26b917360ec99d7d2f2d761bcf1ab"
    },
    {
      "type": "WEB",
      "url": "https://git.kernel.org/stable/c/81d54c766337b923eec26da0a13406760b091093"
    },
    {
      "type": "WEB",
      "url": "https://git.kernel.org/stable/c/96fbafc20ebd9a613736c2998b89c539fe3042f5"
    },
    {
      "type": "WEB",
      "url": "https://git.kernel.org/stable/c/a7a299277959683204d73333c32c092fd69327d4"
    },
    {
      "type": "WEB",
      "url": "https://git.kernel.org/stable/c/e8a9976b61f1bc4aa7fd25fa26726dfdf2adf710"
    },
    {
      "type": "WEB",
      "url": "https://git.kernel.org/stable/c/e8ee198bbc04a32d336e79160fde980e0235b39f"
    },
    {
      "type": "WEB",
      "url": "https://git.kernel.org/stable/c/ff86ea9b7fdf70564e60436fbee68c96bc459943"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-38CC-GG86-24CH

Vulnerability from github – Published: 2026-04-14 18:30 – Updated: 2026-04-14 18:30
VLAI
Details

Concurrent execution using shared resource with improper synchronization ('race condition') in Windows SSDP Service allows an authorized attacker to elevate privileges locally.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-32068"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-362"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-04-14T18:17:06Z",
    "severity": "HIGH"
  },
  "details": "Concurrent execution using shared resource with improper synchronization (\u0027race condition\u0027) in Windows SSDP Service allows an authorized attacker to elevate privileges locally.",
  "id": "GHSA-38cc-gg86-24ch",
  "modified": "2026-04-14T18:30:39Z",
  "published": "2026-04-14T18:30:39Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-32068"
    },
    {
      "type": "WEB",
      "url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-32068"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-38F7-945M-QR2G

Vulnerability from github – Published: 2026-03-20 20:34 – Updated: 2026-03-25 18:11
VLAI
Summary
Effect `AsyncLocalStorage` context lost/contaminated inside Effect fibers under concurrent load with RPC
Details

Versions

  • effect: 3.19.15
  • @effect/rpc: 0.72.1
  • @effect/platform: 0.94.2
  • Node.js: v22.20.0
  • Vercel runtime with Fluid compute
  • Next.js: 16 (App Router)
  • @clerk/nextjs: 6.x

Root cause

Effect's MixedScheduler batches fiber continuations and drains them inside a single microtask or timer callback. The AsyncLocalStorage context active during that callback belongs to whichever request first triggered the scheduler's drain cycle — not the request that owns the fiber being resumed.

Detailed mechanism

1. Scheduler batching (effect/src/Scheduler.ts, MixedScheduler)

// MixedScheduler.starve() — called once when first task is scheduled
private starve(depth = 0) {
  if (depth >= this.maxNextTickBeforeTimer) {
    setTimeout(() => this.starveInternal(0), 0)       // timer queue
  } else {
    Promise.resolve(void 0).then(() => this.starveInternal(depth + 1)) // microtask queue
  }
}

// MixedScheduler.starveInternal() — drains ALL accumulated tasks in one call
private starveInternal(depth: number) {
  const tasks = this.tasks.buckets
  this.tasks.buckets = []
  for (const [_, toRun] of tasks) {
    for (let i = 0; i < toRun.length; i++) {
      toRun[i]()  // ← Every fiber continuation runs in the SAME ALS context
    }
  }
  // ...
}

scheduleTask only calls starve() when running is false. Subsequent tasks accumulate in this.tasks until starveInternal drains them all. The Promise.then() (or setTimeout) callback inherits the ALS context from whichever call site created it — i.e., whichever request's fiber first set running = true.

Result: Under concurrent load, fiber continuations from Request A and Request B execute inside the same starveInternal call, sharing a single ALS context. If Request A triggered starve(), then Request B's fiber reads Request A's ALS context.

2. toWebHandlerRuntime does not propagate ALS (@effect/platform/src/HttpApp.ts:211-240)

export const toWebHandlerRuntime = <R>(runtime: Runtime.Runtime<R>) => {
  const httpRuntime: Types.Mutable<Runtime.Runtime<R>> = Runtime.make(runtime)
  const run = Runtime.runFork(httpRuntime)
  return <E>(self: Default<E, R | Scope.Scope>, middleware?) => {
    return (request: Request, context?): Promise<Response> =>
      new Promise((resolve) => {
        // Per-request Effect context is correctly set via contextMap:
        const contextMap = new Map<string, any>(runtime.context.unsafeMap)
        const httpServerRequest = ServerRequest.fromWeb(request)
        contextMap.set(ServerRequest.HttpServerRequest.key, httpServerRequest)
        httpRuntime.context = Context.unsafeMake(contextMap)

        // But the fiber is forked without any ALS propagation:
        const fiber = run(httpApp as any)  // ← ALS context is NOT captured or restored
      })
  }
}

Effect's own Context (containing HttpServerRequest) is correctly set per-request. But the Node.js ALS context — which frameworks like Next.js, Clerk, and OpenTelemetry rely on — is not captured at fork time or restored when the fiber's continuations execute.

3. The dangerous pattern this enables

// RPC handler — runs inside an Effect fiber
const handler = Effect.gen(function*() {
  // This calls auth() from @clerk/nextjs/server, which reads from ALS
  const { userId } = yield* Effect.tryPromise({
    try: async () => auth(),  // ← may read WRONG user's session
    catch: () => new UnauthorizedError({ message: "Auth failed" })
  })
  return yield* repository.getUser(userId)
})

The async () => auth() thunk executes when the fiber continuation is scheduled by MixedScheduler. At that point, the ALS context belongs to an arbitrary concurrent request.

Reproduction scenario

Timeline (two concurrent requests to the same toWebHandler endpoint):

T0: Request A arrives → POST handler → webHandler(requestA)
    → Promise executor runs synchronously
    → httpRuntime.context set to A's context
    → fiber A forked, runs first ops synchronously
    → fiber A yields (e.g., at Effect.tryPromise boundary)
    → scheduler.scheduleTask(fiberA_continuation)
    → running=false → starve() called → Promise.resolve().then(drain)
       ↑ ALS context captured = Request A's context

T1: Request B arrives → POST handler → webHandler(requestB)
    → Promise executor runs synchronously
    → httpRuntime.context set to B's context
    → fiber B forked, runs first ops synchronously
    → fiber B yields
    → scheduler.scheduleTask(fiberB_continuation)
    → running=true → task queued, no new starve()

T2: Microtask fires → starveInternal() runs
    → Drains fiberA_continuation → auth() reads ALS → gets A's context ✓
    → Drains fiberB_continuation → auth() reads ALS → gets A's context ✗ ← WRONG USER

Minimal reproduction

import { AsyncLocalStorage } from "node:async_hooks"
import { Effect, Layer } from "effect"
import { RpcServer, RpcSerialization, Rpc, RpcGroup } from "@effect/rpc"
import { HttpServer } from "@effect/platform"
import * as S from "effect/Schema"

// Simulate a framework's ALS (like Next.js / Clerk)
const requestStore = new AsyncLocalStorage<{ userId: string }>()

class GetUser extends Rpc.make("GetUser", {
  success: S.Struct({ userId: S.String, alsUserId: S.String }),
  failure: S.Never,
  payload: {}
}) {}

const MyRpc = RpcGroup.make("MyRpc").add(GetUser)

const MyRpcLive = MyRpc.toLayer(
  RpcGroup.toHandlers(MyRpc, {
    GetUser: () =>
      Effect.gen(function*() {
        // Simulate calling an ALS-dependent API inside an Effect fiber
        const alsResult = yield* Effect.tryPromise({
          try: async () => {
            const store = requestStore.getStore()
            return store?.userId ?? "NONE"
          },
          catch: () => { throw new Error("impossible") }
        })
        return { userId: "from-effect-context", alsUserId: alsResult }
      })
  })
)

const RpcLayer = MyRpcLive.pipe(
  Layer.provideMerge(RpcSerialization.layerJson),
  Layer.provideMerge(HttpServer.layerContext)
)

const { handler } = RpcServer.toWebHandler(MyRpc, { layer: RpcLayer })

// Simulate two concurrent requests with different ALS contexts
async function main() {
  const results = await Promise.all([
    requestStore.run({ userId: "user-A" }, () => handler(makeRpcRequest("GetUser"))),
    requestStore.run({ userId: "user-B" }, () => handler(makeRpcRequest("GetUser"))),
  ])

  // Parse responses and check if alsUserId matches the expected user
  // Under the bug: both responses may show "user-A" (or one shows the other's)
  for (const res of results) {
    console.log(await res.json())
  }
}

Impact

Symptom Severity
auth() returns wrong user's session Critical — authentication bypass
cookies() / headers() from Next.js read wrong request High — data leakage
OpenTelemetry trace context crosses requests Medium — incorrect traces
Works locally, fails in production Hard to diagnose — only manifests under concurrent load

Workaround

Capture ALS-dependent values before entering the Effect runtime and pass them via Effect's own context system:

// In the route handler — OUTSIDE the Effect fiber (ALS is correct here)
export const POST = async (request: Request) => {
  const { userId } = await auth()  // ← Safe: still in Next.js ALS context

  // Inject into request headers or use the `context` parameter
  const headers = new Headers(request.headers)
  headers.set("x-clerk-auth-user-id", userId ?? "")
  const enrichedRequest = new Request(request.url, {
    method: request.method,
    headers,
    body: request.body,
    duplex: "half" as any,
  })

  return webHandler(enrichedRequest)
}

// In Effect handlers — read from HttpServerRequest headers instead of calling auth()
const getAuthenticatedUserId = Effect.gen(function*() {
  const req = yield* HttpServerRequest.HttpServerRequest
  const userId = req.headers["x-clerk-auth-user-id"]
  if (!userId) return yield* Effect.fail(new UnauthorizedError({ message: "Auth required" }))
  return userId
})

Suggested fix (for Effect maintainers)

Option A: Propagate ALS context through the scheduler

Capture the AsyncLocalStorage snapshot when a fiber continuation is scheduled, and restore it when the continuation executes:

// In MixedScheduler or the fiber runtime
import { AsyncLocalStorage } from "node:async_hooks"

scheduleTask(task: Task, priority: number) {
  // Capture current ALS context
  const snapshot = AsyncLocalStorage.snapshot()
  this.tasks.scheduleTask(() => snapshot(task), priority)
  // ...
}

AsyncLocalStorage.snapshot() (Node.js 20.5+) returns a function that, when called, restores the ALS context from the point of capture. This ensures each fiber continuation runs with its originating request's ALS context.

Trade-off: Adds one closure allocation per scheduled task. Could be opt-in via a FiberRef or scheduler option.

Option B: Capture ALS at runFork and restore per fiber step

When Runtime.runFork is called, capture the ALS snapshot and associate it with the fiber. Before each fiber step (in the fiber runtime's evaluateEffect loop), restore the snapshot.

Trade-off: More invasive but provides correct ALS propagation for the fiber's entire lifetime, including across flatMap chains and Effect.tryPromise thunks.

Option C: Document the limitation and provide a context injection API

If ALS propagation is intentionally not supported, document this prominently and provide a first-class API for toWebHandler to accept per-request context. The existing context?: Context.Context<never> parameter on the handler function partially addresses this, but it requires callers to know about the issue and manually extract values before entering Effect.

Related

  • Node.js AsyncLocalStorage docs: https://nodejs.org/api/async_context.html
  • AsyncLocalStorage.snapshot(): https://nodejs.org/api/async_context.html#static-method-asynclocalstoragesnapshot
  • Next.js uses ALS for cookies(), headers(), auth() in App Router
  • Similar issue pattern in other fiber-based runtimes (e.g., ZIO has FiberRef propagation for this)

POC replica of my setup

// Create web handler from Effect RPC
// sharedMemoMap ensures all RPC routes share the same connection pool
const { handler: webHandler, dispose } = RpcServer.toWebHandler(DemoRpc, {
  layer: RpcLayer,
  memoMap: sharedMemoMap,
});

/**
 * POST /api/rpc/demo
 */
export const POST = async (request: Request) => {
  return webHandler(request);
};

registerDispose(dispose);

Used util functions


/**
 * Creates a dispose registry that collects dispose callbacks and runs them
 * when `runAll` is invoked. Handles both sync and async dispose functions,
 * catching errors to prevent one failing dispose from breaking others.
 *
 * @internal Exported for testing — use `registerDispose` in application code.
 */
export const makeDisposeRegistry = () => {
  const disposeFns: Array<() => void | Promise<void>> = []

  const runAll = () => {
    for (const fn of disposeFns) {
      try {
        const result = fn()
        if (result && typeof result.then === "function") {
          result.then(undefined, (err: unknown) => console.error("Dispose error:", err))
        }
      } catch (err) {
        console.error("Dispose error:", err)
      }
    }
  }

  const register = (dispose: () => void | Promise<void>) => {
    disposeFns.push(dispose)
  }

  return { register, runAll }
}

export const registerDispose: (dispose: () => void | Promise<void>) => void = globalValue(
  Symbol.for("@global/RegisterDispose"),
  () => {
    const registry = makeDisposeRegistry()

    if (typeof process !== "undefined") {
      process.once("beforeExit", registry.runAll)
    }

    return registry.register
  }
)

The actual effect that was run within the RPC context that the bug was found

``` export const getAuthenticatedUserId: Effect.Effect = Effect.gen(function() { const authResult = yield Effect.tryPromise({ try: async () => auth(), catch: () => new UnauthorizedError({ message: "Failed to get auth session" }) })

if (!authResult.userId) {
  return yield* Effect.fail(
    new UnauthorizedError({
      message: "Authentication required"
    })
  )
}

return authResult.userId

}) ```

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "effect"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "3.20.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-32887"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-362"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-20T20:34:06Z",
    "nvd_published_at": "2026-03-20T22:16:27Z",
    "severity": "HIGH"
  },
  "details": "## Versions\n\n- `effect`: 3.19.15\n- `@effect/rpc`: 0.72.1\n- `@effect/platform`: 0.94.2\n- Node.js: v22.20.0\n- Vercel runtime with Fluid compute\n- Next.js: 16 (App Router)\n- `@clerk/nextjs`: 6.x\n\n## Root cause\n\nEffect\u0027s `MixedScheduler` batches fiber continuations and drains them inside a **single** microtask or timer callback. The `AsyncLocalStorage` context active during that callback belongs to whichever request first triggered the scheduler\u0027s drain cycle \u2014 **not** the request that owns the fiber being resumed.\n\n### Detailed mechanism\n\n#### 1. Scheduler batching (`effect/src/Scheduler.ts`, `MixedScheduler`)\n\n```typescript\n// MixedScheduler.starve() \u2014 called once when first task is scheduled\nprivate starve(depth = 0) {\n  if (depth \u003e= this.maxNextTickBeforeTimer) {\n    setTimeout(() =\u003e this.starveInternal(0), 0)       // timer queue\n  } else {\n    Promise.resolve(void 0).then(() =\u003e this.starveInternal(depth + 1)) // microtask queue\n  }\n}\n\n// MixedScheduler.starveInternal() \u2014 drains ALL accumulated tasks in one call\nprivate starveInternal(depth: number) {\n  const tasks = this.tasks.buckets\n  this.tasks.buckets = []\n  for (const [_, toRun] of tasks) {\n    for (let i = 0; i \u003c toRun.length; i++) {\n      toRun[i]()  // \u2190 Every fiber continuation runs in the SAME ALS context\n    }\n  }\n  // ...\n}\n```\n\n`scheduleTask` only calls `starve()` when `running` is `false`. Subsequent tasks accumulate in `this.tasks` until `starveInternal` drains them all. The `Promise.then()` (or `setTimeout`) callback inherits the ALS context from whichever call site created it \u2014 i.e., whichever request\u0027s fiber first set `running = true`.\n\n**Result:** Under concurrent load, fiber continuations from Request A and Request B execute inside the same `starveInternal` call, sharing a single ALS context. If Request A triggered `starve()`, then Request B\u0027s fiber reads Request A\u0027s ALS context.\n\n#### 2. `toWebHandlerRuntime` does not propagate ALS (`@effect/platform/src/HttpApp.ts:211-240`)\n\n```typescript\nexport const toWebHandlerRuntime = \u003cR\u003e(runtime: Runtime.Runtime\u003cR\u003e) =\u003e {\n  const httpRuntime: Types.Mutable\u003cRuntime.Runtime\u003cR\u003e\u003e = Runtime.make(runtime)\n  const run = Runtime.runFork(httpRuntime)\n  return \u003cE\u003e(self: Default\u003cE, R | Scope.Scope\u003e, middleware?) =\u003e {\n    return (request: Request, context?): Promise\u003cResponse\u003e =\u003e\n      new Promise((resolve) =\u003e {\n        // Per-request Effect context is correctly set via contextMap:\n        const contextMap = new Map\u003cstring, any\u003e(runtime.context.unsafeMap)\n        const httpServerRequest = ServerRequest.fromWeb(request)\n        contextMap.set(ServerRequest.HttpServerRequest.key, httpServerRequest)\n        httpRuntime.context = Context.unsafeMake(contextMap)\n\n        // But the fiber is forked without any ALS propagation:\n        const fiber = run(httpApp as any)  // \u2190 ALS context is NOT captured or restored\n      })\n  }\n}\n```\n\nEffect\u0027s own `Context` (containing `HttpServerRequest`) is correctly set per-request. But the **Node.js ALS context** \u2014 which frameworks like Next.js, Clerk, and OpenTelemetry rely on \u2014 is not captured at fork time or restored when the fiber\u0027s continuations execute.\n\n#### 3. The dangerous pattern this enables\n\n```typescript\n// RPC handler \u2014 runs inside an Effect fiber\nconst handler = Effect.gen(function*() {\n  // This calls auth() from @clerk/nextjs/server, which reads from ALS\n  const { userId } = yield* Effect.tryPromise({\n    try: async () =\u003e auth(),  // \u2190 may read WRONG user\u0027s session\n    catch: () =\u003e new UnauthorizedError({ message: \"Auth failed\" })\n  })\n  return yield* repository.getUser(userId)\n})\n```\n\nThe `async () =\u003e auth()` thunk executes when the fiber continuation is scheduled by `MixedScheduler`. At that point, the ALS context belongs to an arbitrary concurrent request.\n\n## Reproduction scenario\n\n```\nTimeline (two concurrent requests to the same toWebHandler endpoint):\n\nT0: Request A arrives \u2192 POST handler \u2192 webHandler(requestA)\n    \u2192 Promise executor runs synchronously\n    \u2192 httpRuntime.context set to A\u0027s context\n    \u2192 fiber A forked, runs first ops synchronously\n    \u2192 fiber A yields (e.g., at Effect.tryPromise boundary)\n    \u2192 scheduler.scheduleTask(fiberA_continuation)\n    \u2192 running=false \u2192 starve() called \u2192 Promise.resolve().then(drain)\n       \u2191 ALS context captured = Request A\u0027s context\n\nT1: Request B arrives \u2192 POST handler \u2192 webHandler(requestB)\n    \u2192 Promise executor runs synchronously\n    \u2192 httpRuntime.context set to B\u0027s context\n    \u2192 fiber B forked, runs first ops synchronously\n    \u2192 fiber B yields\n    \u2192 scheduler.scheduleTask(fiberB_continuation)\n    \u2192 running=true \u2192 task queued, no new starve()\n\nT2: Microtask fires \u2192 starveInternal() runs\n    \u2192 Drains fiberA_continuation \u2192 auth() reads ALS \u2192 gets A\u0027s context \u2713\n    \u2192 Drains fiberB_continuation \u2192 auth() reads ALS \u2192 gets A\u0027s context \u2717 \u2190 WRONG USER\n```\n\n## Minimal reproduction\n\n```typescript\nimport { AsyncLocalStorage } from \"node:async_hooks\"\nimport { Effect, Layer } from \"effect\"\nimport { RpcServer, RpcSerialization, Rpc, RpcGroup } from \"@effect/rpc\"\nimport { HttpServer } from \"@effect/platform\"\nimport * as S from \"effect/Schema\"\n\n// Simulate a framework\u0027s ALS (like Next.js / Clerk)\nconst requestStore = new AsyncLocalStorage\u003c{ userId: string }\u003e()\n\nclass GetUser extends Rpc.make(\"GetUser\", {\n  success: S.Struct({ userId: S.String, alsUserId: S.String }),\n  failure: S.Never,\n  payload: {}\n}) {}\n\nconst MyRpc = RpcGroup.make(\"MyRpc\").add(GetUser)\n\nconst MyRpcLive = MyRpc.toLayer(\n  RpcGroup.toHandlers(MyRpc, {\n    GetUser: () =\u003e\n      Effect.gen(function*() {\n        // Simulate calling an ALS-dependent API inside an Effect fiber\n        const alsResult = yield* Effect.tryPromise({\n          try: async () =\u003e {\n            const store = requestStore.getStore()\n            return store?.userId ?? \"NONE\"\n          },\n          catch: () =\u003e { throw new Error(\"impossible\") }\n        })\n        return { userId: \"from-effect-context\", alsUserId: alsResult }\n      })\n  })\n)\n\nconst RpcLayer = MyRpcLive.pipe(\n  Layer.provideMerge(RpcSerialization.layerJson),\n  Layer.provideMerge(HttpServer.layerContext)\n)\n\nconst { handler } = RpcServer.toWebHandler(MyRpc, { layer: RpcLayer })\n\n// Simulate two concurrent requests with different ALS contexts\nasync function main() {\n  const results = await Promise.all([\n    requestStore.run({ userId: \"user-A\" }, () =\u003e handler(makeRpcRequest(\"GetUser\"))),\n    requestStore.run({ userId: \"user-B\" }, () =\u003e handler(makeRpcRequest(\"GetUser\"))),\n  ])\n\n  // Parse responses and check if alsUserId matches the expected user\n  // Under the bug: both responses may show \"user-A\" (or one shows the other\u0027s)\n  for (const res of results) {\n    console.log(await res.json())\n  }\n}\n```\n\n## Impact\n\n| Symptom | Severity |\n|---------|----------|\n| `auth()` returns wrong user\u0027s session | **Critical** \u2014 authentication bypass |\n| `cookies()` / `headers()` from Next.js read wrong request | **High** \u2014 data leakage |\n| OpenTelemetry trace context crosses requests | **Medium** \u2014 incorrect traces |\n| Works locally, fails in production | Hard to diagnose \u2014 only manifests under concurrent load |\n\n## Workaround\n\nCapture ALS-dependent values **before** entering the Effect runtime and pass them via Effect\u0027s own context system:\n\n```typescript\n// In the route handler \u2014 OUTSIDE the Effect fiber (ALS is correct here)\nexport const POST = async (request: Request) =\u003e {\n  const { userId } = await auth()  // \u2190 Safe: still in Next.js ALS context\n\n  // Inject into request headers or use the `context` parameter\n  const headers = new Headers(request.headers)\n  headers.set(\"x-clerk-auth-user-id\", userId ?? \"\")\n  const enrichedRequest = new Request(request.url, {\n    method: request.method,\n    headers,\n    body: request.body,\n    duplex: \"half\" as any,\n  })\n\n  return webHandler(enrichedRequest)\n}\n\n// In Effect handlers \u2014 read from HttpServerRequest headers instead of calling auth()\nconst getAuthenticatedUserId = Effect.gen(function*() {\n  const req = yield* HttpServerRequest.HttpServerRequest\n  const userId = req.headers[\"x-clerk-auth-user-id\"]\n  if (!userId) return yield* Effect.fail(new UnauthorizedError({ message: \"Auth required\" }))\n  return userId\n})\n```\n\n## Suggested fix (for Effect maintainers)\n\n### Option A: Propagate ALS context through the scheduler\n\nCapture the `AsyncLocalStorage` snapshot when a fiber continuation is scheduled, and restore it when the continuation executes:\n\n```typescript\n// In MixedScheduler or the fiber runtime\nimport { AsyncLocalStorage } from \"node:async_hooks\"\n\nscheduleTask(task: Task, priority: number) {\n  // Capture current ALS context\n  const snapshot = AsyncLocalStorage.snapshot()\n  this.tasks.scheduleTask(() =\u003e snapshot(task), priority)\n  // ...\n}\n```\n\n`AsyncLocalStorage.snapshot()` (Node.js 20.5+) returns a function that, when called, restores the ALS context from the point of capture. This ensures each fiber continuation runs with its originating request\u0027s ALS context.\n\n**Trade-off:** Adds one closure allocation per scheduled task. Could be opt-in via a `FiberRef` or scheduler option.\n\n### Option B: Capture ALS at `runFork` and restore per fiber step\n\nWhen `Runtime.runFork` is called, capture the ALS snapshot and associate it with the fiber. Before each fiber step (in the fiber runtime\u0027s `evaluateEffect` loop), restore the snapshot.\n\n**Trade-off:** More invasive but provides correct ALS propagation for the fiber\u0027s entire lifetime, including across `flatMap` chains and `Effect.tryPromise` thunks.\n\n### Option C: Document the limitation and provide a `context` injection API\n\nIf ALS propagation is intentionally not supported, document this prominently and provide a first-class API for `toWebHandler` to accept per-request context. The existing `context?: Context.Context\u003cnever\u003e` parameter on the handler function partially addresses this, but it requires callers to know about the issue and manually extract values before entering Effect.\n\n## Related\n\n- Node.js `AsyncLocalStorage` docs: https://nodejs.org/api/async_context.html\n- `AsyncLocalStorage.snapshot()`: https://nodejs.org/api/async_context.html#static-method-asynclocalstoragesnapshot\n- Next.js uses ALS for `cookies()`, `headers()`, `auth()` in App Router\n- Similar issue pattern in other fiber-based runtimes (e.g., ZIO has `FiberRef` propagation for this)\n\n\n## POC replica of my setup\n\n```\n// Create web handler from Effect RPC\n// sharedMemoMap ensures all RPC routes share the same connection pool\nconst { handler: webHandler, dispose } = RpcServer.toWebHandler(DemoRpc, {\n  layer: RpcLayer,\n  memoMap: sharedMemoMap,\n});\n\n/**\n * POST /api/rpc/demo\n */\nexport const POST = async (request: Request) =\u003e {\n  return webHandler(request);\n};\n\nregisterDispose(dispose);\n```\n\n### Used util functions\n\n```\n\n/**\n * Creates a dispose registry that collects dispose callbacks and runs them\n * when `runAll` is invoked. Handles both sync and async dispose functions,\n * catching errors to prevent one failing dispose from breaking others.\n *\n * @internal Exported for testing \u2014 use `registerDispose` in application code.\n */\nexport const makeDisposeRegistry = () =\u003e {\n  const disposeFns: Array\u003c() =\u003e void | Promise\u003cvoid\u003e\u003e = []\n\n  const runAll = () =\u003e {\n    for (const fn of disposeFns) {\n      try {\n        const result = fn()\n        if (result \u0026\u0026 typeof result.then === \"function\") {\n          result.then(undefined, (err: unknown) =\u003e console.error(\"Dispose error:\", err))\n        }\n      } catch (err) {\n        console.error(\"Dispose error:\", err)\n      }\n    }\n  }\n\n  const register = (dispose: () =\u003e void | Promise\u003cvoid\u003e) =\u003e {\n    disposeFns.push(dispose)\n  }\n\n  return { register, runAll }\n}\n\nexport const registerDispose: (dispose: () =\u003e void | Promise\u003cvoid\u003e) =\u003e void = globalValue(\n  Symbol.for(\"@global/RegisterDispose\"),\n  () =\u003e {\n    const registry = makeDisposeRegistry()\n\n    if (typeof process !== \"undefined\") {\n      process.once(\"beforeExit\", registry.runAll)\n    }\n\n    return registry.register\n  }\n)\n```\n\n### The actual effect that was run within the RPC context that the bug was found\n\n```\nexport const getAuthenticatedUserId: Effect.Effect\u003cstring, UnauthorizedError\u003e =\n  Effect.gen(function*() {\n    const authResult = yield* Effect.tryPromise({\n      try: async () =\u003e auth(),\n      catch: () =\u003e\n        new UnauthorizedError({\n          message: \"Failed to get auth session\"\n        })\n    })\n\n    if (!authResult.userId) {\n      return yield* Effect.fail(\n        new UnauthorizedError({\n          message: \"Authentication required\"\n        })\n      )\n    }\n\n    return authResult.userId\n  })\n ```",
  "id": "GHSA-38f7-945m-qr2g",
  "modified": "2026-03-25T18:11:18Z",
  "published": "2026-03-20T20:34:06Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/Effect-TS/effect/security/advisories/GHSA-38f7-945m-qr2g"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-32887"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/Effect-TS/effect"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Effect `AsyncLocalStorage` context lost/contaminated inside Effect fibers under concurrent load with RPC"
}

GHSA-38GP-WR3C-CQW7

Vulnerability from github – Published: 2022-05-24 16:52 – Updated: 2024-04-04 01:29
VLAI
Details

cPanel before 68.0.27 allows attackers to read root's crontab file during a short time interval upon the enabling of backups (SEC-342).

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2018-20940"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-362"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2019-08-01T17:15:00Z",
    "severity": "LOW"
  },
  "details": "cPanel before 68.0.27 allows attackers to read root\u0027s crontab file during a short time interval upon the enabling of backups (SEC-342).",
  "id": "GHSA-38gp-wr3c-cqw7",
  "modified": "2024-04-04T01:29:05Z",
  "published": "2022-05-24T16:52:10Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2018-20940"
    },
    {
      "type": "WEB",
      "url": "https://documentation.cpanel.net/display/CL/68+Change+Log"
    },
    {
      "type": "WEB",
      "url": "https://news.cpanel.com/cpanel-tsr-2018-0001-full-disclosure"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-38PP-34CQ-8XPR

Vulnerability from github – Published: 2022-05-24 17:19 – Updated: 2022-06-03 00:00
VLAI
Details

A race condition was addressed with improved state handling. This issue is fixed in iOS 13.5 and iPadOS 13.5, macOS Catalina 10.15.5, tvOS 13.4.5, watchOS 6.2.5. An application may be able to gain elevated privileges.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2020-9839"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-362"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2020-06-09T17:15:00Z",
    "severity": "MODERATE"
  },
  "details": "A race condition was addressed with improved state handling. This issue is fixed in iOS 13.5 and iPadOS 13.5, macOS Catalina 10.15.5, tvOS 13.4.5, watchOS 6.2.5. An application may be able to gain elevated privileges.",
  "id": "GHSA-38pp-34cq-8xpr",
  "modified": "2022-06-03T00:00:35Z",
  "published": "2022-05-24T17:19:44Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2020-9839"
    },
    {
      "type": "WEB",
      "url": "https://support.apple.com/HT211168"
    },
    {
      "type": "WEB",
      "url": "https://support.apple.com/HT211170"
    },
    {
      "type": "WEB",
      "url": "https://support.apple.com/HT211171"
    },
    {
      "type": "WEB",
      "url": "https://support.apple.com/HT211175"
    },
    {
      "type": "WEB",
      "url": "http://packetstormsecurity.com/files/159084/macOS-cfprefsd-Arbitrary-File-Write-Local-Privilege-Escalation.html"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-38QW-V9Q4-HM9J

Vulnerability from github – Published: 2024-08-22 06:30 – Updated: 2024-08-23 03:30
VLAI
Details

In the Linux kernel, the following vulnerability has been resolved:

configfs: fix a race in configfs_{,un}register_subsystem()

When configfs_register_subsystem() or configfs_unregister_subsystem() is executing link_group() or unlink_group(), it is possible that two processes add or delete list concurrently. Some unfortunate interleavings of them can cause kernel panic.

One of cases is: A --> B --> C --> D A <-- B <-- C <-- D

 delete list_head *B        |      delete list_head *C

--------------------------------|----------------------------------- configfs_unregister_subsystem | configfs_unregister_subsystem unlink_group | unlink_group unlink_obj | unlink_obj list_del_init | list_del_init __list_del_entry | __list_del_entry __list_del | __list_del // next == C | next->prev = prev | | next->prev = prev prev->next = next | | // prev == B | prev->next = next

Fix this by adding mutex when calling link_group() or unlink_group(), but parent configfs_subsystem is NULL when config_item is root. So I create a mutex configfs_subsystem_mutex.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-48931"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-362"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-08-22T04:15:16Z",
    "severity": "MODERATE"
  },
  "details": "In the Linux kernel, the following vulnerability has been resolved:\n\nconfigfs: fix a race in configfs_{,un}register_subsystem()\n\nWhen configfs_register_subsystem() or configfs_unregister_subsystem()\nis executing link_group() or unlink_group(),\nit is possible that two processes add or delete list concurrently.\nSome unfortunate interleavings of them can cause kernel panic.\n\nOne of cases is:\nA --\u003e B --\u003e C --\u003e D\nA \u003c-- B \u003c-- C \u003c-- D\n\n     delete list_head *B        |      delete list_head *C\n--------------------------------|-----------------------------------\nconfigfs_unregister_subsystem   |   configfs_unregister_subsystem\n  unlink_group                  |     unlink_group\n    unlink_obj                  |       unlink_obj\n      list_del_init             |         list_del_init\n        __list_del_entry        |           __list_del_entry\n          __list_del            |             __list_del\n            // next == C        |\n            next-\u003eprev = prev   |\n                                |               next-\u003eprev = prev\n            prev-\u003enext = next   |\n                                |                 // prev == B\n                                |                 prev-\u003enext = next\n\nFix this by adding mutex when calling link_group() or unlink_group(),\nbut parent configfs_subsystem is NULL when config_item is root.\nSo I create a mutex configfs_subsystem_mutex.",
  "id": "GHSA-38qw-v9q4-hm9j",
  "modified": "2024-08-23T03:30:59Z",
  "published": "2024-08-22T06:30:29Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-48931"
    },
    {
      "type": "WEB",
      "url": "https://git.kernel.org/stable/c/3aadfd46858b1f64d4d6a0654b863e21aabff975"
    },
    {
      "type": "WEB",
      "url": "https://git.kernel.org/stable/c/40805099af11f68c5ca7dbcfacf455da8f99f622"
    },
    {
      "type": "WEB",
      "url": "https://git.kernel.org/stable/c/84ec758fb2daa236026506868c8796b0500c047d"
    },
    {
      "type": "WEB",
      "url": "https://git.kernel.org/stable/c/a37024f7757c25550accdebf49e497ad6ae239fe"
    },
    {
      "type": "WEB",
      "url": "https://git.kernel.org/stable/c/a7ab53d3c27dfe83bb594456b9f38a37796ec39b"
    },
    {
      "type": "WEB",
      "url": "https://git.kernel.org/stable/c/b7e2b91fcb5c78c414e33dc8d50642e307ca0c5a"
    },
    {
      "type": "WEB",
      "url": "https://git.kernel.org/stable/c/d1654de19d42f513b6cfe955cc77e7f427e05a77"
    },
    {
      "type": "WEB",
      "url": "https://git.kernel.org/stable/c/e7a66dd2687758718eddd79b542a95cf3aa488cc"
    }
  ],
  "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-38WQ-HQMP-4JJ6

Vulnerability from github – Published: 2026-07-28 15:32 – Updated: 2026-07-28 18:33
VLAI
Details

[This CNA information record relates to multiple CVEs; the text explains which aspects/vulnerabilities correspond to which CVE.]

With the introduction of Grant Table v2 came the requirement to be able to switch between versions. Switching from v1 to v2 reduces the number of valid grant references, as a bigger shared entry structure is then needed while the shared table doesn't change size. Switching from v2 back to v1 the status frames, which are separate in v2, go away.

Code holding, but intermediately dropping and then re-acquiring the grant table lock, sometimes wrongly assumes that said properties wouldn't change across the window in time where the lock is not being held.

The v1 -> v2 issue is CVE-2026-62435.

The v2 -> v1 issue is CVE-2026-62436.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-62435"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-362"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-07-28T13:19:02Z",
    "severity": "MODERATE"
  },
  "details": "[This CNA information record relates to multiple CVEs; the\ntext explains which aspects/vulnerabilities correspond to which CVE.]\n\nWith the introduction of Grant Table v2 came the requirement to be able to\nswitch between versions.  Switching from v1 to v2 reduces the number of\nvalid grant references, as a bigger shared entry structure is then needed\nwhile the shared table doesn\u0027t change size.  Switching from v2 back to v1\nthe status frames, which are separate in v2, go away.\n\nCode holding, but intermediately dropping and then re-acquiring the grant\ntable lock, sometimes wrongly assumes that said properties wouldn\u0027t change\nacross the window in time where the lock is not being held.\n\nThe v1 -\u003e v2 issue is CVE-2026-62435.\n\nThe v2 -\u003e v1 issue is CVE-2026-62436.",
  "id": "GHSA-38wq-hqmp-4jj6",
  "modified": "2026-07-28T18:33:02Z",
  "published": "2026-07-28T15:32:17Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-62435"
    },
    {
      "type": "WEB",
      "url": "https://xenbits.xenproject.org/xsa/advisory-501.html"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:L",
      "type": "CVSS_V3"
    }
  ]
}

Mitigation
Architecture and Design

In languages that support it, use synchronization primitives. Only wrap these around critical code to minimize the impact on performance.

Mitigation
Architecture and Design

Use thread-safe capabilities such as the data access abstraction in Spring.

Mitigation
Architecture and Design
  • 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
Implementation

When using multithreading and operating on shared variables, only use thread-safe functions.

Mitigation
Implementation

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
Implementation

Use a mutex if available, but be sure to avoid related weaknesses such as CWE-412.

Mitigation
Implementation

Avoid double-checked locking (CWE-609) and other implementation errors that arise when trying to avoid the overhead of synchronization.

Mitigation
Implementation

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
Implementation

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
Architecture and Design Operation

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.