Segfaults in MIT libkrb5

Theodore Tso tytso at MIT.EDU
Sun Dec 17 00:43:02 EST 2006


On Fri, Dec 15, 2006 at 02:55:02AM +0100, Fredrik Tolf wrote:
> However, this does seem like a bug, right? As I see it, the fault can be
> considered to lie with the Kerberos library, in which case it should be
> fixed. I would guess that the right fix would be using the _fini symbol
> to unregister the tables again. (However, it seems that the manpage for
> dlopen, on Linux at least, recommends against that, for reasons that
> aren't entirely clear to me, but may have to do with that GNU's
> __attribute__((constructor)) might stop working then.) I don't know how
> portable that is, though.

The _fini symbol is being registered as a destructor, so it should be
getting called when the krb5 library is unloaded.  At least, it is on
krb5 1.4.4 from Debian unstable.  However, you said that your program
was linking against krb5 as well, and at least in the past, dynamic
linkers have not always done the right thing when multiple libraries
which define the same symbol.  

If you are willing to recompile e2fsprogs (which is the source of the
system com_err library), please try applying this patch and try
running your program (without the LD_PRELOAD hack) with the
environment variable COMERR_DEBUG set to the value 1 and let us know
what you see.  That should help us see if the remove_error_table is
getting called, and with what arguments.

Regards,

						- Ted

diff -r fb115aec5b93 lib/et/error_message.c
--- a/lib/et/error_message.c	Thu Nov 30 14:48:48 2006 -0500
+++ b/lib/et/error_message.c	Sun Dec 17 00:42:13 2006 -0500
@@ -92,6 +92,24 @@ oops:
     return(buffer);
 }
 
+#define DEBUG_INIT	0x8000
+#define DEBUG_ADDREMOVE 0x0001
+
+static int debug_mask = 0;
+
+static void init_debug()
+{
+	char *dstr;
+
+	if (debug_mask & DEBUG_INIT)
+		return;
+
+	dstr = getenv("COMERR_DEBUG");
+	if (dstr)
+		debug_mask = strtoul(dstr, 0, 0);
+	debug_mask |= DEBUG_INIT;
+}
+
 /*
  * New interface provided by krb5's com_err library
  */
@@ -106,6 +124,12 @@ errcode_t add_error_table(const struct e
 	el->next = _et_dynamic_list;
 	_et_dynamic_list = el;
 
+	init_debug();
+	if (debug_mask & DEBUG_ADDREMOVE)
+		printf("add_error_table: %s (0x%p)\n", 
+		       error_table_name(et->base),
+		       (void *) et);
+
 	return 0;
 }
 
@@ -117,6 +141,7 @@ errcode_t remove_error_table(const struc
 	struct et_list *el = _et_dynamic_list;
 	struct et_list *el2 = 0;
 
+	init_debug();
 	while (el) {
 		if (el->table->base == et->base) {
 			if (el2)	/* Not the beginning of the list */
@@ -124,11 +149,19 @@ errcode_t remove_error_table(const struc
 			else
 				_et_dynamic_list = el->next;
 			(void) free(el);
+			if (debug_mask & DEBUG_ADDREMOVE)
+				printf("remove_error_table: %s (0x%p)\n", 
+				       error_table_name(et->base),
+				       (void *) et);
 			return 0;
 		}
 		el2 = el;
 		el = el->next;
 	}
+	if (debug_mask & DEBUG_ADDREMOVE)
+		printf("remove_error_table FAILED: %s (0x%p)\n", 
+		       error_table_name(et->base),
+		       (void *) et);
 	return ENOENT;
 }
 



More information about the Kerberos mailing list