krb5: add buffer size precaution in Curl_sec_read_msg

To make sure the copy never overwrites the buffer, as this function
decodes "in place".

Inspired-by: Ryan Lefkowitz
This commit is contained in:
Daniel Stenberg 2025-09-16 09:49:54 +02:00
parent f6ddc1fc1e
commit 6bf86c7504
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
3 changed files with 19 additions and 15 deletions

View file

@ -42,7 +42,8 @@ struct Curl_sec_client_mech {
#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_FTP)
void Curl_sec_conn_init(struct connectdata *);
void Curl_sec_conn_destroy(struct connectdata *);
int Curl_sec_read_msg(struct Curl_easy *data, struct connectdata *conn, char *,
int Curl_sec_read_msg(struct Curl_easy *data, struct connectdata *conn,
char *buffer, const size_t buflen,
enum protection_level);
CURLcode Curl_sec_login(struct Curl_easy *, struct connectdata *);
int Curl_sec_request_prot(struct connectdata *conn, const char *level);

View file

@ -582,17 +582,18 @@ static CURLcode ftp_readresp(struct Curl_easy *data,
{
struct connectdata *conn = data->conn;
char * const buf = curlx_dyn_ptr(&ftpc->pp.recvbuf);
size_t buflen = curlx_dyn_len(&ftpc->pp.recvbuf);
/* handle the security-oriented responses 6xx ***/
switch(code) {
case 631:
code = Curl_sec_read_msg(data, conn, buf, PROT_SAFE);
code = Curl_sec_read_msg(data, conn, buf, buflen, PROT_SAFE);
break;
case 632:
code = Curl_sec_read_msg(data, conn, buf, PROT_PRIVATE);
code = Curl_sec_read_msg(data, conn, buf, buflen, PROT_PRIVATE);
break;
case 633:
code = Curl_sec_read_msg(data, conn, buf, PROT_CONFIDENTIAL);
code = Curl_sec_read_msg(data, conn, buf, buflen, PROT_CONFIDENTIAL);
break;
default:
/* normal ftp stuff we pass through! */

View file

@ -713,7 +713,8 @@ static CURLcode sec_send(struct Curl_easy *data, int sockindex,
}
int Curl_sec_read_msg(struct Curl_easy *data, struct connectdata *conn,
char *buffer, enum protection_level level)
char *buffer, const size_t buflen,
enum protection_level level)
{
/* decoded_len should be size_t or ssize_t but conn->mech->decode returns an
int */
@ -723,8 +724,6 @@ int Curl_sec_read_msg(struct Curl_easy *data, struct connectdata *conn,
size_t decoded_sz = 0;
CURLcode error;
(void)data;
if(!conn->mech)
/* not initialized, return error */
return -1;
@ -748,22 +747,25 @@ int Curl_sec_read_msg(struct Curl_easy *data, struct connectdata *conn,
return -1;
}
{
buf[decoded_len] = '\n';
Curl_debug(data, CURLINFO_HEADER_IN, buf, decoded_len + 1);
}
buf[decoded_len] = '\n';
Curl_debug(data, CURLINFO_HEADER_IN, buf, decoded_len + 1);
buf[decoded_len] = '\0';
if(decoded_len <= 3)
/* suspiciously short */
return 0;
return -1;
if(buf[3] != '-')
ret_code = atoi(buf);
if(buf[decoded_len - 1] == '\n')
buf[decoded_len - 1] = '\0';
strcpy(buffer, buf);
buf[--decoded_len] = '\0';
if((size_t)decoded_len > buflen)
/* too big */
ret_code = -1;
else
memcpy(buffer, buf, decoded_len + 1);
free(buf);
return ret_code;
}