Permit NULL context to krb5_get_error_message()
Application developers have a tendency to use krb5_get_error_message() as a drop in replacement for error_message() and under various circumstances they pass in a NULL context. This method works fine for MIT's implementation which ignores the context but in Heimdal passing in a NULL context would dump core. This patch set modifies krb5_get_error_message() in order to permit the passing of a NULL context. First, if the context is NULL, an attempt will be made to allocate one locally for the purpose of evaluating the error code. Second, if a local context cannot be allocated, fall back on calling error_message(). If error_message() fails to return a string, then generate an "unknown error" response. Only if all of the above fails is NULL returned. Change-Id: If4baf7d6c428cf0baf11c044b8dfd5c2b3cdf7e4
This commit is contained in:
		| @@ -206,29 +206,53 @@ krb5_vprepend_error_message(krb5_context context, krb5_error_code ret, | ||||
| KRB5_LIB_FUNCTION const char * KRB5_LIB_CALL | ||||
| krb5_get_error_message(krb5_context context, krb5_error_code code) | ||||
| { | ||||
|     char *str; | ||||
|     char *str = NULL; | ||||
|     const char *cstr = NULL; | ||||
|     char buf[128]; | ||||
|     int free_context = 0; | ||||
|  | ||||
|     if (code == 0) | ||||
| 	return strdup("Success"); | ||||
|  | ||||
|     /* | ||||
|      * The MIT version of this function ignores the krb5_context | ||||
|      * and several widely deployed applications call krb5_get_error_message() | ||||
|      * with a NULL context in order to translate an error code as a | ||||
|      * replacement for error_message().  Another reason a NULL context | ||||
|      * might be provided is if the krb5_init_context() call itself | ||||
|      * failed. | ||||
|      */ | ||||
|     if (context) | ||||
|     { | ||||
|         HEIMDAL_MUTEX_lock(context->mutex); | ||||
|         if (context->error_string && | ||||
|             (code == context->error_code || context->error_code == 0)) | ||||
|         { | ||||
|             str = strdup(context->error_string); | ||||
| 	if (str) { | ||||
| 	    HEIMDAL_MUTEX_unlock(context->mutex); | ||||
| 	    return str; | ||||
| 	} | ||||
|         } | ||||
|         HEIMDAL_MUTEX_unlock(context->mutex); | ||||
|  | ||||
|     if (code == 0) | ||||
| 	return strdup("Success"); | ||||
|     { | ||||
| 	const char *msg; | ||||
| 	char buf[128]; | ||||
| 	msg = com_right_r(context->et_list, code, buf, sizeof(buf)); | ||||
| 	if (msg) | ||||
| 	    return strdup(msg); | ||||
|         if (str) | ||||
|             return str; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (krb5_init_context(&context) == 0) | ||||
|             free_context = 1; | ||||
|     } | ||||
|  | ||||
|     if (context) | ||||
|         cstr = com_right_r(context->et_list, code, buf, sizeof(buf)); | ||||
|  | ||||
|     if (free_context) | ||||
|         krb5_free_context(context); | ||||
|  | ||||
|     if (cstr) | ||||
|         return strdup(cstr); | ||||
|  | ||||
|     cstr = error_message(code); | ||||
|     if (cstr) | ||||
|         return strdup(cstr); | ||||
|  | ||||
|     if (asprintf(&str, "<unknown error: %d>", (int)code) == -1 || str == NULL) | ||||
| 	return NULL; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jeffrey Altman
					Jeffrey Altman