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

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