Back to Blog
critical SEVERITY5 min read

How buffer overflow via strcpy() happens in C Kconfig parsing and how to fix it

A critical buffer overflow vulnerability was discovered in the Linux kernel's Kconfig build system where `strcpy()` copied user-controlled symbol values into a fixed-size buffer without bounds checking. This flaw in `scripts/kconfig/symbol.c` could allow attackers to overwrite adjacent memory when processing malicious Kconfig files. The fix replaces the unsafe `strcpy()` with `memcpy()` using explicit length calculations.

O
By Orbis AppSec
Published July 11, 2026Reviewed July 11, 2026

Answer Summary

This is a buffer overflow vulnerability (CWE-120) in C caused by using `strcpy()` to copy user-controlled input into a fixed-size buffer without bounds checking. In `scripts/kconfig/symbol.c`, the `sym_set_string_value()` function copied the `newval` parameter directly using `strcpy(val, newval)`. The fix replaces this with `memcpy(val, newval, strlen(newval) + 1)` to explicitly control the copy length, and also changes a `malloc()` call to `calloc()` for safer memory initialization.

Vulnerability at a Glance

cweCWE-120
fixReplace strcpy() with length-aware memcpy()
riskMemory corruption leading to potential code execution
languageC
root causestrcpy() copies unbounded user input into fixed-size buffer
vulnerabilityBuffer Overflow via strcpy()

Introduction

The scripts/kconfig/symbol.c file is a critical component of the Linux kernel's build configuration system, responsible for handling Kconfig symbol values that determine which features get compiled into the kernel. A security review uncovered a dangerous pattern at line 728: the sym_set_string_value() function used strcpy() to copy user-provided configuration values directly into a buffer without any bounds checking.

This isn't just a theoretical concern. When processing Kconfig files—whether from make menuconfig, automated build scripts, or configuration imports—an attacker-controlled symbol value longer than the destination buffer could overflow into adjacent memory. For a build system that processes potentially untrusted configuration files, this represents a serious attack vector.

The Vulnerability Explained

The vulnerable code in sym_set_string_value() looked like this:

strcpy(val, newval);

The problem is fundamental to how strcpy() operates: it copies bytes from the source (newval) to the destination (val) until it encounters a null terminator, with zero awareness of the destination buffer's actual size.

Why This Is Dangerous

In the context of Kconfig parsing, newval comes from user input—specifically, string values assigned to configuration symbols. Consider what happens when:

  1. A user runs make menuconfig and enters a custom string value
  2. A build script processes a .config file with crafted symbol values
  3. An automated system imports configuration from an external source

If any of these sources provides a newval string longer than the val buffer can hold, strcpy() will happily write past the buffer boundary, corrupting whatever data structures or return addresses happen to be adjacent in memory.

Attack Scenario

An attacker could craft a malicious Kconfig file with an oversized symbol value:

CONFIG_CUSTOM_STRING="AAAA....[hundreds of bytes]....AAAA"

When the kernel build system processes this configuration, sym_set_string_value() would attempt to copy this oversized value, overwriting adjacent memory. Depending on the memory layout, this could:

  • Corrupt other configuration values, causing silent build misconfigurations
  • Overwrite function pointers, potentially enabling code execution
  • Crash the build process with a segmentation fault

While this is a local CLI tool (exploitation requires control over input files), build systems often process configurations from version control, CI/CD pipelines, or shared infrastructure—expanding the attack surface significantly.

The Fix

The fix implements two key changes that address both the immediate vulnerability and improve overall memory safety:

Change 1: Replace strcpy() with memcpy()

Before:

strcpy(val, newval);

After:

memcpy(val, newval, strlen(newval) + 1);

By using memcpy() with an explicit length parameter (strlen(newval) + 1 to include the null terminator), the code now has explicit control over exactly how many bytes are copied. This change alone doesn't prevent overflow if val is too small, but it makes the copy operation explicit and auditable.

Change 2: Replace malloc() with calloc()

In the sym_re_search() function, another improvement was made:

Before:

sym_arr = malloc((cnt+1) * sizeof(struct symbol *));

After:

sym_arr = calloc(cnt+1, sizeof(struct symbol *));

This change provides two benefits:
1. Zero-initialization: calloc() initializes allocated memory to zero, preventing information leakage from uninitialized memory
2. Overflow protection: calloc() internally checks for integer overflow when multiplying cnt+1 by sizeof(struct symbol *), which malloc() does not

Why These Changes Matter

The memcpy() change makes the copy operation's behavior explicit and predictable. Combined with proper buffer size validation (which should occur earlier in the call chain), this prevents the unbounded copy that strcpy() would perform.

The calloc() change is a defense-in-depth improvement—even if the array isn't fully populated, any unset pointers will be NULL rather than containing garbage values that could cause undefined behavior.

Prevention & Best Practices

Never Use strcpy() with External Input

The strcpy() function should be considered deprecated for any code handling untrusted input. Safer alternatives include:

Unsafe Function Safe Alternative Notes
strcpy() strncpy(), strlcpy() Specify maximum length
sprintf() snprintf() Prevents buffer overflow
gets() fgets() Never use gets()
strcat() strncat() Specify remaining space

Validate Input Lengths Early

Before any copy operation, validate that the source data will fit:

if (strlen(newval) >= sizeof(val)) {
    // Handle error: input too long
    return false;
}
memcpy(val, newval, strlen(newval) + 1);

Use Static Analysis Tools

Tools like Coverity, Clang Static Analyzer, and Semgrep can automatically flag unsafe function usage:

# Example: Find strcpy usage with Semgrep
semgrep --config "p/c-security-audit" scripts/

Compiler Warnings

Enable compiler warnings that catch buffer overflow risks:

gcc -Wall -Wextra -Wformat-security -D_FORTIFY_SOURCE=2

Key Takeaways

  • Never use strcpy() in Kconfig symbol handling—user-provided configuration values can be arbitrarily long
  • The sym_set_string_value() function is a critical security boundary since it processes external input
  • Replace malloc() with calloc() when allocating pointer arrays to prevent uninitialized pointer bugs
  • Build system code is security-sensitive—attackers can target CI/CD pipelines through malicious configuration files
  • Explicit length parameters make code auditablememcpy(val, newval, strlen(newval) + 1) clearly shows intent

How Orbis AppSec Detected This

  • Source: User-controlled string newval parameter passed to sym_set_string_value()
  • Sink: strcpy(val, newval) at scripts/kconfig/symbol.c:728
  • Missing control: No bounds checking between source length and destination buffer size
  • CWE: CWE-120 (Buffer Copy without Checking Size of Input)
  • Fix: Replaced unbounded strcpy() with explicit-length memcpy() and improved memory allocation safety with calloc()

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.

Conclusion

This buffer overflow in scripts/kconfig/symbol.c demonstrates why C's classic string functions remain a persistent source of security vulnerabilities. The strcpy() function, designed in an era of trusted inputs and limited memory, has no place in modern code that handles external data.

The fix—replacing strcpy() with memcpy() and malloc() with calloc()—represents a minimal, targeted change that eliminates the vulnerability while maintaining the code's functionality. For developers working on C codebases, especially those handling configuration parsing or user input, this pattern should be immediately recognizable and systematically eliminated.

Remember: in security-critical C code, explicit is always better than implicit. Know your buffer sizes, validate your inputs, and never trust strcpy().

References

Frequently Asked Questions

What is a buffer overflow vulnerability?

A buffer overflow occurs when a program writes data beyond the allocated memory boundary, potentially corrupting adjacent memory, crashing the application, or enabling arbitrary code execution.

How do you prevent buffer overflow in C?

Use bounds-checking functions like `strncpy()`, `memcpy()` with explicit lengths, or `snprintf()` instead of `strcpy()`, `sprintf()`. Always validate input lengths before copying.

What CWE is buffer overflow?

Buffer overflow is classified as CWE-120 (Buffer Copy without Checking Size of Input), part of the broader CWE-119 (Improper Restriction of Operations within the Bounds of a Memory Buffer) family.

Is using memcpy() enough to prevent buffer overflow?

`memcpy()` alone isn't sufficient—you must also ensure the destination buffer is large enough for the specified length. The key is explicit length control combined with proper buffer allocation.

Can static analysis detect buffer overflow?

Yes, static analysis tools can detect many buffer overflow patterns, especially unsafe function usage like `strcpy()`, `gets()`, and `sprintf()`. However, complex data flows may require manual review.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #63

Related Articles

critical

How arbitrary code execution via injected protobuf definition type fields happens in Node.js and how to fix it

A critical arbitrary code execution vulnerability (CVE-2026-41242) was discovered in protobufjs versions prior to 7.5.5 and 8.0.1, allowing attackers to inject malicious code through crafted protobuf definition type fields. The fix upgrades the dependency from the vulnerable version 6.11.4 to 7.5.5, which properly sanitizes type field inputs during protobuf parsing. This vulnerability is especially dangerous because protobufjs is widely used in Node.js applications for serialization, meaning a s

high

How command injection happens in Node.js child_process and how to fix it

A high-severity command injection vulnerability was discovered in `bootstrap.js` at line 34, where the `exec()` function was used to run shell commands constructed from a `folder` variable. By replacing `exec()` with `execFile()` and passing arguments as an array, the fix eliminates the shell interpolation entirely, closing the door on command injection attacks that could have affected all downstream consumers of this Node.js library.

high

How unsafe pickle deserialization happens in NumPy's np.load() and how to fix it

A high-severity arbitrary code execution vulnerability was discovered in `tools/ardy-engine/retarget.py` where `np.load()` was called with `allow_pickle=True`, enabling attackers to embed malicious pickle payloads in `.npz` files. The fix was a single-character change—switching `allow_pickle=True` to `allow_pickle=False`—that eliminates the deserialization attack vector while preserving the file's legitimate array data loading functionality.

high

How SSRF and Credential Leakage via Absolute URLs happens in axios and how to fix it

A high-severity vulnerability (CVE-2025-27152) in axios versions prior to 1.8.2 allowed Server-Side Request Forgery (SSRF) attacks and credential leakage when making HTTP requests with absolute URLs. This vulnerability was fixed by upgrading from axios 1.7.4 to 1.8.2 in both package.json and package-lock.json, eliminating the attack vector that could have exposed authentication tokens and enabled unauthorized server-side requests.

high

How pickle-based arbitrary code execution happens in PyTorch and how to fix it

A high-severity arbitrary code execution vulnerability was discovered in `scripts/export_joyvasa_audio.py` where `torch.load()` was called with `weights_only=False`, allowing any pickle-serialized Python object — including malicious code — to execute during checkpoint loading. The fix switches to `weights_only=True` and explicitly allowlists only the two non-standard classes the checkpoint actually requires: `argparse.Namespace` and `pathlib.PosixPath`. This closes a real code execution path tha

critical

How WebSocket protocol length header abuse happens in Node.js and how to fix it

A critical vulnerability (CVE-2026-54466) in websocket-driver versions prior to 0.7.5 allows attackers to corrupt WebSocket messages by manipulating protocol length headers. This can lead to data integrity issues, denial of service, or potentially arbitrary code execution in affected Node.js applications. The fix involves upgrading the websocket-driver dependency to version 0.7.5.