Blame doc/thread-safe.txt

Packit fd8b60
[May be out of date.  Last significant update: Jan 2005.]
Packit fd8b60
Packit fd8b60
In general, it's assumed that the library initialization function (if
Packit fd8b60
initialization isn't delayed) and the library finalization function
Packit fd8b60
are run in some thread-safe fashion, with no other parts of the
Packit fd8b60
library in question in use.  (If dlopen or dlsym in one thread starts
Packit fd8b60
running the initializer, and then dlopen/dlsym in another thread
Packit fd8b60
returns and lets you start accessing functions or data in the library
Packit fd8b60
before the initializer is finished, that really seems like a
Packit fd8b60
dlopen/dlsym bug.)
Packit fd8b60
Packit fd8b60
It's also assumed that if library A depends on library B, then library
Packit fd8b60
B's initializer runs first, and its finalizer last, whether loading
Packit fd8b60
dynamically at run time or at process startup/exit.  (It appears that
Packit fd8b60
AIX 4.3.3 may violate this, at least when we use gcc's
Packit fd8b60
constructor/destructor attributes in shared libraries.)
Packit fd8b60
Packit fd8b60
Support for freeing the heap storage allocated by a library has NOT,
Packit fd8b60
in general, been written.  There are hooks, but often they ignore some
Packit fd8b60
of the library's local storage, mutexes, etc.
Packit fd8b60
Packit fd8b60
If shared library finalization code doesn't get run at all at dlclose
Packit fd8b60
time, or if we can't use it because the execution order is wrong, then
Packit fd8b60
you'll get memory leaks.  Deal with it.
Packit fd8b60
Packit fd8b60
Several debugging variables that are not part of our official API are
Packit fd8b60
not protected by mutexes.  In general, the only way to set them is by
Packit fd8b60
changing the sources and recompiling, which obviously has no run-time
Packit fd8b60
thread safety issues, or by stopping the process under a debugger,
Packit fd8b60
which we blithely assert is "safe enough".
Packit fd8b60
Packit fd8b60
Debug code that we don't normally enable may be less thread safe than
Packit fd8b60
might be desired.  For example, multiple printf calls may be made,
Packit fd8b60
with the assumption that the output will not be intermixed with output
Packit fd8b60
from some other thread.  Offhand, I'm not aware of any cases where
Packit fd8b60
debugging code is "really" unsafe, as in likely to crash the program
Packit fd8b60
or produce insecure results.
Packit fd8b60
Packit fd8b60
Various libraries may call assert() and abort().  This should only be
Packit fd8b60
for "can't happen" cases, and indicate programming errors.  In some
Packit fd8b60
cases, the compiler may be able to infer that the "can't happen" cases
Packit fd8b60
really can't happen, and drop the calls, but in many cases, this is
Packit fd8b60
not possible.
Packit fd8b60
Packit fd8b60
There are cases (e.g., in the com_err library) where errors arising
Packit fd8b60
when dealing with other errors are handled by calling abort, for lack
Packit fd8b60
of anything better.  We should probably clean those up someday.
Packit fd8b60
Packit fd8b60
Various libraries call getenv().  This is perfectly safe, as long as
Packit fd8b60
nothing is calling setenv or putenv or what have you, while multiple
Packit fd8b60
threads are executing.  Of course, that severely curtails the ability
Packit fd8b60
to control our libraries through that "interface".
Packit fd8b60
Packit fd8b60
Various libraries call the ctype functions/macros (isupper, etc).  It
Packit fd8b60
is assumed that the program does not call setlocale, or does so only
Packit fd8b60
while the program is still single-threaded or while calls into the
Packit fd8b60
Kerberos libraries are not in progress.
Packit fd8b60
Packit fd8b60
The Windows thread safety support is unfinished.
Packit fd8b60
Packit fd8b60
I'm assuming that structure fields that are never written to (e.g.,
Packit fd8b60
after a structure has been initialized and *then* made possibly
Packit fd8b60
visible to multiple threads) are safe to read from one thread while
Packit fd8b60
another field is being updated by another thread.  If that's not the
Packit fd8b60
case, some more work is needed (and I'd like details on why it's not
Packit fd8b60
safe).
Packit fd8b60
Packit fd8b60
----------------
Packit fd8b60
Packit fd8b60
libcom_err
Packit fd8b60
Packit fd8b60
Issues:
Packit fd8b60
Packit fd8b60
The callback hook support (set_com_err_hook, reset_com_err_hook, and
Packit fd8b60
calls to com_err and com_err_va) uses a mutex to protect the handle on
Packit fd8b60
the hook function.  As a side effect of this, if a callback function
Packit fd8b60
is registered which pops up a window and waits for the users'
Packit fd8b60
acknowledgement, then other errors cannot be reported by other threads
Packit fd8b60
until after the acknowledgement.  This could be fixed with
Packit fd8b60
multiple-reader-one-writer type locks, but that's a bit more
Packit fd8b60
complicated.
Packit fd8b60
Packit fd8b60
The string returned by error_message may be per-thread storage.  It
Packit fd8b60
can be passed off between threads, but it shouldn't be in use by any
Packit fd8b60
thread by the time the originating thread calls error_message again.
Packit fd8b60
Packit fd8b60
Error tables must no longer be in use (including pointers returned by
Packit fd8b60
error_message) when the library containing them is unloaded.
Packit fd8b60
Packit fd8b60
Temporary: A flag variable has been created in error_message.c which
Packit fd8b60
is used to try to catch cases where remove_error_table is called after
Packit fd8b60
the library finalization function.  This generally indicates
Packit fd8b60
out-of-order execution of the library finalization functions.  The
Packit fd8b60
handling of this flag is not thread-safe, but if the finalization
Packit fd8b60
function is called, other threads should in theory be finished with
Packit fd8b60
this library anyways.
Packit fd8b60
Packit fd8b60
Statics: error_message.c, com_err.c, covered above.
Packit fd8b60
Packit fd8b60
----------------
Packit fd8b60
Packit fd8b60
libprofile (and its use in libkrb5)
Packit fd8b60
Packit fd8b60
Does no checks to see if it's opened multiple instances of the same
Packit fd8b60
file under different names.  Does not guard against trying to open a
Packit fd8b60
file while another thread or process is in the process of replacing
Packit fd8b60
it, or two threads trying to update a file at the same time.  The
Packit fd8b60
former should be pretty safe on UNIX with atomic rename, but on
Packit fd8b60
Windows there's a race condition; there's a window (so to speak) where
Packit fd8b60
the filename does not correspond to an actual file.
Packit fd8b60
Packit fd8b60
Statics: prof_file.c, a list of opened config files and their parse
Packit fd8b60
trees, and a mutex to protect it.
Packit fd8b60
Packit fd8b60
----------------
Packit fd8b60
Packit fd8b60
libk5crypto
Packit fd8b60
Packit fd8b60
Uses of the Yarrow code from the krb5 crypto interface are protected
Packit fd8b60
by a single mutex.  Initialization of the Yarrow state will be done
Packit fd8b60
once, the first time these routines are called.  Calls directly to the
Packit fd8b60
Yarrow functions are not protected.
Packit fd8b60
Packit fd8b60
Uses ctype macros; what happens if the locale is changed in a
Packit fd8b60
multi-threaded program?
Packit fd8b60
Packit fd8b60
Debug var in pbkdf2.c.
Packit fd8b60
Packit fd8b60
Statics: pbkdf2.c: debug variable.
Packit fd8b60
Packit fd8b60
Statics: prng.c: Global Yarrow data and mutex.
Packit fd8b60
Packit fd8b60
Statics: crypto_libinit.c: library initializer aux data.
Packit fd8b60
Packit fd8b60
----------------
Packit fd8b60
Packit fd8b60
libkrb5
Packit fd8b60
Packit fd8b60
(TBD)
Packit fd8b60
Packit fd8b60
Uses: ctype macros
Packit fd8b60
Packit fd8b60
Uses: getaddrinfo, getnameinfo.  According to current specifications,
Packit fd8b60
getaddrinfo should be thread-safe; some implementations are not, and
Packit fd8b60
we're not attempting to figure out which ones.  NetBSD 1.6, for
Packit fd8b60
example, had an unsafe implementation.
Packit fd8b60
Packit fd8b60
Uses: res_ninit, res_nsearch.  If these aren't available, the non-'n'
Packit fd8b60
versions will be used, and they are sometimes not thread-safe.
Packit fd8b60
Packit fd8b60
Uses: mkstemp, mktemp -- Are these, or our uses of them, likely to be
Packit fd8b60
thread-safe?
Packit fd8b60
Packit fd8b60
Uses: sigaction
Packit fd8b60
Packit fd8b60
The use of sigaction is in the code prompting for a password; we try
Packit fd8b60
to catch the keyboard interrupt character being used and turn it into
Packit fd8b60
an error return from that function.  THIS IS NOT THREAD-SAFE.
Packit fd8b60
Packit fd8b60
Uses: tcgetattr, tcsetattr.  This is also in the password-prompting
Packit fd8b60
code.  These are fine as long as no other threads are accessing the
Packit fd8b60
same terminal at the same time.
Packit fd8b60
Packit fd8b60
Uses: fopen.  This is thread-safe, actually, but a multi-threaded
Packit fd8b60
server is likely to be using lots of file descriptors.  On 32-bit
Packit fd8b60
Solaris platforms, fopen will not work if the next available file
Packit fd8b60
descriptor number is 256 or higher.  This can cause the keytab code to
Packit fd8b60
fail.
Packit fd8b60
Packit fd8b60
Statics: prompter.c: interrupt flag
Packit fd8b60
Packit fd8b60
Statics: ccdefops.c: default operations table pointer
Packit fd8b60
Packit fd8b60
Statics: ktdefname.c: variable to override default keytab name, NO
Packit fd8b60
LOCKING.  DON'T TOUCH THESE VARIABLES, at least in threaded programs.
Packit fd8b60
Packit fd8b60
Statics: conv_creds.c: debug variable
Packit fd8b60
Packit fd8b60
Statics: sendto_kdc.c: debug variable, in export list for KDC
Packit fd8b60
Packit fd8b60
Statics: parse.c: default realm cache, changed to not cache
Packit fd8b60
Packit fd8b60
Statics: krb5_libinit.c: lib init aux data
Packit fd8b60
Packit fd8b60
Statics: osconfig.c: various internal variables, probably should be const
Packit fd8b60
Packit fd8b60
Statics: init_ctx.c: "brand" string; not written.
Packit fd8b60
Packit fd8b60
Statics: cc_memory.c: list of caches, with mutex.
Packit fd8b60
Packit fd8b60
Statics: c_ustime.c: last timestamp, to implement "microseconds must
Packit fd8b60
always increment"
Packit fd8b60
Packit fd8b60
Statics: ktbase.c, ccbase.c, rc_base.c: type registries and mutexes.
Packit fd8b60
Packit fd8b60
----------------
Packit fd8b60
Packit fd8b60
libgssapi_krb5
Packit fd8b60
Packit fd8b60
(TBD)
Packit fd8b60
Packit fd8b60
Uses: ctype macros
Packit fd8b60
Packit fd8b60
Statics: acquire_cred.c: name of keytab to use, and mutex.
Packit fd8b60
Packit fd8b60
Statics: gssapi_krb5.c:
Packit fd8b60
Packit fd8b60
Statics: init_sec_context.c:
Packit fd8b60
Packit fd8b60
Statics: set_ccache.c:
Packit fd8b60
Packit fd8b60
Statics: gssapi_generic.c: OID definitions, non-const by
Packit fd8b60
specification.  We probably could make them const anyways.
Packit fd8b60
Packit fd8b60
The keytab name saved away by krb5_gss_register_acceptor_identity is
Packit fd8b60
global and protected by a mutex; the ccache name stored by
Packit fd8b60
gss_krb5_ccache_name is per-thread.  This inconsistency is due to the
Packit fd8b60
anticipated usage patterns.
Packit fd8b60
Packit fd8b60
The old ccache name returned by gss_krb5_ccache_name if the last
Packit fd8b60
parameter is not a null pointer is also stored per-thread, and will be
Packit fd8b60
discarded at the next call to that routine from the same thread, or at
Packit fd8b60
thread termination.
Packit fd8b60
Packit fd8b60
Needs work: check various objects for thread safety
Packit fd8b60
Packit fd8b60
----------------
Packit fd8b60
Packit fd8b60
libgssrpc
Packit fd8b60
Packit fd8b60
New version is in place.  Ignore it for now?
Packit fd8b60
Packit fd8b60
----------------
Packit fd8b60
Packit fd8b60
libkadm5*
Packit fd8b60
libkdb5
Packit fd8b60
Packit fd8b60
Skip these for now.  We may want the KDC libraries to be thread-safe
Packit fd8b60
eventually, so the KDC can take better advantage of hyperthreaded or
Packit fd8b60
multiprocessor systems.
Packit fd8b60
Packit fd8b60
----------------
Packit fd8b60
Packit fd8b60
libapputils
Packit fd8b60
libss
Packit fd8b60
Packit fd8b60
Used by single-threaded programs only (but see above re KDC).  Don't
Packit fd8b60
bother for now.