{"id":"CVE-2021-21401","aliases":["GHSA-7mv5-5mxh-qg88","PYSEC-2021-432"],"title":"nanopb vulnerable to invalid free() call with oneofs and PB_ENABLE_MALLOC","summary":"nanopb vulnerable to invalid free() call with oneofs and PB_ENABLE_MALLOC","severity":"high","cvss":7.1,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L","vendor":"nanopb","product":"nanopb","ecosystem":"pip","affected":["nanopb >= 0.3.2, < 0.3.9.8","nanopb >= 0.4.0, < 0.4.5"],"patched":["nanopb 0.3.9.8","nanopb 0.4.5"],"published":"2024-08-30","updated":"2026-07-08","source":"OSV","sourceUrl":"https://osv.dev/vulnerability/GHSA-7mv5-5mxh-qg88","references":[{"url":"https://github.com/nanopb/nanopb/security/advisories/GHSA-7mv5-5mxh-qg88"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2021-21401"},{"url":"https://github.com/nanopb/nanopb/issues/647"},{"url":"https://github.com/nanopb/nanopb/commit/4a375a560651a86726e5283be85a9231fd0efe9c"},{"url":"https://github.com/nanopb/nanopb/commit/e2f0ccf939d9f82931d085acb6df8e9a182a4261"},{"url":"https://github.com/nanopb/nanopb"},{"url":"https://github.com/nanopb/nanopb/blob/c9124132a604047d0ef97a09c0e99cd9bed2c818/CHANGELOG.txt#L1"},{"url":"https://github.com/pypa/advisory-database/tree/main/vulns/nanopb/PYSEC-2021-432.yaml"}],"tags":["osv","pip","exploit-available"],"epss":0.01811,"epssPercentile":0.77672,"ingestedAt":"2026-07-08T18:25:47.048Z","exploits":{"github":1,"githubRepos":["https://github.com/uthrasri/CVE-2021-21401_nanopb-c_AOSP10_R33"],"checkedAt":"2026-09-23T07:13:26.925Z"},"exploitAvailable":true,"slug":"CVE-2021-21401","body":"## Overview\n\n### Impact\nDecoding a specifically formed message can cause invalid `free()` or `realloc()` calls if the message type contains an `oneof` field, and the `oneof` directly contains both a pointer field and a non-pointer field. If the message data first contains the non-pointer field and then the pointer field, the data of the non-pointer field is incorrectly treated as if it was a pointer value. Such message data rarely occurs in normal messages, but it is a concern when untrusted data is parsed.\n\n### Patches\nPreliminary patch is available on git for [0.4.x](https://github.com/nanopb/nanopb/commit/e2f0ccf939d9f82931d085acb6df8e9a182a4261) and [0.3.x](https://github.com/nanopb/nanopb/commit/4a375a560651a86726e5283be85a9231fd0efe9c) branches. The fix will be released in versions 0.3.9.8 and 0.4.5 once testing has been completed.\n\n### Workarounds\nFollowing workarounds are available:\n* Set the option `no_unions` for the oneof field. This will generate fields as separate instead of C union, and avoids triggering the problematic code.\n* Set the type of all fields inside the oneof to `FT_POINTER`. This ensures that the data contained inside the `union` is always a valid pointer.\n* Heap implementations that guard against invalid `free()` provide a partial mitigation. Depending on the message type, the pointer value may be attacker controlled and can be used to bypass heap protections.\n\n### References\nBug report: https://github.com/nanopb/nanopb/issues/647\n\n### For more information\nIf you have any questions or comments about this advisory, comment on the bug report linked above.\n\n## Affected packages\n\n- `nanopb >= 0.3.2, < 0.3.9.8`\n- `nanopb >= 0.4.0, < 0.4.5`\n\n## Remediation\n\nUpgrade to a patched release:\n\n- `nanopb 0.3.9.8`\n- `nanopb 0.4.5`","depth":"midnight","depthScore":51,"depthScoreParts":{"impact":39.1,"likelihood":0.4,"exploitation":12,"ransomware":0},"changes":[{"seq":4675,"id":"CVE-2021-21401","ts":1788887198194,"field":"exploit_available","old":"false","new":"true"},{"seq":3558,"id":"CVE-2021-21401","ts":1788886314376,"field":"exploit_available","old":"true","new":"false"},{"seq":2412,"id":"CVE-2021-21401","ts":1788882983581,"field":"exploit_available","old":"false","new":"true"},{"seq":1441,"id":"CVE-2021-21401","ts":1788882396551,"field":"exploit_available","old":"true","new":"false"},{"seq":555,"id":"CVE-2021-21401","ts":1788881832879,"field":"exploit_available","old":"false","new":"true"}]}