From 330b119be68f95f6f8fbdef8bf16bba314783973 Mon Sep 17 00:00:00 2001 From: Rickard Green Date: Sat, 29 Apr 2023 00:30:12 +0200 Subject: [erts] ensure no mix of external and internal identifiers Silently reject proposed creation and select another one when a node goes alive if there are external identifiers in the system with the proposed creation and the same node name that are to be used. Such identifiers would not work as expected in various situations, and are not from the instance of the node that are about to go alive. --- erts/emulator/beam/dist.c | 13 +++++++++++++ erts/emulator/beam/erl_node_tables.c | 12 ++++++++++++ erts/emulator/beam/erl_node_tables.h | 8 ++++++++ 3 files changed, 33 insertions(+) (limited to 'erts/emulator/beam') diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c index c79c0834f6..f3b702ed78 100644 --- a/erts/emulator/beam/dist.c +++ b/erts/emulator/beam/dist.c @@ -4636,6 +4636,19 @@ BIF_RETTYPE setnode_2(BIF_ALIST_2) success = (!ERTS_PROC_IS_EXITING(net_kernel) & !ERTS_PROC_GET_DIST_ENTRY(net_kernel)); if (success) { + /* + * Ensure we don't use a nodename-creation pair with + * external identifiers existing in the system. + */ + while (!0) { + ErlNode *nep; + if (creation < 4) + creation = 4; + nep = erts_find_node(BIF_ARG_1, creation); + if (!nep || erts_node_refc(nep) == 0) + break; + creation++; + } inc_no_nodes(); erts_set_this_node(BIF_ARG_1, (Uint32) creation); erts_this_dist_entry->creation = creation; diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c index 75c6b6abce..9784e17660 100644 --- a/erts/emulator/beam/erl_node_tables.c +++ b/erts/emulator/beam/erl_node_tables.c @@ -881,6 +881,18 @@ erts_node_table_info(fmtfn_t to, void *to_arg) erts_rwmtx_runlock(&erts_node_table_rwmtx); } +ErlNode *erts_find_node(Eterm sysname, Uint32 creation) +{ + ErlNode *res; + ErlNode ne; + ne.sysname = sysname; + ne.creation = creation; + + erts_rwmtx_rlock(&erts_node_table_rwmtx); + res = hash_get(&erts_node_table, (void *) &ne); + erts_rwmtx_runlock(&erts_node_table_rwmtx); + return res; +} ErlNode *erts_find_or_insert_node(Eterm sysname, Uint32 creation, Eterm book) { diff --git a/erts/emulator/beam/erl_node_tables.h b/erts/emulator/beam/erl_node_tables.h index 937bfb1d9e..c3ee2eaa36 100644 --- a/erts/emulator/beam/erl_node_tables.h +++ b/erts/emulator/beam/erl_node_tables.h @@ -258,6 +258,7 @@ void erts_set_dist_entry_not_connected(DistEntry *); void erts_set_dist_entry_pending(DistEntry *); void erts_set_dist_entry_connected(DistEntry *, Eterm, Uint64); ErlNode *erts_find_or_insert_node(Eterm, Uint32, Eterm); +ErlNode *erts_find_node(Eterm, Uint32); void erts_schedule_delete_node(ErlNode *); void erts_set_this_node(Eterm, Uint32); Uint erts_node_table_size(void); @@ -285,6 +286,7 @@ ERTS_GLB_INLINE void erts_deref_node_entry__(ErlNode *np, Eterm term, char *file ERTS_GLB_INLINE erts_aint_t erts_ref_node_entry(ErlNode *np, int min_val, Eterm term); ERTS_GLB_INLINE void erts_deref_node_entry(ErlNode *np, Eterm term); #endif +ERTS_GLB_INLINE erts_aint_t erts_node_refc(ErlNode *np); ERTS_GLB_INLINE void erts_de_rlock(DistEntry *dep); ERTS_GLB_INLINE void erts_de_runlock(DistEntry *dep); ERTS_GLB_INLINE void erts_de_rwlock(DistEntry *dep); @@ -335,6 +337,12 @@ erts_deref_node_entry(ErlNode *np, Eterm term) erts_schedule_delete_node(np); } +ERTS_GLB_INLINE erts_aint_t +erts_node_refc(ErlNode *np) +{ + return erts_refc_read(&np->refc, 0); +} + #endif ERTS_GLB_INLINE void -- cgit v1.2.1