✓ProveIt
Examples / Report #3468410 Saved analysis

Heap buffer overflow in Curl_ipv4_resolve_r due to incorrect buffer alignment and size calculation on AmigaOS

curl · 2025-12-1721.7s analysis · $0.015 in model calls

What the report claims

Heap buffer overflow in Curl_ipv4_resolve_r due to incorrect buffer alignment and size calculation on AmigaOS

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

Needs human review

The available evidence does not settle the report. A maintainer should investigate.

Why this finding?
  • The core claim (C1) about incorrect alignment/size calculation depends on AmigaOS bsdsocket.library ABI and struct hostent definition, which are not in the provided curl source.
  • The code uses sizeof(struct hostent) for the hostent buffer offset, which includes internal padding, but the data buffer pointer may need stricter alignment than the hostent structure provides.
  • Without the platform-specific headers or documentation for gethostbyname_r, the claim cannot be confirmed or contradicted from the provided code alone.
  • If the alignment issue exists, it would be a heap buffer overflow reachable via attacker-controlled hostnames (C5 supported), making it a plausible security issue on AmigaOS.
What still needs checking
  • Definition of struct hostent on AmigaOS (from system headers)
  • Signature and buffer alignment requirements of gethostbyname_r in bsdsocket.library
  • AmigaOS SDK documentation for the reentrant resolver API
How this analysis ran 5 claims · 8 citations verified

Checked against curl master on 2025-12-17 (1b205078bd7f). Dev evaluation split. Citation verification checks that a referenced line was in the evidence; it does not prove the model interpreted it correctly.

1 · Grounding
grounded
no model · 4 references checked out, 0 did not
2 · Claims
NVIDIA-Nemotron-3-Nano-30B-A3B
5 claims · 1131 tokens · $0.0001
3 · Evidence
3 code snippets
real curl source at 1b205078bd7f
4 · Judgment
Nemotron-3-Ultra-550b-a55b
7971 tokens · 20.0s · $0.0147
5 · Receipts
8 of 8 citations verified
every citation must point at code the judge was shown
Review a draft reply to the reporter

Edit and verify before sending.

Thank you for the report. The code in lib/amigaos.c does show a fixed-size buffer (CURL_HOSTENT_SIZE=9000) split between struct hostent and a data buffer using sizeof(struct hostent). However, whether this calculation is incorrect depends on the alignment requirements of AmigaOS's bsdsocket.library gethostbyname_r and the definition of struct hostent, which are not in the curl source. Could you provide the relevant AmigaOS header definitions or bsdsocket.library documentation that specifies the required alignment for the data buffer pointer? This would allow us to verify if the offset (char *)buf + sizeof(struct hostent) meets the ABI requirements.

Inspect all claims and source code 5 claims · 3 code excerpts

Report claims

C1flaw not verifiable

incorrect buffer alignment and size calculation

Read the reasoning

The code shows the buffer size calculation, but whether it is incorrect depends on the alignment requirements of the AmigaOS bsdsocket.library's gethostbyname_r and the definition of struct hostent, which are not in the provided source. sizeof(struct hostent) includes internal padding, but the data buffer pointer may need stricter alignment than the hostent structure's natural alignment. Without the platform ABI or header definitions, the claim cannot be verified from the provided code alone.

C2location supported

in lib/amigaos.c

Read the reasoning

The function Curl_ipv4_resolve_r is defined in lib/amigaos.c at line 123 in the provided source.

C3trigger supported

uses gethostbyname_r() with a fixed-size heap buffer

Read the reasoning

The code shows a fixed-size heap buffer (CURL_HOSTENT_SIZE = 9000) allocated via curlx_calloc and passed to gethostbyname_r.

C4impact not verifiable

may trigger heap memory corruption

Read the reasoning

Whether heap memory corruption can be triggered depends on whether C1 (incorrect alignment/size calculation) is true. Since C1 is not_verifiable from the provided code, the impact claim cannot be verified either.

C5reproduction supported

DNS responses or resolution of attacker-controlled hostnames

Read the reasoning

The function resolves hostnames passed to it; an attacker who can influence DNS responses or control resolved hostnames could trigger this code path.

Read the original report

Full report on HackerOne ↗

Summary: A heap-based buffer overflow exists in the AmigaOS-specific DNS resolution function Curl_ipv4_resolve_r located in lib/amigaos.c. The function uses gethostbyname_r() with a fixed-size heap buffer (CURL_HOSTENT_SIZE) and performs incorrect pointer arithmetic when calculating the data buffer offset and size. This fails to account for structure alignment and padding requirements, which can result in the resolver writing past the allocated heap buffer. The issue is specific to AmigaOS builds using the bsdsocket.library backend. ## Impact Impact Summary: An attacker who can influence DNS responses or cause resolution of attacker- controlled hostnames may trigger heap memory corruption in curl or libcurl processes on AmigaOS. Potential impacts include: - Process crash (denial of service) - Heap memory corruption - Possible code execution depending on heap layout and mitigations The impact is limited to AmigaOS platforms.

Source code

lib/amigaos.clines 123–172 · definition of Curl_ipv4_resolve_r
123struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port)
C2: Curl_ipv4_resolve_r defined in lib/amigaos.c
C5: Curl_ipv4_resolve_r takes hostname parameter
124{
125 struct Curl_addrinfo *ai = NULL;
126 struct hostent *h;
127 struct SocketIFace *ISocket = __CurlISocket;
128
129 if(SocketFeatures & HAVE_BSDSOCKET_GETHOSTBYNAME_R) {
130 LONG h_errnop = 0;
131 struct hostent *buf;
132
133 buf = curlx_calloc(1, CURL_HOSTENT_SIZE);
C1: Buffer allocated with curlx_calloc(1, CURL_HOSTENT_SIZE)
C3: buf = curlx_calloc(1, CURL_HOSTENT_SIZE) allocates fixed-size heap buffer
134 if(buf) {
135 h = gethostbyname_r((STRPTR)hostname, buf,
C1: gethostbyname_r called with data buffer at (char *)buf + sizeof(struct hostent) and size CURL_HOSTENT_SIZE - sizeof(struct hostent)
C3: gethostbyname_r called with this buffer
C5: hostname passed to gethostbyname_r
136 (char *)buf + sizeof(struct hostent),
137 CURL_HOSTENT_SIZE - sizeof(struct hostent),
138 &h_errnop);
139 if(h) {
140 ai = Curl_he2ai(h, port);
141 }
142 curlx_free(buf);
143 }
144 }
145 else {
146#ifdef CURLRES_THREADED
147 /* gethostbyname() is not thread-safe, so we need to reopen bsdsocket
148 * on the thread's context
149 */
150 struct Library *base = OpenLibrary("bsdsocket.library", 4);
151 if(base) {
152 ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL);
153 if(ISocket) {
154 h = gethostbyname((STRPTR)hostname);
155 if(h) {
156 ai = Curl_he2ai(h, port);
157 }
158 DropInterface((struct Interface *)ISocket);
159 }
160 CloseLibrary(base);
161 }
162#else
163 /* not using threaded resolver - safe to use this as-is */
164 h = gethostbyname(hostname);
165 if(h) {
166 ai = Curl_he2ai(h, port);
167 }
168#endif
169 }
170
171 return ai;
172}
lib/hostip.hlines 45–45 · definition of CURL_HOSTENT_SIZE
45#define CURL_HOSTENT_SIZE 9000
C1: CURL_HOSTENT_SIZE defined as 9000
lib/amigaos.c@curl-8_17_0lines 127–177 · definition of Curl_ipv4_resolve_r as in release curl-8_17_0; differs from master; commits that changed it since: 61273f5812 badwords: catch and fix threading-related words | 47a1ab2ebe lib: fix formatting nits (part 1) | 193cb00ce9 build: stop overriding standard memory allocation functions
Show 51 lines (not cited by the judge)
127struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
128 int port)
129{
130 struct Curl_addrinfo *ai = NULL;
131 struct hostent *h;
132 struct SocketIFace *ISocket = __CurlISocket;
133
134 if(SocketFeatures & HAVE_BSDSOCKET_GETHOSTBYNAME_R) {
135 LONG h_errnop = 0;
136 struct hostent *buf;
137
138 buf = calloc(1, CURL_HOSTENT_SIZE);
139 if(buf) {
140 h = gethostbyname_r((STRPTR)hostname, buf,
141 (char *)buf + sizeof(struct hostent),
142 CURL_HOSTENT_SIZE - sizeof(struct hostent),
143 &h_errnop);
144 if(h) {
145 ai = Curl_he2ai(h, port);
146 }
147 free(buf);
148 }
149 }
150 else {
151 #ifdef CURLRES_THREADED
152 /* gethostbyname() is not thread safe, so we need to reopen bsdsocket
153 * on the thread's context
154 */
155 struct Library *base = OpenLibrary("bsdsocket.library", 4);
156 if(base) {
157 ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL);
158 if(ISocket) {
159 h = gethostbyname((STRPTR)hostname);
160 if(h) {
161 ai = Curl_he2ai(h, port);
162 }
163 DropInterface((struct Interface *)ISocket);
164 }
165 CloseLibrary(base);
166 }
167 #else
168 /* not using threaded resolver - safe to use this as-is */
169 h = gethostbyname(hostname);
170 if(h) {
171 ai = Curl_he2ai(h, port);
172 }
173 #endif
174 }
175
176 return ai;
177}