CVE-2023-36327 - Integer Overflow in RELIC’s bn_get_prime() Lets Attackers Run Any Code
---
Summary:
A critical vulnerability, CVE-2023-36327, was discovered in the RELIC Cryptographic Toolkit. This bug is an *integer overflow* in the bn_get_prime() function, which may allow an attacker to execute arbitrary code or crash your application (Denial of Service). In this post, I’ll walk you through what happened, show you code snippets to help you understand, and explain why it’s such a big deal—using simple American English.
What is RELIC?
RELIC Toolkit is an open-source cryptographic library, often used in blockchain, research, and privacy-focused software. It provides primitives for things like big numbers, elliptic curves, and advanced mathematics.
The Vulnerability Explained
The root of the problem is in the function bn_get_prime(), which is designed to generate big (probably safe) prime numbers—a must-have for crypto systems. Before commit 421f2e91cf2ba42473d4d54daf24e295679e290e, the code did not correctly check its calculations on the pos argument, allowing an *integer overflow* to slip in.
- Integer Overflow: This is when a number gets too big for its variable and “wraps around” into negative or very small values—imagine your car’s odometer turning back to zero after too many miles.
- What this means: The attacker can send in a sneaky number as the pos argument, tricking your app into allocating a too-small buffer, then writing past it. This opens up code execution and DOS.
Here’s an unsafe version of the function (simplified)
int bn_get_prime(bn_t a, int bits, int safe, int pos, int rem, int checks) {
bn_zero(a);
bn_set_bit(a, bits - 1); // Set top bit
for (int i = ; i < pos; i++) {
bn_rand(a); // Fill numbers
}
// More operations...
// At some point, the lack of boundary checks causes trouble!
}
In the buggy code, there are no checks for how big pos is. If you pass in a huge pos value, the loop will misbehave, possibly allocating and writing memory where it shouldn't.
The Patch
The RELIC team fixed the error in commit 421f2e91cf2ba42473d4d54daf24e295679e290e:
Also changed how allocations happen so memory is not under-allocated.
Check the actual diff here.
Buffer is too small: The rest of the function writes more data than there's room for.
3. Overwrite memory: Classic buffer overflow—so things like pointers, return addresses, or function hooks are in danger.
4. Remote Code Execution: If the attacker is lucky, they can control the memory enough to hijack the program and run their code.
We're not giving real exploit code, but here’s a pseudo-code idea
# This only works if bn_get_prime() is exposed somehow (rare!).
payload = {
"bits": 256,
"safe": 1,
"pos": 2**31, # INT_MAX or similar
"rem": 1,
"checks": 1
}
# Send this to software using old RELIC (before the patch).
# The library crashes, or attacker controls execution flow.
If your system uses RELIC and receives untrusted input for these functions, you are at high risk!
How to Stay Safe
- Upgrade Now: Use RELIC with commit 421f2e91cf2ba42473d4d54daf24e295679e290e or newer.
References
- GitHub Commit Fixing the Bug
- CVE Record on Mitre
- RELIC Homepage
- OSS-Security List Reference
Conclusion
CVE-2023-36327 is a textbook example of how small mistakes in cryptographic code can lead to big risks. Integer overflows are easy to miss but can be devastating in deep C code, especially in libraries handling cryptography. If you’re building or maintaining apps with RELIC, updating is not just a recommendation—it’s essential.
Stay safe, keep libraries up to date, and remember: in security, the devil is always in the details!
Timeline
Published on: 09/01/2023 16:15:08 UTC
Last modified on: 09/06/2023 00:05:15 UTC