Skip to content

Commit 4c7f9c7

Browse files
authored
libmicrohttpd2: Add third set of targets for daemon fuzzing (#13858)
This PR adds the final batch of targets for request handling in daemon for project libmicrohttpd2. Signed-off-by: Arthur Chan <[email protected]>
1 parent 27b1b68 commit 4c7f9c7

File tree

3 files changed

+80
-7
lines changed

3 files changed

+80
-7
lines changed

projects/libmicrohttpd2/fuzz_daemon.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@ static void start_daemon_once() {
4040

4141
if (g_fdp->ConsumeBool()) {
4242
g_daemon = MHD_daemon_create(&req_cb, NULL);
43-
} else {
43+
} else if (g_fdp->ConsumeBool()) {
4444
g_daemon = MHD_daemon_create(&req_cb_stream, NULL);
45+
} else {
46+
g_daemon = MHD_daemon_create(&req_cb_process, NULL);
4547
}
4648
if (!g_daemon) {
4749
continue;
@@ -105,24 +107,29 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
105107
std::lock_guard<std::mutex> lk(g_fdp_mu);
106108
if (g_fdp) {
107109
static const char* kCommon[] = {"GET","POST","PUT","DELETE","HEAD","PATCH","OPTIONS"};
108-
if (g_fdp->ConsumeBool())
110+
if (g_fdp->ConsumeBool()) {
109111
method = g_fdp->PickValueInArray(kCommon);
110-
else {
112+
} else {
111113
method = g_fdp->ConsumeRandomLengthString(8);
112-
if (method.empty()) method = "GET";
114+
if (method.empty()) {
115+
method = "GET";
116+
}
113117
}
114118

115119
path = g_fdp->ConsumeRandomLengthString(
116120
g_fdp->ConsumeIntegralInRange<size_t>(0, 64));
117-
for (char &c : path) if (c == ' ') c = '_';
121+
for (char &c : path) {
122+
if (c == ' ') {
123+
c = '_';
124+
}
125+
}
118126

119127
user = g_fdp->ConsumeRandomLengthString(16);
120128
pass = g_fdp->ConsumeRandomLengthString(16);
121129
garble_auth = g_fdp->ConsumeBool();
122130

123131
if (method == "POST" || g_fdp->ConsumeBool()) {
124-
body = g_fdp->ConsumeBytesAsString(
125-
g_fdp->ConsumeIntegralInRange<size_t>(0, 2048));
132+
body = g_fdp->ConsumeRandomLengthString(2048);
126133
}
127134
}
128135
}

projects/libmicrohttpd2/mhd_helper.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,3 +799,62 @@ req_cb_stream(void*,
799799
MHD_response_destroy(resp);
800800
return act ? act : MHD_action_abort_request(request);
801801
}
802+
803+
MHD_FN_PAR_NONNULL_(2) MHD_FN_PAR_NONNULL_(3)
804+
const struct MHD_Action*
805+
req_cb_process(void*,
806+
struct MHD_Request* MHD_RESTRICT request,
807+
const struct MHD_String* MHD_RESTRICT path,
808+
enum MHD_HTTP_Method method,
809+
uint_fast64_t upload_size) {
810+
// Create info unions
811+
union MHD_RequestInfoFixedData f;
812+
union MHD_RequestInfoDynamicData d;
813+
814+
// Fuzz MHD_request_get_info_fixed_sz for different parameters on random request
815+
MHD_request_get_info_fixed_sz(request, MHD_REQUEST_INFO_FIXED_HTTP_VER, &f, sizeof(f));
816+
MHD_request_get_info_fixed_sz(request, MHD_REQUEST_INFO_FIXED_HTTP_METHOD, &f, sizeof(f));
817+
MHD_request_get_info_fixed_sz(request, MHD_REQUEST_INFO_FIXED_DAEMON, &f, sizeof(f));
818+
MHD_request_get_info_fixed_sz(request, MHD_REQUEST_INFO_FIXED_CONNECTION, &f, sizeof(f));
819+
MHD_request_get_info_fixed_sz(request, MHD_REQUEST_INFO_FIXED_STREAM, &f, sizeof(f));
820+
MHD_request_get_info_fixed_sz(request, MHD_REQUEST_INFO_FIXED_APP_CONTEXT, &f, sizeof(f));
821+
822+
// Fuzz MHD_request_get_info_dynamic_sz for different parameters on random request
823+
MHD_request_get_info_dynamic_sz(request, MHD_REQUEST_INFO_DYNAMIC_HTTP_METHOD_STRING, &d, sizeof(d));
824+
MHD_request_get_info_dynamic_sz(request, MHD_REQUEST_INFO_DYNAMIC_URI, &d, sizeof(d));
825+
MHD_request_get_info_dynamic_sz(request, MHD_REQUEST_INFO_DYNAMIC_NUMBER_URI_PARAMS, &d, sizeof(d));
826+
MHD_request_get_info_dynamic_sz(request, MHD_REQUEST_INFO_DYNAMIC_NUMBER_COOKIES, &d, sizeof(d));
827+
MHD_request_get_info_dynamic_sz(request, MHD_REQUEST_INFO_DYNAMIC_HEADER_SIZE, &d, sizeof(d));
828+
MHD_request_get_info_dynamic_sz(request, MHD_REQUEST_INFO_DYNAMIC_AUTH_DIGEST_INFO, &d, sizeof(d));
829+
MHD_request_get_info_dynamic_sz(request, MHD_REQUEST_INFO_DYNAMIC_AUTH_BASIC_CREDS, &d, sizeof(d));
830+
831+
{
832+
static const char realm[] = "fuzz-realm";
833+
static const char user[] = "u";
834+
static const char pass[] = "p";
835+
836+
enum MHD_DigestAuthAlgo algos[] = {
837+
MHD_DIGEST_AUTH_ALGO_MD5,
838+
MHD_DIGEST_AUTH_ALGO_SHA256,
839+
MHD_DIGEST_AUTH_ALGO_SHA512_256
840+
};
841+
842+
for (unsigned i = 0; i < (unsigned)(sizeof(algos)/sizeof(algos[0])); ++i) {
843+
size_t sz = MHD_digest_get_hash_size(algos[i]);
844+
if (sz == 0 || sz > 64) {
845+
continue;
846+
}
847+
unsigned char ha1[64];
848+
if (MHD_SC_OK == MHD_digest_auth_calc_userdigest(algos[i], user, realm, pass, sz, ha1)) {
849+
MHD_digest_auth_check_digest(
850+
request, realm, user, sz, ha1,
851+
0, MHD_DIGEST_AUTH_MULT_QOP_AUTH_ANY,
852+
MHD_DIGEST_AUTH_MULT_ALGO_ANY_NON_SESSION);
853+
}
854+
}
855+
}
856+
857+
// Force OK response
858+
struct MHD_Response* r = MHD_response_from_empty(MHD_HTTP_STATUS_OK);
859+
return MHD_action_from_response(request, r);
860+
}

projects/libmicrohttpd2/mhd_helper.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@ const struct MHD_Action* req_cb_stream(void* cls,
8989
enum MHD_HTTP_Method method,
9090
uint_fast64_t upload_size);
9191

92+
MHD_FN_PAR_NONNULL_(2) MHD_FN_PAR_NONNULL_(3)
93+
const struct MHD_Action* req_cb_process(void* cls,
94+
struct MHD_Request* MHD_RESTRICT request,
95+
const struct MHD_String* MHD_RESTRICT path,
96+
enum MHD_HTTP_Method method,
97+
uint_fast64_t upload_size);
98+
9299
// Provide base64 encoding for the response/request
93100
std::string b64encode(const std::string &in);
94101

0 commit comments

Comments
 (0)