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: Alexander Dahl
Subject: Re: [libmicrohttpd] [PATCH] MHD_add_response_header: Check on passed nullptr
Date: Thu, 27 Jan 2022 19:12:28 +0100

Hello Evgeny,

Am Thu, Jan 27, 2022 at 08:15:37PM +0300 schrieb Evgeny Grin:
> Thanks for the patch.
> Breaking API is always a bad idea, unless API itself is broken badly by
> design.
> 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.

> 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.

> 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.

> 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? 

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.

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

Greets
Alex

> 
> -- 
> Evgeny
> 
> 
> On 27.01.2022 14:10, Alexander Dahl wrote:
> > The response argument is passed to `add_response_entry()` eventually
> > which does a check on NULL.  This was done without accessing struct
> > members of *response* in the past, however since 185f740e0684 ("allow
> > clients to override sanity check for content-length header") an access
> > to response->flags leads to a segfault.
> > 
> > This was spotted when building an app with libhttpserver which currently
> > might pass a nullptr to `MHD_add_response_header()`, see the bug report
> > over there for details.
> > 
> > Link: https://github.com/etr/libhttpserver/issues/255
> > Fixes: 185f740e0684 ("allow clients to override sanity check for 
> > content-length header")
> > Signed-off-by: Alexander Dahl <ada@thorsis.com>
> > ---
> > 
> > Notes:
> >      Hello everyone,
> >      I discovered this when working with libhttpserver [1] which currently
> >      does not check some return codes and thus ends up passing a null
> >      pointer.  This was no problem against version 0.9.62-1 from the debian
> >      package, but is against recent 0.9.75.  I'm working on fixing that
> >      potentially harmful behaviour of the other lib, but I think the check
> >      here is valuable in itself, because it prevents libmicrohttpd to
> >      segfault.
> >      Greets
> >      Alex
> >      [1] https://github.com/etr/libhttpserver
> > 
> >   src/microhttpd/response.c | 3 +++
> >   1 file changed, 3 insertions(+)
> > 
> > diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
> > index ca3639f4..2a8b3cbe 100644
> > --- a/src/microhttpd/response.c
> > +++ b/src/microhttpd/response.c
> > @@ -494,6 +494,9 @@ MHD_add_response_header (struct MHD_Response *response,
> >                            const char *header,
> >                            const char *content)
> >   {
> > +  if (response == NULL)
> > +    return MHD_NO;
> > +
> >     if (MHD_str_equal_caseless_ (header, MHD_HTTP_HEADER_CONNECTION))
> >       return add_response_header_connection (response, content);
> > 
> > base-commit: 1b1361e4c6e07a74e1a70f96fc570510aaa36815






reply via email to

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