Timo Sirainen [Fri, 17 May 2019 07:33:53 +0000 (10:33 +0300)]
lib-imap: Make sure str_unescape() won't be writing past allocated memory
The previous commit should already prevent this, but this makes sure it
can't become broken in the future either. It makes the performance a tiny
bit worse, but that's not practically noticeable.
Timo Sirainen [Fri, 10 May 2019 16:24:51 +0000 (19:24 +0300)]
lib-imap: Don't accept strings with NULs
IMAP doesn't allow NULs except in binary literals. We'll still allow them
in regular literals as well, but just not in strings.
This fixes a bug with unescaping a string with NULs: str_unescape() could
have been called for memory that points outside the allocated string,
causing heap corruption. This could cause crashes or theoretically even
result in remote code execution exploit.
Stephan Bosch [Mon, 15 Jul 2019 19:50:11 +0000 (21:50 +0200)]
lib-smtp: smtp-params - Assume all capabilities are supported when adding parameter event fields.
The actual capabilities are not really needed, since any assigned field is
relevent for event processing, whether the remote end will accept it or not.
This also fixes an assert failure occuring for proxied connections. Since the
server and client (proxy) connections can have different capabilities and since
the client connection does not have a proper capability list available in the
beginning of the handshake, the event created for a client transaction would
cause an assert failure when parameters were assigned that did not match the
capabilities (none).
Timo Sirainen [Fri, 12 Jul 2019 07:16:26 +0000 (10:16 +0300)]
config: Fix memory leaks when failing to convert ssl-parameters.dat
If ssl_dh setting isn't set and ssl-parameters.dat isn't found or there's
some error reading it, memory is leaked for every config request. This
eventually results in config process dying due to reaching vsz_limit.
Stephan Bosch [Mon, 1 Jul 2019 23:04:03 +0000 (19:04 -0400)]
lib-http: guard against hshared use-after-free
This fixes a race condition where the http_client_host_shared_idle_timeout()
function would get called with an already freed hshared argument.
Specifically, the situation arises from the hshared idle timeout calling
http_client_host_shared_free(), which removes the timeout and then proceeds to
free the client queue. The client queue freeing code indirectly calls
http_client_host_shared_check_idle(), which notices that there is no idle
timeout and allocates one.
The backtrace at the point of this new timeout allocation:
frame #3: 0x00007f0c775897f0 libdovecot.so.0`timeout_add_to(...) ioloop.c:280
frame #4: 0x00007f0c7751a45f libdovecot.so.0`http_client_host_shared_check_idle(hshared=<unavailable>) at http-client-host.c:69
frame #5: 0x00007f0c7750de89 libdovecot.so.0`http_client_request_error(_req=<unavailable>, status=9000, error="") at http-client-request.c:1525
frame #6: 0x00007f0c77517f38 libdovecot.so.0`http_client_queue_fail_full(queue=0x000055e13cff0e10, status=9000, error="", all=<unavailable>) at http-client-queue.c:183
frame #7: 0x00007f0c77518baa libdovecot.so.0`http_client_queue_free(queue=0x000055e13cff0e10) at http-client-queue.c:141
frame #8: 0x00007f0c7751a8bc libdovecot.so.0`http_client_host_free_shared(_host=<unavailable>) at http-client-host.c:391
frame #9: 0x00007f0c7751ab4c libdovecot.so.0`http_client_host_shared_free(_hshared=0x00007ffdac109e48) at http-client-host.c:294
frame #10: 0x00007f0c7751ace8 libdovecot.so.0`http_client_host_shared_idle_timeout(hshared=<unavailable>) at http-client-host.c:40
frame #11: 0x00007f0c7758a1a4 libdovecot.so.0`io_loop_handle_timeouts at ioloop.c:682
frame #12: 0x00007f0c7758a089 libdovecot.so.0`io_loop_handle_timeouts(ioloop=0x000055e13cfc8d80) at ioloop.c:696
frame #13: 0x00007f0c7758befc libdovecot.so.0`io_loop_handler_run_internal(ioloop=0x000055e13cfc8d80) at ioloop-select.c:126
frame #14: 0x00007f0c7758a56d libdovecot.so.0`io_loop_handler_run(ioloop=<unavailable>) at ioloop.c:767
frame #15: 0x00007f0c7758a798 libdovecot.so.0`io_loop_run(ioloop=0x000055e13cfc8d80) at ioloop.c:740
frame #16: 0x00007f0c774f61eb libdovecot.so.0`master_service_run(service=0x000055e13cfc8c10, callback=<unavailable>) at master-service.c:782
frame #17: 0x000055e13b48e3a5 stats`main(argc=<unavailable>, argv=<unavailable>) at main.c:99
frame #18: 0x00007f0c771092e1 libc.so.6`__libc_start_main + 241
frame #19: 0x000055e13b48e41a stats`_start + 42
Timo Sirainen [Mon, 8 Jul 2019 15:56:12 +0000 (18:56 +0300)]
lib-index: After recreating cache, make sure offsets are immediately updated to map
They were most likely refreshed anyway before the next cache usage, but this
caused an assert-crash if the dovecot.index was also recreated in the same
sync.
Timo Sirainen [Mon, 8 Jul 2019 15:59:21 +0000 (18:59 +0300)]
lib-index: Fix using old map when checking for unexpected changes during log rotate
This shouldn't normally be possible. The log is locked, so other processes
shouldn't be able to write anything to it. This was mainly found by the
earlier bug.
Timo Sirainen [Mon, 10 Jun 2019 20:07:56 +0000 (23:07 +0300)]
lib-index: Compress cache immediately after enough mails have been expunged
This fixes a bug where cache may never become compressed in certain mailbox
access patterns. Especially for autoexpunging in lazy_expunge mailboxes.
The cache compression happened only when:
a) After the mailbox_sync() that finishes expunging there was another
mailbox_sync(). If mailbox was immediately closed after expunging, this
didn't happen.
b) Fields are fetched from cache
If neither of these happened, the cache just kept growing. This happened
especially with lazy_expunge mailboxes.
sdbox format was always doing b) during expunging, because it looked up
GUIDs from cache. However, this helped only with regular expunges, not
with autoexpunges, because autoexpunging didn't finish with any
mailbox_sync() (which is a bug on its own).
mdbox also did GUID lookups from cache, but it wasn't doing cache
compressions due the bug fixed by the previous commit.
Timo Sirainen [Mon, 10 Jun 2019 20:01:16 +0000 (23:01 +0300)]
lib-index: Fix calling expunge handlers with mdbox
This fixes updating deleted_record_count in dovecot.index.cache files.
Because they were wrong, the cache wasn't always compressed as early as
it should have been.
mdbox uses a separate transaction to commit expunges while mailbox is being
synced. When syncing was finished, tail_offset was updated too early so
mail_index_map(MAIL_INDEX_SYNC_HANDLER_FILE) was always a no-op and expunge
handlers were never called.
There doesn't seem to be any downside to not updating tail_offset early.
sdbox saving also uses such a transaction, but there is no difference in
the resulting dovecot.index.log file. The main worry I had was that
tail_offset wouldn't be updated to point to the end of the log file.
However, this doesn't happen with the old code either. This is because the
extra transaction is external, and tail_offset updating skips over all
external transactions anyway.
Timo Sirainen [Wed, 12 Jun 2019 07:58:37 +0000 (10:58 +0300)]
lib-storage: Sync mailbox after autoexpunging
This actually finishes expunging the mails. Previously the mails were
just marked to be expunged in the transaction log, and the next session
that opened the mailbox finished the expunging.
Stephan Bosch [Thu, 28 Feb 2019 08:55:17 +0000 (09:55 +0100)]
lib: connection - Use the connection event for all connection types directly.
This way, the common event fields for the connection are available to each
connection type and its descendant events for objects like commands, requests,
and transactions.
This also creates a standard log prefix used by all connection types.