Blame SOURCES/GSSAPI-0.28-Fix-a-crash-in-gss_release_oid-when-destructing-out_.patch

b58c49
From 159042c71bbdd5909f792208dcdffffb1674ecfe Mon Sep 17 00:00:00 2001
b58c49
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
b58c49
Date: Thu, 19 Aug 2021 16:07:06 +0200
b58c49
Subject: [PATCH] Fix a crash in gss_release_oid() when destructing out_mech
b58c49
 returned by gss_accept_sec_context()
b58c49
MIME-Version: 1.0
b58c49
Content-Type: text/plain; charset=UTF-8
b58c49
Content-Transfer-Encoding: 8bit
b58c49
b58c49
If Perl GSSAPI was built against MIT krb5, an example gss-server.pl
b58c49
script crashed like this:
b58c49
b58c49
    Program terminated with signal SIGSEGV, Segmentation fault.
b58c49
    #0  0x00007f27f3d48b23 in __GI___libc_free (mem=<optimized out>)
b58c49
        at malloc.c:3131
b58c49
    3131	  ar_ptr = arena_for_chunk (p);
b58c49
    (gdb) bt
b58c49
    #0  0x00007f27f3d48b23 in __GI___libc_free (mem=<optimized out>)
b58c49
        at malloc.c:3131
b58c49
    #1  0x00007f27f2fe17c6 in generic_gss_release_oid (
b58c49
        minor_status=minor_status@entry=0x7fffc750333c,
b58c49
        oid=oid@entry=0x7fffc7503340) at oid_ops.c:102
b58c49
    #2  0x00007f27f2fee6df in gss_release_oid (
b58c49
        minor_status=minor_status@entry=0x7fffc750333c,
b58c49
        oid=oid@entry=0x7fffc7503340) at g_initialize.c:202
b58c49
    #3  0x00007f27f322f5cf in XS_GSSAPI__OID_DESTROY (my_perl=<optimized out>,
b58c49
        cv=0x564037c87130) at ./xs/OID.xs:24
b58c49
    #4  0x00007f27f4f58149 in Perl_pp_entersub (my_perl=0x5640378d42a0)
b58c49
        at pp_hot.c:4227
b58c49
b58c49
The cause is that gss_accept_sec_context() returns a pointer to
b58c49
a static storage in out_mech argument. When GSSAPI passed out_mech to
b58c49
a desctructor, the invoked gss_release_oid() crashed when freeing the
b58c49
memory.
b58c49
b58c49
Accoding to RFC 2744, the static storage is correct. Hence the flaw is
b58c49
on Perl GSSAPI side. This patch fixes it by copying the out_mech OID
b58c49
object on a heap which is then correctly processed by
b58c49
gss_release_oid().
b58c49
b58c49
CPAN RT#121873.
b58c49
b58c49
Signed-off-by: Petr Písař <ppisar@redhat.com>
b58c49
---
b58c49
 xs/Context.xs | 18 ++++++++++++++++++
b58c49
 1 file changed, 18 insertions(+)
b58c49
b58c49
diff --git a/xs/Context.xs b/xs/Context.xs
b58c49
index d176f08..4549595 100644
b58c49
--- a/xs/Context.xs
b58c49
+++ b/xs/Context.xs
b58c49
@@ -80,6 +80,24 @@ accept(context, acc_cred, in_token, binding, out_name, out_mech, out_token, out_
b58c49
 				       &in_token, binding, out_name, out_mech,
b58c49
 				       &out_token, out_flags, out_time,
b58c49
 				       delegated_cred);
b58c49
+#if !defined(HEIMDAL)
b58c49
+	if (out_mech && *out_mech) {
b58c49
+		/* RFC 2744 documents that the returned *out_mech is a pointer
b58c49
+		 * to static data. To prevent from freeing them when destructing
b58c49
+		 * out_mech, we change *out_mech into a pointer to a heap-allocated
b58c49
+		 * buffer with the same content. Otherwise, MITKRB5-provided
b58c49
+		 * gss_release_oid() deallocator which cannot recognize this static
b58c49
+		 * storage would crash. We use malloc() because gss_release_oid() used
b58c49
+		 * free(). */
b58c49
+		GSSAPI__OID copy = malloc(sizeof(*copy));
b58c49
+		if (!copy) croak("Not enough memory for copying out_mech!");
b58c49
+		copy->elements = malloc((*out_mech)->length);
b58c49
+		if (!copy->elements) croak("Not enough memory for copying out_mech!");
b58c49
+		memcpy(copy->elements, (*out_mech)->elements, (*out_mech)->length);
b58c49
+		copy->length = (*out_mech)->length;
b58c49
+		*out_mech = copy;
b58c49
+    }
b58c49
+#endif
b58c49
     OUTPUT:
b58c49
 	RETVAL
b58c49
 	context
b58c49
-- 
b58c49
2.31.1
b58c49