From: Daniel Stenberg Date: Tue, 5 Dec 2023 14:55:35 +0000 (+0100) Subject: lib: strndup/memdup instead of malloc, memcpy and null-terminate X-Git-Tag: curl-8_6_0~246 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7309b9cbbf1dac71dc538e16082bbdb4642f023c;p=thirdparty%2Fcurl.git lib: strndup/memdup instead of malloc, memcpy and null-terminate - bufref: use strndup - cookie: use strndup - formdata: use strndup - ftp: use strndup - gtls: use aprintf instead of malloc + strcpy * 2 - http: use strndup - mbedtls: use strndup - md4: use memdup - ntlm: use memdup - ntlm_sspi: use strndup - pingpong: use memdup - rtsp: use strndup instead of malloc, memcpy and null-terminate - sectransp: use strndup - socks_gssapi.c: use memdup - vtls: use dynbuf instead of malloc, snprintf and memcpy - vtls: use strdup instead of malloc + memcpy - wolfssh: use strndup Closes #12453 --- diff --git a/lib/bufref.c b/lib/bufref.c index ce686b6f37..013eba10b2 100644 --- a/lib/bufref.c +++ b/lib/bufref.c @@ -25,6 +25,7 @@ #include "curl_setup.h" #include "urldata.h" #include "bufref.h" +#include "strdup.h" #include "curl_memory.h" #include "memdebug.h" @@ -116,12 +117,9 @@ CURLcode Curl_bufref_memdup(struct bufref *br, const void *ptr, size_t len) DEBUGASSERT(len <= CURL_MAX_INPUT_LENGTH); if(ptr) { - cpy = malloc(len + 1); + cpy = Curl_strndup(ptr, len); if(!cpy) return CURLE_OUT_OF_MEMORY; - if(len) - memcpy(cpy, ptr, len); - cpy[len] = '\0'; } Curl_bufref_set(br, cpy, len, curl_free); diff --git a/lib/cookie.c b/lib/cookie.c index 9095cea3e9..156322a904 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -821,10 +821,8 @@ Curl_cookie_add(struct Curl_easy *data, endslash = memrchr(path, '/', (queryp - path)); if(endslash) { size_t pathlen = (endslash-path + 1); /* include end slash */ - co->path = malloc(pathlen + 1); /* one extra for the zero byte */ + co->path = Curl_strndup(path, pathlen); if(co->path) { - memcpy(co->path, path, pathlen); - co->path[pathlen] = 0; /* null-terminate */ co->spath = sanitize_cookie_path(co->path); if(!co->spath) badcookie = TRUE; /* out of memory bad */ diff --git a/lib/formdata.c b/lib/formdata.c index 05dc9b53d6..81ed5fe61d 100644 --- a/lib/formdata.c +++ b/lib/formdata.c @@ -779,11 +779,9 @@ static CURLcode setname(curl_mimepart *part, const char *name, size_t len) if(!name || !len) return curl_mime_name(part, name); - zname = malloc(len + 1); + zname = Curl_strndup(name, len); if(!zname) return CURLE_OUT_OF_MEMORY; - memcpy(zname, name, len); - zname[len] = '\0'; res = curl_mime_name(part, zname); free(zname); return res; diff --git a/lib/ftp.c b/lib/ftp.c index c9ceaaac31..ae98530e92 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -72,6 +72,7 @@ #include "warnless.h" #include "http_proxy.h" #include "socks.h" +#include "strdup.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" @@ -4169,13 +4170,12 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data) return CURLE_OUT_OF_MEMORY; } - ftpc->dirs[0] = calloc(1, dirlen + 1); + ftpc->dirs[0] = Curl_strndup(rawPath, dirlen); if(!ftpc->dirs[0]) { free(rawPath); return CURLE_OUT_OF_MEMORY; } - strncpy(ftpc->dirs[0], rawPath, dirlen); ftpc->dirdepth = 1; /* we consider it to be a single dir */ fileName = slashPos + 1; /* rest is file name */ } @@ -4214,12 +4214,11 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data) CWD requires a parameter and a non-existent parameter a) doesn't work on many servers and b) has no effect on the others. */ if(compLen > 0) { - char *comp = calloc(1, compLen + 1); + char *comp = Curl_strndup(curPos, compLen); if(!comp) { free(rawPath); return CURLE_OUT_OF_MEMORY; } - strncpy(comp, curPos, compLen); ftpc->dirs[ftpc->dirdepth++] = comp; } curPos = slashPos + 1; diff --git a/lib/http.c b/lib/http.c index be6d442e8b..2597937623 100644 --- a/lib/http.c +++ b/lib/http.c @@ -297,7 +297,6 @@ char *Curl_copy_header_value(const char *header) { const char *start; const char *end; - char *value; size_t len; /* Find the end of the header name */ @@ -330,14 +329,7 @@ char *Curl_copy_header_value(const char *header) /* get length of the type */ len = end - start + 1; - value = malloc(len + 1); - if(!value) - return NULL; - - memcpy(value, start, len); - value[len] = 0; /* null-terminate */ - - return value; + return Curl_strndup(start, len); } #ifndef CURL_DISABLE_HTTP_AUTH diff --git a/lib/md4.c b/lib/md4.c index 486e5fa6a0..067c211e42 100644 --- a/lib/md4.c +++ b/lib/md4.c @@ -194,11 +194,9 @@ static int MD4_Init(MD4_CTX *ctx) static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) { if(!ctx->data) { - ctx->data = malloc(size); - if(ctx->data) { - memcpy(ctx->data, data, size); + ctx->data = Curl_memdup(data, size); + if(ctx->data) ctx->size = size; - } } } diff --git a/lib/pingpong.c b/lib/pingpong.c index 0081c9ca62..2e062e2496 100644 --- a/lib/pingpong.c +++ b/lib/pingpong.c @@ -36,6 +36,7 @@ #include "pingpong.h" #include "multiif.h" #include "vtls/vtls.h" +#include "strdup.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -424,10 +425,8 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data, if(clipamount) { pp->cache_size = clipamount; - pp->cache = malloc(pp->cache_size); - if(pp->cache) - memcpy(pp->cache, pp->linestart_resp, pp->cache_size); - else + pp->cache = Curl_memdup(pp->linestart_resp, pp->cache_size); + if(!pp->cache) return CURLE_OUT_OF_MEMORY; } if(restart) { diff --git a/lib/rtsp.c b/lib/rtsp.c index e673bb8dc0..f05ee727eb 100644 --- a/lib/rtsp.c +++ b/lib/rtsp.c @@ -922,7 +922,7 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, char *header) /* If the Session ID is set, then compare */ if(strlen(data->set.str[STRING_RTSP_SESSION_ID]) != idlen || - strncmp(start, data->set.str[STRING_RTSP_SESSION_ID], idlen) != 0) { + strncmp(start, data->set.str[STRING_RTSP_SESSION_ID], idlen)) { failf(data, "Got RTSP Session ID Line [%s], but wanted ID [%s]", start, data->set.str[STRING_RTSP_SESSION_ID]); return CURLE_RTSP_SESSION_ERROR; @@ -934,11 +934,9 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, char *header) */ /* Copy the id substring into a new buffer */ - data->set.str[STRING_RTSP_SESSION_ID] = malloc(idlen + 1); + data->set.str[STRING_RTSP_SESSION_ID] = Curl_strndup(start, idlen); if(!data->set.str[STRING_RTSP_SESSION_ID]) return CURLE_OUT_OF_MEMORY; - memcpy(data->set.str[STRING_RTSP_SESSION_ID], start, idlen); - (data->set.str[STRING_RTSP_SESSION_ID])[idlen] = '\0'; } } else if(checkprefix("Transport:", header)) { diff --git a/lib/socks_gssapi.c b/lib/socks_gssapi.c index 2ede8c7c29..243715055c 100644 --- a/lib/socks_gssapi.c +++ b/lib/socks_gssapi.c @@ -35,6 +35,7 @@ #include "timeval.h" #include "socks.h" #include "warnless.h" +#include "strdup.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -139,10 +140,9 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, /* prepare service name */ if(strchr(serviceptr, '/')) { service.length = serviceptr_length; - service.value = malloc(service.length); + service.value = Curl_memdup(serviceptr, service.length); if(!service.value) return CURLE_OUT_OF_MEMORY; - memcpy(service.value, serviceptr, service.length); gss_major_status = gss_import_name(&gss_minor_status, &service, (gss_OID) GSS_C_NULL_OID, &server); @@ -387,12 +387,11 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(struct Curl_cfilter *cf, } else { gss_send_token.length = 1; - gss_send_token.value = malloc(1); + gss_send_token.value = Curl_memdup(&gss_enc, 1); if(!gss_send_token.value) { gss_delete_sec_context(&gss_status, &gss_context, NULL); return CURLE_OUT_OF_MEMORY; } - memcpy(gss_send_token.value, &gss_enc, 1); gss_major_status = gss_wrap(&gss_minor_status, gss_context, 0, GSS_C_QOP_DEFAULT, &gss_send_token, diff --git a/lib/vauth/ntlm.c b/lib/vauth/ntlm.c index ed7cee8def..018e6a67ef 100644 --- a/lib/vauth/ntlm.c +++ b/lib/vauth/ntlm.c @@ -44,6 +44,7 @@ #include "warnless.h" #include "rand.h" #include "vtls/vtls.h" +#include "strdup.h" #define BUILDING_CURL_NTLM_MSGS_C #include "vauth/vauth.h" @@ -184,11 +185,10 @@ static CURLcode ntlm_decode_type2_target(struct Curl_easy *data, } free(ntlm->target_info); /* replace any previous data */ - ntlm->target_info = malloc(target_info_len); + ntlm->target_info = Curl_memdup(&type2[target_info_offset], + target_info_len); if(!ntlm->target_info) return CURLE_OUT_OF_MEMORY; - - memcpy(ntlm->target_info, &type2[target_info_offset], target_info_len); } } diff --git a/lib/vauth/ntlm_sspi.c b/lib/vauth/ntlm_sspi.c index 5118963f4d..06079a6ffc 100644 --- a/lib/vauth/ntlm_sspi.c +++ b/lib/vauth/ntlm_sspi.c @@ -34,6 +34,7 @@ #include "warnless.h" #include "curl_multibyte.h" #include "sendf.h" +#include "strdup.h" /* The last #include files should be: */ #include "curl_memory.h" @@ -213,11 +214,10 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, } /* Store the challenge for later use */ - ntlm->input_token = malloc(Curl_bufref_len(type2) + 1); + ntlm->input_token = Curl_strndup((const char *)Curl_bufref_ptr(type2), + Curl_bufref_len(type2)); if(!ntlm->input_token) return CURLE_OUT_OF_MEMORY; - memcpy(ntlm->input_token, Curl_bufref_ptr(type2), Curl_bufref_len(type2)); - ntlm->input_token[Curl_bufref_len(type2)] = '\0'; ntlm->input_token_len = Curl_bufref_len(type2); return CURLE_OK; diff --git a/lib/vssh/wolfssh.c b/lib/vssh/wolfssh.c index 4da7e9dea6..8d152d43c7 100644 --- a/lib/vssh/wolfssh.c +++ b/lib/vssh/wolfssh.c @@ -42,6 +42,7 @@ #include "select.h" #include "multiif.h" #include "warnless.h" +#include "strdup.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -512,15 +513,9 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) return CURLE_OK; } else if(name && (rc == WS_SUCCESS)) { - sshc->homedir = malloc(name->fSz + 1); - if(!sshc->homedir) { + sshc->homedir = Curl_strndup(name->fName, name->fSz); + if(!sshc->homedir) sshc->actualcode = CURLE_OUT_OF_MEMORY; - } - else { - memcpy(sshc->homedir, name->fName, name->fSz); - sshc->homedir[name->fSz] = 0; - infof(data, "wolfssh SFTP realpath succeeded"); - } wolfSSH_SFTPNAME_list_free(name); state(data, SSH_STOP); return CURLE_OK; diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index 4e337f5dd3..f42b6d6691 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -584,13 +584,9 @@ CURLcode gtls_client_init(struct Curl_easy *data, /* Only add SRP to the cipher list if SRP is requested. Otherwise * GnuTLS will disable TLS 1.3 support. */ if(config->username) { - size_t len = strlen(prioritylist); - - char *prioritysrp = malloc(len + sizeof(GNUTLS_SRP) + 1); + char *prioritysrp = aprintf("%s:" GNUTLS_SRP, prioritylist); if(!prioritysrp) return CURLE_OUT_OF_MEMORY; - strcpy(prioritysrp, prioritylist); - strcpy(prioritysrp + len, ":" GNUTLS_SRP); rc = gnutls_priority_set_direct(gtls->session, prioritysrp, &err); free(prioritysrp); diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index 38f7de7f75..f0fb7f3e42 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -67,6 +67,7 @@ #include "select.h" #include "multiif.h" #include "mbedtls_threadlock.h" +#include "strdup.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -367,11 +368,10 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null terminated even when provided the exact length, forcing us to waste extra memory here. */ - unsigned char *newblob = malloc(ca_info_blob->len + 1); + unsigned char *newblob = Curl_strndup(ca_info_blob->data, + ca_info_blob->len); if(!newblob) return CURLE_OUT_OF_MEMORY; - memcpy(newblob, ca_info_blob->data, ca_info_blob->len); - newblob[ca_info_blob->len] = 0; /* null terminate */ ret = mbedtls_x509_crt_parse(&backend->cacert, newblob, ca_info_blob->len + 1); free(newblob); @@ -441,11 +441,10 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) /* Unfortunately, mbedtls_x509_crt_parse() requires the data to be null terminated even when provided the exact length, forcing us to waste extra memory here. */ - unsigned char *newblob = malloc(ssl_cert_blob->len + 1); + unsigned char *newblob = Curl_strndup(ssl_cert_blob->data, + ssl_cert_blob->len); if(!newblob) return CURLE_OUT_OF_MEMORY; - memcpy(newblob, ssl_cert_blob->data, ssl_cert_blob->len); - newblob[ssl_cert_blob->len] = 0; /* null terminate */ ret = mbedtls_x509_crt_parse(&backend->clicert, newblob, ssl_cert_blob->len + 1); free(newblob); diff --git a/lib/vtls/sectransp.c b/lib/vtls/sectransp.c index e3205e3acd..19c00e0350 100644 --- a/lib/vtls/sectransp.c +++ b/lib/vtls/sectransp.c @@ -2367,19 +2367,16 @@ static CURLcode verify_cert(struct Curl_cfilter *cf, const struct curl_blob *ca_info_blob, SSLContextRef ctx) { - int result; + CURLcode result; unsigned char *certbuf; size_t buflen; if(ca_info_blob) { CURL_TRC_CF(data, cf, "verify_peer, CA from config blob"); - certbuf = (unsigned char *)malloc(ca_info_blob->len + 1); - if(!certbuf) { + certbuf = (unsigned char *)Curl_strndup(ca_info_blob->data, + buflen = ca_info_blob->len); + if(!certbuf) return CURLE_OUT_OF_MEMORY; - } - buflen = ca_info_blob->len; - memcpy(certbuf, ca_info_blob->data, ca_info_blob->len); - certbuf[ca_info_blob->len]='\0'; } else if(cafile) { CURL_TRC_CF(data, cf, "verify_peer, CA from file '%s'", cafile); diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c index 34eda3e5a0..9980d4405b 100644 --- a/lib/vtls/vtls.c +++ b/lib/vtls/vtls.c @@ -883,28 +883,21 @@ CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data, size_t valuelen) { struct curl_certinfo *ci = &data->info.certs; - char *output; struct curl_slist *nl; CURLcode result = CURLE_OK; - size_t labellen = strlen(label); - size_t outlen = labellen + 1 + valuelen + 1; /* label:value\0 */ + struct dynbuf build; - output = malloc(outlen); - if(!output) - return CURLE_OUT_OF_MEMORY; - - /* sprintf the label and colon */ - msnprintf(output, outlen, "%s:", label); + Curl_dyn_init(&build, 10000); - /* memcpy the value (it might not be null-terminated) */ - memcpy(&output[labellen + 1], value, valuelen); - - /* null-terminate the output */ - output[labellen + 1 + valuelen] = 0; + if(Curl_dyn_add(&build, label) || + Curl_dyn_addn(&build, ":", 1) || + Curl_dyn_addn(&build, value, valuelen)) + return CURLE_OUT_OF_MEMORY; - nl = Curl_slist_append_nodup(ci->certinfo[certnum], output); + nl = Curl_slist_append_nodup(ci->certinfo[certnum], + Curl_dyn_ptr(&build)); if(!nl) { - free(output); + Curl_dyn_free(&build); curl_slist_free_all(ci->certinfo[certnum]); result = CURLE_OUT_OF_MEMORY; } @@ -1002,7 +995,7 @@ CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data, /* only do this if pinnedpubkey starts with "sha256//", length 8 */ if(strncmp(pinnedpubkey, "sha256//", 8) == 0) { CURLcode encode; - size_t encodedlen = 0, pinkeylen; + size_t encodedlen = 0; char *encoded = NULL, *pinkeycopy, *begin_pos, *end_pos; unsigned char *sha256sumdigest; @@ -1030,13 +1023,11 @@ CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data, infof(data, " public key hash: sha256//%s", encoded); /* it starts with sha256//, copy so we can modify it */ - pinkeylen = strlen(pinnedpubkey) + 1; - pinkeycopy = malloc(pinkeylen); + pinkeycopy = strdup(pinnedpubkey); if(!pinkeycopy) { Curl_safefree(encoded); return CURLE_OUT_OF_MEMORY; } - memcpy(pinkeycopy, pinnedpubkey, pinkeylen); /* point begin_pos to the copy, and start extracting keys */ begin_pos = pinkeycopy; do {