libmicrohttpd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [libmicrohttpd] [PATCH] MHD_add_response_header: Check on passed nul


From: Evgeny Grin
Subject: Re: [libmicrohttpd] [PATCH] MHD_add_response_header: Check on passed nullptr
Date: Fri, 28 Jan 2022 12:31:26 +0300
User-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.5.1

Hello Alexander,

On 27.01.2022 21:12, Alexander Dahl wrote:
However this is not a such case. MHD never have guaranteed tolerating of
NULL in this function. The data must be a valid C string. The NULL pointer
is definitely not a valid C string.

Well, I could not tell based on the API documentation, what's intended
behaviour here.

Pointer to char is always C sting in C, unless another type is explicitly documented (like pointer to a single char).
NULL is not a valid C string.

Even if something is unclear from documentation, it is called "undefined behaviour". Undefined behaviour should be avoided as it may work on one platform or version and may not work on another platform or version.

MHD would (silently) ignore bad parameters with your patch. This may mask
some bug in code that use MHD_add_response_header() function so while this
patch may look useful for production code, actually it makes situation even
worse as it may give false feeling of correct functioning instead of
revealing bug as soon as possible.

Well, my patch just restores the behaviour of libmicrohttpd from
before 185f740e0684, where MHD_add_response_header() returned what
add_response_entry() returns.  That function add_response_entry()
checks for (response == NULL) and silently returns MHD_NO in that
case.

Intended or not, changeset 185f740e0684 broke that behaviour, and it
did not mention in commit message nor in code itself.

If behaviour is undefined, it cannot be broken.
You should not expect that NULL will be processed as a valid C string. On the other hand, it was not guaranteed that MHD would segfault on NULL.

Hypothetical situation:
===============================
MHD_add_response_header (r, "System-Command", "sudo rm -rf /
--no-preserve-root");
char *behaviour = strdup ("no-execute, check-syntax-only");
MHD_add_response_header (r, "Modify-Behavior", behaviour);
free (behaviour);
MHD_queue_response (c, MHD_HTTP_OK, r);
==============================
Very typical mistake: no checks for returned values. The code may work fine,
but at some moment, due to some leak in another place, strdup() fail. With
your patch second header would not be added, but response would be sent. I
think it's better to crash earlier in such situation than trying to fix
automatically wrong parameters.

You're absolutely right. Users of your library must check return
values, no doubt about that.

Also users of the library should provide correct data.

 From the description of the issue in your library, it's clear than you was
able to find another error (return 200 instead of 404) with wrong filename
only when MHD stopped tolerating NULL. If MHD would not tolerate NULL
initially (which was not intentional behaviour), you would be able to find
and fix this bug earlier.

It's not my library, I'm just a user.  And I'm sorry, I'm confused
now.  What is the intentional behaviour of libmicrohttpd?

Intentional behaviour is correct processing of correct data. So tricky and/or complicated combination of strings are detected on run-time, but fundamental types expected to be correct, like strings are zero-terminated and in valid readable memory area.
I mean, libmicrohttpd detecting NULL and returning MHD_NO tells me
something went wrong at runtime, if I check for return value, which I
should do.

Yes, you should check the return value as well as you should provide valid C strings. When application pass NULL as a C string, it's clear indication that something goes terribly wrong in the application, right? The best thing that you can do in such situation is to abort the broken application, before it overwrites some valid data with some invalid data or does other horrible unexpected things.

Checking for return value is pointless, however, if libmicrohttpd
crashes before returning anything.

That's correct. But if application supplies such obvious invalid input, there is a high chance that return value is not checked as well, just because most probably the invalid input was the return value from another function that was not checked before.

Crash/segfault is your friend when something is badly broken. Masking obvious problems does not help debugging and testing and makes things worse in production. On the other hand "libmicrohttpd" is still "micro". The library core without optional parts still could be very small. So library expects that parameters have valid types. Otherwise we should bloat up the code with checks for every single parameter validity, including readability of pointed memory region.

--
Best Regards,
Evgeny

Attachment: OpenPGP_signature
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]