File 0225-ets-insert-list-Fix-potential-false-positive-assert-.patch of Package erlang

From d81f3f0c39a89d3560e79ba7d9c6ae6d7585f211 Mon Sep 17 00:00:00 2001
From: Kjell Winblad <kjellwinblad@gmail.com>
Date: Wed, 28 Apr 2021 15:53:45 +0200
Subject: [PATCH] ets:insert(list): Fix potential false-positive assert crash

The YCF extra context obtained by YCF_GET_EXTRA_CONTEXT() could change
between yields as the context is stack allocated before the first
yield. This could lead to a crash in debug builds as there is debug
code that checks that the data that is saved when yielding does not
contain pointers to the stack.
---
 erts/emulator/beam/erl_db.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c
index c23f38a4a5..06cf04f9ee 100644
--- a/erts/emulator/beam/erl_db.c
+++ b/erts/emulator/beam/erl_db.c
@@ -1699,7 +1699,6 @@ static void ets_insert_2_list_lock_tbl(Eterm table_id,
 {
     BIF_RETTYPE fail_ret;
     DbTable* tb;
-    ets_insert_2_list_info *ctx;
     do {
         fail_ret = db_get_table_or_fail_return(&tb,
                                                table_id,
@@ -1707,16 +1706,29 @@ static void ets_insert_2_list_lock_tbl(Eterm table_id,
                                                LCK_WRITE,
                                                bif_ix,
                                                p);
-        ctx = YCF_GET_EXTRA_CONTEXT();
         if (tb == NULL) {
+            ets_insert_2_list_info *ctx = YCF_GET_EXTRA_CONTEXT();
             if (p->freason == TRAP) {
                 ctx->status = ETS_INSERT_2_LIST_FAILED_TO_GET_LOCK;
             } else {
                 ctx->status = ETS_INSERT_2_LIST_FAILED_TO_GET_LOCK_DESTROY;
                 ctx->destroy_return_value = fail_ret;
             }
+#ifdef DEBUG
+            /*
+             *  Setting ctx to NULL to avoid that YCF crashes with a
+             *  pointer to stack error when running a debug
+             *  build. YCF_GET_EXTRA_CONTEXT() may change between
+             *  yields as we use stack allocated data for the context
+             *  before the first yield so it is important that the
+             *  context is obtained again with YCF_GET_EXTRA_CONTEXT()
+             *  if a yield might have happened.
+             */
+            ctx = NULL;
+#endif
             YCF_YIELD();
         } else {
+            ets_insert_2_list_info *ctx = YCF_GET_EXTRA_CONTEXT();
             ctx->status = on_success_status;
             ASSERT(DB_LOCK_FREE(tb) || erts_lc_rwmtx_is_rwlocked(&tb->common.rwlock));
             ASSERT(!(tb->common.status & DB_DELETE));
-- 
2.26.2

openSUSE Build Service is sponsored by