|
From: Andrea V. <ml...@ne...> - 2025-06-16 15:45:33
|
Hello.
Recently fetchmail has started crashing on a couple of servers of mine.
The problem seems to be in socket.c:
> int SockWrite(int sock, const char *buf, int len)
> {
> /* WARNING: This is messy - we use an int pointer, so does SSL_write, but fm_write/write would use ssize_t instead.
> Assume that write() won't ever return something that wouldn't fit an int. */
> int n;
> int wrlen = 0;
> #ifdef SSL_ENABLE
> SSL *ssl = SSLGetContext(sock);
> #endif
>
> while (len)
> {
> #ifdef SSL_ENABLE
> if (ssl) {
> ERR_clear_error();
> n = SSL_write(ssl, buf, len);
> } else
> #endif /* SSL_ENABLE */
> n = fm_write(sock, buf, len);
> #ifdef SSL_ENABLE
> if (n <= 0) {
> int ssle = SSL_get_error(ssl, n); // do this before flushing the error queue!
> // map error code to n = 0 -> retryable or n = -1 -> true error
> switch(ssle) {
> case SSL_ERROR_ZERO_RETURN:
> case SSL_ERROR_SYSCALL:
> case SSL_ERROR_SSL:
> n = -1; break;
> default:
> /* assume retryable */
> n = 0; break;
> }
> if (n)
> ERR_print_errors_fp(stderr); // do this after SSL_get_error - and only on fatal errors
> }
> #endif
> if (n < 0)
> return -1;
> len -= n;
> wrlen += n;
> buf += n;
> }
> return wrlen;
> }
Here ssl is first checked in order to decide if SSL_write or fm_write
should be called.
Then, regardless of the choice, in case of error, SSL_get_error is
called (even when ssl is NULL) and that's where the program crashes.
Maybe I'm wrong, but I think the lines:
>> if (n <= 0) {
>> int ssle = SSL_get_error(ssl, n); // do this before flushing the error queue!
should be changed to:
>> if (ssl && n <= 0) {
>> int ssle = SSL_get_error(ssl, n); // do this before flushing the error queue!
(Or the whole "if {...}" could be moved inside the first "if (ssl)").
In any case, thanks a lot for providing this software!
bye
av.
|