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

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