mirror of
https://github.com/curl/curl.git
synced 2026-04-11 12:01:42 +08:00
krb5: fix output_token allocators in the GSS debug stub (Windows)
Before this patch system `malloc()`/`free()` were used to allocate
the buffer returned in the `output_token` object from the debug stub
of `gss_init_sec_context()` when enabled via `CURL_STUB_GSS_CREDS` in
debug-enabled libcurl builds. This object is later released via stock
`gss_release_buffer()`, which, in the Windows builds of MIT Kerberos,
doesn't use the system `free()`, but the Win32 `HeapFree()`.
Fix it by using the GSS alloc/free macros: `gssalloc_malloc()` and
`gssalloc_free()` from `gssapi_alloc.h`.
To make this work without MIT Kerberos feature detection, use a canary
macro to detect a version which installs `gssapi_alloc.h` for Windows.
For <1.15 (2016-11-30) releases, that do not install it, disable the GSS
debug stub in libcurl.
Strictly speaking, non-Windows builds would also need to use GSS
allocators, but, detecting support for `gssapi_alloc.h` is impossible
without build-level logic. Built-level logic is complex and overkill,
and MIT Kerberos, as of 1.22.1, uses standard malloc/free on
non-Windows platforms anyway. (except in GSS debug builds.)
Follow-up to 73840836a5 #17752
Closes #19064
This commit is contained in:
parent
25eb34dd3e
commit
87b72b8182
@ -29,6 +29,28 @@
|
||||
#include "curl_gssapi.h"
|
||||
#include "sendf.h"
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#if defined(HAVE_GSSGNU) || !defined(_WIN32)
|
||||
/* To avoid memdebug macro replacement, wrap the name in parentheses to call
|
||||
the original version. It is freed via the GSS API gss_release_buffer(). */
|
||||
#define Curl_gss_alloc (malloc)
|
||||
#define Curl_gss_free (free)
|
||||
#define CURL_GSS_STUB
|
||||
/* For correctness this would be required for all platforms, not only Windows,
|
||||
but, as of v1.22.1, MIT Kerberos uses a special allocator only for Windows,
|
||||
and the availability of 'gssapi/gssapi_alloc.h' is difficult to detect,
|
||||
because GSS headers are not versioned, and there is also no other macro to
|
||||
indicate 1.18+ vs. previous versions. On Windows we can use 'GSS_S_BAD_MIC'.
|
||||
*/
|
||||
#elif defined(_WIN32) && defined(GSS_S_BAD_MIC) /* MIT Kerberos 1.15+ */
|
||||
/* MIT Kerberos 1.10+ (Windows), 1.18+ (all platforms), missing from GNU GSS */
|
||||
#include <gssapi/gssapi_alloc.h>
|
||||
#define Curl_gss_alloc gssalloc_malloc
|
||||
#define Curl_gss_free gssalloc_free
|
||||
#define CURL_GSS_STUB
|
||||
#endif
|
||||
#endif /* DEBUGBUILD */
|
||||
|
||||
/* The last 2 #include files should be in this order */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
@ -51,7 +73,7 @@ gss_OID_desc Curl_krb5_mech_oid CURL_ALIGN8 = {
|
||||
9, CURL_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02")
|
||||
};
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#ifdef CURL_GSS_STUB
|
||||
enum min_err_code {
|
||||
STUB_GSS_OK = 0,
|
||||
STUB_GSS_NO_MEMORY,
|
||||
@ -212,9 +234,7 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
||||
ctx->flags = req_flags;
|
||||
}
|
||||
|
||||
/* To avoid memdebug macro replacement, wrap the name in parentheses to call
|
||||
the original version. It is freed via the GSS API gss_release_buffer(). */
|
||||
token = (malloc)(length);
|
||||
token = Curl_gss_alloc(length);
|
||||
if(!token) {
|
||||
free(ctx);
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
@ -229,14 +249,14 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
||||
major_status = gss_display_name(&minor_status, target_name,
|
||||
&target_desc, &name_type);
|
||||
if(GSS_ERROR(major_status)) {
|
||||
(free)(token);
|
||||
Curl_gss_free(token);
|
||||
free(ctx);
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if(strlen(creds) + target_desc.length + 5 >= sizeof(ctx->creds)) {
|
||||
(free)(token);
|
||||
Curl_gss_free(token);
|
||||
free(ctx);
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
return GSS_S_FAILURE;
|
||||
@ -252,7 +272,7 @@ stub_gss_init_sec_context(OM_uint32 *min,
|
||||
}
|
||||
|
||||
if(used >= length) {
|
||||
(free)(token);
|
||||
Curl_gss_free(token);
|
||||
free(ctx);
|
||||
*min = STUB_GSS_NO_MEMORY;
|
||||
return GSS_S_FAILURE;
|
||||
@ -294,7 +314,7 @@ stub_gss_delete_sec_context(OM_uint32 *min,
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
#endif /* DEBUGBUILD */
|
||||
#endif /* CURL_GSS_STUB */
|
||||
|
||||
OM_uint32 Curl_gss_init_sec_context(struct Curl_easy *data,
|
||||
OM_uint32 *minor_status,
|
||||
@ -324,7 +344,7 @@ OM_uint32 Curl_gss_init_sec_context(struct Curl_easy *data,
|
||||
if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_FLAG)
|
||||
req_flags |= GSS_C_DELEG_FLAG;
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#ifdef CURL_GSS_STUB
|
||||
if(getenv("CURL_STUB_GSS_CREDS"))
|
||||
return stub_gss_init_sec_context(minor_status,
|
||||
GSS_C_NO_CREDENTIAL, /* cred_handle */
|
||||
@ -339,7 +359,7 @@ OM_uint32 Curl_gss_init_sec_context(struct Curl_easy *data,
|
||||
output_token,
|
||||
ret_flags,
|
||||
NULL /* time_rec */);
|
||||
#endif /* DEBUGBUILD */
|
||||
#endif /* CURL_GSS_STUB */
|
||||
|
||||
return gss_init_sec_context(minor_status,
|
||||
GSS_C_NO_CREDENTIAL, /* cred_handle */
|
||||
@ -360,12 +380,12 @@ OM_uint32 Curl_gss_delete_sec_context(OM_uint32 *min,
|
||||
gss_ctx_id_t *context,
|
||||
gss_buffer_t output_token)
|
||||
{
|
||||
#ifdef DEBUGBUILD
|
||||
#ifdef CURL_GSS_STUB
|
||||
if(getenv("CURL_STUB_GSS_CREDS"))
|
||||
return stub_gss_delete_sec_context(min,
|
||||
(struct stub_gss_ctx_id_t_desc **)context,
|
||||
output_token);
|
||||
#endif /* DEBUGBUILD */
|
||||
#endif /* CURL_GSS_STUB */
|
||||
|
||||
return gss_delete_sec_context(min, context, output_token);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user