|
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.
|