CWE-681
AllowedIncorrect Conversion between Numeric Types
Abstraction: Base · Status: Draft
When converting from one data type to another, such as long to integer, data can be omitted or translated in a way that produces unexpected values. If the resulting values are used in a sensitive context, then dangerous behaviors may occur.
138 vulnerabilities reference this CWE, most recent first.
GHSA-MC57-H6J3-3HMV
Vulnerability from github – Published: 2026-05-18 16:22 – Updated: 2026-06-09 10:32Integer Overflow in Avro Decoder
Summary
Several Avro decoder paths read attacker-controlled 64-bit values from the wire format and either narrowed them to platform-sized int before bounds-checking, or summed them with overflow-prone signed-int arithmetic. On 32-bit targets (GOARCH=386, arm, mips, wasm, etc.), the truncation paths can silently bypass byte-slice limits, select the wrong union branch, or hit the OCF negative-make panic via wrap. Three sub-issues are not 32-bit-specific: cumulative-size arithmetic overflow in arrayDecoder.Decode / mapDecoder.Decode / mapDecoderUnmarshaler.Decode (wraps at math.MaxInt64 on amd64 / arm64 and bypasses MaxSliceAllocSize / MaxMapAllocSize), math.MinInt negation in block-header handling, and make([]byte, size) with a negative size in OCF block reads — all three panic or bypass caps on any platform, giving an attacker a denial-of-service primitive there.
Exploitation requires only an untrusted Avro stream. No primitives reach beyond denial-of-service on current code paths; see the union-index discussion below for a caveat.
Description
Six call sites in the decoder accepted int64 values from the Avro wire format and converted to int before validation. On a 32-bit build any wire value with magnitude ≥ 2³¹ truncates and the post-conversion value bears no useful relationship to the original. A value of (1<<32) + 5 narrows to 5; 1<<32 narrows to 0; values just past MaxInt32 narrow to large negatives.
This is distinct from the existing Config.MaxSliceAllocSize, Config.MaxByteSliceSize, and the new Config.MaxMapAllocSize limits, because narrowing happens before the limit comparison — the limit sees the truncated value, not the original wire value, so the cap is bypassed.
Three further sub-issues are not 32-bit-specific:
arrayDecoder.Decode,mapDecoder.Decode, andmapDecoderUnmarshaler.Decodesummed attacker-controlled block lengths viasize += int(l)and then checkedsize > limit. On amd64 / arm64 the running total wraps atmath.MaxInt64; the post-wrap negative value passes the> limitcheck, and the decoder proceeds. Regression test:TestDecoder_ArrayMultiBlockExceedsMaxIntusesmath.MaxInt − 2for the second block's count and aMaxSliceAllocSizeof 13 to demonstrate this on amd64. The Avro block-count field is a signedlongon the wire, so block counts up tomath.MaxInt64are admissible — there is no implicit 2³¹ ceiling.ReadBlockHeader()returns the absolute value of negative block lengths; the negation is unsafe formath.MinInt, which on every platform panics on overflow.ocf/ocf.go readBlock()passes the decoded block size directly tomake([]byte, size). A negative wire value panics on every platform; on 32-bit, values> MaxInt32additionally panic via the narrowing path.
Affected components
| File | Function(s) | Bug class | Platforms |
|---|---|---|---|
reader.go |
ReadBlockHeader — narrowing |
Narrowing | 32-bit |
reader.go |
ReadBlockHeader — -math.MinInt |
Signed overflow (CWE-191) | all |
reader.go |
readBytes (via Reader.ReadBytes, Reader.ReadString) |
Narrowing | 32-bit |
reader_skip.go |
SkipString, SkipBytes (and OCF skip path) |
Narrowing | 32-bit |
codec_array.go |
arrayDecoder.Decode |
Cumulative-size arithmetic overflow (CWE-190) | all |
codec_map.go |
mapDecoder.Decode, mapDecoderUnmarshaler.Decode |
Cumulative-size arithmetic overflow (CWE-190) | all |
ocf/ocf.go |
skipToEnd, readBlock — narrowing |
Narrowing | 32-bit |
ocf/ocf.go |
readBlock — negative make([]byte, …) |
Unchecked-negative (CWE-1284) | all |
reader_generic.go |
union-type index decoding in Reader.ReadNext |
Narrowing, possible wrong-branch selection | 32-bit |
PR #9 (commit bed99b3) covered ReadBlockHeader, the cumulative checks in array/map codecs, and the skip helpers. The completeness pass (commit e1a570f) covered the union index, readBytes, and OCF readBlock, and added a 32-bit CI job.
Note: the typed-codec union decoder in codec_union.go (getUnionSchema → Reader.ReadInt) is not affected by the union-index narrowing — ReadInt returns int32, no narrowing occurs. The narrowing is specific to Reader.ReadNext in the generic decode path (reached via Unmarshal into any / map[string]any).
Technical details
-
Block-header narrowing and
MinIntnegation.ReadBlockHeader()returned wire-formatint64values through narrower operations; on 32-bit, large positives truncated. Negatingmath.MinIntto convert a negative block-count signal into a positive size is undefined-on-overflow, and on every platform-MinIntpanics on overflow when used in subsequent arithmetic. The fix reads into a*64-suffixed local, range-checks againstMinInt32/MaxInt32(orMinInt/MaxIntas appropriate), and narrows after validation. -
Cumulative array and map size overflow (all platforms).
arrayDecoder.Decode,mapDecoder.Decode, andmapDecoderUnmarshaler.Decodesummed attacker-controlled block lengths using overflow-prone addition; cumulative size could wrap before reaching the configured limit. On amd64 withMaxSliceAllocSize = 13, block 1 of 3 elements, block 2 ofmath.MaxInt − 2elements: the pre-fixsize += int(l)wraps tomath.MinInt, thenMinInt > 13is false, so the check passes and the decoder proceeds. The fix uses subtraction-safe comparisons (l > limit - sizerather thansize + l > limit), which is overflow-immune. -
Skip-length truncation.
SkipString,SkipBytes, and the OCF skip helper now route throughSkipNBytesInt64(), which keeps the length asint64and range-checks before any narrowing. -
Byte-slice length truncation. A wire-format length such as
(1<<32) + 5truncated to5inreadBytes(), slipping pastConfig.MaxByteSliceSizeon 32-bit. The fix reads the length asint64, compares againstMaxByteSliceSizebefore narrowing, and returns "value is too big" if exceeded. -
Union index narrowing (generic decode path only).
Reader.ReadNextdecoded the union index asint64and immediately cast toint. On 32-bit,1<<32narrowed to0and silently selectedtypes[0]despite the explicit upper-bound check immediately above. Iftypes[0]is the null branch (idiomatic for["null", T]nullable unions), the practical result is a null value where the producer encoded a non-null payload — a DoS-grade logic error. Iftypes[0]is a non-trivial schema, downstream bytes are parsed against the wrong schema and produce well-typed but semantically wrong values; treat this as the worst-case interpretation when assessing impact on your own deployment. The typed-codec union decoder (codec_union.gogetUnionSchema→Reader.ReadInt) is not affected. -
OCF block-size narrowing and negative
make.readBlock()passes the decodedint64size directly tomake([]byte, size). A negative wire value panics on every platform; a value> MaxInt32additionally panics via the 32-bit narrowing path. The fix validates the size is in[0, MaxByteSliceSize]before narrowing.
Fixed behavior
Both commits apply the same pattern across every site:
- Read the wire value into an
int64-typed local. - Range-check upper and lower bounds before narrowing.
- Compare cumulative limits using subtraction-safe arithmetic.
- Route skip operations through
SkipNBytesInt64(). - Return descriptive errors using the consistent
"value is too big"/"value is too small"wording. - Cast to
intonly after validation succeeds.
CI: a test-386 job runs the suite under GOARCH=386 with CGO_ENABLED=0 (-race is amd64/arm64-only). Three tests with untyped 2147483648 constants whose t.Skipf gates fire too late (the file fails to compile before any test runs) were split into sibling *_64bit_test.go files gated by //go:build amd64 || arm64 || ....
Affected versions
github.com/hamba/avro/v2— all versions up to and includingv2.31.0(repository is read-only upstream).github.com/iskorotkov/avro/v2— all versions prior tov2.33.0.
Fixed versions
github.com/iskorotkov/avro/v2 v2.33.0 and later. There is no upstream fix for github.com/hamba/avro/v2 — module path is archived. Migrate to the fork as described under Mitigation.
Mitigation
Migrate from github.com/hamba/avro/v2 to github.com/iskorotkov/avro/v2 >= v2.33.0. The packages share the same API surface; replace the import path and run go mod tidy:
- import "github.com/hamba/avro/v2"
+ import "github.com/iskorotkov/avro/v2"
For consumers that prefer the original import path, a replace directive in go.mod is supported:
replace github.com/hamba/avro/v2 => github.com/iskorotkov/avro/v2 v2.33.0
replace is honoured only for the main module of a build — transitive consumers must add their own replace, or migrate the import path directly.
No further configuration is required to benefit from the integer-narrowing fixes — the validation runs on the existing decode path.
If you cannot upgrade immediately:
- Do not decode untrusted Avro data on any platform — the cumulative-arithmetic overflow paths (
arrayDecoder.Decode,mapDecoder.Decode,mapDecoderUnmarshaler.Decode) are reachable on amd64 / arm64. The truncation paths on 32-bit cannot be mitigated by settingConfig.MaxByteSliceSizelower, because the truncated post-narrowing value is what the limit sees, not the original wire value. - For the cross-platform
math.MinIntand OCF negative-size panic paths, wrappingDecode/ OCF read calls in a goroutine withdefer recover()contains the crash, but is not a substitute for upgrading. The other narrowing paths return errors rather than panicking, sorecover()does nothing for them. - Isolate decoding workers so a crash is bounded.
Proof-of-concept inputs
- A
bytesorstringlength of(1<<32) + Nfor smallN, which narrows toNon 32-bit and bypassesConfig.MaxByteSliceSize. - A union index of
1<<32, which narrows to0on 32-bit and selectstypes[0]despite the upper-bound check. - An array or map encoded across multiple blocks whose cumulative element count wraps the signed
intrunning total before the limit check fires. Demonstrated on amd64 byTestDecoder_ArrayMultiBlockExceedsMaxInt:MaxSliceAllocSize = 13, block 1 of3, block 2 ofmath.MaxInt − 2. Wraps tomath.MinInt, check passes, decoder proceeds. - A block header whose absolute value is
math.MinInt, triggering the unsafe negation (cross-platform). - An OCF block size that is negative on the wire, causing
make([]byte, size)to panic (cross-platform); or a positive value> MaxInt32on 32-bit, same outcome via narrowing.
References
- Initial hardening PR: iskorotkov/avro#9
- Completeness pass PR: iskorotkov/avro#10
- Fix commits:
bed99b3,e1a570f - Release:
v2.33.0 - Security policy:
SECURITY.md - Related advisories on this fork:
GHSA-w8j3-pq8g-8m7w(CPU exhaustion — overlaps via the same large-block-count payload shape),GHSA-mx64-mj3q-7prj(unbounded map allocation) - Cross-module precedent on
hamba/avro:GO-2023-1930/CVE-2023-37475/GHSA-9x44-9pgq-cf45 - Upstream (read-only):
hamba/avro
Credits
- Discovery and initial fixes (PR #9, commit
bed99b3—ReadBlockHeader, cumulative array/map checks, skip helpers): Daniel Błażewicz (@klajok) - Completeness fixes (commit
e1a570f— union index,readBytes, OCFreadBlock, 32-bit CI coverage): Ivan Korotkov (@iskorotkov)
Timeline
- 2026-05-04 — Initial integer-overflow hardening (PR #9,
bed99b3) merged. - 2026-05-04 — Completeness pass (
e1a570f) merged; 32-bit CI job added. - 2026-05-06 —
v2.33.0tagged and released. - 2026-05-11 — Advisory published.
- 2026-05-15 — Advisory revised.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/iskorotkov/avro/v2"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.33.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-46384"
],
"database_specific": {
"cwe_ids": [
"CWE-1284",
"CWE-190",
"CWE-191",
"CWE-681"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-18T16:22:27Z",
"nvd_published_at": "2026-05-29T20:16:27Z",
"severity": "HIGH"
},
"details": "# Integer Overflow in Avro Decoder\n\n## Summary\n\nSeveral Avro decoder paths read attacker-controlled 64-bit values from the wire format and either narrowed them to platform-sized `int` before bounds-checking, or summed them with overflow-prone signed-`int` arithmetic. On 32-bit targets (`GOARCH=386`, `arm`, `mips`, `wasm`, etc.), the truncation paths can silently bypass byte-slice limits, select the wrong union branch, or hit the OCF negative-`make` panic via wrap. Three sub-issues are not 32-bit-specific: cumulative-size arithmetic overflow in `arrayDecoder.Decode` / `mapDecoder.Decode` / `mapDecoderUnmarshaler.Decode` (wraps at `math.MaxInt64` on amd64 / arm64 and bypasses `MaxSliceAllocSize` / `MaxMapAllocSize`), `math.MinInt` negation in block-header handling, and `make([]byte, size)` with a negative size in OCF block reads \u2014 all three panic or bypass caps on any platform, giving an attacker a denial-of-service primitive there.\n\nExploitation requires only an untrusted Avro stream. No primitives reach beyond denial-of-service on current code paths; see the union-index discussion below for a caveat.\n\n\n## Description\n\nSix call sites in the decoder accepted `int64` values from the Avro wire format and converted to `int` before validation. On a 32-bit build any wire value with magnitude `\u2265 2\u00b3\u00b9` truncates and the post-conversion value bears no useful relationship to the original. A value of `(1\u003c\u003c32) + 5` narrows to `5`; `1\u003c\u003c32` narrows to `0`; values just past `MaxInt32` narrow to large negatives.\n\nThis is distinct from the existing `Config.MaxSliceAllocSize`, `Config.MaxByteSliceSize`, and the new `Config.MaxMapAllocSize` limits, because narrowing happens *before* the limit comparison \u2014 the limit sees the truncated value, not the original wire value, so the cap is bypassed.\n\nThree further sub-issues are not 32-bit-specific:\n\n- `arrayDecoder.Decode`, `mapDecoder.Decode`, and `mapDecoderUnmarshaler.Decode` summed attacker-controlled block lengths via `size += int(l)` and then checked `size \u003e limit`. On amd64 / arm64 the running total wraps at `math.MaxInt64`; the post-wrap negative value passes the `\u003e limit` check, and the decoder proceeds. Regression test: `TestDecoder_ArrayMultiBlockExceedsMaxInt` uses `math.MaxInt \u2212 2` for the second block\u0027s count and a `MaxSliceAllocSize` of 13 to demonstrate this on amd64. The Avro block-count field is a signed `long` on the wire, so block counts up to `math.MaxInt64` are admissible \u2014 there is no implicit 2\u00b3\u00b9 ceiling.\n- `ReadBlockHeader()` returns the absolute value of negative block lengths; the negation is unsafe for `math.MinInt`, which on every platform panics on overflow.\n- `ocf/ocf.go readBlock()` passes the decoded block size directly to `make([]byte, size)`. A negative wire value panics on every platform; on 32-bit, values `\u003e MaxInt32` additionally panic via the narrowing path.\n\n## Affected components\n\n| File | Function(s) | Bug class | Platforms |\n|------|-------------|-----------|-----------|\n| `reader.go` | `ReadBlockHeader` \u2014 narrowing | Narrowing | 32-bit |\n| `reader.go` | `ReadBlockHeader` \u2014 `-math.MinInt` | Signed overflow (CWE-191) | all |\n| `reader.go` | `readBytes` (via `Reader.ReadBytes`, `Reader.ReadString`) | Narrowing | 32-bit |\n| `reader_skip.go` | `SkipString`, `SkipBytes` (and OCF skip path) | Narrowing | 32-bit |\n| `codec_array.go` | `arrayDecoder.Decode` | Cumulative-size arithmetic overflow (CWE-190) | all |\n| `codec_map.go` | `mapDecoder.Decode`, `mapDecoderUnmarshaler.Decode` | Cumulative-size arithmetic overflow (CWE-190) | all |\n| `ocf/ocf.go` | `skipToEnd`, `readBlock` \u2014 narrowing | Narrowing | 32-bit |\n| `ocf/ocf.go` | `readBlock` \u2014 negative `make([]byte, \u2026)` | Unchecked-negative (CWE-1284) | all |\n| `reader_generic.go` | union-type index decoding in `Reader.ReadNext` | Narrowing, possible wrong-branch selection | 32-bit |\n\nPR #9 (commit [`bed99b3`](https://github.com/iskorotkov/avro/commit/bed99b315ec097a1a5eb7ae074ef57a91848c583)) covered `ReadBlockHeader`, the cumulative checks in array/map codecs, and the skip helpers. The completeness pass (commit [`e1a570f`](https://github.com/iskorotkov/avro/commit/e1a570f9a8a4fe4b1bc2b4b1fb6d24e4a5f04358)) covered the union index, `readBytes`, and OCF `readBlock`, and added a 32-bit CI job.\n\nNote: the typed-codec union decoder in `codec_union.go` (`getUnionSchema` \u2192 `Reader.ReadInt`) is **not** affected by the union-index narrowing \u2014 `ReadInt` returns `int32`, no narrowing occurs. The narrowing is specific to `Reader.ReadNext` in the generic decode path (reached via `Unmarshal` into `any` / `map[string]any`).\n\n## Technical details\n\n1. **Block-header narrowing and `MinInt` negation.** `ReadBlockHeader()` returned wire-format `int64` values through narrower operations; on 32-bit, large positives truncated. Negating `math.MinInt` to convert a negative block-count signal into a positive size is undefined-on-overflow, and on every platform `-MinInt` panics on overflow when used in subsequent arithmetic. The fix reads into a `*64`-suffixed local, range-checks against `MinInt32`/`MaxInt32` (or `MinInt`/`MaxInt` as appropriate), and narrows after validation.\n\n2. **Cumulative array and map size overflow (all platforms).** `arrayDecoder.Decode`, `mapDecoder.Decode`, and `mapDecoderUnmarshaler.Decode` summed attacker-controlled block lengths using overflow-prone addition; cumulative size could wrap before reaching the configured limit. On amd64 with `MaxSliceAllocSize = 13`, block 1 of 3 elements, block 2 of `math.MaxInt \u2212 2` elements: the pre-fix `size += int(l)` wraps to `math.MinInt`, then `MinInt \u003e 13` is false, so the check passes and the decoder proceeds. The fix uses subtraction-safe comparisons (`l \u003e limit - size` rather than `size + l \u003e limit`), which is overflow-immune.\n\n3. **Skip-length truncation.** `SkipString`, `SkipBytes`, and the OCF skip helper now route through `SkipNBytesInt64()`, which keeps the length as `int64` and range-checks before any narrowing.\n\n4. **Byte-slice length truncation.** A wire-format length such as `(1\u003c\u003c32) + 5` truncated to `5` in `readBytes()`, slipping past `Config.MaxByteSliceSize` on 32-bit. The fix reads the length as `int64`, compares against `MaxByteSliceSize` before narrowing, and returns \"value is too big\" if exceeded.\n\n5. **Union index narrowing (generic decode path only).** `Reader.ReadNext` decoded the union index as `int64` and immediately cast to `int`. On 32-bit, `1\u003c\u003c32` narrowed to `0` and silently selected `types[0]` despite the explicit upper-bound check immediately above. If `types[0]` is the null branch (idiomatic for `[\"null\", T]` nullable unions), the practical result is a null value where the producer encoded a non-null payload \u2014 a DoS-grade logic error. If `types[0]` is a non-trivial schema, downstream bytes are parsed against the wrong schema and produce well-typed but semantically wrong values; treat this as the worst-case interpretation when assessing impact on your own deployment. The typed-codec union decoder (`codec_union.go` `getUnionSchema` \u2192 `Reader.ReadInt`) is not affected.\n\n6. **OCF block-size narrowing and negative `make`.** `readBlock()` passes the decoded `int64` size directly to `make([]byte, size)`. A negative wire value panics on every platform; a value `\u003e MaxInt32` additionally panics via the 32-bit narrowing path. The fix validates the size is in `[0, MaxByteSliceSize]` before narrowing.\n\n## Fixed behavior\n\nBoth commits apply the same pattern across every site:\n\n1. Read the wire value into an `int64`-typed local.\n2. Range-check upper and lower bounds before narrowing.\n3. Compare cumulative limits using subtraction-safe arithmetic.\n4. Route skip operations through `SkipNBytesInt64()`.\n5. Return descriptive errors using the consistent `\"value is too big\"` / `\"value is too small\"` wording.\n6. Cast to `int` only after validation succeeds.\n\nCI: a `test-386` job runs the suite under `GOARCH=386` with `CGO_ENABLED=0` (`-race` is amd64/arm64-only). Three tests with untyped `2147483648` constants whose `t.Skipf` gates fire too late (the file fails to compile before any test runs) were split into sibling `*_64bit_test.go` files gated by `//go:build amd64 || arm64 || ...`.\n\n## Affected versions\n\n- `github.com/hamba/avro/v2` \u2014 all versions up to and including `v2.31.0` (repository is read-only upstream).\n- `github.com/iskorotkov/avro/v2` \u2014 all versions prior to `v2.33.0`.\n\n## Fixed versions\n\n`github.com/iskorotkov/avro/v2` `v2.33.0` and later. There is no upstream fix for `github.com/hamba/avro/v2` \u2014 module path is archived. Migrate to the fork as described under Mitigation.\n\n## Mitigation\n\nMigrate from `github.com/hamba/avro/v2` to `github.com/iskorotkov/avro/v2 \u003e= v2.33.0`. The packages share the same API surface; replace the import path and run `go mod tidy`:\n\n```diff\n- import \"github.com/hamba/avro/v2\"\n+ import \"github.com/iskorotkov/avro/v2\"\n```\n\nFor consumers that prefer the original import path, a `replace` directive in `go.mod` is supported:\n\n```\nreplace github.com/hamba/avro/v2 =\u003e github.com/iskorotkov/avro/v2 v2.33.0\n```\n\n`replace` is honoured only for the **main** module of a build \u2014 transitive consumers must add their own `replace`, or migrate the import path directly.\n\nNo further configuration is required to benefit from the integer-narrowing fixes \u2014 the validation runs on the existing decode path.\n\nIf you cannot upgrade immediately:\n\n- Do not decode untrusted Avro data on any platform \u2014 the cumulative-arithmetic overflow paths (`arrayDecoder.Decode`, `mapDecoder.Decode`, `mapDecoderUnmarshaler.Decode`) are reachable on amd64 / arm64. The truncation paths on 32-bit cannot be mitigated by setting `Config.MaxByteSliceSize` lower, because the truncated post-narrowing value is what the limit sees, not the original wire value.\n- For the cross-platform `math.MinInt` and OCF negative-size panic paths, wrapping `Decode` / OCF read calls in a goroutine with `defer recover()` contains the crash, but is not a substitute for upgrading. The other narrowing paths return errors rather than panicking, so `recover()` does nothing for them.\n- Isolate decoding workers so a crash is bounded.\n\n## Proof-of-concept inputs\n\n- A `bytes` or `string` length of `(1\u003c\u003c32) + N` for small `N`, which narrows to `N` on 32-bit and bypasses `Config.MaxByteSliceSize`.\n- A union index of `1\u003c\u003c32`, which narrows to `0` on 32-bit and selects `types[0]` despite the upper-bound check.\n- An array or map encoded across multiple blocks whose cumulative element count wraps the signed `int` running total before the limit check fires. Demonstrated on amd64 by `TestDecoder_ArrayMultiBlockExceedsMaxInt`: `MaxSliceAllocSize = 13`, block 1 of `3`, block 2 of `math.MaxInt \u2212 2`. Wraps to `math.MinInt`, check passes, decoder proceeds.\n- A block header whose absolute value is `math.MinInt`, triggering the unsafe negation (cross-platform).\n- An OCF block size that is negative on the wire, causing `make([]byte, size)` to panic (cross-platform); or a positive value `\u003e MaxInt32` on 32-bit, same outcome via narrowing.\n\n## References\n\n- Initial hardening PR: [iskorotkov/avro#9](https://github.com/iskorotkov/avro/pull/9)\n- Completeness pass PR: [iskorotkov/avro#10](https://github.com/iskorotkov/avro/pull/10)\n- Fix commits: [`bed99b3`](https://github.com/iskorotkov/avro/commit/bed99b315ec097a1a5eb7ae074ef57a91848c583), [`e1a570f`](https://github.com/iskorotkov/avro/commit/e1a570f9a8a4fe4b1bc2b4b1fb6d24e4a5f04358)\n- Release: [`v2.33.0`](https://github.com/iskorotkov/avro/releases/tag/v2.33.0)\n- Security policy: [`SECURITY.md`](https://github.com/iskorotkov/avro/blob/main/SECURITY.md)\n- Related advisories on this fork: [`GHSA-w8j3-pq8g-8m7w`](https://github.com/iskorotkov/avro/security/advisories/GHSA-w8j3-pq8g-8m7w) (CPU exhaustion \u2014 overlaps via the same large-block-count payload shape), [`GHSA-mx64-mj3q-7prj`](https://github.com/iskorotkov/avro/security/advisories/GHSA-mx64-mj3q-7prj) (unbounded map allocation)\n- Cross-module precedent on `hamba/avro`: [`GO-2023-1930`](https://pkg.go.dev/vuln/GO-2023-1930) / `CVE-2023-37475` / `GHSA-9x44-9pgq-cf45`\n- Upstream (read-only): [`hamba/avro`](https://github.com/hamba/avro)\n\n## Credits\n\n- **Discovery and initial fixes** (PR #9, commit `bed99b3` \u2014 `ReadBlockHeader`, cumulative array/map checks, skip helpers): Daniel B\u0142a\u017cewicz ([@klajok](https://github.com/klajok))\n- **Completeness fixes** (commit `e1a570f` \u2014 union index, `readBytes`, OCF `readBlock`, 32-bit CI coverage): Ivan Korotkov ([@iskorotkov](https://github.com/iskorotkov))\n\n## Timeline\n\n- **2026-05-04** \u2014 Initial integer-overflow hardening (PR #9, `bed99b3`) merged.\n- **2026-05-04** \u2014 Completeness pass (`e1a570f`) merged; 32-bit CI job added.\n- **2026-05-06** \u2014 `v2.33.0` tagged and released.\n- **2026-05-11** \u2014 Advisory published.\n- **2026-05-15** \u2014 Advisory revised.",
"id": "GHSA-mc57-h6j3-3hmv",
"modified": "2026-06-09T10:32:44Z",
"published": "2026-05-18T16:22:27Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/iskorotkov/avro/security/advisories/GHSA-mc57-h6j3-3hmv"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-46384"
},
{
"type": "PACKAGE",
"url": "https://github.com/iskorotkov/avro"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"type": "CVSS_V4"
}
],
"summary": "iskorotkov/avro: Integer Overflow in Decoder"
}
GHSA-MWQ6-9RWW-WMJH
Vulnerability from github – Published: 2022-06-19 00:00 – Updated: 2022-06-28 00:00A vulnerability was found in FFmpeg 2.0. It has been classified as problematic. Affected is an unknown function of the file libavcodec/dxtroy.c. The manipulation leads to integer coercion error. It is possible to launch the attack remotely. It is recommended to apply a patch to fix this issue.
{
"affected": [],
"aliases": [
"CVE-2014-125012"
],
"database_specific": {
"cwe_ids": [
"CWE-681"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-06-18T07:15:00Z",
"severity": "MODERATE"
},
"details": "A vulnerability was found in FFmpeg 2.0. It has been classified as problematic. Affected is an unknown function of the file libavcodec/dxtroy.c. The manipulation leads to integer coercion error. It is possible to launch the attack remotely. It is recommended to apply a patch to fix this issue.",
"id": "GHSA-mwq6-9rww-wmjh",
"modified": "2022-06-28T00:00:45Z",
"published": "2022-06-19T00:00:22Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2014-125012"
},
{
"type": "WEB",
"url": "https://vuldb.com/?id.12390"
},
{
"type": "WEB",
"url": "http://git.videolan.org/?p=ffmpeg.git;a=commit;h=a392bf657015c9a79a5a13adfbfb15086c1943b9"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-P9M7-CFXQ-C6RF
Vulnerability from github – Published: 2022-05-06 00:00 – Updated: 2022-05-14 00:01On F5 BIG-IP 16.1.x versions prior to 16.1.2.2, 15.1.x versions prior to 15.1.5.1, 14.1.x versions prior to 14.1.4.6, 13.1.x versions prior to 13.1.5, and all versions of 12.1.x and 11.6.x, when an Internet Content Adaptation Protocol (ICAP) profile is configured on a virtual server, undisclosed traffic can cause an increase in Traffic Management Microkernel (TMM) memory resource utilization. Note: Software versions which have reached End of Technical Support (EoTS) are not evaluated
{
"affected": [],
"aliases": [
"CVE-2022-27189"
],
"database_specific": {
"cwe_ids": [
"CWE-681"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-05-05T17:15:00Z",
"severity": "HIGH"
},
"details": "On F5 BIG-IP 16.1.x versions prior to 16.1.2.2, 15.1.x versions prior to 15.1.5.1, 14.1.x versions prior to 14.1.4.6, 13.1.x versions prior to 13.1.5, and all versions of 12.1.x and 11.6.x, when an Internet Content Adaptation Protocol (ICAP) profile is configured on a virtual server, undisclosed traffic can cause an increase in Traffic Management Microkernel (TMM) memory resource utilization. Note: Software versions which have reached End of Technical Support (EoTS) are not evaluated",
"id": "GHSA-p9m7-cfxq-c6rf",
"modified": "2022-05-14T00:01:23Z",
"published": "2022-05-06T00:00:33Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-27189"
},
{
"type": "WEB",
"url": "https://support.f5.com/csp/article/K16187341"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-PGRF-4654-3GQ8
Vulnerability from github – Published: 2026-08-20 18:43 – Updated: 2026-08-20 18:43Summary
io.netty.incubator:netty-incubator-codec-bhttp uses attacker-controlled Binary HTTP variable-length integers as long values but accumulates them into int offsets. Large valid varint lengths wrap the internal offset negative, leading to unchecked ArrayIndexOutOfBoundsException / IndexOutOfBoundsException from a tiny malformed BHTTP payload. A remote peer can trigger connection-level denial of service in applications that expose BinaryHttpParser / BinaryHttpDecoder to untrusted input.
Details
In codec-bhttp/src/main/java/io/netty/incubator/codec/bhttp/BinaryHttpParser.java, several parser paths store cumulative byte offsets in int sumBytes and then add attacker-controlled long lengths using compound assignment. In Java, int += long narrows the result back to int, so a length such as 2^31 wraps sumBytes negative.
Primary request-control-data path:
readRequestHead(...)declaresint sumBytes = 0atBinaryHttpParser.java:386.- It reads
methodLengthas alongatBinaryHttpParser.java:394. - It performs
sumBytes += methodLengthatBinaryHttpParser.java:395, narrowing the result toint. - If
methodLengthis2^31,sumByteswraps negative and bypassesif (sumBytes >= in.readableBytes()) return nullatBinaryHttpParser.java:396-398. - The parser then computes
schemeLengthIdx = in.readerIndex() + sumBytesand callsin.getByte(schemeLengthIdx)atBinaryHttpParser.java:401-402, producing a negative index exception.
The same pattern is present in header parsing:
readFieldLine(...)usesint sumBytesand addslong nameLength/long valueLengthatBinaryHttpParser.java:659-680.valueLengthIdx = nameIdx + (int) nameLengthatBinaryHttpParser.java:674can also overflow.
getIndeterminateLength(...) similarly uses int sumBytes and long possibleTerminator at BinaryHttpParser.java:544-553.
Proof of concept
Safe local verification performed in this repository. After compiling codec-bhttp, the following minimal verifier uses a 15-byte payload:
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.incubator.codec.bhttp.BinaryHttpParser;
public final class VerifyBhttpOverflow {
public static void main(String[] args) {
byte[] payload = new byte[] {
0x00, (byte)0xc0, 0x00, 0x00, 0x00, (byte)0x80, 0x00, 0x00, 0x00,
0x47, 0x45, 0x54, 0x58, 0x58, 0x58
};
ByteBuf input = Unpooled.wrappedBuffer(payload);
try {
new BinaryHttpParser(8192).parse(input, false);
System.out.println("returned");
} catch (Throwable t) {
System.out.println(t.getClass().getName());
System.out.println(t.getMessage());
}
}
}
Payload interpretation:
00: known-length request frame indicator.c000000080000000: valid 8-byte varint encoding of0x80000000(2^31) as the method length.474554585858: a few dummy bytes so the parser proceeds far enough to compute the next index.
Observed result:
java.lang.ArrayIndexOutOfBoundsException
Index -2147483639 out of bounds for length 15
The parser should reject the malformed/incomplete message with a controlled decoder exception or return null awaiting more bytes; it should not allow integer wraparound to reach unchecked buffer indexing.
Impact
A remote peer can trigger an unchecked exception in the Binary HTTP decoder using a tiny payload. In typical Netty pipelines this closes or fails the affected channel. Depending on application-level exception handling, repeated payloads can cause sustained denial of service for exposed BHTTP endpoints. No memory corruption or information disclosure was observed because the failure occurs in Java/Netty bounds checks.
Suggested remediation
- Use
longfor all cumulative byte counts derived from protocol lengths. - Before converting any protocol length to
int, verify it is non-negative, no larger thanInteger.MAX_VALUE, and no larger than available readable bytes and configured limits. - Replace
sumBytes >= in.readableBytes()checks with precise checked arithmetic that permits exact-boundary complete fields but rejects impossible lengths. - Throw a controlled
CorruptedFrameException/TooLongFrameExceptionfor invalid or unsupported lengths. - Add regression tests for 8-byte varint lengths at and above
Integer.MAX_VALUEin request control data, response control data, known and indeterminate field sections, and field lines.
References
codec-bhttp/src/main/java/io/netty/incubator/codec/bhttp/BinaryHttpParser.java:386-402codec-bhttp/src/main/java/io/netty/incubator/codec/bhttp/BinaryHttpParser.java:659-680codec-bhttp/src/main/java/io/netty/incubator/codec/bhttp/BinaryHttpParser.java:544-553- RFC 9292: Binary Representation of HTTP Messages
- RFC 9000 variable-length integer encoding
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.0.22.Final"
},
"package": {
"ecosystem": "Maven",
"name": "io.netty.incubator:netty-incubator-codec-bhttp"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.0.23.Final"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-61799"
],
"database_specific": {
"cwe_ids": [
"CWE-190",
"CWE-248",
"CWE-681"
],
"github_reviewed": true,
"github_reviewed_at": "2026-08-20T18:43:21Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "## Summary\n\n`io.netty.incubator:netty-incubator-codec-bhttp` uses attacker-controlled Binary HTTP variable-length integers as `long` values but accumulates them into `int` offsets. Large valid varint lengths wrap the internal offset negative, leading to unchecked `ArrayIndexOutOfBoundsException` / `IndexOutOfBoundsException` from a tiny malformed BHTTP payload. A remote peer can trigger connection-level denial of service in applications that expose `BinaryHttpParser` / `BinaryHttpDecoder` to untrusted input.\n\n## Details\n\nIn `codec-bhttp/src/main/java/io/netty/incubator/codec/bhttp/BinaryHttpParser.java`, several parser paths store cumulative byte offsets in `int sumBytes` and then add attacker-controlled `long` lengths using compound assignment. In Java, `int += long` narrows the result back to `int`, so a length such as `2^31` wraps `sumBytes` negative.\n\nPrimary request-control-data path:\n\n- `readRequestHead(...)` declares `int sumBytes = 0` at `BinaryHttpParser.java:386`.\n- It reads `methodLength` as a `long` at `BinaryHttpParser.java:394`.\n- It performs `sumBytes += methodLength` at `BinaryHttpParser.java:395`, narrowing the result to `int`.\n- If `methodLength` is `2^31`, `sumBytes` wraps negative and bypasses `if (sumBytes \u003e= in.readableBytes()) return null` at `BinaryHttpParser.java:396-398`.\n- The parser then computes `schemeLengthIdx = in.readerIndex() + sumBytes` and calls `in.getByte(schemeLengthIdx)` at `BinaryHttpParser.java:401-402`, producing a negative index exception.\n\nThe same pattern is present in header parsing:\n\n- `readFieldLine(...)` uses `int sumBytes` and adds `long nameLength` / `long valueLength` at `BinaryHttpParser.java:659-680`.\n- `valueLengthIdx = nameIdx + (int) nameLength` at `BinaryHttpParser.java:674` can also overflow.\n\n`getIndeterminateLength(...)` similarly uses `int sumBytes` and `long possibleTerminator` at `BinaryHttpParser.java:544-553`.\n\n## Proof of concept\n\nSafe local verification performed in this repository. After compiling `codec-bhttp`, the following minimal verifier uses a 15-byte payload:\n\n```java\nimport io.netty.buffer.ByteBuf;\nimport io.netty.buffer.Unpooled;\nimport io.netty.incubator.codec.bhttp.BinaryHttpParser;\n\npublic final class VerifyBhttpOverflow {\n public static void main(String[] args) {\n byte[] payload = new byte[] {\n 0x00, (byte)0xc0, 0x00, 0x00, 0x00, (byte)0x80, 0x00, 0x00, 0x00,\n 0x47, 0x45, 0x54, 0x58, 0x58, 0x58\n };\n ByteBuf input = Unpooled.wrappedBuffer(payload);\n try {\n new BinaryHttpParser(8192).parse(input, false);\n System.out.println(\"returned\");\n } catch (Throwable t) {\n System.out.println(t.getClass().getName());\n System.out.println(t.getMessage());\n }\n }\n}\n```\n\nPayload interpretation:\n\n- `00`: known-length request frame indicator.\n- `c000000080000000`: valid 8-byte varint encoding of `0x80000000` (`2^31`) as the method length.\n- `474554585858`: a few dummy bytes so the parser proceeds far enough to compute the next index.\n\nObserved result:\n\n```text\njava.lang.ArrayIndexOutOfBoundsException\nIndex -2147483639 out of bounds for length 15\n```\n\nThe parser should reject the malformed/incomplete message with a controlled decoder exception or return `null` awaiting more bytes; it should not allow integer wraparound to reach unchecked buffer indexing.\n\n## Impact\n\nA remote peer can trigger an unchecked exception in the Binary HTTP decoder using a tiny payload. In typical Netty pipelines this closes or fails the affected channel. Depending on application-level exception handling, repeated payloads can cause sustained denial of service for exposed BHTTP endpoints. No memory corruption or information disclosure was observed because the failure occurs in Java/Netty bounds checks.\n\n## Suggested remediation\n\n- Use `long` for all cumulative byte counts derived from protocol lengths.\n- Before converting any protocol length to `int`, verify it is non-negative, no larger than `Integer.MAX_VALUE`, and no larger than available readable bytes and configured limits.\n- Replace `sumBytes \u003e= in.readableBytes()` checks with precise checked arithmetic that permits exact-boundary complete fields but rejects impossible lengths.\n- Throw a controlled `CorruptedFrameException` / `TooLongFrameException` for invalid or unsupported lengths.\n- Add regression tests for 8-byte varint lengths at and above `Integer.MAX_VALUE` in request control data, response control data, known and indeterminate field sections, and field lines.\n\n## References\n\n- `codec-bhttp/src/main/java/io/netty/incubator/codec/bhttp/BinaryHttpParser.java:386-402`\n- `codec-bhttp/src/main/java/io/netty/incubator/codec/bhttp/BinaryHttpParser.java:659-680`\n- `codec-bhttp/src/main/java/io/netty/incubator/codec/bhttp/BinaryHttpParser.java:544-553`\n- RFC 9292: Binary Representation of HTTP Messages\n- RFC 9000 variable-length integer encoding",
"id": "GHSA-pgrf-4654-3gq8",
"modified": "2026-08-20T18:43:21Z",
"published": "2026-08-20T18:43:21Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/netty/netty-incubator-codec-ohttp/security/advisories/GHSA-pgrf-4654-3gq8"
},
{
"type": "PACKAGE",
"url": "https://github.com/netty/netty-incubator-codec-ohttp"
},
{
"type": "WEB",
"url": "https://github.com/netty/netty-incubator-codec-ohttp/releases/tag/netty-incubator-codec-parent-ohttp-0.0.23.Final"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L",
"type": "CVSS_V3"
}
],
"summary": "netty-incubator-codec-ohttp: Binary HTTP parser unchecked varint length overflow causes decoder crash"
}
GHSA-PJXJ-PCHX-4C3M
Vulnerability from github – Published: 2026-07-31 19:40 – Updated: 2026-07-31 19:40An integer overflow in the XCF decoder can result in an out of bounds read when a crafted image is read and that can result in a crash.
{
"affected": [
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-AnyCPU"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.15.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-HDRI-AnyCPU"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.15.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-HDRI-OpenMP-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.15.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-HDRI-x64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.15.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-HDRI-x86"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.15.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-OpenMP-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.15.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-OpenMP-x64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.15.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.15.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-x64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.15.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-x86"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.15.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-AnyCPU"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.15.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-OpenMP-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.15.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-OpenMP-x64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.15.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.15.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-x64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.15.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q8-x86"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.15.0"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "NuGet",
"name": "Magick.NET-Q16-HDRI-arm64"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "14.15.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-53466"
],
"database_specific": {
"cwe_ids": [
"CWE-190",
"CWE-681"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-31T19:40:08Z",
"nvd_published_at": "2026-07-01T19:16:54Z",
"severity": "MODERATE"
},
"details": "An integer overflow in the XCF decoder can result in an out of bounds read when a crafted image is read and that can result in a crash.",
"id": "GHSA-pjxj-pchx-4c3m",
"modified": "2026-07-31T19:40:08Z",
"published": "2026-07-31T19:40:08Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-pjxj-pchx-4c3m"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-53466"
},
{
"type": "WEB",
"url": "https://github.com/ImageMagick/ImageMagick/commit/47ca7210515f3c9ea033b86fe4323a70caa74468"
},
{
"type": "PACKAGE",
"url": "https://github.com/ImageMagick/ImageMagick"
},
{
"type": "WEB",
"url": "https://github.com/ImageMagick/ImageMagick/releases/tag/7.1.2-26"
},
{
"type": "WEB",
"url": "https://github.com/dlemstra/Magick.NET/releases/tag/14.15.0"
}
],
"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"
}
],
"summary": "ImageMagick: Heap Buffer Over-Read in XCF decoder due to integer conversion overflow"
}
GHSA-PM4J-7R4Q-CCG8
Vulnerability from github – Published: 2026-03-07 02:39 – Updated: 2026-03-07 02:39Summary
Soroban host ensures that MuxedAddress objects can't be used as storage keys in order to proactively prevent the contract logic bugs. However, due to a bug in Soroban host implementation, a failure in Val->ScVal conversion during the storage key computation will have the flag indicating that storage conversion is happening stuck in the true state until the next storage access. While the flag is stuck in true state, any MuxedAddress object conversions to ScVal will fail, i.e. a failure will occur if a MuxedAddress is emitted in the event or is serialized to XDR via a host function.
Impact
The bug may cause unexpected contract failures in the rare edge case scenarios. In the worst case scenario the whole transaction will fail and the changes will be rolled back. Because the contract call is simply rolled back, there is no risk of the state corruption.
An example scenario that would be affected by the bug is as follows:
- Contract A calls contract B via
try_call - Contract B calls a storage function (e.g.
put_contract_data) with a non-convertibleValas a key (e.g. aMuxedAddressobject, or a deeply nested vector) - Contract B fails
- Contract A handles the failure gracefully and proceeds without accessing any storage methods
- Contract A tries to emit an event with a
MuxedAddressargument. That should be allowed, but instead of succeeding, contract A fails.
Patches
The bug will be fixed in protocol 26.
Workarounds
We believe that the bug is highly unlikely to occur in practice, as it involves three rare events happening simultaneously: Val conversion failure (these should normally not occur for the audited protocols), graceful handling of a cross-contract call failure (most protocols need cross-contract calls to succeed, or fail with a contract error), and MuxedAddress write (most of the contracts don't support MuxedAddress at all).
In the case if the bug does occur, the mitigation depends on the reason of the value conversion failure:
- If the conversion failure has been caused by a malicious contract, then either no action is necessary (because the whole interaction is malicious and has been correctly rolled back), or the contract invocation should be replaced by a non-malicious contract
- If the conversion failure has been caused by a bad user input for a non-malicious contract (e.g. a bad user input passed to a legitimate protocol), then the user input has to be fixed
In both scenarios the mitigation is to basically retry the transaction with proper arguments.
{
"affected": [
{
"package": {
"ecosystem": "crates.io",
"name": "soroban-env-host"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "26.0.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-681"
],
"github_reviewed": true,
"github_reviewed_at": "2026-03-07T02:39:44Z",
"nvd_published_at": null,
"severity": "LOW"
},
"details": "### Summary\n\nSoroban host ensures that `MuxedAddress` objects can\u0027t be used as storage keys in order to proactively prevent the contract logic bugs. However, due to a bug in Soroban host implementation, a failure in `Val`-\u003e`ScVal` conversion during the storage key computation will have the flag indicating that storage conversion is happening stuck in the `true` state until the next storage access. While the flag is stuck in `true` state, any `MuxedAddress` object conversions to `ScVal` will fail, i.e. a failure will occur if a `MuxedAddress` is emitted in the event or is serialized to XDR via a host function.\n\n### Impact\n\nThe bug may cause unexpected contract failures in the rare edge case scenarios. In the worst case scenario the whole transaction will fail and the changes will be rolled back. Because the contract call is simply rolled back, there is no risk of the state corruption.\n\nAn example scenario that would be affected by the bug is as follows:\n\n- Contract A calls contract B via `try_call`\n- Contract B calls a storage function (e.g. `put_contract_data`) with a non-convertible `Val` as a key (e.g. a `MuxedAddress` object, or a deeply nested vector)\n- Contract B fails\n- Contract A handles the failure gracefully and proceeds without accessing any storage methods\n- Contract A tries to emit an event with a `MuxedAddress` argument. That should be allowed, but instead of succeeding, contract A fails.\n\n### Patches\n\nThe bug will be fixed in protocol 26.\n\n### Workarounds\n\nWe believe that the bug is highly unlikely to occur in practice, as it involves three rare events happening simultaneously: `Val` conversion failure (these should normally not occur for the audited protocols), graceful handling of a cross-contract call failure (most protocols need cross-contract calls to succeed, or fail with a contract error), and `MuxedAddress` write (most of the contracts don\u0027t support `MuxedAddress` at all).\n\nIn the case if the bug does occur, the mitigation depends on the reason of the value conversion failure:\n\n- If the conversion failure has been caused by a malicious contract, then either no action is necessary (because the whole interaction is malicious and has been correctly rolled back), or the contract invocation should be replaced by a non-malicious contract\n- If the conversion failure has been caused by a bad user input for a non-malicious contract (e.g. a bad user input passed to a legitimate protocol), then the user input has to be fixed\n\nIn both scenarios the mitigation is to basically retry the transaction with proper arguments.",
"id": "GHSA-pm4j-7r4q-ccg8",
"modified": "2026-03-07T02:39:44Z",
"published": "2026-03-07T02:39:44Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/stellar/rs-soroban-env/security/advisories/GHSA-pm4j-7r4q-ccg8"
},
{
"type": "PACKAGE",
"url": "https://github.com/stellar/rs-soroban-env"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:U",
"type": "CVSS_V4"
}
],
"summary": "Soroban: Muxed address\u003c-\u003eScVal conversions may break after a conversion failure"
}
GHSA-PPQ3-433V-JP43
Vulnerability from github – Published: 2022-05-14 03:17 – Updated: 2025-04-20 03:34The packet_set_ring function in net/packet/af_packet.c in the Linux kernel through 4.10.6 does not properly validate certain block-size data, which allows local users to cause a denial of service (integer signedness error and out-of-bounds write), or gain privileges (if the CAP_NET_RAW capability is held), via crafted system calls.
{
"affected": [],
"aliases": [
"CVE-2017-7308"
],
"database_specific": {
"cwe_ids": [
"CWE-119",
"CWE-681",
"CWE-787"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2017-03-29T20:59:00Z",
"severity": "HIGH"
},
"details": "The packet_set_ring function in net/packet/af_packet.c in the Linux kernel through 4.10.6 does not properly validate certain block-size data, which allows local users to cause a denial of service (integer signedness error and out-of-bounds write), or gain privileges (if the CAP_NET_RAW capability is held), via crafted system calls.",
"id": "GHSA-ppq3-433v-jp43",
"modified": "2025-04-20T03:34:58Z",
"published": "2022-05-14T03:17:31Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2017-7308"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2017:1297"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2017:1298"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2017:1308"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2018:1854"
},
{
"type": "WEB",
"url": "https://googleprojectzero.blogspot.com/2017/05/exploiting-linux-kernel-via-packet.html"
},
{
"type": "WEB",
"url": "https://patchwork.ozlabs.org/patch/744811"
},
{
"type": "WEB",
"url": "https://patchwork.ozlabs.org/patch/744812"
},
{
"type": "WEB",
"url": "https://patchwork.ozlabs.org/patch/744813"
},
{
"type": "WEB",
"url": "https://source.android.com/security/bulletin/2017-07-01"
},
{
"type": "WEB",
"url": "https://www.exploit-db.com/exploits/41994"
},
{
"type": "WEB",
"url": "https://www.exploit-db.com/exploits/44654"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/97234"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-PPX5-Q359-PVWJ
Vulnerability from github – Published: 2024-04-25 19:53 – Updated: 2024-04-25 19:53Summary
When looping over a range of the form range(start, start + N), if start is negative, the execution will always revert.
Details
This issue is caused by an incorrect assertion inserted by the code generation of the range (stmt.parse_For_range()):
https://github.com/vyperlang/vyper/blob/9136169468f317a53b4e7448389aa315f90b95ba/vyper/codegen/stmt.py#L286-L287
This assertion was introduced in https://github.com/vyperlang/vyper/commit/3de1415ee77a9244eb04bdb695e249d3ec9ed868 to fix https://github.com/advisories/GHSA-6r8q-pfpv-7cgj. The issue arises when start is signed, instead of using sle, le is used and start is interpreted as an unsigned integer for the comparison. If it is a negative number, its 255th bit is set to 1 and is hence interpreted as a very large unsigned integer making the assertion always fail.
PoC
@external
def foo():
x:int256 = min_value(int256)
# revert when it should not since we have the following assertion that fails:
# [assert, [le, min_value(int256), max_value(int256) + 1 - 10]],
for i in range(x, x + 10):
pass
Patches
patched in v0.4.0, specifically, https://github.com/vyperlang/vyper/pull/3679 disallows this form of range().
Impact
Any contract having a range(start, start + N) where start is a signed integer with the possibility for start to be negative is affected. If a call goes through the loop while supplying a negative start the execution will revert.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "vyper"
},
"ranges": [
{
"events": [
{
"introduced": "0.3.8"
},
{
"fixed": "0.4.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-32481"
],
"database_specific": {
"cwe_ids": [
"CWE-681"
],
"github_reviewed": true,
"github_reviewed_at": "2024-04-25T19:53:43Z",
"nvd_published_at": "2024-04-25T17:15:50Z",
"severity": "MODERATE"
},
"details": "### Summary\n\nWhen looping over a `range` of the form `range(start, start + N)`, if `start` is negative, the execution will always revert.\n \n### Details\n\nThis issue is caused by an incorrect assertion inserted by the code generation of the range (`stmt.parse_For_range()`):\n\nhttps://github.com/vyperlang/vyper/blob/9136169468f317a53b4e7448389aa315f90b95ba/vyper/codegen/stmt.py#L286-L287\n\nThis assertion was introduced in https://github.com/vyperlang/vyper/commit/3de1415ee77a9244eb04bdb695e249d3ec9ed868 to fix https://github.com/advisories/GHSA-6r8q-pfpv-7cgj. The issue arises when `start` is signed, instead of using `sle`, `le` is used and `start` is interpreted as an unsigned integer for the comparison. If it is a negative number, its 255th bit is set to `1` and is hence interpreted as a very large unsigned integer making the assertion always fail. \n### PoC\n\n```Vyper\n@external\ndef foo():\n x:int256 = min_value(int256)\n # revert when it should not since we have the following assertion that fails:\n # [assert, [le, min_value(int256), max_value(int256) + 1 - 10]],\n for i in range(x, x + 10):\n pass\n```\n\n### Patches\n\npatched in v0.4.0, specifically, https://github.com/vyperlang/vyper/pull/3679 disallows this form of `range()`.\n\n### Impact\n\nAny contract having a `range(start, start + N)` where `start` is a signed integer with the possibility for `start` to be negative is affected. If a call goes through the loop while supplying a negative `start` the execution will revert.",
"id": "GHSA-ppx5-q359-pvwj",
"modified": "2024-04-25T19:53:43Z",
"published": "2024-04-25T19:53:43Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/vyperlang/vyper/security/advisories/GHSA-ppx5-q359-pvwj"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-32481"
},
{
"type": "WEB",
"url": "https://github.com/vyperlang/vyper/commit/3de1415ee77a9244eb04bdb695e249d3ec9ed868"
},
{
"type": "WEB",
"url": "https://github.com/vyperlang/vyper/commit/5319cfbe14951e007ccdb323257e5ada869b35d5"
},
{
"type": "PACKAGE",
"url": "https://github.com/vyperlang/vyper"
},
{
"type": "WEB",
"url": "https://github.com/vyperlang/vyper/blob/9136169468f317a53b4e7448389aa315f90b95ba/vyper/codegen/stmt.py#L286-L287"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "vyper\u0027s range(start, start + N) reverts for negative numbers"
}
GHSA-PWFG-G35M-WRCW
Vulnerability from github – Published: 2022-05-13 01:44 – Updated: 2022-05-13 01:44The Mem_File_Reader::read_avail function in Data_Reader.cpp in the Game_Music_Emu library (aka game-music-emu) 0.6.1 does not ensure a non-negative size, which allows remote attackers to cause a denial of service (application crash) via a crafted file.
{
"affected": [],
"aliases": [
"CVE-2017-17446"
],
"database_specific": {
"cwe_ids": [
"CWE-681"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2017-12-06T19:29:00Z",
"severity": "MODERATE"
},
"details": "The Mem_File_Reader::read_avail function in Data_Reader.cpp in the Game_Music_Emu library (aka game-music-emu) 0.6.1 does not ensure a non-negative size, which allows remote attackers to cause a denial of service (application crash) via a crafted file.",
"id": "GHSA-pwfg-g35m-wrcw",
"modified": "2022-05-13T01:44:24Z",
"published": "2022-05-13T01:44:24Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2017-17446"
},
{
"type": "WEB",
"url": "https://bitbucket.org/mpyne/game-music-emu/issues/14/addresssanitizer-negative-size-param-size"
},
{
"type": "WEB",
"url": "https://bugs.debian.org/883691"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-QG8W-6WVF-6VP6
Vulnerability from github – Published: 2022-10-11 12:00 – Updated: 2022-10-12 12:00An integer conversion error in Hermes bytecode generation, prior to commit 6aa825e480d48127b480b08d13adf70033237097, could have been used to perform Out-Of-Bounds operations and subsequently execute arbitrary code. Note that this is only exploitable in cases where Hermes is used to execute untrusted JavaScript. Hence, most React Native applications are not affected.
{
"affected": [],
"aliases": [
"CVE-2022-40138"
],
"database_specific": {
"cwe_ids": [
"CWE-681"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-10-11T02:15:00Z",
"severity": "CRITICAL"
},
"details": "An integer conversion error in Hermes bytecode generation, prior to commit 6aa825e480d48127b480b08d13adf70033237097, could have been used to perform Out-Of-Bounds operations and subsequently execute arbitrary code. Note that this is only exploitable in cases where Hermes is used to execute untrusted JavaScript. Hence, most React Native applications are not affected.",
"id": "GHSA-qg8w-6wvf-6vp6",
"modified": "2022-10-12T12:00:29Z",
"published": "2022-10-11T12:00:46Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-40138"
},
{
"type": "WEB",
"url": "https://github.com/facebook/hermes/commit/6aa825e480d48127b480b08d13adf70033237097"
},
{
"type": "WEB",
"url": "https://www.facebook.com/security/advisories/CVE-2022-40138"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
Mitigation
Avoid making conversion between numeric types. Always check for the allowed ranges.
No CAPEC attack patterns related to this CWE.