On 7/3/24 2:59 AM, Yann Ylavic wrote:
> On Tue, Jul 2, 2024 at 10:57 AM Ruediger Pluem <rpl...@apache.org> wrote:
>>
>> On 7/1/24 3:01 PM, Ruediger Pluem wrote:
>>>
>>>
>>> On 6/27/24 3:48 PM, Ruediger Pluem wrote:
>>>>
>>>>
>>>> On 6/27/24 12:47 PM, Yann Ylavic wrote:
>>>>> On Thu, Jun 27, 2024 at 12:38 PM Yann Ylavic <ylavic....@gmail.com> wrote:
>>>>>>
>>>>>> On Thu, Jun 27, 2024 at 12:07 PM Ruediger Pluem <rpl...@apache.org> 
>>>>>> wrote:
>>>>>>>
>>>>>>> How about the below? I am yet undecided if I should follow the below 
>>>>>>> approach to have
>>>>>>> two completely separate callbacks depending on the OpenSSL version or 
>>>>>>> one with a lot of
>>>>>>> #If statements in it, but as much shared code as possible. Thoughts?
>>>>>>
>>>>>> Hm, I wouldn't duplicate the whole thing depending on openssl version.
>>>>>>
>>>>>> Something like the attached maybe? modssl_io_cb() will just consider
>>>>>> up to APR_INT32_MAX bytes, more shouldn't happen anyway and it's more
>>>>>> than enough for debug logs..
>>>>>
>>>>> We could even log the real length still if it matters, see attached v2.
>>>>
>>>> Thanks. Unfortunately the meaning of rc varies depending on if we have the 
>>>> ex or the non ex callback.
>>>> This is not in the documentation but only in the OpenSSL code :-(.
>>>> Furthermore the processed amount of data is in *processed in the ex case 
>>>> whereas in the non ex case it is in
>>>> rc. The intended amount of data to be processed is in len in the ex case 
>>>> and in argi in the non ex case.
>>>> Hence I propose the patch below. Of course we can have a longer debate if 
>>>> the len parameter to ssl_io_data_dump
>>>> should be int or size_t :-). And yes dumping more than APR_INT32_MAX bytes 
>>>> to the log might be bad.
>>>
>>> Any further comments on whether we should limit the dump to APR_INT32_MAX 
>>> or not? I would guess that it will not matter
>>> in practice, but I am still open to it.
>>> BTW: I guess
>>>
>>>  int len = data_len & APR_INT32_MAX;
>>>
>>> would be wrong. It would need to be
>>>
>>>  int len = data_len > APR_INT32_MAX ? APR_INT32_MAX : (int)data_len;
>>>
>>> instead.
> 
> Right! Maybe APR_UINT16_MAX is enough, I don't think we should log
> more undecipherable text than that :)
> IIRC an SSL/TLS payload is 16K (still?) anyway so we shouldn't be
> called for more than that (though multiple times)?
> 
>>
>> Updated patch.
>>
>> Index: modules/ssl/ssl_engine_io.c
>> ===================================================================
>> --- modules/ssl/ssl_engine_io.c (revision 1918813)
>> +++ modules/ssl/ssl_engine_io.c (working copy)
>> @@ -2308,7 +2308,7 @@
>>  #define DUMP_WIDTH 16
>>
>>  static void ssl_io_data_dump(conn_rec *c, server_rec *s,
>> -                             const char *b, long len)
>> +                             const char *b, size_t len)
>>  {
>>      char buf[256];
>>      int i, j, rows, trunc, pos;
>> @@ -2361,7 +2361,7 @@
>>      }
>>      if (trunc > 0)
>>          ap_log_cserror(APLOG_MARK, APLOG_TRACE7, 0, c, s,
>> -                "| %04ld - <SPACES/NULS>", len + trunc);
>> +                "| %04" APR_SIZE_T_FMT " - <SPACES/NULS>", len + 
>> (size_t)trunc);
>>      ap_log_cserror(APLOG_MARK, APLOG_TRACE7, 0, c, s,
>>              
>> "+-------------------------------------------------------------------------+");
>>  }
>> @@ -2379,9 +2379,9 @@
>>      conn_rec *c;
>>      server_rec *s;
>>  #if OPENSSL_VERSION_NUMBER >= 0x30000000L
>> -    (void)len;
>> -    (void)processed;
>> +    (void)argi;
>>  #endif
>> +    (void)argl;
>>
>>      if ((ssl = (SSL *)BIO_get_callback_arg(bio)) == NULL)
>>          return rc;
>> @@ -2391,7 +2391,20 @@
>>
>>      if (   cmd == (BIO_CB_WRITE|BIO_CB_RETURN)
>>          || cmd == (BIO_CB_READ |BIO_CB_RETURN) ) {
>> +#if OPENSSL_VERSION_NUMBER >= 0x30000000L
>> +#define requested_len (len)
>> +#define actual_len (*processed)
>            requested_len = len
>> +        /*
>> +         * On OpenSSL >= 3 rc uses the meaning of the BIO_read_ex and
>> +         * BIO_write_ex functions return value and not the one of
>> +         * BIO_read and BIO_write. Hence 0 indicates an error.
>> +         */
>> +        if (rc > 0) {
>> +#else
>> +#define requested_len ((size_t)argi)
>> +#define actual_len ((size_t)rc)
>>          if (rc >= 0) {
>> +#endif
> Maybe use variables like:
> #if OPENSSL_VERSION_NUMBER >= 0x30000000L
>            apr_size_t requested_len = len;
>            int ok = (rc > 0);
> #else
>            apr_size_t requested_len = argi;
>            int ok = (rc >= 0);
> #endif
>            if (ok) {
> #if OPENSSL_VERSION_NUMBER >= 0x30000000L
>                apr_size_t actual_len = *processed;
> #else
>                apr_size_t actual_len = rc;
> #endif

I am fine with this. Maybe my desire to save stack memory by not using further
variables was a bit over the top here.

>>              const char *dump = "";
>>              if (APLOG_CS_IS_LEVEL(c, s, APLOG_TRACE7)) {
>>                  if (argp != NULL)
>> @@ -2400,23 +2413,28 @@
>>                      dump = "(Oops, no memory buffer?)";
>>              }
>>              ap_log_cserror(APLOG_MARK, APLOG_TRACE4, 0, c, s,
>> -                    "%s: %s %ld/%d bytes %s BIO#%pp [mem: %pp] %s",
>> +                    "%s: %s %" APR_SIZE_T_FMT "/%" APR_SIZE_T_FMT
>> +                    " bytes %s BIO#%pp [mem: %pp] %s",
>>                      MODSSL_LIBRARY_NAME,
>>                      (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : 
>> "read"),
>> -                    (long)rc, argi, (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? 
>> "to" : "from"),
>> +                    actual_len, requested_len,
>> +                    (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "to" : "from"),
>>                      bio, argp, dump);
>>              if (*dump != '\0' && argp != NULL)
>> -                ssl_io_data_dump(c, s, argp, rc);
>> +                ssl_io_data_dump(c, s, argp, actual_len);
> And here:
>                    long dump_len = (actual_len >= APR_UINT16_MAX
>                                     ? APR_UINT16_MAX
>                                     : actual_len);

Hm. As you point out: SSL records should be of limited length anyway, but if we 
really truncate the output shouldn't we log this?
A log message like: Dump truncated to first XXX bytes?

>                    ssl_io_data_dump(c, s, argp, dump_len);
>>          }
>>          else {
>>              ap_log_cserror(APLOG_MARK, APLOG_TRACE4, 0, c, s,
>> -                    "%s: I/O error, %d bytes expected to %s on BIO#%pp 
>> [mem: %pp]",
>> -                    MODSSL_LIBRARY_NAME, argi,
>> +                    "%s: I/O error, %" APR_SIZE_T_FMT
>> +                    " bytes expected to %s on BIO#%pp [mem: %pp]",
>> +                    MODSSL_LIBRARY_NAME, requested_len,
>>                      (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : 
>> "read"),
>>                      bio, argp);
>>          }
>>      }
>>      return rc;
>> +#undef requested_len
>> +#undef actual_len
>>  }
> ?

Regards

Rüdiger

Reply via email to