Dear List while implementing the Dovecot SASL protocol in a custom server I noticed that the `smtpd` process crashes with a segmentation fault if a specific protocol error occurs.
To reproduce I downloaded Postfix 3.4.6 and compiled it with: make makefiles CCARGS='-DUSE_SASL_AUTH \ -DDEF_SERVER_SASL_TYPE=\"dovecot\"' After `make install` I added the following configuration options to `main.cf`: smtpd_sasl_type = dovecot smtpd_sasl_path = inet:localhost:2525 smtpd_sasl_security_options = noanonymous smtpd_sasl_local_domain = $mydomain and enabled `submission` in `master.cf`. --- I'm running `nc` on port 2525 for this demo: When I connect to submission I perform the Dovecot SASL handshake: > root@postfix-crash:~# nc -l 2525 > VERSION 1 0 > CPID 18617 > MECH PLAIN plaintext > VERSION 1 0 > SPID 1 > CUID 1 > COOKIE abcd > DONE Then the client sends the `EHLO`, followed by `AUTH PLAIN`. Postfix sends the following to `nc`: > AUTH 1 PLAIN service=smtp nologin lip=*snip* rip=*snip* I reply with `CONT 1` with empty base64 data, but I omit the trailing tab that is required by the protocol (https://wiki2.dovecot.org/Design/AuthProtocol#Authentication_Request): > CONT 1 Now the smtpd process crashes with a segmentation fault / null pointer dereference. The backtrace is as follows: > (gdb) bt > #0 vstring_strcpy (vp=vp@entry=0x559d7e238dc0, src=0x0) at vstring.c:454 > #1 0x0000559d7c90e194 in xsasl_dovecot_handle_reply > (server=server@entry=0x559d7e234c10, reply=reply@entry=0x559d7e238dc0) at > xsasl_dovecot_server.c:591 > #2 0x0000559d7c90e494 in xsasl_dovecot_server_first (xp=0x559d7e234c10, > sasl_method=0x559d7e23b4c0 "PLAIN", init_response=0x0, reply=0x559d7e238dc0) > at xsasl_dovecot_server.c:703 > #3 0x0000559d7c90973a in smtpd_sasl_authenticate > (state=state@entry=0x7ffe55ba58e0, sasl_method=0x559d7e23b4c0 "PLAIN", > init_response=init_response@entry=0x0) at smtpd_sasl_glue.c:298 > #4 0x0000559d7c909258 in smtpd_sasl_auth_cmd (state=0x7ffe55ba58e0, argc=2, > argv=0x559d7e23b600) at smtpd_sasl_proto.c:227 > #5 0x0000559d7c8f7b51 in smtpd_sasl_auth_cmd_wrapper (state=0x7ffe55ba58e0, > argc=2, argv=0x559d7e23b600) at smtpd.c:2004 > #6 0x0000559d7c8f9078 in smtpd_proto (state=0x7ffe55ba58e0) at smtpd.c:5715 > #7 0x0000559d7c8fc663 in smtpd_service (stream=0x559d7e234160, > service=0x7ffe55ba6df1 "submission", argv=<optimized out>) at smtpd.c:5967 > #8 0x0000559d7c90c3b7 in single_server_wakeup (fd=fd@entry=13, > attr=attr@entry=0x0) at single_server.c:303 > #9 0x0000559d7c90c6b9 in single_server_accept_inet (unused_event=<optimized > out>, context=<optimized out>) at single_server.c:422 > #10 0x0000559d7c933306 in event_loop (delay=<optimized out>) at events.c:1186 > #11 0x0000559d7c90d3ec in single_server_main (argc=<optimized out>, > argv=<optimized out>, service=0x559d7c8fc44d <smtpd_service>) at > single_server.c:819 > #12 0x0000559d7c8fd74d in main (argc=26, argv=0x7ffe55ba6498) at > ../../include/mail_server.h:96 The beginning of the full backtrace is as follows: > #0 vstring_strcpy (vp=vp@entry=0x559d7e238dc0, src=0x0) at vstring.c:454 > No locals. > #1 0x0000559d7c90e194 in xsasl_dovecot_handle_reply > (server=server@entry=0x559d7e234c10, reply=reply@entry=0x559d7e238dc0) at > xsasl_dovecot_server.c:591 > myname = 0x559d7c94e99d "xsasl_dovecot_handle_reply" > line = 0x0 > cmd = <optimized out> > #2 0x0000559d7c90e494 in xsasl_dovecot_server_first (xp=0x559d7e234c10, > sasl_method=0x559d7e23b4c0 "PLAIN", init_response=0x0, reply=0x559d7e238dc0) > at xsasl_dovecot_server.c:703 > myname = 0x559d7c94e9da "xsasl_dovecot_server_first" > server = 0x559d7e234c10 > i = 0 > cpp = <optimized out> I have created the following patch that fixes this issue. I also attached it to this email. > diff -Nurw postfix-3.4.6.orig/src/xsasl/xsasl_dovecot_server.c > postfix-3.4.6/src/xsasl/xsasl_dovecot_server.c > --- postfix-3.4.6.orig/src/xsasl/xsasl_dovecot_server.c 2019-08-23 > 20:40:31.699488762 +0200 > +++ postfix-3.4.6/src/xsasl/xsasl_dovecot_server.c 2019-08-23 > 20:57:56.587043528 +0200 > @@ -588,6 +588,10 @@ > } > } else if (strcmp(cmd, "CONT") == 0) { > if (xsasl_dovecot_parse_reply(server, &line) == 0) { > + if (line == NULL) { > + msg_warn("SASL: Protocol error"); > + continue; > + } > vstring_strcpy(reply, line); > return XSASL_AUTH_MORE; > } Let me know if you need any further information. Best regards Tim Düsterhus
diff -Nurw postfix-3.4.6.orig/src/xsasl/xsasl_dovecot_server.c postfix-3.4.6/src/xsasl/xsasl_dovecot_server.c --- postfix-3.4.6.orig/src/xsasl/xsasl_dovecot_server.c 2019-08-23 20:40:31.699488762 +0200 +++ postfix-3.4.6/src/xsasl/xsasl_dovecot_server.c 2019-08-23 20:57:56.587043528 +0200 @@ -588,6 +588,10 @@ } } else if (strcmp(cmd, "CONT") == 0) { if (xsasl_dovecot_parse_reply(server, &line) == 0) { + if (line == NULL) { + msg_warn("SASL: Protocol error"); + continue; + } vstring_strcpy(reply, line); return XSASL_AUTH_MORE; }