Index | Thread | Search

From:
Theo Buehler <tb@theobuehler.org>
Subject:
py3-M2Crypto: deal with opaque STACK_OF()
To:
ports@openbsd.org
Cc:
jsing@openbsd.org
Date:
Mon, 22 Jan 2024 21:48:37 +0100

Download raw body.

Thread
  • Theo Buehler:

    py3-M2Crypto: deal with opaque STACK_OF()

jsing will make _STACK opaque. Only two things notice: rust-openssl
(already fixed upstream) and M2Crypto.

M2Crypto contains two compat shims for STACK_OF().  sk_free() has been
available since forever so I don't really understand why that was ever
needed, but it's easy to fix.

I made deep_copy() always fail. I doubt it is needed for anything
(although I would be happy to learn how to know for sure).

Also, sk_TYPE_deep_copy() requires TYPE_dup() and TYPE_free() with usual
signatures, they are then cast to a "generic" OPENSSL_sk_{copy,free}func
before they're called. My understanding is that that's undefined because
void * and TYPE * have different alignment requirements.

Regress tests look the same with or without this patch.

Index: Makefile
===================================================================
RCS file: /cvs/ports/security/py-M2Crypto/Makefile,v
diff -u -p -r1.41 Makefile
--- Makefile	20 Dec 2023 13:10:10 -0000	1.41
+++ Makefile	22 Jan 2024 17:15:28 -0000
@@ -3,6 +3,7 @@ COMMENT =		crypto and TLS toolkit for Py
 MODPY_EGG_VERSION =	0.40.1
 DISTNAME =		M2Crypto-${MODPY_EGG_VERSION}
 PKGNAME =		py-${DISTNAME}
+REVISION =		0
 
 CATEGORIES =		security
 
Index: patches/patch-src_SWIG__lib_i
===================================================================
RCS file: /cvs/ports/security/py-M2Crypto/patches/patch-src_SWIG__lib_i,v
diff -u -p -r1.3 patch-src_SWIG__lib_i
--- patches/patch-src_SWIG__lib_i	11 Mar 2022 19:53:53 -0000	1.3
+++ patches/patch-src_SWIG__lib_i	22 Jan 2024 15:32:50 -0000
@@ -12,3 +12,54 @@ Index: src/SWIG/_lib.i
  typedef void (*OPENSSL_sk_freefunc)(void *);
  typedef void *(*OPENSSL_sk_copyfunc)(const void *);
  typedef struct stack_st OPENSSL_STACK;
+@@ -31,47 +31,15 @@ typedef struct stack_st OPENSSL_STACK;
+ 
+ void OPENSSL_sk_free(OPENSSL_STACK *st)
+ {
+-    if (st == NULL)
+-        return;
+-    OPENSSL_free(st->data);
+-    OPENSSL_free(st);
++    sk_free(st);
+ }
+ 
+ OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk,
+                              OPENSSL_sk_copyfunc copy_func,
+                              OPENSSL_sk_freefunc free_func)
+ {
+-    OPENSSL_STACK *ret;
+-    int i;
+-
+-    if (sk->num < 0)
+-        return NULL;
+-
+-    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
+-        return NULL;
+-
+-    /* direct structure assignment */
+-    *ret = *sk;
+-
+-    ret->num_alloc = sk->num > MIN_NODES ? (size_t)sk->num : MIN_NODES;
+-    ret->data = OPENSSL_zalloc(sizeof(*ret->data) * ret->num_alloc);
+-    if (ret->data == NULL) {
+-        OPENSSL_free(ret);
+-        return NULL;
+-    }
+-
+-    for (i = 0; i < ret->num; ++i) {
+-        if (sk->data[i] == NULL)
+-            continue;
+-        if ((ret->data[i] = copy_func(sk->data[i])) == NULL) {
+-            while (--i >= 0)
+-                if (ret->data[i] != NULL)
+-                    free_func((void *)ret->data[i]);
+-            OPENSSL_sk_free(ret);
+-            return NULL;
+-        }
+-    }
+-    return ret;
++    /* Do not support this. It relieas on UB via function pointer casting. */
++    return NULL;
+ }
+ #endif /* OpenSSL 1.0.2 copmatbility shim */
+