Buffer Overflow (OOB Write/Read) in `Hardware` and `Revision` Parsing
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 1.2k
- Forks
- 409
- PR merge metrics
- No merged PRs in 30d
Description
I found this while trying to figure out why I was getting errors when running under strict checks (#402). While this wasn't the cause of my errors, I think it's a real (separate) bug.
The /proc/cpuinfo parser in src/arm/linux/cpuinfo.c has a logic error when handling Hardware and Revision values that are equal to or longer than the maximum buffer size (CPUINFO_HARDWARE_VALUE_MAX and CPUINFO_REVISION_VALUE_MAX, both 64).
This leads to:
- Out-of-bounds write of 1 byte (null terminator) if the value length is exactly 64.
- Lack of null-termination (potentially leading to out-of-bounds reads later) if the value length is greater than 64.
Affected Code
In src/arm/linux/cpuinfo.c:
Scenario 1: value_length == 64 (equal to CPUINFO_HARDWARE_VALUE_MAX)
- The
ifconditionvalue_length > 64is false. - The
elsebranch is executed:state->hardware[64] = '\0';. - Since
state->hardwareischar hardware[64], index 64 is out of bounds (valid indices are 0-63). This is a 1-byte OOB write.
Scenario 2: value_length > 64 (e.g., 70)
- The
ifcondition is true. value_lengthis truncated to64.- The
elsebranch is skipped, so no null terminator is written. memcpycopies 64 bytes tostate->hardware.state->hardwareis left non-null-terminated. If it is later read as a C-string, it will cause an OOB read.
The same logic error exists for the Revision field.
Suggested Fix
Check for value_length >= LIMIT. If so, truncate to LIMIT - 1 and warn. Always write the null terminator at value_length after truncation/copying.
--- a/src/arm/linux/cpuinfo.c
+++ b/src/arm/linux/cpuinfo.c
@@ -872,31 +873,29 @@
/* BogoMIPS is useless, don't parse */
} else if (memcmp(line_start, "Hardware", key_length) == 0) {
size_t value_length = value_end - value_start;
- if (value_length > CPUINFO_HARDWARE_VALUE_MAX) {
+ if (value_length >= CPUINFO_HARDWARE_VALUE_MAX) {
cpuinfo_log_warning(
"length of Hardware value \"%.*s\" in /proc/cpuinfo exceeds limit (%d): truncating to the limit",
(int)value_length,
value_start,
- CPUINFO_HARDWARE_VALUE_MAX);
- value_length = CPUINFO_HARDWARE_VALUE_MAX;
- } else {
- state->hardware[value_length] = '\0';
+ CPUINFO_HARDWARE_VALUE_MAX - 1);
+ value_length = CPUINFO_HARDWARE_VALUE_MAX - 1;
}
+ state->hardware[value_length] = '\0';
memcpy(state->hardware, value_start, value_length);
cpuinfo_log_debug(
"parsed /proc/cpuinfo Hardware = \"%.*s\"", (int)value_length, value_start);
} else if (memcmp(line_start, "Revision", key_length) == 0) {
size_t value_length = value_end - value_start;
- if (value_length > CPUINFO_REVISION_VALUE_MAX) {
+ if (value_length >= CPUINFO_REVISION_VALUE_MAX) {
cpuinfo_log_warning(
"length of Revision value \"%.*s\" in /proc/cpuinfo exceeds limit (%d): truncating to the limit",
(int)value_length,
value_start,
- CPUINFO_REVISION_VALUE_MAX);
- value_length = CPUINFO_REVISION_VALUE_MAX;
- } else {
- state->revision[value_length] = '\0';
+ CPUINFO_REVISION_VALUE_MAX - 1);
+ value_length = CPUINFO_REVISION_VALUE_MAX - 1;
}
+ state->revision[value_length] = '\0';
memcpy(state->revision, value_start, value_length);
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/arm/linux/cpuinfo.c at the linked Hardware and Revision parsing code, and inspect how value_length is handled against CPUINFO_HARDWARE_VALUE_MAX and CPUINFO_REVISION_VALUE_MAX. Exercise the parser with values of length 64 and greater than 64 for both fields; done means the buffers remain safely terminated without out-of-bounds access and the existing truncation warning behavior is preserved.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- operating-systems, security
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100