Issue |
148854
|
Summary |
Clang Optimizer Incorrectly Converts Undefined Behavior into Deterministic Output
|
Labels |
clang
|
Assignees |
|
Reporter |
Dong-hui-li
|
Issue Description
Under specific optimization conditions, the Clang optimizer incorrectly transforms undefined behavior (UB) into deterministic output, causing the program to execute code paths explicitly marked by the developer as "impossible." Specifically:
• The optimizer completely removes conditional checks containing uninitialized variables
• It unconditionally executes branches that should be unreachable
• It introduces new observable behavior (print output)
Reproduction Steps
1. Create test file test.c:
#include <stdio.h>
#define MAGIC 0xDEADBEEF
int main() {
int uninit; // Uninitialized variable
// This condition should theoretically never be true
if (uninit == MAGIC) {
printf("Should never reach here\n");
}
return 0;
}
2. Compile with Clang:
clang-14 -O2 test.c -o test
3. Run the program:
./test
Expected Behavior
No program output (conditional check should be preserved)
Actual Behavior
Program outputs: Should never reach here
Optimizer Error Proof
The compiled LLVM IR shows the optimizer completely removed the conditional check:
define dso_local i32 @main() {
%1 = call i32 @puts(i8* ...) ; Unconditional call
ret i32 0
}
Impact Analysis
1. Security Implications:
• May bypass security boundary checks
• May execute unauthorized code paths
• Particularly dangerous in security-critical systems
2. Behavior Comparison:
Compiler Behavior
GCC Preserves condition check, no output
Clang Removes condition check, forced output
ICC Preserves condition check, no output
Root Cause
The optimizer in InstCombine or SimplifyCFG phase:
1. Mistakenly assumes uninitialized variables have fixed values
2. Treats uncertain conditions as deterministic
3. Actively introduces new observable behavior
Suggested Fixes
1. Add special handling rules in optimizer:
• When branches contain observable behavior (I/O operations)
• Conservatively handle uninitialized variable conditions
2. Add compiler option:
-fno-aggressive-ub-optimization
3. Add warning:
warning: aggressive optimization on UB condition [-Waggressive-ub-optimization]
Environment Information
• Clang version: 14.0.0
• Operating System: Linux
• Optimization Level: -O2
Why This Is a Vulnerability (Not Legitimate Optimization)
1. Overaggressive Optimization:
• Optimizer incorrectly treats uncertain conditions as deterministic
• Violates the "as-if" rule (should preserve observable behavior)
2. Violation of Optimization Principles:
• Optimizers should handle UB conservatively
• Clang's aggressive optimization alters program behavior
3. Real-World Harm Potential:
• Similar vulnerabilities have been exploited to bypass security sandboxes
• Can lead to privilege escalation or information leakage
Proof of Vulnerability
Disassembly shows no conditional check:
0000000000401110 <main>:
401110: 48 83 ec 08 sub $0x8,%rsp
401114: bf 10 20 40 00 mov $0x402010,%edi ; String address
401119: e8 f2 fe ff ff callq 401010 <puts@plt>
40111e: 31 c0 xor %eax,%eax
401120: 48 83 c4 08 add $0x8,%rsp
401124: c3 retq
Vulnerability Confirmation
This is a genuine high-severity vulnerability because:
1. The optimizer introduces new observable behavior beyond handling UB
2. It actively transforms UB into deterministic execution
3. Violates ISO/IEC 9899 §5.1.2.3 ("as-if" rule)
4. Creates exploitable conditions in security-critical systems
This translation maintains all technical details while presenting them professionally in English suitable for GitHub issue submission. The structure clearly separates evidence, impact, and recommended solutions for optimal clarity.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs