From: Otto Moerbeek Date: Mon, 30 Oct 2023 09:37:10 +0000 (+0100) Subject: Add endbr64 instructions in the right spots for OpenBSD/amd64 X-Git-Tag: rec-5.0.0-beta1~29^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=69aed0d58a2266d82fe3eba414fcf67e4e5f5fa6;p=thirdparty%2Fpdns.git Add endbr64 instructions in the right spots for OpenBSD/amd64 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. --- diff --git a/pdns/recursordist/mtasker_fcontext.cc b/pdns/recursordist/mtasker_fcontext.cc index dd3eb707ba..1a7c976a61 100644 --- a/pdns/recursordist/mtasker_fcontext.cc +++ b/pdns/recursordist/mtasker_fcontext.cc @@ -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 #endif /* PDNS_USE_VALGRIND */ @@ -132,6 +141,7 @@ extern "C" static_cast(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(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& start) #else transfer_t res = jump_fcontext(static_cast(ctx.uc_mcontext), &args); + CET_ENDBR; /* back from threadwrapper, updating the context */ ctx.uc_mcontext = res.fctx; #endif