From: Pankaj Raghav p.raghav@samsung.com
[ Upstream commit ff5c0466486ba8d07ab2700380e8fd6d5344b4e9 ]
The run_readelf() function reads the entire output of readelf into a single shell variable. For large object files with extensive debug information, the size of this variable can exceed the system's command-line argument length limit.
When this variable is subsequently passed to sed via `echo "${out}"`, it triggers an "Argument list too long" error, causing the script to fail.
Fix this by redirecting the output of readelf to a temporary file instead of a variable. The sed commands are then modified to read from this file, avoiding the argument length limitation entirely.
Signed-off-by: Pankaj Raghav p.raghav@samsung.com Signed-off-by: Josh Poimboeuf jpoimboe@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
## Comprehensive Analysis of Commit ff5c0466486ba
### 1. COMMIT MESSAGE ANALYSIS
**Subject**: `scripts/faddr2line: Fix "Argument list too long" error`
The commit message clearly identifies this as a **bug fix** with explicit use of the word "Fix" and a specific error being addressed.
**Key elements**: - **Problem identified**: The `run_readelf()` function stores readelf output in a shell variable, which can exceed the system's `ARG_MAX` limit (typically 2MB on Linux) - **Failure mode**: When `echo "${out}"` is used to pipe to sed, the shell expansion triggers "Argument list too long" (E2BIG error) - **Solution**: Redirect readelf output to a temporary file, have sed read from the file directly
**Important missing tags**: - **No `Cc: stable@vger.kernel.org` tag** - maintainer did not explicitly request backport - **No `Fixes:` tag** - though the bug was clearly introduced in commit `b8d9d9496c1e7`
---
### 2. CODE CHANGE ANALYSIS
The change modifies the `run_readelf()` function in `scripts/faddr2line`:
**Before (buggy code):** ```bash run_readelf() { local objfile=$1 local out=$(${READELF} --file-header --section-headers --symbols --wide $objfile)
ELF_FILEHEADER=$(echo "${out}" | sed -n '...') ELF_SECHEADERS=$(echo "${out}" | sed -n '...') ELF_SYMS=$(echo "${out}" | sed -n '...') } ```
**After (fixed code):** ```bash run_readelf() { local objfile=$1 local tmpfile tmpfile=$(mktemp)
${READELF} --file-header --section-headers --symbols --wide "$objfile" > "$tmpfile"
ELF_FILEHEADER=$(sed -n '...' "$tmpfile") ELF_SECHEADERS=$(sed -n '...' "$tmpfile") ELF_SYMS=$(sed -n '...' "$tmpfile")
rm -f -- "$tmpfile" } ```
**Technical mechanism of the bug**: 1. `readelf` output for large vmlinux with `CONFIG_DEBUG_INFO` can easily exceed 2MB 2. When bash expands `${out}` in `echo "${out}"`, the expanded text becomes part of the argument vector 3. Linux enforces `ARG_MAX` limit (~2MB by default) on total argument size for `execve()` 4. When exceeded, the kernel returns `E2BIG` error, causing "Argument list too long"
**Why the fix works**: - Writing to a file bypasses `ARG_MAX` entirely - `sed` can read arbitrarily large files without limit - `mktemp` ensures safe temp file creation; `rm -f -- "$tmpfile"` properly cleans up
**Code quality**: - Proper quoting of `"$objfile"` (fixed unquoted variable) - Uses `--` in `rm` to handle files starting with `-` - Clean, minimal change
---
### 3. CLASSIFICATION
- **Bug type**: Real functional bug causing tool failure - **Exception category**: This is a **BUILD/TOOL FIX** - faddr2line is a developer tool used for analyzing stack traces from kernel oopses - **Security implications**: None
---
### 4. SCOPE AND RISK ASSESSMENT
| Metric | Value | |--------|-------| | Lines changed | +9/-4 (13 total) | | Files modified | 1 (`scripts/faddr2line`) | | Subsystem | Developer scripts (not kernel runtime code) | | Risk level | **VERY LOW** |
**Why risk is minimal**: - It's a shell script, not compiled kernel code - Cannot cause kernel crashes or data corruption - Logically equivalent transformation (temp file vs shell variable) - Well-understood shell programming pattern
---
### 5. USER IMPACT
**Who is affected**: - Kernel developers debugging oopses/crashes using faddr2line - Anyone using faddr2line on vmlinux with `CONFIG_DEBUG_INFO` enabled
**Impact severity**: - **HIGH within scope**: The tool fails completely on large object files - **Limited audience**: Developer tool, not end-user facing
**Real-world trigger**: - Building vmlinux with `CONFIG_DEBUG_INFO=y` (common for debugging) - Running `scripts/faddr2line vmlinux func+0x123` - If readelf output > 2MB, **script fails completely**
---
### 6. STABILITY INDICATORS
- **Author**: Pankaj Raghav (Samsung) - active kernel contributor - **Signed-off-by**: Josh Poimboeuf - **official MAINTAINER** for faddr2line per `MAINTAINERS` file - **No Tested-by tag**, but the fix is straightforward
---
### 7. DEPENDENCY CHECK
**Bug introduction**: Commit `b8d9d9496c1e7` ("scripts/faddr2line: Combine three readelf calls into one") first appeared in **v6.11-rc1**
**Affected stable versions**: - v6.11.y: **HAS BUGGY CODE** ✓ - v6.12.y: **HAS BUGGY CODE** ✓ - v6.6.y: Does NOT have buggy code (older implementation) - v6.1.y: Does NOT have buggy code (older implementation)
**Patch applicability**: - ✓ Applies cleanly to v6.11 - ✓ Applies cleanly to v6.12 - Not needed for v6.6 and earlier
**Dependencies**: None - completely self-contained fix
---
### 8. HISTORICAL CONTEXT
The bug was introduced as an unintended side effect of a performance optimization:
``` 39cf650d68289 (Apr 2024): Introduced run_readelf() with 3 separate readelf calls b8d9d9496c1e7 (Jul 2024): Combined into single readelf call, storing in variable ← BUG INTRODUCED HERE ff5c0466486ba (Oct 2025): Fix by using temp file instead of variable ```
The original optimization was well-intentioned (reduce readelf invocations from many to one), but the implementer didn't account for the `ARG_MAX` limit.
---
### FINAL ASSESSMENT
**Arguments FOR backporting**: 1. ✓ **Obviously correct**: The fix is a standard shell scripting pattern to avoid `ARG_MAX` limits 2. ✓ **Fixes real bug**: Tool fails completely on large vmlinux files (not theoretical) 3. ✓ **Small and contained**: Only 13 lines changed in one file 4. ✓ **No new features**: Pure bug fix 5. ✓ **Applies cleanly**: Tested on v6.11 and v6.12 6. ✓ **No dependencies**: Self-contained 7. ✓ **Zero runtime risk**: It's a shell script, not kernel code 8. ✓ **Maintainer approved**: Josh Poimboeuf signed off
**Arguments AGAINST backporting**: 1. ✗ No explicit `Cc: stable@vger.kernel.org` tag 2. ✗ No `Fixes:` tag pointing to the introducing commit 3. ✗ Developer tool, not end-user visible
**Verdict**: The lack of explicit stable tags is not disqualifying. This is a clear, surgical bug fix to a commonly-used developer tool. The fix has zero risk of causing regressions (it's a shell script), and it enables faddr2line to work correctly on large vmlinux files. For developers using stable kernels (6.11.y, 6.12.y) who need to debug kernel issues, having a functioning faddr2line is valuable.
The fix meets all the technical criteria for stable backporting: - Obviously correct - Fixes a real bug that affects users - Small and contained - No new features
**YES**
scripts/faddr2line | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/scripts/faddr2line b/scripts/faddr2line index 1fa6beef9f978..477b6d2aa3179 100755 --- a/scripts/faddr2line +++ b/scripts/faddr2line @@ -107,14 +107,19 @@ find_dir_prefix() {
run_readelf() { local objfile=$1 - local out=$(${READELF} --file-header --section-headers --symbols --wide $objfile) + local tmpfile + tmpfile=$(mktemp) + + ${READELF} --file-header --section-headers --symbols --wide "$objfile" > "$tmpfile"
# This assumes that readelf first prints the file header, then the section headers, then the symbols. # Note: It seems that GNU readelf does not prefix section headers with the "There are X section headers" # line when multiple options are given, so let's also match with the "Section Headers:" line. - ELF_FILEHEADER=$(echo "${out}" | sed -n '/There are [0-9]* section headers, starting at offset|Section Headers:/q;p') - ELF_SECHEADERS=$(echo "${out}" | sed -n '/There are [0-9]* section headers, starting at offset|Section Headers:/,$p' | sed -n '/Symbol table .* contains [0-9]* entries:/q;p') - ELF_SYMS=$(echo "${out}" | sed -n '/Symbol table .* contains [0-9]* entries:/,$p') + ELF_FILEHEADER=$(sed -n '/There are [0-9]* section headers, starting at offset|Section Headers:/q;p' "$tmpfile") + ELF_SECHEADERS=$(sed -n '/There are [0-9]* section headers, starting at offset|Section Headers:/,$p' "$tmpfile" | sed -n '/Symbol table .* contains [0-9]* entries:/q;p') + ELF_SYMS=$(sed -n '/Symbol table .* contains [0-9]* entries:/,$p' "$tmpfile") + + rm -f -- "$tmpfile" }
check_vmlinux() {