mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
SSL: Avoid magic allocation of SSL backend specific data
Originally, my idea was to allocate the two structures (or more precisely, the connectdata structure and the four SSL backend-specific strucutres required for ssl[0..1] and proxy_ssl[0..1]) in one go, so that they all could be free()d together. However, getting the alignment right is tricky. Too tricky. So let's just bite the bullet and allocate the SSL backend-specific data separately. As a consequence, we now have to be very careful to release the memory allocated for the SSL backend-specific data whenever we release any connectdata. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Closes #2119
This commit is contained in:
parent
744ee58386
commit
9194a9959b
49
lib/url.c
49
lib/url.c
@ -716,6 +716,10 @@ static void conn_free(struct connectdata *conn)
|
|||||||
Curl_safefree(conn->unix_domain_socket);
|
Curl_safefree(conn->unix_domain_socket);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SSL
|
||||||
|
Curl_safefree(conn->ssl_extra);
|
||||||
|
#endif
|
||||||
|
|
||||||
free(conn); /* free all the connection oriented data */
|
free(conn); /* free all the connection oriented data */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1793,38 +1797,27 @@ static void llist_dtor(void *user, void *element)
|
|||||||
*/
|
*/
|
||||||
static struct connectdata *allocate_conn(struct Curl_easy *data)
|
static struct connectdata *allocate_conn(struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct connectdata *conn;
|
struct connectdata *conn = calloc(1, sizeof(struct connectdata));
|
||||||
size_t connsize = sizeof(struct connectdata);
|
|
||||||
|
|
||||||
#ifdef USE_SSL
|
|
||||||
/* SSLBK_MAX_ALIGN: The max byte alignment a CPU would use */
|
|
||||||
#define SSLBK_MAX_ALIGN 32
|
|
||||||
/* The SSL backend-specific data (ssl_backend_data) objects are allocated as
|
|
||||||
part of connectdata at the end. To ensure suitable alignment we will
|
|
||||||
assume a maximum of SSLBK_MAX_ALIGN for alignment. Since calloc returns a
|
|
||||||
pointer suitably aligned for any variable this will ensure the
|
|
||||||
ssl_backend_data array has proper alignment, even if that alignment turns
|
|
||||||
out to be less than SSLBK_MAX_ALIGN. */
|
|
||||||
size_t paddingsize = sizeof(struct connectdata) % SSLBK_MAX_ALIGN;
|
|
||||||
size_t alignsize = paddingsize ? (SSLBK_MAX_ALIGN - paddingsize) : 0;
|
|
||||||
size_t sslbksize = Curl_ssl->sizeof_ssl_backend_data;
|
|
||||||
connsize += alignsize + (4 * sslbksize);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
conn = calloc(1, connsize);
|
|
||||||
if(!conn)
|
if(!conn)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
/* Point to the ssl_backend_data objects at the end of connectdata.
|
/* The SSL backend-specific data (ssl_backend_data) objects are allocated as
|
||||||
|
a separate array to ensure suitable alignment.
|
||||||
Note that these backend pointers can be swapped by vtls (eg ssl backend
|
Note that these backend pointers can be swapped by vtls (eg ssl backend
|
||||||
data becomes proxy backend data). */
|
data becomes proxy backend data). */
|
||||||
{
|
{
|
||||||
char *end = (char *)conn + connsize;
|
size_t sslsize = Curl_ssl->sizeof_ssl_backend_data;
|
||||||
conn->ssl[0].backend = ((void *)(end - (4 * sslbksize)));
|
char *ssl = calloc(4, sslsize);
|
||||||
conn->ssl[1].backend = ((void *)(end - (3 * sslbksize)));
|
if(!ssl) {
|
||||||
conn->proxy_ssl[0].backend = ((void *)(end - (2 * sslbksize)));
|
free(conn);
|
||||||
conn->proxy_ssl[1].backend = ((void *)(end - (1 * sslbksize)));
|
return NULL;
|
||||||
|
}
|
||||||
|
conn->ssl_extra = ssl;
|
||||||
|
conn->ssl[0].backend = (void *)ssl;
|
||||||
|
conn->ssl[1].backend = (void *)(ssl + sslsize);
|
||||||
|
conn->proxy_ssl[0].backend = (void *)(ssl + 2 * sslsize);
|
||||||
|
conn->proxy_ssl[1].backend = (void *)(ssl + 3 * sslsize);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1953,6 +1946,9 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
|
|||||||
|
|
||||||
free(conn->master_buffer);
|
free(conn->master_buffer);
|
||||||
free(conn->localdev);
|
free(conn->localdev);
|
||||||
|
#ifdef USE_SSL
|
||||||
|
free(conn->ssl_extra);
|
||||||
|
#endif
|
||||||
free(conn);
|
free(conn);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -4438,6 +4434,9 @@ static CURLcode create_conn(struct Curl_easy *data,
|
|||||||
conn_temp->inuse = TRUE; /* mark this as being in use so that no other
|
conn_temp->inuse = TRUE; /* mark this as being in use so that no other
|
||||||
handle in a multi stack may nick it */
|
handle in a multi stack may nick it */
|
||||||
reuse_conn(conn, conn_temp);
|
reuse_conn(conn, conn_temp);
|
||||||
|
#ifdef USE_SSL
|
||||||
|
free(conn->ssl_extra);
|
||||||
|
#endif
|
||||||
free(conn); /* we don't need this anymore */
|
free(conn); /* we don't need this anymore */
|
||||||
conn = conn_temp;
|
conn = conn_temp;
|
||||||
*in_connect = conn;
|
*in_connect = conn;
|
||||||
|
@ -860,6 +860,9 @@ struct connectdata {
|
|||||||
#endif /* USE_RECV_BEFORE_SEND_WORKAROUND */
|
#endif /* USE_RECV_BEFORE_SEND_WORKAROUND */
|
||||||
struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */
|
struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */
|
||||||
struct ssl_connect_data proxy_ssl[2]; /* this is for proxy ssl-stuff */
|
struct ssl_connect_data proxy_ssl[2]; /* this is for proxy ssl-stuff */
|
||||||
|
#ifdef USE_SSL
|
||||||
|
void *ssl_extra; /* separately allocated backend-specific data */
|
||||||
|
#endif
|
||||||
struct ssl_primary_config ssl_config;
|
struct ssl_primary_config ssl_config;
|
||||||
struct ssl_primary_config proxy_ssl_config;
|
struct ssl_primary_config proxy_ssl_config;
|
||||||
bool tls_upgraded;
|
bool tls_upgraded;
|
||||||
|
Loading…
Reference in New Issue
Block a user