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