[Pkg-erlang-devel] Bug#1106834: unblock: erlang/1:27.3.4+dfsg-1
Sergei Golovan
sgolovan at debian.org
Fri May 30 11:33:30 BST 2025
Package: release.debian.org
Severity: normal
X-Debbugs-Cc: erlang at packages.debian.org
Control: affects -1 + src:erlang
User: release.debian.org at packages.debian.org
Usertags: unblock
Please unblock package erlang
[ Reason ]
Erlang 1:27.3.4+dfsg-1 fixes a few bugs among which is a fix for
CVE-2025-46712 (a vulnerability in key exchange procedure in
the Erlang SSH module).
[ Impact ]
The vulnerability is no very serious (the Debian security team
reckons that it doesn't warrant DSA), but it'd be good to have
it fixed in trixie.
[ Tests ]
The Erlang sources include exhausting set of internal tests,
I've run them manually, and did not get new failures with respect
to the 1:27.3.3+dfsg-1 currently in trixie. There are a few new tests
for the code which fixes CVE-2025-46712, they are also run successfully.
[ Risks ]
I estimate the risk of breakage of packages which depend on Erlang as
low. The new version is a bugfix release with moderate changes.
[ Checklist ]
[+] all changes are documented in the d/changelog
[+] I reviewed all changes and I approve them
[+] attach debdiff against the package in testing
[ Other info ]
I've attached an incomplete changelog, without new code in tests.
unblock erlang/1:27.3.4+dfsg-1
-------------- next part --------------
diff -Nru erlang-27.3.3+dfsg/debian/changelog erlang-27.3.4+dfsg/debian/changelog
--- erlang-27.3.3+dfsg/debian/changelog 2025-04-16 17:20:18.000000000 +0300
+++ erlang-27.3.4+dfsg/debian/changelog 2025-05-09 09:04:59.000000000 +0300
@@ -1,3 +1,12 @@
+erlang (1:27.3.4+dfsg-1) unstable; urgency=medium
+
+ * New upstream release.
+ * Fix CVE-2025-46712 in erlang-ssh application, where a man-in-the-middle
+ could use optional KEX messages to impact the KEX process (closes:
+ #1104963).
+
+ -- Sergei Golovan <sgolovan at debian.org> Fri, 09 May 2025 09:04:59 +0300
+
erlang (1:27.3.3+dfsg-1) unstable; urgency=medium
* New upstream release.
diff -Nru erlang-27.3.3+dfsg/erts/doc/notes.md erlang-27.3.4+dfsg/erts/doc/notes.md
--- erlang-27.3.3+dfsg/erts/doc/notes.md 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/erts/doc/notes.md 2025-05-08 14:03:33.000000000 +0300
@@ -21,6 +21,21 @@
This document describes the changes made to the ERTS application.
+## Erts 15.2.7
+
+### Fixed Bugs and Malfunctions
+
+- Fixed an emulator crash when setting an error_handler module that was not yet loaded.
+
+ Own Id: OTP-19577 Aux Id: ERIERL-1220, [PR-9696]
+
+- Fixed a rare bug that could cause an emulator crash after unloading a module or erasing a persistent_term.
+
+ Own Id: OTP-19599 Aux Id: [PR-9724]
+
+[PR-9696]: https://github.com/erlang/otp/pull/9696
+[PR-9724]: https://github.com/erlang/otp/pull/9724
+
## Erts 15.2.6
### Fixed Bugs and Malfunctions
diff -Nru erlang-27.3.3+dfsg/erts/emulator/beam/beam_bif_load.c erlang-27.3.4+dfsg/erts/emulator/beam/beam_bif_load.c
--- erlang-27.3.3+dfsg/erts/emulator/beam/beam_bif_load.c 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/erts/emulator/beam/beam_bif_load.c 2025-05-08 14:03:33.000000000 +0300
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1999-2024. All Rights Reserved.
+ * Copyright Ericsson AB 1999-2025. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1082,7 +1082,24 @@
goto done;
}
}
-
+
+ /* Check if there are any *direct* references to literals in the process'
+ * registers.
+ *
+ * These are not guaranteed to be kept up to date, but as we can only land
+ * here during signal handling we KNOW that these are either up to date, or
+ * they are not actually live (effective arity is 0 in a `receive`). Should
+ * any of these registers contain garbage, we merely risk scheduling a
+ * pointless garbage collection as `any_heap_ref_ptrs` doesn't follow
+ * pointers, it just range-checks them. */
+ scanned += c_p->arity;
+ if (any_heap_ref_ptrs(&c_p->arg_reg[0],
+ &c_p->arg_reg[c_p->arity],
+ literals,
+ lit_bsize)) {
+ goto done;
+ }
+
res = 0; /* no need for gc */
done: {
diff -Nru erlang-27.3.3+dfsg/erts/emulator/beam/beam_common.c erlang-27.3.4+dfsg/erts/emulator/beam/beam_common.c
--- erlang-27.3.3+dfsg/erts/emulator/beam/beam_common.c 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/erts/emulator/beam/beam_common.c 2025-05-08 14:03:33.000000000 +0300
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2024. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2025. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1333,46 +1333,6 @@
return ep;
}
-static Export*
-apply_setup_error_handler(Process* p, Eterm module, Eterm function, Uint arity, Eterm* reg)
-{
- Export* ep;
-
- /*
- * Find the export table index for the error handler. Return NULL if
- * there is no error handler module.
- */
-
- if ((ep = erts_active_export_entry(erts_proc_get_error_handler(p),
- am_undefined_function, 3)) == NULL) {
- return NULL;
- } else {
- int i;
- Uint sz = 2*arity;
- Eterm* hp;
- Eterm args = NIL;
-
- /*
- * Always copy args from registers to a new list; this ensures
- * that we have the same behaviour whether or not this was
- * called from apply or fixed_apply (any additional last
- * THIS-argument will be included, assuming that arity has been
- * properly adjusted).
- */
-
- hp = HAlloc(p, sz);
- for (i = arity-1; i >= 0; i--) {
- args = CONS(hp, reg[i], args);
- hp += 2;
- }
- reg[0] = module;
- reg[1] = function;
- reg[2] = args;
- }
-
- return ep;
-}
-
static ERTS_INLINE void
apply_bif_error_adjustment(Process *p, Export *ep,
Eterm *reg, Uint arity,
@@ -1547,18 +1507,13 @@
goto error;
}
- /*
- * Get the index into the export table, or failing that the export
- * entry for the error handler.
- *
- * Note: All BIFs have export entries; thus, no special case is needed.
- */
+ /* Call the referenced function, if any: should the function not be found,
+ * create a stub entry which in turn calls the error handler. */
+ ep = erts_export_get_or_make_stub(module, function, arity);
- if ((ep = erts_active_export_entry(module, function, arity)) == NULL) {
- if ((ep = apply_setup_error_handler(p, module, function, arity, reg)) == NULL) goto error;
- }
apply_bif_error_adjustment(p, ep, reg, arity, I, stack_offset);
DTRACE_GLOBAL_CALL_FROM_EXPORT(p, ep);
+
return ep;
}
@@ -1593,17 +1548,9 @@
return apply(p, reg, I, stack_offset);
}
- /*
- * Get the index into the export table, or failing that the export
- * entry for the error handler module.
- *
- * Note: All BIFs have export entries; thus, no special case is needed.
- */
-
- if ((ep = erts_active_export_entry(module, function, arity)) == NULL) {
- if ((ep = apply_setup_error_handler(p, module, function, arity, reg)) == NULL)
- goto error;
- }
+ /* Call the referenced function, if any: should the function not be found,
+ * create a stub entry which in turn calls the error handler. */
+ ep = erts_export_get_or_make_stub(module, function, arity);
apply_bif_error_adjustment(p, ep, reg, arity, I, stack_offset);
DTRACE_GLOBAL_CALL_FROM_EXPORT(p, ep);
diff -Nru erlang-27.3.3+dfsg/erts/emulator/beam/beam_debug.c erlang-27.3.4+dfsg/erts/emulator/beam/beam_debug.c
--- erlang-27.3.3+dfsg/erts/emulator/beam/beam_debug.c 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/erts/emulator/beam/beam_debug.c 2025-05-08 14:03:33.000000000 +0300
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2024. All Rights Reserved.
+ * Copyright Ericsson AB 1998-2025. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1313,13 +1313,15 @@
dirty_send_message(c_p, arg2, AM_done);
ERTS_BIF_PREP_RET(ret, am_ok);
}
- else if (ERTS_IS_ATOM_STR("alive_waitexiting", arg1)) {
+ else if (ERTS_IS_ATOM_STR("alive_waitexiting", arg1)
+ || ERTS_IS_ATOM_STR("alive_waitexitingonly", arg1)) {
Process *real_c_p = erts_proc_shadow2real(c_p);
Eterm *hp, *hp2;
Uint sz;
int i;
ErtsSchedulerData *esdp = erts_get_scheduler_data();
int dirty_io = esdp->type == ERTS_SCHED_DIRTY_IO;
+ int no_wait_alloc = ERTS_IS_ATOM_STR("alive_waitexitingonly", arg1);
if (ERTS_PROC_IS_EXITING(real_c_p))
goto badarg;
@@ -1333,16 +1335,21 @@
erts_thr_yield();
}
- ms_wait(c_p, make_small(1000), 0);
+ if (no_wait_alloc) {
+ ERTS_BIF_PREP_RET(ret, am_ok);
+ }
+ else {
+ ms_wait(c_p, make_small(1000), 0);
- /* Should still be able to allocate memory */
- hp = HAlloc(c_p, 3); /* Likely on heap */
- sz = 10000;
- hp2 = HAlloc(c_p, sz); /* Likely in heap fragment */
- *hp2 = make_pos_bignum_header(sz);
- for (i = 1; i < sz; i++)
- hp2[i] = (Eterm) 4711;
- ERTS_BIF_PREP_RET(ret, TUPLE2(hp, am_ok, make_big(hp2)));
+ /* Should still be able to allocate memory */
+ hp = HAlloc(c_p, 3); /* Likely on heap */
+ sz = 10000;
+ hp2 = HAlloc(c_p, sz); /* Likely in heap fragment */
+ *hp2 = make_pos_bignum_header(sz);
+ for (i = 1; i < sz; i++)
+ hp2[i] = (Eterm) 4711;
+ ERTS_BIF_PREP_RET(ret, TUPLE2(hp, am_ok, make_big(hp2)));
+ }
}
else {
badarg:
diff -Nru erlang-27.3.3+dfsg/erts/emulator/beam/bif.c erlang-27.3.4+dfsg/erts/emulator/beam/bif.c
--- erlang-27.3.3+dfsg/erts/emulator/beam/bif.c 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/erts/emulator/beam/bif.c 2025-05-08 14:03:33.000000000 +0300
@@ -159,6 +159,8 @@
if (!prt)
goto res_no_proc;
+ ERTS_UNDEF(ref, THE_NON_VALUE);
+
lnk = erts_link_internal_tree_lookup_create(&ERTS_P_LINKS(BIF_P),
&created,
ERTS_LNK_TYPE_PORT,
@@ -1100,6 +1102,8 @@
ErtsPortOpResult res = ERTS_PORT_OP_DROPPED;
Port *prt;
+ ERTS_UNDEF(ref, THE_NON_VALUE);
+
/* Send unlink signal */
prt = erts_port_lookup(BIF_ARG_1, ERTS_PORT_SFLGS_DEAD);
if (!prt) {
diff -Nru erlang-27.3.3+dfsg/erts/emulator/beam/emu/beam_emu.c erlang-27.3.4+dfsg/erts/emulator/beam/emu/beam_emu.c
--- erlang-27.3.3+dfsg/erts/emulator/beam/emu/beam_emu.c 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/erts/emulator/beam/emu/beam_emu.c 2025-05-08 14:03:33.000000000 +0300
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1996-2023. All Rights Reserved.
+ * Copyright Ericsson AB 1996-2025. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -531,19 +531,25 @@
* code[3]: &&call_error_handler
* code[4]: Not used
*/
+ const ErtsCodeMFA *mfa;
Export *error_handler;
HEAVY_SWAPOUT;
- error_handler = call_error_handler(c_p, erts_code_to_codemfa(I),
- reg, am_undefined_function);
+ mfa = erts_code_to_codemfa(I);
+ error_handler = call_error_handler(c_p,
+ mfa,
+ reg,
+ am_undefined_function);
HEAVY_SWAPIN;
if (error_handler) {
I = error_handler->dispatch.addresses[erts_active_code_ix()];
Goto(*I);
}
+
+ I = handle_error(c_p, cp_val(*E), reg, mfa);
+ goto post_error_handling;
}
- /* Fall through */
OpCase(error_action_code): {
handle_error:
SWAPOUT;
diff -Nru erlang-27.3.3+dfsg/erts/emulator/beam/erl_alloc.c erlang-27.3.4+dfsg/erts/emulator/beam/erl_alloc.c
--- erlang-27.3.3+dfsg/erts/emulator/beam/erl_alloc.c 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/erts/emulator/beam/erl_alloc.c 2025-05-08 14:03:33.000000000 +0300
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2002-2023. All Rights Reserved.
+ * Copyright Ericsson AB 2002-2025. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -2907,6 +2907,7 @@
hpp = NULL;
szp = &sz;
sz = 0;
+ ERTS_UNDEF(hp, NULL);
bld_term:
diff -Nru erlang-27.3.3+dfsg/erts/emulator/beam/erl_bif_info.c erlang-27.3.4+dfsg/erts/emulator/beam/erl_bif_info.c
--- erlang-27.3.3+dfsg/erts/emulator/beam/erl_bif_info.c 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/erts/emulator/beam/erl_bif_info.c 2025-05-08 14:03:33.000000000 +0300
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1999-2024. All Rights Reserved.
+ * Copyright Ericsson AB 1999-2025. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -3857,6 +3857,7 @@
case am_module:
/* Unloaded funs must report their module even though we can't find
* their full MFA. */
+ ASSERT(fe != NULL || mfa != NULL);
val = (mfa != NULL) ? mfa->module : fe->module;
hp = HAlloc(p, 3);
break;
diff -Nru erlang-27.3.3+dfsg/erts/emulator/beam/erl_db_hash.c erlang-27.3.4+dfsg/erts/emulator/beam/erl_db_hash.c
--- erlang-27.3.3+dfsg/erts/emulator/beam/erl_db_hash.c 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/erts/emulator/beam/erl_db_hash.c 2025-05-08 14:03:33.000000000 +0300
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1998-2024. All Rights Reserved.
+ * Copyright Ericsson AB 1998-2025. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1645,6 +1645,7 @@
bp = &b->next;
b = b->next;
}
+ ERTS_UNDEF(nitems, -1);
if (nitems_diff) {
ADD_NITEMS(tb, lck_ctr, hval, nitems_diff);
nitems = NITEMS_ESTIMATE(tb, lck_ctr, hval);
@@ -1710,6 +1711,7 @@
bp = &b->next;
b = b->next;
}
+ ERTS_UNDEF(nitems, -1);
if (nitems_diff) {
ADD_NITEMS(tb, lck_ctr, hval, nitems_diff);
nitems = NITEMS_ESTIMATE(tb, lck_ctr, hval);
@@ -2975,6 +2977,7 @@
break;
}
}
+ ERTS_UNDEF(nitems, -1);
if (nitems_diff) {
ADD_NITEMS(tb, lck_ctr, hval, nitems_diff);
nitems = NITEMS_ESTIMATE(tb, lck_ctr, hval);
diff -Nru erlang-27.3.3+dfsg/erts/emulator/beam/erl_process.c erlang-27.3.4+dfsg/erts/emulator/beam/erl_process.c
--- erlang-27.3.3+dfsg/erts/emulator/beam/erl_process.c 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/erts/emulator/beam/erl_process.c 2025-05-08 14:03:33.000000000 +0300
@@ -10726,6 +10726,7 @@
if (c_p->flags & F_DISABLE_GC) {
save_gc_task(c_p, st, st_prio);
st = NULL;
+ ERTS_UNDEF(st_res, am_undefined);
reds--;
}
else {
@@ -10739,6 +10740,7 @@
if (c_p->flags & (F_DIRTY_MAJOR_GC|F_DIRTY_MINOR_GC)) {
save_dirty_task(c_p, st);
st = NULL;
+ ERTS_UNDEF(st_res, am_undefined);
break;
}
if (type == ERTS_PSTT_GC_MAJOR)
@@ -10781,6 +10783,7 @@
* but instead unconditionally schedule this as dirty
* work...
*/
+ ERTS_UNDEF(st_res, am_undefined);
if (c_p->flags & F_DISABLE_GC) {
/* We might need to GC, but GC was disabled */
save_gc_task(c_p, st, st_prio);
@@ -13031,8 +13034,10 @@
type = child ? am_ok : am_error;
- if (have_seqtrace(token) && child)
+ if (have_seqtrace(token) && child) {
token_sz = size_object(token);
+ ERTS_UNDEF(token_copy, NIL);
+ }
else {
token_copy = token = NIL;
token_sz = 0;
diff -Nru erlang-27.3.3+dfsg/erts/emulator/beam/erl_proc_sig_queue.c erlang-27.3.4+dfsg/erts/emulator/beam/erl_proc_sig_queue.c
--- erlang-27.3.3+dfsg/erts/emulator/beam/erl_proc_sig_queue.c 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/erts/emulator/beam/erl_proc_sig_queue.c 2025-05-08 14:03:33.000000000 +0300
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2018-2024. All Rights Reserved.
+ * Copyright Ericsson AB 2018-2025. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -4292,6 +4292,7 @@
Eterm reason;
Eterm from;
+ ERTS_UNDEF(reason, THE_NON_VALUE);
ASSERT(ERTS_PROC_SIG_TYPE(tag) == ERTS_SIG_Q_TYPE_GEN_EXIT);
xsigd = get_exit_signal_data(sig);
@@ -4788,6 +4789,8 @@
ErtsMessage *first = NULL, *prev, *last;
Uint hsz = size_object(msg);
Uint i;
+ ERTS_UNDEF(last,NULL);
+ ERTS_UNDEF(prev,NULL);
for (i = 0; i < n; i++) {
Eterm *hp;
@@ -9023,11 +9026,9 @@
int nonmsg = ERTS_SIG_IS_NON_MSG(first);
int restarted = 0;
ErtsSignalInQueueBuffer* buffer;
- Uint64 nonempty_slots_before;
+ Uint64 nonempty_slots_before = 0;
Uint32 slot, state;
- ERTS_UNDEF(nonempty_slots_before, 0);
-
ASSERT(is_value(from));
/* Use the sender id to hash to an outer signal queue buffer. This
diff -Nru erlang-27.3.3+dfsg/erts/emulator/beam/jit/arm/beam_asm_global.cpp erlang-27.3.4+dfsg/erts/emulator/beam/jit/arm/beam_asm_global.cpp
--- erlang-27.3.3+dfsg/erts/emulator/beam/jit/arm/beam_asm_global.cpp 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/erts/emulator/beam/jit/arm/beam_asm_global.cpp 2025-05-08 14:03:33.000000000 +0300
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2020-2024. All Rights Reserved.
+ * Copyright Ericsson AB 2020-2025. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -199,12 +199,15 @@
a.bind(error_handler);
{
+ lea(ARG2, arm::Mem(ARG1, offsetof(Export, info.mfa)));
+ a.str(ARG2, TMP_MEM1q);
+
emit_enter_runtime_frame();
emit_enter_runtime<Update::eReductions | Update::eHeapAlloc |
Update::eXRegs>();
- lea(ARG2, arm::Mem(ARG1, offsetof(Export, info.mfa)));
a.mov(ARG1, c_p);
+ /* ARG2 set above */
load_x_reg_array(ARG3);
mov_imm(ARG4, am_undefined_function);
runtime_call<4>(call_error_handler);
@@ -215,7 +218,8 @@
Update::eXRegs>();
emit_leave_runtime_frame();
- a.cbz(ARG1, labels[process_exit]);
+ a.ldr(ARG4, TMP_MEM1q);
+ a.cbz(ARG1, labels[raise_exception]);
branch(emit_setup_dispatchable_call(ARG1));
}
diff -Nru erlang-27.3.3+dfsg/erts/emulator/beam/jit/x86/beam_asm_global.cpp erlang-27.3.4+dfsg/erts/emulator/beam/jit/x86/beam_asm_global.cpp
--- erlang-27.3.3+dfsg/erts/emulator/beam/jit/x86/beam_asm_global.cpp 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/erts/emulator/beam/jit/x86/beam_asm_global.cpp 2025-05-08 14:03:33.000000000 +0300
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2020-2024. All Rights Reserved.
+ * Copyright Ericsson AB 2020-2025. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -203,22 +203,42 @@
a.bind(error_handler);
{
+ Label error;
+
+#ifdef NATIVE_ERLANG_STACK
+ error = labels[raise_exception];
+#else
+ error = a.newLabel();
+#endif
+
+ a.lea(ARG2, x86::qword_ptr(RET, offsetof(Export, info.mfa)));
+ a.mov(TMP_MEM1q, ARG2);
+
emit_enter_frame();
emit_enter_runtime<Update::eReductions | Update::eHeapAlloc>();
a.mov(ARG1, c_p);
- a.lea(ARG2, x86::qword_ptr(RET, offsetof(Export, info.mfa)));
+ /* ARG2 set above */
load_x_reg_array(ARG3);
mov_imm(ARG4, am_undefined_function);
runtime_call<4>(call_error_handler);
emit_leave_runtime<Update::eReductions | Update::eHeapAlloc>();
+ emit_leave_frame();
+ a.mov(ARG4, TMP_MEM1q);
a.test(RET, RET);
- a.je(labels[process_exit]);
-
- emit_leave_frame();
+ a.je(error);
a.jmp(emit_setup_dispatchable_call(RET));
+
+#ifndef NATIVE_ERLANG_STACK
+ a.bind(error);
+ {
+ a.push(getCPRef());
+ a.mov(getCPRef(), imm(NIL));
+ a.jmp(labels[raise_exception]);
+ }
+#endif
}
}
diff -Nru erlang-27.3.3+dfsg/erts/vsn.mk erlang-27.3.4+dfsg/erts/vsn.mk
--- erlang-27.3.3+dfsg/erts/vsn.mk 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/erts/vsn.mk 2025-05-08 14:03:33.000000000 +0300
@@ -18,7 +18,7 @@
# %CopyrightEnd%
#
-VSN = 15.2.6
+VSN = 15.2.7
# Port number 4365 in 4.2
# Port number 4366 in 4.3
diff -Nru erlang-27.3.3+dfsg/lib/kernel/doc/notes.md erlang-27.3.4+dfsg/lib/kernel/doc/notes.md
--- erlang-27.3.3+dfsg/lib/kernel/doc/notes.md 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/lib/kernel/doc/notes.md 2025-05-08 14:03:33.000000000 +0300
@@ -21,6 +21,23 @@
This document describes the changes made to the Kernel application.
+## Kernel 10.2.7
+
+### Fixed Bugs and Malfunctions
+
+- With this change, disk_log will not crash when using chunk_step/3 after log size was decreased.
+
+ Own Id: OTP-19605 Aux Id: [GH-9720], [PR-9765]
+
+- With this change, disk_log will not run into infinite loop when using chunk/2,3 after log size was decreased.
+
+ Own Id: OTP-19608 Aux Id: [GH-9707], [PR-9767]
+
+[GH-9720]: https://github.com/erlang/otp/issues/9720
+[PR-9765]: https://github.com/erlang/otp/pull/9765
+[GH-9707]: https://github.com/erlang/otp/issues/9707
+[PR-9767]: https://github.com/erlang/otp/pull/9767
+
## Kernel 10.2.6
### Fixed Bugs and Malfunctions
diff -Nru erlang-27.3.3+dfsg/lib/kernel/src/disk_log_1.erl erlang-27.3.4+dfsg/lib/kernel/src/disk_log_1.erl
--- erlang-27.3.3+dfsg/lib/kernel/src/disk_log_1.erl 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/lib/kernel/src/disk_log_1.erl 2025-05-08 14:03:33.000000000 +0300
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2024. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2025. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -979,13 +979,14 @@
%% -> {ok, handle()} | throw(FileError)
change_size_wrap(#handle{filename = FName} = Handle, {NewMaxB, NewMaxF}, Version) ->
{_MaxB, MaxF} = get_wrap_size(Handle),
+ BiggerMaxF = lists:max([MaxF, get_old_max_f(Handle#handle.maxF)]),
write_size_file(read_write, FName, NewMaxB, NewMaxF, Version),
if
- NewMaxF > MaxF ->
+ NewMaxF > BiggerMaxF ->
remove_files(wrap, FName, MaxF + 1, NewMaxF),
{ok, Handle#handle{maxB = NewMaxB, maxF = NewMaxF}};
- NewMaxF < MaxF ->
- {ok, Handle#handle{maxB = NewMaxB, maxF = {NewMaxF, MaxF}}};
+ NewMaxF < BiggerMaxF ->
+ {ok, Handle#handle{maxB = NewMaxB, maxF = {NewMaxF, BiggerMaxF}}};
true ->
{ok, Handle#handle{maxB = NewMaxB, maxF = NewMaxF}}
end.
@@ -1564,9 +1565,10 @@
{NewFt, MaxF}
end.
-inc(N, {_NewMax, OldMax}) -> inc(N, OldMax, 1);
inc(N, Max) -> inc(N, Max, 1).
+inc(N, {_NewMax, OldMax}, Step) ->
+ inc(N, OldMax, Step);
inc(N, Max, Step) ->
Nx = (N + Step) rem Max,
if
@@ -1797,3 +1799,8 @@
file_error_close(Fd, FileName, {error, Error}) ->
_ = file:close(Fd),
throw({error, {file_error, FileName, Error}}).
+
+get_old_max_f({_, OldMaxF}) ->
+ OldMaxF;
+get_old_max_f(MaxF) ->
+ MaxF.
diff -Nru erlang-27.3.3+dfsg/lib/kernel/src/kernel.appup.src erlang-27.3.4+dfsg/lib/kernel/src/kernel.appup.src
--- erlang-27.3.3+dfsg/lib/kernel/src/kernel.appup.src 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/lib/kernel/src/kernel.appup.src 2025-05-08 14:03:33.000000000 +0300
@@ -42,6 +42,7 @@
{<<"^10\\.2\\.3(?:\\.[0-9]+)*$">>,[restart_new_emulator]},
{<<"^10\\.2\\.4(?:\\.[0-9]+)*$">>,[restart_new_emulator]},
{<<"^10\\.2\\.5(?:\\.[0-9]+)*$">>,[restart_new_emulator]},
+ {<<"^10\\.2\\.6(?:\\.[0-9]+)*$">>,[restart_new_emulator]},
{<<"^8\\.4$">>,[restart_new_emulator]},
{<<"^8\\.4\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]},
{<<"^8\\.4\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]},
@@ -78,6 +79,7 @@
{<<"^10\\.2\\.3(?:\\.[0-9]+)*$">>,[restart_new_emulator]},
{<<"^10\\.2\\.4(?:\\.[0-9]+)*$">>,[restart_new_emulator]},
{<<"^10\\.2\\.5(?:\\.[0-9]+)*$">>,[restart_new_emulator]},
+ {<<"^10\\.2\\.6(?:\\.[0-9]+)*$">>,[restart_new_emulator]},
{<<"^8\\.4$">>,[restart_new_emulator]},
{<<"^8\\.4\\.0(?:\\.[0-9]+)+$">>,[restart_new_emulator]},
{<<"^8\\.4\\.1(?:\\.[0-9]+)*$">>,[restart_new_emulator]},
diff -Nru erlang-27.3.3+dfsg/lib/kernel/vsn.mk erlang-27.3.4+dfsg/lib/kernel/vsn.mk
--- erlang-27.3.3+dfsg/lib/kernel/vsn.mk 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/lib/kernel/vsn.mk 2025-05-08 14:03:33.000000000 +0300
@@ -1 +1 @@
-KERNEL_VSN = 10.2.6
+KERNEL_VSN = 10.2.7
diff -Nru erlang-27.3.3+dfsg/lib/ssh/doc/notes.md erlang-27.3.4+dfsg/lib/ssh/doc/notes.md
--- erlang-27.3.3+dfsg/lib/ssh/doc/notes.md 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/lib/ssh/doc/notes.md 2025-05-08 14:03:33.000000000 +0300
@@ -19,6 +19,14 @@
-->
# SSH Release Notes
+## Ssh 5.2.11
+
+### Fixed Bugs and Malfunctions
+
+- Fix KEX strict implementation according to draft-miller-sshm-strict-kex-01 document.
+
+ Own Id: OTP-19625 Aux Id: CVE-2025-46712
+
## Ssh 5.2.10
### Fixed Bugs and Malfunctions
diff -Nru erlang-27.3.3+dfsg/lib/ssh/src/ssh_connection_handler.erl erlang-27.3.4+dfsg/lib/ssh/src/ssh_connection_handler.erl
--- erlang-27.3.3+dfsg/lib/ssh/src/ssh_connection_handler.erl 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/lib/ssh/src/ssh_connection_handler.erl 2025-05-08 14:03:33.000000000 +0300
@@ -35,7 +35,6 @@
-include("ssh_transport.hrl").
-include("ssh_auth.hrl").
-include("ssh_connect.hrl").
-
-include("ssh_fsm.hrl").
%%====================================================================
@@ -732,16 +731,6 @@
disconnect_fun("Received disconnect: "++Desc, D),
{stop_and_reply, {shutdown,Desc}, Actions, D};
-handle_event(internal, #ssh_msg_ignore{}, {_StateName, _Role, init},
- #data{ssh_params = #ssh{kex_strict_negotiated = true,
- send_sequence = SendSeq,
- recv_sequence = RecvSeq}}) ->
- ?DISCONNECT(?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
- io_lib:format("strict KEX violation: unexpected SSH_MSG_IGNORE "
- "send_sequence = ~p recv_sequence = ~p",
- [SendSeq, RecvSeq])
- );
-
handle_event(internal, #ssh_msg_ignore{}, _StateName, _) ->
keep_state_and_data;
@@ -1145,11 +1134,14 @@
of
{packet_decrypted, DecryptedBytes, EncryptedDataRest, Ssh1} ->
D1 = D0#data{ssh_params =
- Ssh1#ssh{recv_sequence = ssh_transport:next_seqnum(Ssh1#ssh.recv_sequence)},
- decrypted_data_buffer = <<>>,
- undecrypted_packet_length = undefined,
- aead_data = <<>>,
- encrypted_data_buffer = EncryptedDataRest},
+ Ssh1#ssh{recv_sequence =
+ ssh_transport:next_seqnum(StateName,
+ Ssh1#ssh.recv_sequence,
+ SshParams)},
+ decrypted_data_buffer = <<>>,
+ undecrypted_packet_length = undefined,
+ aead_data = <<>>,
+ encrypted_data_buffer = EncryptedDataRest},
try
ssh_message:decode(set_kex_overload_prefix(DecryptedBytes,D1))
of
diff -Nru erlang-27.3.3+dfsg/lib/ssh/src/ssh_fsm_kexinit.erl erlang-27.3.4+dfsg/lib/ssh/src/ssh_fsm_kexinit.erl
--- erlang-27.3.3+dfsg/lib/ssh/src/ssh_fsm_kexinit.erl 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/lib/ssh/src/ssh_fsm_kexinit.erl 2025-05-08 14:03:33.000000000 +0300
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2024. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2025. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -44,6 +44,11 @@
-export([callback_mode/0, handle_event/4, terminate/3,
format_status/2, code_change/4]).
+-behaviour(ssh_dbg).
+-export([ssh_dbg_trace_points/0, ssh_dbg_flags/1,
+ ssh_dbg_on/1, ssh_dbg_off/1,
+ ssh_dbg_format/2]).
+
%%====================================================================
%% gen_statem callbacks
%%====================================================================
@@ -54,8 +59,13 @@
%%--------------------------------------------------------------------
-%%% ######## {kexinit, client|server, init|renegotiate} ####
+handle_event(Type, Event = prepare_next_packet, StateName, D) ->
+ ssh_connection_handler:handle_event(Type, Event, StateName, D);
+handle_event(Type, Event = {send_disconnect, _, _, _, _}, StateName, D) ->
+ ssh_connection_handler:handle_event(Type, Event, StateName, D);
+
+%%% ######## {kexinit, client|server, init|renegotiate} ####
handle_event(internal, {#ssh_msg_kexinit{}=Kex, Payload}, {kexinit,Role,ReNeg},
D = #data{key_exchange_init_msg = OwnKex}) ->
Ssh1 = ssh_transport:key_init(peer_role(Role), D#data.ssh_params, Payload),
@@ -68,11 +78,10 @@
end,
{next_state, {key_exchange,Role,ReNeg}, D#data{ssh_params=Ssh}};
-
%%% ######## {key_exchange, client|server, init|renegotiate} ####
-
%%%---- diffie-hellman
handle_event(internal, #ssh_msg_kexdh_init{} = Msg, {key_exchange,server,ReNeg}, D) ->
+ ok = check_kex_strict(Msg, D),
{ok, KexdhReply, Ssh1} = ssh_transport:handle_kexdh_init(Msg, D#data.ssh_params),
ssh_connection_handler:send_bytes(KexdhReply, D),
{ok, NewKeys, Ssh2} = ssh_transport:new_keys_message(Ssh1),
@@ -82,6 +91,7 @@
{next_state, {new_keys,server,ReNeg}, D#data{ssh_params=Ssh}};
handle_event(internal, #ssh_msg_kexdh_reply{} = Msg, {key_exchange,client,ReNeg}, D) ->
+ ok = check_kex_strict(Msg, D),
{ok, NewKeys, Ssh1} = ssh_transport:handle_kexdh_reply(Msg, D#data.ssh_params),
ssh_connection_handler:send_bytes(NewKeys, D),
{ok, ExtInfo, Ssh} = ssh_transport:ext_info_message(Ssh1),
@@ -90,24 +100,28 @@
%%%---- diffie-hellman group exchange
handle_event(internal, #ssh_msg_kex_dh_gex_request{} = Msg, {key_exchange,server,ReNeg}, D) ->
+ ok = check_kex_strict(Msg, D),
{ok, GexGroup, Ssh1} = ssh_transport:handle_kex_dh_gex_request(Msg, D#data.ssh_params),
ssh_connection_handler:send_bytes(GexGroup, D),
Ssh = ssh_transport:parallell_gen_key(Ssh1),
{next_state, {key_exchange_dh_gex_init,server,ReNeg}, D#data{ssh_params=Ssh}};
handle_event(internal, #ssh_msg_kex_dh_gex_request_old{} = Msg, {key_exchange,server,ReNeg}, D) ->
+ ok = check_kex_strict(Msg, D),
{ok, GexGroup, Ssh1} = ssh_transport:handle_kex_dh_gex_request(Msg, D#data.ssh_params),
ssh_connection_handler:send_bytes(GexGroup, D),
Ssh = ssh_transport:parallell_gen_key(Ssh1),
{next_state, {key_exchange_dh_gex_init,server,ReNeg}, D#data{ssh_params=Ssh}};
handle_event(internal, #ssh_msg_kex_dh_gex_group{} = Msg, {key_exchange,client,ReNeg}, D) ->
+ ok = check_kex_strict(Msg, D),
{ok, KexGexInit, Ssh} = ssh_transport:handle_kex_dh_gex_group(Msg, D#data.ssh_params),
ssh_connection_handler:send_bytes(KexGexInit, D),
{next_state, {key_exchange_dh_gex_reply,client,ReNeg}, D#data{ssh_params=Ssh}};
%%%---- elliptic curve diffie-hellman
handle_event(internal, #ssh_msg_kex_ecdh_init{} = Msg, {key_exchange,server,ReNeg}, D) ->
+ ok = check_kex_strict(Msg, D),
{ok, KexEcdhReply, Ssh1} = ssh_transport:handle_kex_ecdh_init(Msg, D#data.ssh_params),
ssh_connection_handler:send_bytes(KexEcdhReply, D),
{ok, NewKeys, Ssh2} = ssh_transport:new_keys_message(Ssh1),
@@ -117,16 +131,25 @@
{next_state, {new_keys,server,ReNeg}, D#data{ssh_params=Ssh}};
handle_event(internal, #ssh_msg_kex_ecdh_reply{} = Msg, {key_exchange,client,ReNeg}, D) ->
+ ok = check_kex_strict(Msg, D),
{ok, NewKeys, Ssh1} = ssh_transport:handle_kex_ecdh_reply(Msg, D#data.ssh_params),
ssh_connection_handler:send_bytes(NewKeys, D),
{ok, ExtInfo, Ssh} = ssh_transport:ext_info_message(Ssh1),
ssh_connection_handler:send_bytes(ExtInfo, D),
{next_state, {new_keys,client,ReNeg}, D#data{ssh_params=Ssh}};
+%%% ######## handle KEX strict
+handle_event(internal, _Event, {key_exchange,_Role,init},
+ #data{ssh_params = #ssh{algorithms = #alg{kex_strict_negotiated = true},
+ send_sequence = SendSeq,
+ recv_sequence = RecvSeq}}) ->
+ ?DISCONNECT(?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ io_lib:format("KEX strict violation: send_sequence = ~p recv_sequence = ~p",
+ [SendSeq, RecvSeq]));
%%% ######## {key_exchange_dh_gex_init, server, init|renegotiate} ####
-
handle_event(internal, #ssh_msg_kex_dh_gex_init{} = Msg, {key_exchange_dh_gex_init,server,ReNeg}, D) ->
+ ok = check_kex_strict(Msg, D),
{ok, KexGexReply, Ssh1} = ssh_transport:handle_kex_dh_gex_init(Msg, D#data.ssh_params),
ssh_connection_handler:send_bytes(KexGexReply, D),
{ok, NewKeys, Ssh2} = ssh_transport:new_keys_message(Ssh1),
@@ -134,20 +157,33 @@
{ok, ExtInfo, Ssh} = ssh_transport:ext_info_message(Ssh2),
ssh_connection_handler:send_bytes(ExtInfo, D),
{next_state, {new_keys,server,ReNeg}, D#data{ssh_params=Ssh}};
-
+%%% ######## handle KEX strict
+handle_event(internal, _Event, {key_exchange_dh_gex_init,_Role,init},
+ #data{ssh_params = #ssh{algorithms = #alg{kex_strict_negotiated = true},
+ send_sequence = SendSeq,
+ recv_sequence = RecvSeq}}) ->
+ ?DISCONNECT(?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ io_lib:format("KEX strict violation: send_sequence = ~p recv_sequence = ~p",
+ [SendSeq, RecvSeq]));
%%% ######## {key_exchange_dh_gex_reply, client, init|renegotiate} ####
-
handle_event(internal, #ssh_msg_kex_dh_gex_reply{} = Msg, {key_exchange_dh_gex_reply,client,ReNeg}, D) ->
+ ok = check_kex_strict(Msg, D),
{ok, NewKeys, Ssh1} = ssh_transport:handle_kex_dh_gex_reply(Msg, D#data.ssh_params),
ssh_connection_handler:send_bytes(NewKeys, D),
{ok, ExtInfo, Ssh} = ssh_transport:ext_info_message(Ssh1),
ssh_connection_handler:send_bytes(ExtInfo, D),
{next_state, {new_keys,client,ReNeg}, D#data{ssh_params=Ssh}};
-
+%%% ######## handle KEX strict
+handle_event(internal, _Event, {key_exchange_dh_gex_reply,_Role,init},
+ #data{ssh_params = #ssh{algorithms = #alg{kex_strict_negotiated = true},
+ send_sequence = SendSeq,
+ recv_sequence = RecvSeq}}) ->
+ ?DISCONNECT(?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ io_lib:format("KEX strict violation: send_sequence = ~p recv_sequence = ~p",
+ [SendSeq, RecvSeq]));
%%% ######## {new_keys, client|server} ####
-
%% First key exchange round:
handle_event(internal, #ssh_msg_newkeys{} = Msg, {new_keys,client,init}, D0) ->
{ok, Ssh1} = ssh_transport:handle_new_keys(Msg, D0#data.ssh_params),
@@ -163,6 +199,15 @@
%% ssh_connection_handler:send_bytes(ExtInfo, D),
{next_state, {ext_info,server,init}, D#data{ssh_params=Ssh}};
+%%% ######## handle KEX strict
+handle_event(internal, _Event, {new_keys,_Role,init},
+ #data{ssh_params = #ssh{algorithms = #alg{kex_strict_negotiated = true},
+ send_sequence = SendSeq,
+ recv_sequence = RecvSeq}}) ->
+ ?DISCONNECT(?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ io_lib:format("KEX strict violation (send_sequence = ~p recv_sequence = ~p)",
+ [SendSeq, RecvSeq]));
+
%% Subsequent key exchange rounds (renegotiation):
handle_event(internal, #ssh_msg_newkeys{} = Msg, {new_keys,Role,renegotiate}, D) ->
{ok, Ssh} = ssh_transport:handle_new_keys(Msg, D#data.ssh_params),
@@ -184,7 +229,6 @@
handle_event(internal, #ssh_msg_newkeys{}=Msg, {ext_info,_Role,renegotiate}, D) ->
{ok, Ssh} = ssh_transport:handle_new_keys(Msg, D#data.ssh_params),
{keep_state, D#data{ssh_params = Ssh}};
-
handle_event(internal, Msg, {ext_info,Role,init}, D) when is_tuple(Msg) ->
%% If something else arrives, goto next state and handle the event in that one
@@ -218,3 +262,70 @@
peer_role(client) -> server;
peer_role(server) -> client.
+check_kex_strict(Msg,
+ #data{ssh_params =
+ #ssh{algorithms =
+ #alg{
+ kex = Kex,
+ kex_strict_negotiated = KexStrictNegotiated},
+ send_sequence = SendSeq,
+ recv_sequence = RecvSeq}}) ->
+ case check_msg_group(Msg, get_alg_group(Kex), KexStrictNegotiated) of
+ ok ->
+ ok;
+ error ->
+ ?DISCONNECT(?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ io_lib:format("KEX strict violation: send_sequence = ~p recv_sequence = ~p",
+ [SendSeq, RecvSeq]))
+ end.
+
+get_alg_group(Kex) when Kex == 'diffie-hellman-group16-sha512';
+ Kex == 'diffie-hellman-group18-sha512';
+ Kex == 'diffie-hellman-group14-sha256';
+ Kex == 'diffie-hellman-group14-sha1';
+ Kex == 'diffie-hellman-group1-sha1' ->
+ dh_alg;
+get_alg_group(Kex) when Kex == 'diffie-hellman-group-exchange-sha256';
+ Kex == 'diffie-hellman-group-exchange-sha1' ->
+ dh_gex_alg;
+get_alg_group(Kex) when Kex == 'curve25519-sha256';
+ Kex == 'curve25519-sha256 at libssh.org';
+ Kex == 'curve448-sha512';
+ Kex == 'ecdh-sha2-nistp521';
+ Kex == 'ecdh-sha2-nistp384';
+ Kex == 'ecdh-sha2-nistp256' ->
+ ecdh_alg.
+
+check_msg_group(_Msg, _AlgGroup, false) -> ok;
+check_msg_group(#ssh_msg_kexdh_init{}, dh_alg, true) -> ok;
+check_msg_group(#ssh_msg_kexdh_reply{}, dh_alg, true) -> ok;
+check_msg_group(#ssh_msg_kex_dh_gex_request_old{}, dh_gex_alg, true) -> ok;
+check_msg_group(#ssh_msg_kex_dh_gex_request{}, dh_gex_alg, true) -> ok;
+check_msg_group(#ssh_msg_kex_dh_gex_group{}, dh_gex_alg, true) -> ok;
+check_msg_group(#ssh_msg_kex_dh_gex_init{}, dh_gex_alg, true) -> ok;
+check_msg_group(#ssh_msg_kex_dh_gex_reply{}, dh_gex_alg, true) -> ok;
+check_msg_group(#ssh_msg_kex_ecdh_init{}, ecdh_alg, true) -> ok;
+check_msg_group(#ssh_msg_kex_ecdh_reply{}, ecdh_alg, true) -> ok;
+check_msg_group(_Msg, _AlgGroup, _) -> error.
+
+%%%################################################################
+%%%#
+%%%# Tracing
+%%%#
+
+ssh_dbg_trace_points() -> [connection_events].
+
+ssh_dbg_flags(connection_events) -> [c].
+
+ssh_dbg_on(connection_events) -> dbg:tp(?MODULE, handle_event, 4, x).
+
+ssh_dbg_off(connection_events) -> dbg:ctpg(?MODULE, handle_event, 4).
+
+ssh_dbg_format(connection_events, {call, {?MODULE,handle_event, [EventType, EventContent, State, _Data]}}) ->
+ ["Connection event\n",
+ io_lib:format("[~w] EventType: ~p~nEventContent: ~p~nState: ~p~n", [?MODULE, EventType, EventContent, State])
+ ];
+ssh_dbg_format(connection_events, {return_from, {?MODULE,handle_event,4}, Ret}) ->
+ ["Connection event result\n",
+ io_lib:format("[~w] ~p~n", [?MODULE, ssh_dbg:reduce_state(Ret, #data{})])
+ ].
diff -Nru erlang-27.3.3+dfsg/lib/ssh/src/ssh_transport.erl erlang-27.3.4+dfsg/lib/ssh/src/ssh_transport.erl
--- erlang-27.3.3+dfsg/lib/ssh/src/ssh_transport.erl 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/lib/ssh/src/ssh_transport.erl 2025-05-08 14:03:33.000000000 +0300
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2024. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2025. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -27,12 +27,11 @@
-include_lib("public_key/include/public_key.hrl").
-include_lib("kernel/include/inet.hrl").
-
-include("ssh_transport.hrl").
-include("ssh.hrl").
-export([versions/2, hello_version_msg/1]).
--export([next_seqnum/1,
+-export([next_seqnum/3,
supported_algorithms/0, supported_algorithms/1,
default_algorithms/0, default_algorithms/1,
clear_default_algorithms_env/0,
@@ -296,7 +295,12 @@
hello_version_msg(Data) ->
[Data,"\r\n"].
-next_seqnum(SeqNum) ->
+next_seqnum({State, _Role, init}, 16#ffffffff,
+ #ssh{algorithms = #alg{kex_strict_negotiated = true}})
+ when State == kexinit; State == key_exchange; State == new_keys ->
+ ?DISCONNECT(?SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
+ io_lib:format("KEX strict violation: recv_sequence = 16#ffffffff", []));
+next_seqnum(_State, SeqNum, _) ->
(SeqNum + 1) band 16#ffffffff.
is_valid_mac(_, _ , #ssh{recv_mac_size = 0}) ->
@@ -1081,7 +1085,7 @@
%% algorithm. Each string MUST contain at least one algorithm name.
select_algorithm(Role, Client, Server,
#ssh{opts = Opts,
- kex_strict_negotiated = KexStrictNegotiated0},
+ kex_strict_negotiated = KexStrictNegotiated0},
ReNeg) ->
KexStrictNegotiated =
case ReNeg of
@@ -1106,7 +1110,6 @@
_ ->
KexStrictNegotiated0
end,
-
{Encrypt0, Decrypt0} = select_encrypt_decrypt(Role, Client, Server),
{SendMac0, RecvMac0} = select_send_recv_mac(Role, Client, Server),
diff -Nru erlang-27.3.3+dfsg/lib/ssh/vsn.mk erlang-27.3.4+dfsg/lib/ssh/vsn.mk
--- erlang-27.3.3+dfsg/lib/ssh/vsn.mk 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/lib/ssh/vsn.mk 2025-05-08 14:03:33.000000000 +0300
@@ -1,4 +1,4 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
-SSH_VSN = 5.2.10
+SSH_VSN = 5.2.11
APP_VSN = "ssh-$(SSH_VSN)"
diff -Nru erlang-27.3.3+dfsg/lib/xmerl/doc/notes.md erlang-27.3.4+dfsg/lib/xmerl/doc/notes.md
--- erlang-27.3.3+dfsg/lib/xmerl/doc/notes.md 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/lib/xmerl/doc/notes.md 2025-05-08 14:03:33.000000000 +0300
@@ -21,6 +21,18 @@
This document describes the changes made to the Xmerl application.
+## Xmerl 2.1.3
+
+### Improvements and New Features
+
+- A new option to discard whitespace before the `xml` tag when reading from a stream has been added to the Xmerl SAX parser.
+
+ * __`{discard_ws_before_xml_document, Boolean}`__ - Discard whitespace before `xml` tag instead of returning a fatal error if set to `true` (`false` is default)
+
+ Own Id: OTP-19602 Aux Id: [PR-9753]
+
+[PR-9753]: https://github.com/erlang/otp/pull/9753
+
## Xmerl 2.1.2
### Fixed Bugs and Malfunctions
diff -Nru erlang-27.3.3+dfsg/lib/xmerl/src/xmerl_sax_parser_base.erlsrc erlang-27.3.4+dfsg/lib/xmerl/src/xmerl_sax_parser_base.erlsrc
--- erlang-27.3.3+dfsg/lib/xmerl/src/xmerl_sax_parser_base.erlsrc 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/lib/xmerl/src/xmerl_sax_parser_base.erlsrc 2025-05-08 14:03:33.000000000 +0300
@@ -187,6 +187,11 @@
%% Description: Parsing an XML document
%% [1] document ::= prolog element Misc*
%%----------------------------------------------------------------------
+parse_document(Rest, #xmerl_sax_parser_state{discard_ws_before_xml_document = true} = State) ->
+ {_WS, Rest1, State1} = whitespace(Rest, State, []),
+ {Rest2, State2} = parse_byte_order_mark(Rest1, State1),
+ {Rest3, State3} = parse_misc(Rest2, State2, true),
+ {ok, Rest3, State3};
parse_document(Rest, State) when is_record(State, xmerl_sax_parser_state) ->
{Rest1, State1} = parse_byte_order_mark(Rest, State),
{Rest2, State2} = parse_misc(Rest1, State1, true),
@@ -336,8 +341,9 @@
case parse_pi(Rest, State) of
{Rest1, State1} ->
parse_prolog(Rest1, State1);
- {endDocument, Rest1, State1} ->
- parse_prolog(Rest1, State1)
+ {endDocument, _Rest1, State1} ->
+ ?fatal_error(State1, "<?xml ...?> not first in document")
+ %% parse_prolog(Rest1, State1)
end;
parse_prolog(?STRING_REST("<!", Rest), State) ->
parse_prolog_1(Rest, State);
diff -Nru erlang-27.3.3+dfsg/lib/xmerl/src/xmerl_sax_parser.erl erlang-27.3.4+dfsg/lib/xmerl/src/xmerl_sax_parser.erl
--- erlang-27.3.3+dfsg/lib/xmerl/src/xmerl_sax_parser.erl 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/lib/xmerl/src/xmerl_sax_parser.erl 2025-05-08 14:03:33.000000000 +0300
@@ -1,7 +1,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2024. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2025. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -92,6 +92,9 @@
- **`{fail_undeclared_ref,?Boolean}`** - Decides how the parser should behave
when an undeclared reference is found. Can be useful if one has turned of
external entities so that an external DTD is not parsed. Default is `true`.
+
+- **`{discard_ws_before_xml_document,?Boolean}`** - Discard whitespace before
+ `xml` tag instead of returning a fatal error. Default is `false`.
""".
-type options() :: [{continuation_fun, continuation_fun()} |
{continuation_state, continuation_state()} |
@@ -102,7 +105,8 @@
skip_external_dtd | disallow_entities |
{entity_recurse_limit, non_neg_integer()} |
{external_entities, all | file | none} |
- {fail_undeclared_ref, boolean()}].
+ {fail_undeclared_ref, boolean()} |
+ {discard_ws_before_xml_document, boolean()}].
-type continuation_state() :: term().
@@ -472,6 +476,8 @@
parse_options(Options, State#xmerl_sax_parser_state{external_entities = Type});
parse_options([{fail_undeclared_ref, Bool} |Options], State) when is_boolean(Bool) ->
parse_options(Options, State#xmerl_sax_parser_state{fail_undeclared_ref = Bool});
+parse_options([{discard_ws_before_xml_document, Bool} |Options], State) when is_boolean(Bool) ->
+ parse_options(Options, State#xmerl_sax_parser_state{discard_ws_before_xml_document = Bool});
parse_options([O |_], _State) ->
{error, lists:flatten(io_lib:format("Option: ~p not supported", [O]))}.
diff -Nru erlang-27.3.3+dfsg/lib/xmerl/src/xmerl_sax_parser.hrl erlang-27.3.4+dfsg/lib/xmerl/src/xmerl_sax_parser.hrl
--- erlang-27.3.3+dfsg/lib/xmerl/src/xmerl_sax_parser.hrl 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/lib/xmerl/src/xmerl_sax_parser.hrl 2025-05-08 14:03:33.000000000 +0300
@@ -1,7 +1,7 @@
%%--------------------------------------------------------------------
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2024. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2025. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -93,9 +93,7 @@
attribute_values = [], % default attribute values
allow_entities = true, % If true entities are allowed in the document
entity_recurse_limit = 3, % How many levels of recursion is allowed for entities
- external_entities = none, % Which types of external entities are allowed: all, file or none(default)
- fail_undeclared_ref = true % If false the reference will be left unresolved in the document, true is default
+ external_entities = none, % Which types of external entities are allowed: all, file or none(default)
+ fail_undeclared_ref = true, % If false the reference will be left unresolved in the document, true is default
+ discard_ws_before_xml_document = false % If true allow whitespace fefore the xml tag
}).
-
-
-
diff -Nru erlang-27.3.3+dfsg/lib/xmerl/vsn.mk erlang-27.3.4+dfsg/lib/xmerl/vsn.mk
--- erlang-27.3.3+dfsg/lib/xmerl/vsn.mk 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/lib/xmerl/vsn.mk 2025-05-08 14:03:33.000000000 +0300
@@ -1 +1 @@
-XMERL_VSN = 2.1.2
+XMERL_VSN = 2.1.3
diff -Nru erlang-27.3.3+dfsg/make/ex_doc.exs erlang-27.3.4+dfsg/make/ex_doc.exs
--- erlang-27.3.3+dfsg/make/ex_doc.exs 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/make/ex_doc.exs 2025-05-08 14:03:33.000000000 +0300
@@ -197,28 +197,34 @@
before_closing_body_tag: fn
:html ->
"""
- <script>
- function mermaidLoaded() {
- mermaid.initialize({
- startOnLoad: false,
- theme: document.body.className.includes("dark") ? "dark" : "default"
- });
- let id = 0;
- for (const codeEl of document.querySelectorAll("pre code.mermaid")) {
+ <script defer src="https://cdn.jsdelivr.net/npm/mermaid@11.4.1/dist/mermaid.min.js"></script>
+ <script>
+ let initialized = false;
+
+ window.addEventListener("exdoc:loaded", () => {
+ if (!initialized) {
+ mermaid.initialize({
+ startOnLoad: false,
+ theme: document.body.className.includes("dark") ? "dark" : "default"
+ });
+ initialized = true;
+ }
+
+ let id = 0;
+ for (const codeEl of document.querySelectorAll("pre code.mermaid")) {
const preEl = codeEl.parentElement;
const graphDefinition = codeEl.textContent;
const graphEl = document.createElement("div");
const graphId = "mermaid-graph-" + id++;
mermaid.render(graphId, graphDefinition).then(({svg, bindFunctions}) => {
- graphEl.innerHTML = svg;
- bindFunctions?.(graphEl);
- preEl.insertAdjacentElement("afterend", graphEl);
- preEl.remove();
+ graphEl.innerHTML = svg;
+ bindFunctions?.(graphEl);
+ preEl.insertAdjacentElement("afterend", graphEl);
+ preEl.remove();
});
- }
- }
- </script>
- <script async src="https://cdn.jsdelivr.net/npm/mermaid@10.2.3/dist/mermaid.min.js" onload="mermaidLoaded();"></script>
+ }
+ });
+ </script>
"""
_ ->
diff -Nru erlang-27.3.3+dfsg/make/otp_version_tickets erlang-27.3.4+dfsg/make/otp_version_tickets
--- erlang-27.3.3+dfsg/make/otp_version_tickets 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/make/otp_version_tickets 2025-05-08 14:03:33.000000000 +0300
@@ -1,5 +1,6 @@
-OTP-19581
-OTP-19582
-OTP-19585
-OTP-19592
-OTP-19595
+OTP-19577
+OTP-19599
+OTP-19602
+OTP-19605
+OTP-19608
+OTP-19625
diff -Nru erlang-27.3.3+dfsg/OTP_VERSION erlang-27.3.4+dfsg/OTP_VERSION
--- erlang-27.3.3+dfsg/OTP_VERSION 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/OTP_VERSION 2025-05-08 14:03:33.000000000 +0300
@@ -1 +1 @@
-27.3.3
+27.3.4
diff -Nru erlang-27.3.3+dfsg/otp_versions.table erlang-27.3.4+dfsg/otp_versions.table
--- erlang-27.3.3+dfsg/otp_versions.table 2025-04-16 15:32:46.000000000 +0300
+++ erlang-27.3.4+dfsg/otp_versions.table 2025-05-08 14:03:33.000000000 +0300
@@ -1,3 +1,4 @@
+OTP-27.3.4 : erts-15.2.7 kernel-10.2.7 ssh-5.2.11 xmerl-2.1.3 # asn1-5.3.4 common_test-1.27.7 compiler-8.6.1 crypto-5.5.3 debugger-5.5 dialyzer-5.3.1 diameter-2.4.1 edoc-1.3.2 eldap-1.2.14 erl_interface-5.5.2 et-1.7.1 eunit-2.9.1 ftp-1.2.3 inets-9.3.2 jinterface-1.14.1 megaco-4.7.2 mnesia-4.23.5 observer-2.17 odbc-2.15 os_mon-2.10.1 parsetools-2.6 public_key-1.17.1 reltool-1.0.1 runtime_tools-2.1.1 sasl-4.2.2 snmp-5.18.2 ssl-11.2.12 stdlib-6.2.2 syntax_tools-3.2.2 tftp-1.2.2 tools-4.1.1 wx-2.4.3 :
OTP-27.3.3 : erts-15.2.6 kernel-10.2.6 megaco-4.7.2 ssh-5.2.10 ssl-11.2.12 # asn1-5.3.4 common_test-1.27.7 compiler-8.6.1 crypto-5.5.3 debugger-5.5 dialyzer-5.3.1 diameter-2.4.1 edoc-1.3.2 eldap-1.2.14 erl_interface-5.5.2 et-1.7.1 eunit-2.9.1 ftp-1.2.3 inets-9.3.2 jinterface-1.14.1 mnesia-4.23.5 observer-2.17 odbc-2.15 os_mon-2.10.1 parsetools-2.6 public_key-1.17.1 reltool-1.0.1 runtime_tools-2.1.1 sasl-4.2.2 snmp-5.18.2 stdlib-6.2.2 syntax_tools-3.2.2 tftp-1.2.2 tools-4.1.1 wx-2.4.3 xmerl-2.1.2 :
OTP-27.3.2 : asn1-5.3.4 compiler-8.6.1 erts-15.2.5 kernel-10.2.5 megaco-4.7.1 snmp-5.18.2 ssl-11.2.11 xmerl-2.1.2 # common_test-1.27.7 crypto-5.5.3 debugger-5.5 dialyzer-5.3.1 diameter-2.4.1 edoc-1.3.2 eldap-1.2.14 erl_interface-5.5.2 et-1.7.1 eunit-2.9.1 ftp-1.2.3 inets-9.3.2 jinterface-1.14.1 mnesia-4.23.5 observer-2.17 odbc-2.15 os_mon-2.10.1 parsetools-2.6 public_key-1.17.1 reltool-1.0.1 runtime_tools-2.1.1 sasl-4.2.2 ssh-5.2.9 stdlib-6.2.2 syntax_tools-3.2.2 tftp-1.2.2 tools-4.1.1 wx-2.4.3 :
OTP-27.3.1 : asn1-5.3.3 erts-15.2.4 kernel-10.2.4 mnesia-4.23.5 ssh-5.2.9 ssl-11.2.10 stdlib-6.2.2 # common_test-1.27.7 compiler-8.6 crypto-5.5.3 debugger-5.5 dialyzer-5.3.1 diameter-2.4.1 edoc-1.3.2 eldap-1.2.14 erl_interface-5.5.2 et-1.7.1 eunit-2.9.1 ftp-1.2.3 inets-9.3.2 jinterface-1.14.1 megaco-4.7 observer-2.17 odbc-2.15 os_mon-2.10.1 parsetools-2.6 public_key-1.17.1 reltool-1.0.1 runtime_tools-2.1.1 sasl-4.2.2 snmp-5.18.1 syntax_tools-3.2.2 tftp-1.2.2 tools-4.1.1 wx-2.4.3 xmerl-2.1.1 :
More information about the Pkg-erlang-devel
mailing list