mirror of
https://github.com/curl/curl.git
synced 2026-08-26 06:53:32 +03:00
hardening: add API guards
Add call stacks to easy and multi instances. Record ongoing API calls and callback invocations there to detect recursion and not allowed invocations. Define enums for easy, multi and callbacks in `api.h`. In `api.c` define properties for these functions: - can they recurse - is the easy/multi handle destroyed during the call or should it be good afterwards - is the call allowed when a multi event callback is ongoing - is the call allowed when a notification callback is ongoing Entering a guard - checks that passed CURL*/CURLM* are GOOD on entering - checks that easy handle's `mid` is correct and it is known for it in the multi. - checks that call properties are obeyed (recursion, callback checks) - checks that passed CURL*/CURLM* are GOOD on leaving, unless call is known to kill it Checks for ongoing callbacks inspect the whole call stack and catches nested invocations (which our current flags can not). Call stacks in easy/multi handle are fixed size and will deny recursion when the limit is reached. The current limits are 7 for easy and 15 for multi now. Removes: - multi->in_callback, check is done via call stack - multi->in_ntfy_cb, check is done via call stack The overhead in my tests seems minimal, if noticeable at all. Closes #22237
This commit is contained in:
parent
ab8d771d31
commit
dfc01ea2a3
30 changed files with 1667 additions and 943 deletions
|
|
@ -430,11 +430,12 @@ static CURLcode socket_open(struct Curl_easy *data,
|
|||
* might have been changed and this 'new' address will actually be used
|
||||
* here to connect.
|
||||
*/
|
||||
Curl_set_in_callback(data, TRUE);
|
||||
struct Curl_mapi_guard guard;
|
||||
CURL_CBAPI_START(&guard, data, easy_fopensocket);
|
||||
*sockfd = data->set.fopensocket(data->set.opensocket_client,
|
||||
CURLSOCKTYPE_IPCXN,
|
||||
(struct curl_sockaddr *)addr);
|
||||
Curl_set_in_callback(data, FALSE);
|
||||
CURL_CBAPI_END(&guard);
|
||||
}
|
||||
else {
|
||||
/* opensocket callback not set, so create the socket now */
|
||||
|
|
@ -521,11 +522,12 @@ static int socket_close(struct Curl_easy *data, struct connectdata *conn,
|
|||
return 0;
|
||||
|
||||
if(use_callback && conn && conn->fclosesocket) {
|
||||
struct Curl_mapi_guard guard;
|
||||
int rc;
|
||||
Curl_multi_will_close(data, sock);
|
||||
Curl_set_in_callback(data, TRUE);
|
||||
CURL_CBAPI_START(&guard, data, easy_closesocket);
|
||||
rc = conn->fclosesocket(conn->closesocket_client, sock);
|
||||
Curl_set_in_callback(data, FALSE);
|
||||
CURL_CBAPI_END(&guard);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -1220,11 +1222,12 @@ static CURLcode cf_socket_open(struct Curl_cfilter *cf,
|
|||
|
||||
if(data->set.fsockopt) {
|
||||
/* activate callback for setting socket options */
|
||||
Curl_set_in_callback(data, TRUE);
|
||||
struct Curl_mapi_guard guard;
|
||||
CURL_CBAPI_START(&guard, data, easy_fsockopt);
|
||||
error = data->set.fsockopt(data->set.sockopt_client,
|
||||
ctx->sock,
|
||||
CURLSOCKTYPE_IPCXN);
|
||||
Curl_set_in_callback(data, FALSE);
|
||||
CURL_CBAPI_END(&guard);
|
||||
|
||||
if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
|
||||
isconnected = TRUE;
|
||||
|
|
@ -2231,13 +2234,14 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
|
|||
ctx->sock, ctx->ip.remote_ip, ctx->ip.remote_port);
|
||||
|
||||
if(data->set.fsockopt) {
|
||||
struct Curl_mapi_guard guard;
|
||||
int error = 0;
|
||||
|
||||
/* activate callback for setting socket options */
|
||||
Curl_set_in_callback(data, TRUE);
|
||||
CURL_CBAPI_START(&guard, data, easy_fsockopt);
|
||||
error = data->set.fsockopt(data->set.sockopt_client,
|
||||
ctx->sock, CURLSOCKTYPE_ACCEPT);
|
||||
Curl_set_in_callback(data, FALSE);
|
||||
CURL_CBAPI_END(&guard);
|
||||
|
||||
if(error)
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue