Opened 3 years ago

Last modified 3 years ago

#62468 closed defect

_sasl_locate_entry() in Cyrus SASL's lib/dlopen.c assumes a leading underscore is needed for calls to dlsym() — at Version 16

Reported by: steven-michaud (Steven Michaud) Owned by:
Priority: Normal Milestone:
Component: ports Version:
Keywords: Cc:
Port: cyrus-sasl2

Description (last modified by kencu (Ken))

I've installed cyrus-sasl2 @2.1.27_2+kerberos on macOS 11.2.3 and have been using it with postfix @3.5.9_0+dovecot_sasl+pcre+sasl+tls and dovecot @2.3.11.3_2. Sending mail with STARTTLS and the SASL PLAIN mechanism simply didn't work. I've spent the last several days debugging the problem, and now I've found the cause.

Here's a fragment of code from _sasl_locate_entry():

#if defined(DLSYM_NEEDS_UNDERSCORE) || (defined(__OpenBSD__) && !defined(__ELF__))
    snprintf(adj_entryname, sizeof adj_entryname, "_%s", entryname);
#endif

    *entry_point = NULL;
    *entry_point = dlsym(library, adj_entryname);
    if (*entry_point == NULL) {
#if 0 /* This message appears to confuse people */
      _sasl_log(NULL, SASL_LOG_DEBUG,
                "unable to get entry point %s: %s", adj_entryname,
                dlerror());
#endif
      return SASL_FAIL;
    }

By means of various tests, and by looking at libsasl2.3.dylib in a disassembler, I've found that (in your distro) this code is behaving as if DLSYM_NEEDS_UNDERSCORE is defined. Of course it shouldn't be. I don't know why. The sasl_cv_dlsym_adds_uscore test in configure.ac looks like it should work. Could your cyrus_sasl2 distro have been compiled on something other than a Mac? In other words, might it have been cross-compiled on some other kind of system (e.g. Linux)?

Every time I try to send mail via STARTTLS and the SASL PLAIN mechanism, I get the error message "No worthy mechs found". Postfix is correctly set up -- the same setup works fine on other machines which use Cyrus SASL from other providers (like Apple). The reason is that my connection's list of mechanisms (sasl_client_conn_t.mech_list) only includes the "EXTERNAL" mechanism. sasl_client_add_plugin() is only ever called on this mechanism. The reason it isn't called on all the others (including the PLAIN mechanism) is that _sasl_locate_entry() (called from _sasl_plugin_load()) always fails, because it always adds an underscore in front of entryname.

Change History (18)

Changed 3 years ago by steven-michaud (Steven Michaud)

HookCase hook library I tested with

comment:1 Changed 3 years ago by steven-michaud (Steven Michaud)

I just added the source code for a HookCase hook library I've been testing with, as a patch on https://github.com/steven-michaud/HookCase/blob/master/HookLibraryTemplate/hook.mm.

https://github.com/steven-michaud/HookCase

comment:2 Changed 3 years ago by steven-michaud (Steven Michaud)

Port: cyrus-sasl2 @2.1.27_2+kerberos added

Changed 3 years ago by steven-michaud (Steven Michaud)

Attachment: smtp.sh added

'smtp' launcher that loads my hook library

comment:3 Changed 3 years ago by kencu (Ken)

it checks here (configure.ac)

dnl Do we need leading underscores on our symbols?

AC_CHECK_PROGS(NM, nm)

AC_MSG_CHECKING(for underscore before symbols)
AC_CACHE_VAL(sasl_cv_uscore,[
    echo "int main(){int i=1; return 0;}
    void foo(){int i=6;}" > conftest.c
    ${CC} -o a.out conftest.c > /dev/null
    if (${NM} a.out | grep _foo) > /dev/null; then
      sasl_cv_uscore=yes
    else
      sasl_cv_uscore=no
    fi])
AC_MSG_RESULT($sasl_cv_uscore)
rm -f conftest.c a.out

and on my Mojave system, finds this:

configure:15311: checking for underscore before symbols
configure:15327: result: yes

comment:4 Changed 3 years ago by kencu (Ken)

but in the next section, comes something interesting that could be the issue. What system are you on? On some systems, this implicit-function-declaration is raised to an error.

configure:15333: checking whether dlsym adds the underscore for us
configure:15355: /usr/bin/clang -o conftest -Wall -W -pipe -Os -isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk -arch x86_64 -I/opt/local/include -isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk -L/opt/local/lib -Wl,-headerpad_max_install_names -Wl,-syslibroot,/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk -arch x86_64 conftest.c  -ldl >&5
conftest.c:37:18: warning: unused variable 'i' [-Wunused-variable]
void foo() { int i=0;}
                 ^
conftest.c:40:23: warning: implicitly declaring library function 'exit' with type 'void (int) __attribute__((noreturn))' [-Wimplicit-function-declaration]
    if(ptr1 && !ptr2) exit(0); } exit(1); }
                      ^
conftest.c:40:23: note: include the header <stdlib.h> or explicitly provide a declaration for 'exit'
2 warnings generated.
configure:15355: $? = 0
configure:15355: ./conftest
configure:15355: $? = 0
configure:15370: result: yes
Last edited 3 years ago by kencu (Ken) (previous) (diff)

comment:5 Changed 3 years ago by steven-michaud (Steven Michaud)

I used 'smtp.sh' (above) to load my hook library. I replaced 'smtp' in Postfix's master.cf with 'smtp.sh'.

comment:6 Changed 3 years ago by steven-michaud (Steven Michaud)

I'm on macOS 11.2.3. I used "port install" for everything (including cyrus-sasl2 @2.1.27_2+kerberos). I didn't do any explicit compiling.

comment:7 Changed 3 years ago by kencu (Ken)

Yeah, it probably fails that dlsym adds the underscore for us test because of Wimplicit-function-declaration being raised to an error.

can you check in your config.log?

Last edited 3 years ago by kencu (Ken) (previous) (diff)

comment:8 Changed 3 years ago by kencu (Ken)

cd `port work cyrus-sasl2`
cd cy*
bbedit config.log

and search for:

dlsym adds the underscore for us

comment:9 Changed 3 years ago by steven-michaud (Steven Michaud)

can you check in your config.log?

Where is is? I couldn't find it anywhere under /opt/local.

comment:10 Changed 3 years ago by kencu (Ken)

I figured that might happen, so I just outlined how to find it one box above :>

comment:11 Changed 3 years ago by steven-michaud (Steven Michaud)

Oh well. In any case I still can't find it. port work cyrus-sasl2 resolves to my home directory, and there's nothing there that I didn't explicitly create myself.

comment:12 Changed 3 years ago by kencu (Ken)

really? here it is then

$ port work cyrus-sasl2
/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_security_cyrus-sasl2/cyrus-sasl2/work

comment:13 Changed 3 years ago by kencu (Ken)

Oh -- you have to have the work directory for it to be found, of course. Do this:

sudo port -v configure cyrus-sasl2
cd `port work cyrus-sasl2`
cd cy*
bbedit config.log

or just wait if you like, and someone will do it in time. It's about 99.9999% likely that is going to be the issue.

We've seen hundreds of these since Apple raised Wimplicit-function-declaration to an error in Xcode 12.

comment:14 Changed 3 years ago by steven-michaud (Steven Michaud)

"port work cyrus-sasl2" produces no output. And there are no "work" directories at all under /opt/local. I used "sudo find /opt/local -name work".

comment:15 Changed 3 years ago by kencu (Ken)

see one box above.

comment:16 Changed 3 years ago by kencu (Ken)

Description: modified (diff)
Note: See TracTickets for help on using tickets.