✓ProveIt
Examples / Report #550696 Saved analysis

CVE-2019-5436: Heap Buffer Overflow at lib/tftp.c

curl · 2019-04-2911.6s analysis · $0.010 in model calls

What the report claims

A heap buffer overflow can occur in lib/tftp.c due to state->blksize containing the default size instead of the size specified in the --tftp-blksize parameter.

Compare with curl's recorded outcome

Known vulnerability

A real vulnerability: CVE-2019-5436 TFTP receive buffer overflow

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 state->blksize not reflecting --tftp-blksize cannot be verified because the option parsing and blksize initialization code are not in the provided snippets.
  • The recvfrom call at line 1114 is confirmed, but the buffer size (state->rpacket.data) and how blksize is set are unknown from provided code.
  • A human needs to examine the full lib/tftp.c to check: (1) tftp_state_data_t definition for rpacket.data size, (2) where state->blksize is initialized, (3) where --tftp-blksize is parsed and whether it updates state->blksize.
What still needs checking
  • tftp_state_data_t structure definition (showing rpacket.data buffer size)
  • Code that initializes state->blksize (likely in tftp_connect or tftp_do)
  • Code that parses --tftp-blksize option and assigns it to state->blksize
How this analysis ran 5 claims · 1 citations verified

Checked against curl master on 2019-04-29 (9e8f28a8f1fe). 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 · 1289 tokens · $0.0002
3 · Evidence
2 code snippets
real curl source at 9e8f28a8f1fe
4 · Judgment
Nemotron-3-Ultra-550b-a55b
5185 tokens · 6.1s · $0.0094
5 · Receipts
1 of 1 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 recvfrom call at lib/tftp.c:1114 is confirmed. However, to evaluate whether state->blksize incorrectly holds the default instead of the --tftp-blksize value, we need to see: (1) the tftp_state_data_t struct definition (size of rpacket.data), (2) where state->blksize is initialized, and (3) the --tftp-blksize option parsing code. Could you point to those locations or provide a patch showing the fix?

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

Report claims

C1flaw not verifiable

state->blksize contains the default size instead of the size specified in the --tftp-blksize parameter

Read the reasoning

The claim that state->blksize initialization and --tftp-blksize option parsing are not in the provided code snippets. The provided lib/tftp.c excerpt (lines 1089-1139) shows the recvfrom call using state->blksize but not where blksize is set or where the command-line option is processed. The tftp_state_data_t structure definition (which would show rpacket.data size) is also not provided.

C2location supported

line 1114 in file lib/tftp.c

Read the reasoning

The deterministic checks confirm the recvfrom call at line 1114 in lib/tftp.c exists as quoted in the report.

C3trigger not verifiable

using --tftp-blksize N where N is lower than 293

Read the reasoning

The trigger condition depends on the relationship between --tftp-blksize value, state->blksize, and the rpacket.data buffer size. None of the option parsing code, blksize assignment, or buffer allocation is in the provided snippets.

C4impact not verifiable

crash or possibly remote code execution (RCE)

Read the reasoning

Impact depends on C1 being true. Without verifying the buffer size mismatch, crash/RCE potential cannot be assessed from provided code.

C5reproduction not verifiable

run evil-server.py, bind to an address, then connect with curl using --tftp-blksize N where N < 293

Read the reasoning

Reproduction references evil-server.py which is not provided. The steps assume the vulnerability exists but cannot be validated without the missing code context.

Read the original report

Full report on HackerOne ↗

## Summary: A heap buffer overflow can occur at line 1114 in file `lib/tftp.c` due to the fact of `state->blksize` containing the default size instead of containing the one specified in the `--tftp-blksize` parameter. This bug could lead to a **crash** or maybe to **RCE** in the case the attacker also had a memory leak. ### Vulnerable line: ``` state->rbytes = (int)recvfrom(state->sockfd, (void *)state->rpacket.data, state->blksize + 4, 0, (struct sockaddr *)&fromaddr, &fromlen); ``` ## Steps To Reproduce: 1. Download the server script 1. Run it and bind to an address: `$ python evil-server.py IP PORT` 1. Connect to that server with curl: `$ curl --tftp-blksize N tftp://IP:PORT` Where **N** should be a number lower than 293. ## Impact * An attacker would also need a memory leak in order to gain full RCE. * The victim should explicitly set the `--blksize` argument to a value inferior to 293. Thus, the impact is not very high but it's still quite dangerous to not release a patch.

Source code

lib/tftp.clines 1089–1139 · lines 1114-1114 cited by the report
1089 return GETSOCK_BLANK;
1090
1091 socks[0] = conn->sock[FIRSTSOCKET];
1092
1093 return GETSOCK_READSOCK(0);
1094}
1095
1096/**********************************************************
1097 *
1098 * tftp_receive_packet
1099 *
1100 * Called once select fires and data is ready on the socket
1101 *
1102 **********************************************************/
1103static CURLcode tftp_receive_packet(struct connectdata *conn)
1104{
1105 struct Curl_sockaddr_storage fromaddr;
1106 curl_socklen_t fromlen;
1107 CURLcode result = CURLE_OK;
1108 struct Curl_easy *data = conn->data;
1109 tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
1110 struct SingleRequest *k = &data->req;
1111
1112 /* Receive the packet */
1113 fromlen = sizeof(fromaddr);
1114 state->rbytes = (int)recvfrom(state->sockfd,
C2: Deterministic checks confirm lines 1109-1119 at revision 9e8f28a8f1fe contain recvfrom, blksize, state; the quoted recvfrom call matches lines 1114-1119.
1115 (void *)state->rpacket.data,
1116 state->blksize + 4,
1117 0,
1118 (struct sockaddr *)&fromaddr,
1119 &fromlen);
1120 if(state->remote_addrlen == 0) {
1121 memcpy(&state->remote_addr, &fromaddr, fromlen);
1122 state->remote_addrlen = fromlen;
1123 }
1124
1125 /* Sanity check packet length */
1126 if(state->rbytes < 4) {
1127 failf(data, "Received too short packet");
1128 /* Not a timeout, but how best to handle it? */
1129 state->event = TFTP_EVENT_TIMEOUT;
1130 }
1131 else {
1132 /* The event is given by the TFTP packet time */
1133 unsigned short event = getrpacketevent(&state->rpacket);
1134 state->event = (tftp_event_t)event;
1135
1136 switch(state->event) {
1137 case TFTP_EVENT_DATA:
1138 /* Don't pass to the client empty or retransmitted packets */
1139 if(state->rbytes > 4 &&
lib/curl_sasl.clines 194–228 · definition of state
194static void state(struct SASL *sasl, struct connectdata *conn,
195 saslstate newstate)
196{
197#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
198 /* for debug purposes */
199 static const char * const names[]={
200 "STOP",
201 "PLAIN",
202 "LOGIN",
203 "LOGIN_PASSWD",
204 "EXTERNAL",
205 "CRAMMD5",
206 "DIGESTMD5",
207 "DIGESTMD5_RESP",
208 "NTLM",
209 "NTLM_TYPE2MSG",
210 "GSSAPI",
211 "GSSAPI_TOKEN",
212 "GSSAPI_NO_DATA",
213 "OAUTH2",
214 "OAUTH2_RESP",
215 "CANCEL",
216 "FINAL",
217 /* LAST */
218 };
219
220 if(sasl->state != newstate)
221 infof(conn->data, "SASL %p state change from %s to %s\n",
222 (void *)sasl, names[sasl->state], names[newstate]);
223#else
224 (void) conn;
225#endif
226
227 sasl->state = newstate;
228}