Add support for symbol hiding disabled by default.
authorbeck <beck@openbsd.org>
Fri, 11 Nov 2022 11:25:18 +0000 (11:25 +0000)
committerbeck <beck@openbsd.org>
Fri, 11 Nov 2022 11:25:18 +0000 (11:25 +0000)
Fully explained in libcrypto/README. TL;DR make sure libcrypto
and libssl's function calls internally and to each other are via
symbol names that won't get overridden by linking other libraries.

Mostly work by guenther@, which will currently be gated behind a
build setting NAMESPACE=yes. once we convert all the symbols to
this method we will do a major bump and pick up the changes.

ok tb@ jsing@

lib/libcrypto/Makefile
lib/libcrypto/Symbols.namespace [new file with mode: 0644]
lib/libcrypto/hidden/README [new file with mode: 0644]
lib/libcrypto/hidden/crypto_namespace.h [new file with mode: 0644]
lib/libcrypto/hidden/openssl/hmac.h [new file with mode: 0644]
lib/libcrypto/hmac/hmac.c
lib/libssl/Makefile
lib/libssl/bio_ssl.c
lib/libssl/hidden/openssl/ssl.h [new file with mode: 0644]
lib/libssl/hidden/ssl_namespace.h [new file with mode: 0644]

index ffcdc7d..3f5342a 100644 (file)
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.87 2022/11/10 17:53:45 joshua Exp $
+# $OpenBSD: Makefile,v 1.88 2022/11/11 11:25:18 beck Exp $
 
 LIB=   crypto
 LIBREBUILD=y
@@ -19,6 +19,10 @@ CFLAGS+= -Wall -Wundef
 CFLAGS+= -Werror
 .endif
 CFLAGS+= -DLIBRESSL_INTERNAL -DLIBRESSL_CRYPTO_INTERNAL
+.ifdef NAMESPACE
+CFLAGS+= -DLIBRESSL_NAMESPACE -DLIBRESSL_CRYPTO_NAMESPACE
+.endif
+
 
 .if !defined(NOPIC)
 CFLAGS+= -DDSO_DLFCN -DHAVE_DLFCN_H -DHAVE_FUNOPEN
@@ -40,6 +44,7 @@ CFLAGS+= -I${LCRYPTO_SRC}/ec
 CFLAGS+= -I${LCRYPTO_SRC}/ecdh
 CFLAGS+= -I${LCRYPTO_SRC}/ecdsa
 CFLAGS+= -I${LCRYPTO_SRC}/evp
+CFLAGS+= -I${LCRYPTO_SRC}/hidden
 CFLAGS+= -I${LCRYPTO_SRC}/hmac
 CFLAGS+= -I${LCRYPTO_SRC}/kdf
 CFLAGS+= -I${LCRYPTO_SRC}/modes
@@ -51,6 +56,7 @@ CFLAGS+= -I${LCRYPTO_SRC}/x509
 
 VERSION_SCRIPT=        Symbols.map
 SYMBOL_LIST=   ${.CURDIR}/Symbols.list
+SYMBOL_NAMESPACE=      ${.CURDIR}/Symbols.namespace
 
 # crypto/
 SRCS+= cpt_err.c
@@ -875,11 +881,18 @@ includes: prereq
            echo $$j; \
            eval "$$j"; \
        done;
-
+.ifdef NAMESPACE
+${VERSION_SCRIPT}: ${SYMBOL_LIST} ${SYMBOL_NAMESPACE}
+       { printf '{\n\tglobal:\n'; \
+         sed '/^[._a-zA-Z]/s/$$/;/; s/^/               /' ${SYMBOL_NAMESPACE}; \
+         sed '/^[._a-zA-Z]/s/$$/;/; s/^/               /' ${SYMBOL_LIST}; \
+         printf '\n\tlocal:\n\t\t*;\n};\n'; } >$@.tmp && mv $@.tmp $@
+.else
 ${VERSION_SCRIPT}: ${SYMBOL_LIST}
        { printf '{\n\tglobal:\n'; \
          sed '/^[._a-zA-Z]/s/$$/;/; s/^/               /' ${SYMBOL_LIST}; \
          printf '\n\tlocal:\n\t\t*;\n};\n'; } >$@.tmp && mv $@.tmp $@
+.endif
 
 # generated
 CFLAGS+= -I${.OBJDIR}
diff --git a/lib/libcrypto/Symbols.namespace b/lib/libcrypto/Symbols.namespace
new file mode 100644 (file)
index 0000000..31f7fba
--- /dev/null
@@ -0,0 +1,9 @@
+_libre_HMAC
+_libre_HMAC_CTX_copy
+_libre_HMAC_CTX_free
+_libre_HMAC_CTX_get_md
+_libre_HMAC_CTX_new
+_libre_HMAC_CTX_set_flags
+_libre_HMAC_Final
+_libre_HMAC_Init_ex
+_libre_HMAC_Update
diff --git a/lib/libcrypto/hidden/README b/lib/libcrypto/hidden/README
new file mode 100644 (file)
index 0000000..c41830c
--- /dev/null
@@ -0,0 +1,40 @@
+The goals:
+1) calls from inside libcrypto to other libcrypto functions should
+   be via identifiers that are of hidden visibility and -- to avoid
+   confusion or conflicts -- are in the reserved namespace.  By
+   doing this these calls are protected from being overridden by
+   applications and on many platforms can avoid creation or use of
+   GOT or PLT  entries.  I've chosen a prefix of "_lcry_" for this.
+   Note that these symbols aren't in the dynamic symbol table of the
+   libcrypto.so shared library...but they are visible in the static
+   library.
+
+2) calls from libssl to symbols in libcrypto should be via identifiers
+   which won't be accidentally overridden by the application, libc,
+   other random crypto libraries that are pulled in, etc.  I've
+   chosen a prefix of "_libre_" for this.
+
+These will not be declared directly; instead, the gcc "asm labels"
+extension will be used rename the function.  In order to actually
+set up the desired asm labels, we use these in the internal .h
+files:
+
+   LCRYPTO_USED(x)     Symbols used both internally and externally
+       In builds of libcrypto, this makes gcc convert use of x to
+       use _libre_x instead.  In other builds that use these headers,
+       it makes gcc convert use of x to use _libre_x instead.  Use
+       LCRYPTO_ALIAS(x) to create the external aliases.
+       ex: LCRYPTO_USED(SSL_get_verify_mode)
+
+   LCRYPTO_UNUSED(x)   Symbols that are not used internally or by libssl
+       No renaming is done.  In builds of libcrypto, the symbol
+       is marked as deprecated to detect unintentional use of such
+       a synbol, so that it can be marked as used going forward.
+       ex: LCRYPTO_UNUSED(SSL_CIPHER_get_name)
+
+Finally, to create the expected aliases, we use these in the .c files
+where the definitions are:
+   LCRYPTO_ALIAS(x)
+       This defines both x and _libre_x as strong aliases for _lcry_x.
+       Match uses of this with uses of LCRYPTO_USED()
+       ex: LCRYPTO_ALIAS(SSL_get_verify_mode)
diff --git a/lib/libcrypto/hidden/crypto_namespace.h b/lib/libcrypto/hidden/crypto_namespace.h
new file mode 100644 (file)
index 0000000..6ceef26
--- /dev/null
@@ -0,0 +1,44 @@
+/*     $OpenBSD: crypto_namespace.h,v 1.1 2022/11/11 11:25:18 beck Exp $       */
+/*
+ * Copyright (c) 2016 Philip Guenther <guenther@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _LIBCRYPTO_CRYPTO_NAMESPACE_H_
+#define _LIBCRYPTO_CRYPTO_NAMESPACE_H_
+
+/*
+ * If marked as 'used', then internal calls use the name with prefix "_lcry_"
+ * and we alias that to the normal name *and* the name with prefix "_libre_";
+ * external calls use the latter name.
+ */
+
+#ifdef LIBRESSL_NAMESPACE
+# define LCRYPTO_UNUSED(x)             typeof(x) x __attribute__((deprecated))
+#ifdef LIBRESSL_CRYPTO_NAMESPACE
+#  define LCRYPTO_USED(x)              __attribute__((visibility("hidden")))   \
+                               typeof(x) x asm("_lcry_"#x)
+#  define LCRYPTO_ALIAS1(pre,x)        asm(".global "#pre#x"; "#pre#x" = _lcry_"#x)
+#  define LCRYPTO_ALIAS(x)     LCRYPTO_ALIAS1(,x); LCRYPTO_ALIAS1(_libre_,x);
+#else
+#  define LCRYPTO_USED(x)          typeof(x) x asm("_libre_"#x)
+#endif
+#else
+# define LCRYPTO_UNUSED(x)
+# define LCRYPTO_USED(x)
+# define LCRYPTO_ALIAS1(pre,x)
+# define LCRYPTO_ALIAS(x)
+#endif
+
+#endif /* _LIBCRYPTO_CRYPTO_NAMESPACE_H_ */
diff --git a/lib/libcrypto/hidden/openssl/hmac.h b/lib/libcrypto/hidden/openssl/hmac.h
new file mode 100644 (file)
index 0000000..d837094
--- /dev/null
@@ -0,0 +1,36 @@
+/*     $OpenBSD: hmac.h,v 1.1 2022/11/11 11:25:18 beck Exp $   */
+/*
+ * Copyright (c) 2016 Philip Guenther <guenther@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _LIBCRYPTO_HMAC_H_
+#define _LIBCRYPTO_HMAC_H_
+
+#include_next <openssl/hmac.h>
+#include "crypto_namespace.h"
+
+LCRYPTO_USED(HMAC_CTX_new);
+LCRYPTO_USED(HMAC_CTX_free);
+LCRYPTO_UNUSED(HMAC_CTX_reset);
+LCRYPTO_UNUSED(HMAC_Init);
+LCRYPTO_USED(HMAC_Init_ex);
+LCRYPTO_USED(HMAC_Update);
+LCRYPTO_USED(HMAC_Final);
+LCRYPTO_USED(HMAC);
+LCRYPTO_USED(HMAC_CTX_copy);
+LCRYPTO_USED(HMAC_CTX_set_flags);
+LCRYPTO_USED(HMAC_CTX_get_md);
+
+#endif /* _LIBCRYPTO_HMAC_H_ */
index 3421119..b195ca6 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: hmac.c,v 1.28 2022/05/05 18:29:34 tb Exp $ */
+/* $OpenBSD: hmac.c,v 1.29 2022/11/11 11:25:18 beck Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -134,6 +134,7 @@ HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md,
 err:
        return 0;
 }
+LCRYPTO_ALIAS(HMAC_Init_ex)
 
 int
 HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md)
@@ -151,6 +152,7 @@ HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
 
        return EVP_DigestUpdate(&ctx->md_ctx, data, len);
 }
+LCRYPTO_ALIAS(HMAC_Update)
 
 int
 HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
@@ -173,6 +175,7 @@ HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
 err:
        return 0;
 }
+LCRYPTO_ALIAS(HMAC_Final)
 
 HMAC_CTX *
 HMAC_CTX_new(void)
@@ -186,6 +189,7 @@ HMAC_CTX_new(void)
 
        return ctx;
 }
+LCRYPTO_ALIAS(HMAC_CTX_new)
 
 void
 HMAC_CTX_free(HMAC_CTX *ctx)
@@ -197,6 +201,7 @@ HMAC_CTX_free(HMAC_CTX *ctx)
 
        free(ctx);
 }
+LCRYPTO_ALIAS(HMAC_CTX_free)
 
 int
 HMAC_CTX_reset(HMAC_CTX *ctx)
@@ -231,6 +236,7 @@ HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
 err:
        return 0;
 }
+LCRYPTO_ALIAS(HMAC_CTX_copy)
 
 void
 HMAC_CTX_cleanup(HMAC_CTX *ctx)
@@ -248,12 +254,14 @@ HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
        EVP_MD_CTX_set_flags(&ctx->o_ctx, flags);
        EVP_MD_CTX_set_flags(&ctx->md_ctx, flags);
 }
+LCRYPTO_ALIAS(HMAC_CTX_set_flags)
 
 const EVP_MD *
 HMAC_CTX_get_md(const HMAC_CTX *ctx)
 {
        return ctx->md;
 }
+LCRYPTO_ALIAS(HMAC_CTX_get_md)
 
 unsigned char *
 HMAC(const EVP_MD *evp_md, const void *key, int key_len, const unsigned char *d,
@@ -282,3 +290,4 @@ err:
        HMAC_CTX_cleanup(&c);
        return NULL;
 }
+LCRYPTO_ALIAS(HMAC)
index 1788cd7..a6ee26a 100644 (file)
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.77 2022/08/17 07:39:19 jsing Exp $
+# $OpenBSD: Makefile,v 1.78 2022/11/11 11:25:18 beck Exp $
 
 .include <bsd.own.mk>
 .ifndef NOMAN
@@ -16,6 +16,9 @@ CFLAGS+= -Wall -Wundef
 CFLAGS+= -Werror
 .endif
 CFLAGS+= -DLIBRESSL_INTERNAL
+.ifdef NAMESPACE
+CFLAGS+= -DLIBRESSL_NAMESPACE
+.endif
 .ifdef TLS1_3
 CFLAGS+= -DLIBRESSL_HAS_TLS1_3_CLIENT
 CFLAGS+= -DLIBRESSL_HAS_TLS1_3_SERVER
@@ -24,7 +27,9 @@ CFLAGS+= -DLIBRESSL_HAS_TLS1_3_SERVER
 CFLAGS+= -DTLS13_DEBUG
 .endif
 CFLAGS+= -I${.CURDIR}
+CFLAGS+= -I${.CURDIR}/../libcrypto/hidden
 CFLAGS+= -I${.CURDIR}/../libcrypto/bio
+CFLAGS+= -I${.CURDIR}/hidden
 
 LDADD+= -L${BSDOBJDIR}/lib/libcrypto -lcrypto
 
index 04dd22f..d6974cd 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: bio_ssl.c,v 1.35 2022/10/05 21:16:14 tb Exp $ */
+/* $OpenBSD: bio_ssl.c,v 1.36 2022/11/11 11:25:18 beck Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -103,6 +103,7 @@ BIO_f_ssl(void)
 {
        return (&methods_sslp);
 }
+LSSL_ALIAS(BIO_f_ssl)
 
 static int
 ssl_new(BIO *bi)
@@ -532,6 +533,7 @@ BIO_new_ssl_connect(SSL_CTX *ctx)
        BIO_free(ssl);
        return (NULL);
 }
+LSSL_ALIAS(BIO_new_ssl_connect)
 
 BIO *
 BIO_new_ssl(SSL_CTX *ctx, int client)
@@ -556,6 +558,7 @@ BIO_new_ssl(SSL_CTX *ctx, int client)
        BIO_free(ret);
        return (NULL);
 }
+LSSL_ALIAS(BIO_new_ssl)
 
 int
 BIO_ssl_copy_session_id(BIO *t, BIO *f)
diff --git a/lib/libssl/hidden/openssl/ssl.h b/lib/libssl/hidden/openssl/ssl.h
new file mode 100644 (file)
index 0000000..540c6e7
--- /dev/null
@@ -0,0 +1,31 @@
+/*     $OpenBSD: ssl.h,v 1.1 2022/11/11 11:25:18 beck Exp $    */
+/*
+ * Copyright (c) 2022 Philip Guenther <guenther@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _LIBSSL_SSL_H_
+#define _LIBSSL_SSL_H_
+
+#include_next <openssl/ssl.h>
+#include "ssl_namespace.h"
+
+LSSL_USED(BIO_f_ssl);
+LSSL_USED(BIO_new_ssl);
+LSSL_USED(BIO_new_ssl_connect);
+LSSL_UNUSED(BIO_new_buffer_ssl_connect);
+LSSL_UNUSED(BIO_ssl_copy_session_id);
+LSSL_UNUSED(BIO_ssl_shutdown);
+
+#endif /* _LIBSSL_SSL_H_ */
diff --git a/lib/libssl/hidden/ssl_namespace.h b/lib/libssl/hidden/ssl_namespace.h
new file mode 100644 (file)
index 0000000..803f3e6
--- /dev/null
@@ -0,0 +1,37 @@
+/*     $OpenBSD: ssl_namespace.h,v 1.1 2022/11/11 11:25:18 beck Exp $  */
+/*
+ * Copyright (c) 2016 Philip Guenther <guenther@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _LIBSSL_SSL_NAMESPACE_H_
+#define _LIBSSL_SSL_NAMESPACE_H_
+
+/*
+ * If marked as 'used', then internal calls use the name with prefix "_lssl_"
+ * and we alias that to the normal name.
+ */
+
+#ifdef LIBRESSL_NAMESPACE
+#define LSSL_UNUSED(x)         typeof(x) x __attribute__((deprecated))
+#define LSSL_USED(x)           __attribute__((visibility("hidden")))   \
+                               typeof(x) x asm("_lssl_"#x)
+#define LSSL_ALIAS(x)          asm(".global "#x"; "#x" = _lssl_"#x);
+#else
+#define LSSL_UNUSED(x)
+#define LSSL_USED(x)
+#define LSSL_ALIAS(x)
+#endif
+
+#endif /* _LIBSSL_SSL_NAMESPACE_H_ */