Hello devs,

I am currently investigating a potential compat issue between GNU gettext, MIT Kerberos and Cyrus SASL. My goal is to understand how MIT Kerbros achieves threading support, at least here on HP-UX to go further to Cyrus SASL.
Using HP-UX 11.31 and MIT Kerberos 1.22.1.

Two issues noticed here:
First one:
configure: WARNING: Some functions that are needed for library thread
configure: WARNING: safety appear to be missing.
configure: WARNING:   missing thread-safe function: gethostbyname_r
configure: WARNING:   missing thread-safe function: getservbyname_r
configure: WARNING: Without these functions, the installed libraries
configure: WARNING: may not be thread-safe.

Checking the manpage of both functions:
 OBSOLESCENT INTERFACES
      int gethostent_r(struct hostent *result,
                       struct hostent_data *buffer);

      int gethostbyname_r(const char *name,
                          struct hostent *result,
                          struct hostent_data *buffer);

      int gethostbyaddr_r(const char *addr,
                          int len,
                          int type,
                          struct hostent *result,
                          struct hostent_data *buffer);

      int sethostent_r(int stayopen, struct hostent_data *buffer);

      int endhostent_r(struct hostent_data *buffer);

      The above reentrant interfaces have been moved from libc to libd4r.
      They are included to support existing applications and may be removed
      in the future release.  New multithreaded applications should use the
      regular APIs (those without the -r suffix).

      The reentrant interfaces function the same as the regular interfaces
      without the -r suffix. However, gethostent_r(), gethostbyname_r(), and
      gethostbyaddr_r() expect to be passed the address of a struct hostent
      and will store the address of the result at the supplied parameter.
      The passed in address of struct hostent_data in the reentrant
      interfaces cannot be a NULL pointer.

      The reentrant routines return -1 if the operation is unsuccessful, or,
      in the case of gethostent_r(), if the end of the hosts list has been
      reached.  0 is returned otherwise.

The same applies to getservbyname_r. As far as I understand this configure.ac does not take this into account and actual behavior is unclear in util/support/fake-addrinfo.c?

Second one:
The "man pthread" says:
 COMPILATION SUMMARY
      A multithreaded application must define the appropriate POSIX revision
      level (199506) at compile time and link against the pthread library
      with -lpthread.  For example:

           cc -D_POSIX_C_SOURCE=199506L -o myapp myapp.c -lpthread

      All program sources must also include the header file <pthread.h>.
and from "man aCC":
      -mt            Sets various -D flags to enable multi-threading.  Also
                     sets -lpthread.  +Oopenmp automatically implies -mt.
                     For details see HP C/aC++ Online Programmer's Guide.

While I was able to find the define in the generated Makefiles, neither -lpthread or -mt with "grep -r ^PTHREAD_LIBS --include=Makefile ."

Just missing configuration? I see alot of pthread strings in util/.

The actual issue is the following:
Since gettext 0.23 full thread safety is available and properly linked against libpthread. Now, when this lib or any lib which links against like MIT Kerberos fails to load dynamically.

The Cyrus SASL GSSAPI plugin:
# ldd /opt/ports/lib/hpux32/sasl2/libgssapiv2.so

/opt/ports/lib/hpux32/sasl2/libgssapiv2.so:
        libgssapi_krb5.2 =>     /opt/ports/lib/hpux32/libgssapi_krb5.2
        libkrb5.3 =>    /opt/ports/lib/hpux32/libkrb5.3
        libk5crypto.3 =>        /opt/ports/lib/hpux32/libk5crypto.3
        libcom_err.3 => /opt/ports/lib/hpux32/libcom_err.3
        libc.so.1 =>    /usr/lib/hpux32/libc.so.1
        libkrb5support.0 =>     /opt/ports/lib/hpux32/libkrb5support.0
        libintl.so.12 =>        /opt/ports/lib/hpux32/libintl.so.12
        libdl.so.1 =>   /usr/lib/hpux32/libdl.so.1
        libpthread.so.1 =>      /usr/lib/hpux32/libpthread.so.1
        libiconv.so.8 =>        /opt/ports/lib/hpux32/libiconv.so.8
        libc.so.1 =>    /usr/lib/hpux32/libc.so.1

Now let's simulate pluginviewer with shl_load():
# cat loading.c
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <dl.h>  // Required for shl_load

int main() {
    const char *libPath = "/opt/ports/lib/hpux32/sasl2/libgssapiv2.so";

    void *handle = shl_load(libPath, BIND_IMMEDIATE | BIND_VERBOSE, 0L);

    if (handle == NULL) {
        // Error occurred, print errno and corresponding message
        fprintf(stderr, "Failed to load library: %s\n", libPath);
        fprintf(stderr, "Error code: %d\n", errno);
        fprintf(stderr, "Error message: %s\n", strerror(errno));
        return 1;
    }

    printf("Library loaded successfully!\n");

    // You can now use shl_findsym() to locate symbols...

    return 0;
}
Compile and run:
# cc -o loading loading.c
# ./loading
/usr/lib/hpux32/dld.so: Cannot dlopen load module 
'/usr/lib/hpux32/libpthread.so.1' because it contains thread specific data.
Failed to load library: /opt/ports/lib/hpux32/sasl2/libgssapiv2.so
Error code: 8
Error message: Exec format error

Copilot gave me a few options, and I picked the one endorsed by the manpage:
# cc -o loading loading.c -lpthread
# ./loading
Library loaded successfully!

I am not certain whether you need to correct linking on your end, but Cyrus SASL needs to do this because pluginviewer is broken. In any case I will report to Cyrus SASL.

It boils down to the question: May MIT Kerberos in any of its executables with dlopen() suffer from this issue?

Regards,

Michael
________________________________________________
Kerberos mailing list           [email protected]
https://mailman.mit.edu/mailman/listinfo/kerberos

Reply via email to