Hello,

While debugging an smtp process segfault during sasl authentication
with gmail servers in xoauth2 (xoauth2 authentication which I am in the
process of setting up, so I have no idea if this is a recent
regression), I discover this:

(gdb) bt
#0  xsasl_cyrus_client_get_passwd (conn=0x55b2ee539630, context=0x4004, 
id=-761575872, psecret=0x0) at xsasl_cyrus_client.c:197
#1  0x00007f6a3d75cf44 in _plug_get_simple (utils=utils@entry=0x55b2ee54e3b0, 
id=id@entry=16388, required=required@entry=1, 
result=result@entry=0x7ffed29b4640, prompt_need=prompt_need@entry=0x0) at 
./src/saslplugin/plugin_common.c:373
[snip]
(gdb) up
#1  0x00007f6a3d75cf44 in _plug_get_simple (utils=utils@entry=0x55b2ee54e3b0, 
id=id@entry=16388, required=required@entry=1, 
result=result@entry=0x7ffed29b4640, prompt_need=prompt_need@entry=0x0) at 
./src/saslplugin/plugin_common.c:373
373             ret = simple_cb(simple_context, id, result, NULL);
(gdb) print simple_context
$13 = (void *) 0x55b2ee539630
(gdb) print id
$14 = 16388
(gdb) print result
$15 = (const char **) 0x7ffed29b4640

Note how the caller (here, libkdexoauth2.so) is calling with:
- context
- id
- result
- null
but xsasl_cyrus_client_get_passwd's signature is:
  sasl_conn_t *conn, void *context, int id, sasl_secret_t **psecret
which causes id to end up in context (and so on), then context gets
promptly dereferenced and causes the segfault.

sasl_getcallback_t definition seems to indicate that libkdexoauth2.so is 
correct:
  
https://github.com/cyrusimap/cyrus-sasl/blob/2c66fff698bdb489fa23221b8ec56c6df34f12e5/include/saslplug.h#L24-L40
Also, xsasl_cyrus_client_get_user's signature differs from
xsasl_cyrus_client_get_passwd's, and is consistent with the above
typedef:
  void *context, int unused_id, [...]

I believe xsasl_cyrus_client_get_passwd's first argument needs to be
dropped, and its use in this function replaced with "context".
Also,
    if (msg_verbose)
        msg_info("%s: %s", myname, client->password);
should probably be moved after
    if (!conn || !psecret || id != SASL_CB_PASS)
        return (SASL_BADPARAM);
so it gets protected against "easy" conn (then becomming "context")
null dereferences.

But beyond this, I am puzzled as to why this does not crash with every
single sasl plugin: don't they all need a password ?
Especially, I'm sending this email using the very same postfix build,
using libxoauth2.so from
  https://github.com/moriyoshi/cyrus-sasl-xoauth2
and with libkdexoauth2.so.3 out of the way, and authentication worked.
I do not like magic in my authentication.

Regards,
-- 
Vincent Pelletier
GPG fingerprint 983A E8B7 3B91 1598 7A92 3845 CAC9 3691 4257 B0C1

Reply via email to