Segmentation fault in xsasl_dovecot_server.c

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Segmentation fault in xsasl_dovecot_server.c

Tim Düsterhus
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

xsasl_dovecot_server.patch (606 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Segmentation fault in xsasl_dovecot_server.c

Wietse Venema
What can I say? The XSASL Dovecot client assumes that it is talking
to Dovecot. There may be other errors when you send unexpected
responses from a non-Dovecot server.

        Wietse

--- ./src/xsasl/xsasl_dovecot_server.c- 2016-01-23 19:50:54.000000000 -0500
+++ ./src/xsasl/xsasl_dovecot_server.c 2019-08-24 03:58:10.548175894 -0400
@@ -588,6 +588,10 @@
     }
  } else if (strcmp(cmd, "CONT") == 0) {
     if (xsasl_dovecot_parse_reply(server, &line) == 0) {
+ if (line == 0) {
+    msg_warn("missing Dovecot server %s reply field", cmd);
+    return XSASL_AUTH_FAIL;
+ }
  vstring_strcpy(reply, line);
  return XSASL_AUTH_MORE;
     }
Reply | Threaded
Open this post in threaded view
|

Re: Segmentation fault in xsasl_dovecot_server.c

Tim Düsterhus
Yes, I understand that if I'm pretending to be Dovecot that I should
talk like Dovecot or at least follow the protocol as documented in
Dovecot's Wiki. The protocol error in my implementation is already fixed.

It's just that Postfix never ever crashed on me before and I believe
that it should never crash, even when facing protocol errors in talking
to an "internal" service. Therefore I reported this issue with what I
consider as much information as possible to make it easy enough for you
to fix.

I take the patch at the bottom of your email as "this patch is included
in the next release" and thus consider this case closed.

Thank you.

Best regards
Tim Düsterhus
Reply | Threaded
Open this post in threaded view
|

Re: Segmentation fault in xsasl_dovecot_server.c

Wietse Venema
Tim D?sterhus:

> Yes, I understand that if I'm pretending to be Dovecot that I should
> talk like Dovecot or at least follow the protocol as documented in
> Dovecot's Wiki. The protocol error in my implementation is already fixed.
>
> It's just that Postfix never ever crashed on me before and I believe
> that it should never crash, even when facing protocol errors in talking
> to an "internal" service. Therefore I reported this issue with what I
> consider as much information as possible to make it easy enough for you
> to fix.
>
> I take the patch at the bottom of your email as "this patch is included
> in the next release" and thus consider this case closed.

The code was contributed and not subjected to detailed verification.
It needs more work; during cursory examination I found that smtpd(8)
will abort after a safety check fails, when the "Dovecot" server
replies OK without sending username info back to the Dovecot client.
I'm traveling at the moment and do not have time for a detailed
analysis.

        Wietse
Reply | Threaded
Open this post in threaded view
|

Re: Segmentation fault in xsasl_dovecot_server.c

Wietse Venema
Wietse Venema:

> Tim D?sterhus:
> > Yes, I understand that if I'm pretending to be Dovecot that I should
> > talk like Dovecot or at least follow the protocol as documented in
> > Dovecot's Wiki. The protocol error in my implementation is already fixed.
> >
> > It's just that Postfix never ever crashed on me before and I believe
> > that it should never crash, even when facing protocol errors in talking
> > to an "internal" service. Therefore I reported this issue with what I
> > consider as much information as possible to make it easy enough for you
> > to fix.
> >
> > I take the patch at the bottom of your email as "this patch is included
> > in the next release" and thus consider this case closed.
>
> The code was contributed and not subjected to detailed verification.
> It needs more work; during cursory examination I found that smtpd(8)
> will abort after a safety check fails, when the "Dovecot" server
> replies OK without sending username info back to the Dovecot client.
> I'm traveling at the moment and do not have time for a detailed
> analysis.

Updated patch follows. I would appreciate it if someone could verify
that this reports no errors with a real Dovecot server.

        Wietse

20190825

        Bugfix (introduced: 20051222): the Dovecot client could
        segfault (null pointer read) or cause an SMTP server assertion
        to fail when talking to a fake Dovecot server. It now logs
        a proper error instead. File: xsasl/xsasl_dovecot_server.c.

*** ./src/xsasl/xsasl_dovecot_server.c- 2016-01-24 01:50:54.000000000 +0100
--- ./src/xsasl/xsasl_dovecot_server.c 2019-08-25 19:11:02.808234389 +0200
***************
*** 584,593 ****
--- 584,603 ----
     if (xsasl_dovecot_parse_reply(server, &line) == 0) {
  /* authentication successful */
  xsasl_dovecot_parse_reply_args(server, line, reply, 1);
+ if (server->username == 0) {
+    msg_warn("missing Dovecot server %s username field", cmd);
+    vstring_strcpy(reply, "Authentication backend error");
+    return XSASL_AUTH_FAIL;
+ }
  return XSASL_AUTH_DONE;
     }
  } else if (strcmp(cmd, "CONT") == 0) {
     if (xsasl_dovecot_parse_reply(server, &line) == 0) {
+ if (line == 0) {
+    msg_warn("missing Dovecot server %s reply field", cmd);
+    vstring_strcpy(reply, "Authentication backend error");
+    return XSASL_AUTH_FAIL;
+ }
  vstring_strcpy(reply, line);
  return XSASL_AUTH_MORE;
     }
Reply | Threaded
Open this post in threaded view
|

Re: Segmentation fault in xsasl_dovecot_server.c

Eray Aslan-2
On Sun, Aug 25, 2019 at 01:23:09PM -0400, Wietse Venema wrote:
> Updated patch follows. I would appreciate it if someone could verify
> that this reports no errors with a real Dovecot server.

PLAIN / LOGIN works as expected for me on a lightly loaded server.

--
Eray
Reply | Threaded
Open this post in threaded view
|

Re: Segmentation fault in xsasl_dovecot_server.c

Wietse Venema
Eray Aslan:
> On Sun, Aug 25, 2019 at 01:23:09PM -0400, Wietse Venema wrote:
> > Updated patch follows. I would appreciate it if someone could verify
> > that this reports no errors with a real Dovecot server.
>
> PLAIN / LOGIN works as expected for me on a lightly loaded server.

Thanks.

        Wietse