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 */
+ 

Reply via email to