View Issue Details

IDProjectCategoryView StatusLast Update
0010300libmicrohttpdinternal event looppublic2025-08-29 12:06
Reporterarthurscchan Assigned To 
PrioritynormalSeverityminorReproducibilityrandom
Status newResolutionopen 
Summary0010300: Buggy conditional check found in mhd_recv.c
DescriptionA buggy conditional branch check has been found in the `mhd_recv_tls(...)` function.

https://git.gnunet.org/libmicrohttpd2.git/tree/src/mhd2/mhd\_recv.c#n87

```
static MHD_FN_PAR_NONNULL_ALL_
MHD_FN_PAR_OUT_SIZE_ (3,2) MHD_FN_PAR_OUT_ (4) enum mhd_SocketError
mhd_recv_tls (struct MHD_Connection *restrict c,
              size_t buf_size,
              char buf[MHD_FN_PAR_DYN_ARR_SIZE_ (buf_size)],
              size_t *restrict received)
{
  /* TLS connection */
  enum mhd_SocketError res;

  mhd_assert (mhd_C_HAS_TLS (c));
  mhd_assert (0 != buf_size);

  res = mhd_tls_conn_recv (c->tls,
                           buf_size,
                           buf,
                           received);
  c->tls_has_data_in = mhd_TLS_BUF_NO_DATA; /* Updated with the actual value below */

  if (mhd_SOCKET_ERR_AGAIN == res)
    c->sk.ready = (enum mhd_SocketNetState) /* Clear 'recv-ready' */
                  (((unsigned int) c->sk.ready)
                   & (~(enum mhd_SocketNetState)
                      mhd_SOCKET_NET_STATE_RECV_READY));
  else if (mhd_SOCKET_ERR_NO_ERROR == res)
  {
    if (! c->sk.props.is_nonblck)
      c->sk.ready = (enum mhd_SocketNetState) /* Clear 'recv-ready' */
                    (((unsigned int) c->sk.ready)
                     & (~(enum mhd_SocketNetState)
                        mhd_SOCKET_NET_STATE_RECV_READY));
    if (res == buf_size)
    {
      if (mhd_tls_conn_has_data_in (c->tls))
        c->tls_has_data_in = mhd_TLS_BUF_HAS_DATA_IN;
    }
#ifndef NDEBUG
    else
      mhd_assert (! mhd_tls_conn_has_data_in (c->tls));
#endif
  }

  return res;
}
```

On lines 95–103 (https://git.gnunet.org/libmicrohttpd2.git/tree/src/mhd2/mhd_recv.c#n95), the `res` variable is explicitly defined as an `enum mhd_SocketError`. The `buf_size` parameter is asserted to be non-zero. The `res` variable stores the return value from `mhd_tls_conn_recv(...)`, which is expected to be an `enum` indicating either success (`mhd_SOCKET_ERR_NO_ERROR`) or a specific socket error.

```
  enum mhd_SocketError res;

  mhd_assert (mhd_C_HAS_TLS (c));
  mhd_assert (0 != buf_size);

  res = mhd_tls_conn_recv (c->tls,
                           buf_size,
                           buf,
                           received);
```

Later, in lines 111–122 (https://git.gnunet.org/libmicrohttpd2.git/tree/src/mhd2/mhd_recv.c#n111), there is an `else if` branch that executes only if `mhd_SOCKET_ERR_NO_ERROR == res`. This means that `res` must equal `0` (as defined in the enum). However, the subsequent check `if (res == buf_size)` compares this status value (0) to the buffer size (which has been asserted to be non-zero), making the condition impossible to satisfy.

As a result, the block that sets the `c->tls_has_data_in` flag is never executed.

```
  else if (mhd_SOCKET_ERR_NO_ERROR == res)
  {
    if (! c->sk.props.is_nonblck)
      c->sk.ready = (enum mhd_SocketNetState) /* Clear 'recv-ready' */
                    (((unsigned int) c->sk.ready)
                     & (~(enum mhd_SocketNetState)
                        mhd_SOCKET_NET_STATE_RECV_READY));
    if (res == buf_size)
    {
      if (mhd_tls_conn_has_data_in (c->tls))
        c->tls_has_data_in = mhd_TLS_BUF_HAS_DATA_IN;
    }
```

Since `c->tls_has_data_in` is never set, the daemon and connection handler will always assume that there are no pre-decrypted bytes available in the TLS buffer. This means some branches that rely on this flag will never run, leading to the ignoring of already received data and always waiting for another socket event.

This can lead to unnecessary delays, stalls, and reduced throughput because data already decrypted and buffered by the TLS layer is always ignored.

Additional InformationFound during the ongoing security audit carried out by Ada Logics and facilitated by OSTIF in the libmicrohttpd2 project.
TagsNo tags attached.

Activities

There are no notes attached to this issue.

Issue History

Date Modified Username Field Change
2025-08-29 12:06 arthurscchan New Issue