CURLX_SET_BINMODE(NULL) can call fileno(NULL) and cause undefined behavior / crash
What the report claims
Calling CURLX_SET_BINMODE(NULL) leads to an unguarded call to fileno(NULL) causing undefined behavior or crash.
Compare with curl's recorded outcome
Labeled AI slop
curl's maintainer lists this report as AI slop
Shown for comparison after analysis. The pipeline did not see this label.
ProveIt's finding
Key code references could not be verified in the targeted curl version.
curl policy: API misuseWhy this finding?
- The report itself states 'This is non-security; public PR is appropriate.'
- The project policy's 'API misuse' section says issues triggered by using the API in undocumented/unsupported ways are not security problems.
- The macro expects a valid FILE*; passing NULL is API misuse, not a vulnerability.
- The location claim (tool_binmode.h) is factually incorrect — the macro is in lib/curlx/binmode.h.
How this analysis ran 5 claims · 4 citations verified
Checked against curl master on 2025-10-27 (ab20bb47cf4c). Dev evaluation split. Citation verification checks that a referenced line was in the evidence; it does not prove the model interpreted it correctly.
Review a draft reply to the reporter
Edit and verify before sending.
Thank you for the report and the reproducible test case. The macro CURLX_SET_BINMODE in lib/curlx/binmode.h does indeed call fileno(stream) without a NULL check, so passing NULL invokes undefined behavior. However, this falls under our 'API misuse' policy: the macro is documented to take a valid FILE* stream, and passing NULL is not a supported use case. We do not treat such NULL-dereference crashes from API misuse as security vulnerabilities. We may still accept a robustness fix (e.g., a NULL guard) as a regular bug fix via a public PR.
Inspect all claims and source code 5 claims · 3 code excerpts
Report claims
Calling CURLX_SET_BINMODE(NULL) results in an unguarded call to fileno(NULL)
Read the reasoning
The macro expands directly to fileno(stream) with no guard. If stream is NULL, fileno(NULL) is called, which is undefined behavior per POSIX.
in tool_binmode.h
Read the reasoning
The report states the macro is in tool_binmode.h, but the deterministic check confirms no such file exists in curl's history. The macro resides in lib/curlx/binmode.h.
passing NULL as the stream argument to CURLX_SET_BINMODE
Read the reasoning
The trigger is simply passing NULL as the argument, which the macro does not validate.
may crash the process or cause undefined behavior
Read the reasoning
Calling fileno with a NULL FILE* is undefined behavior; the report correctly identifies the consequence.
run the provided test program that calls CURLX_SET_BINMODE(NULL)
Read the reasoning
The reproduction steps are clear and would demonstrate the behavior.
Deterministic checks that failed
- file no file named include/tool_binmode.h has ever existed in curl
Read the original report (excerpt)
Source code
| 31 | # define CURLX_SET_BINMODE(stream) (void)_setmode(fileno(stream), O_BINARY) |
| C1: Macro definition: #define CURLX_SET_BINMODE(stream) (void)_setmode(fileno(stream), O_BINARY) — no NULL check before calling fileno(stream) | |
| C2: The macro is actually defined in lib/curlx/binmode.h, not tool_binmode.h | |
| C3: The macro takes a 'stream' parameter; passing NULL triggers the unguarded fileno(NULL) call | |
| C4: fileno(NULL) is undefined behavior per POSIX and can crash on many platforms |
| 241 | int main(int argc, char **argv) |
| 242 | { |
| 243 | size_t i; |
| 244 | |
| 245 | (void)argc; |
| 246 | (void)argv; |
| 247 | |
| 248 | for(i = 0; i < CURL_ARRAYSIZE(disabled); i++) |
| 249 | /* !checksrc! disable BANNEDFUNC 1 */ |
| 250 | printf("%s\n", disabled[i]); |
| 251 | |
| 252 | return 0; |
| 253 | } |
Show 12 lines (not cited by the judge)
| 243 | int main(int argc, char **argv) |
| 244 | { |
| 245 | int i; |
| 246 | |
| 247 | (void)argc; |
| 248 | (void)argv; |
| 249 | |
| 250 | for(i = 0; disabled[i]; i++) |
| 251 | printf("%s\n", disabled[i]); |
| 252 | |
| 253 | return 0; |
| 254 | } |