]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Add endbr64 instructions in the right spots for OpenBSD/amd64 13430/head
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 30 Oct 2023 09:37:10 +0000 (10:37 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 30 Oct 2023 09:41:03 +0000 (10:41 +0100)
OpenBSD has IBT (aka control flow enforcement) on amd64, for processor
models that support it. But it turns out that the existing endbr64
instructions in the boost assembly for context switching are not
enough: there needs to be endbr64 instructions right after the
jump_fcontext() call, as indirect branches end up there.

pdns/recursordist/mtasker_fcontext.cc

index dd3eb707baf10c2907e6b2dbd47d5819886a8458..1a7c976a6174f37ba71cbb1c179f3cc17098127a 100644 (file)
@@ -32,6 +32,15 @@ using boost::context::make_fcontext;
 using boost::context::detail::make_fcontext;
 #endif /* BOOST_VERSION < 106100 */
 
+// __CET__ is set by the compiler if relevant, so far only relevant/tested for amd64 on OpenBSD
+#if defined(__amd64__)
+#if __CET__ & 0x1
+#define CET_ENDBR __asm("endbr64")
+#else
+#define CET_ENDBR
+#endif
+#endif
+
 #ifdef PDNS_USE_VALGRIND
 #include <valgrind/valgrind.h>
 #endif /* PDNS_USE_VALGRIND */
@@ -132,6 +141,7 @@ extern "C"
                   static_cast<fcontext_t>(args->prev_ctx), 0);
 #else
     transfer_t res = jump_fcontext(t.fctx, 0);
+    CET_ENDBR;
     /* we got switched back from pdns_swapcontext() */
     if (res.data) {
       /* if res.data is not a nullptr, it holds a pointer to the context
@@ -203,6 +213,7 @@ void pdns_swapcontext(pdns_ucontext_t& __restrict octx, pdns_ucontext_t const& _
     std::rethrow_exception(origctx->exception);
 #else
   transfer_t res = jump_fcontext(static_cast<fcontext_t>(ctx.uc_mcontext), &octx.uc_mcontext);
+  CET_ENDBR;
   if (res.data) {
     /* if res.data is not a nullptr, it holds a pointer to the context
        we just switched from, and we need to fill it to be able to
@@ -235,6 +246,7 @@ void pdns_makecontext(pdns_ucontext_t& ctx, std::function<void(void)>& start)
 #else
   transfer_t res = jump_fcontext(static_cast<fcontext_t>(ctx.uc_mcontext),
                                  &args);
+  CET_ENDBR;
   /* back from threadwrapper, updating the context */
   ctx.uc_mcontext = res.fctx;
 #endif