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;
 	    }

Reply via email to