File 0664-Limit-size-of-sctp_event_subscribe-on-Linux.patch of Package erlang
From 00bda45a0478043821d41f3867eb1514569d771f Mon Sep 17 00:00:00 2001
From: Anton Thomasson <anton.thomasson@ericsson.com>
Date: Wed, 22 Oct 2025 17:25:06 +0200
Subject: [PATCH] Limit size of sctp_event_subscribe on Linux
Use only the size which contains the last used option.
This will help with compatibility since some vendor kernels have
backported SCTP options turning simple backwards compatibility into
breaking forward compatibility even for relatively similar versions.
The Linux kernel is robust against using arbitrary sized structs.
---
erts/emulator/drivers/common/inet_drv.c | 5 +++++
erts/emulator/nifs/common/prim_socket_nif.c | 18 +++++++++++++++++-
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index b9267041de..9b58e17559 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -8831,7 +8831,12 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len)
proto = IPPROTO_SCTP;
type = SCTP_EVENTS;
arg_ptr = (char*) (&arg.es);
+#if defined(__linux__)
+ arg_sz = offsetof(struct sctp_event_subscribe,
+ sctp_adaptation_layer_event) + 1;
+#else
arg_sz = sizeof ( arg.es);
+#endif
break;
}
/* The following is not available on
diff --git a/erts/emulator/nifs/common/prim_socket_nif.c b/erts/emulator/nifs/common/prim_socket_nif.c
index f21f6b18a2..40194fb22f 100644
--- a/erts/emulator/nifs/common/prim_socket_nif.c
+++ b/erts/emulator/nifs/common/prim_socket_nif.c
@@ -8010,6 +8010,10 @@ ERL_NIF_TERM esock_setopt_sctp_events(ErlNifEnv* env,
{
struct sctp_event_subscribe events;
BOOLEAN_T error;
+#if defined(__linux__)
+ int last_opt = offsetof(struct sctp_event_subscribe,
+ sctp_adaptation_layer_event) + 1;
+#endif
SSDBG( descP,
("SOCKET", "esock_setopt_sctp_events {%d} -> entry with"
@@ -8047,20 +8051,32 @@ ERL_NIF_TERM esock_setopt_sctp_events(ErlNifEnv* env,
#if defined(HAVE_STRUCT_SCTP_EVENT_SUBSCRIBE_SCTP_AUTHENTICATION_EVENT)
events.sctp_authentication_event =
esock_setopt_sctp_event(env, eVal, atom_authentication, &error);
+#if defined(__linux__)
+ last_opt = offsetof(struct sctp_event_subscribe,
+ sctp_authentication_event) + 1;
+#endif
#endif
#if defined(HAVE_STRUCT_SCTP_EVENT_SUBSCRIBE_SCTP_SENDER_DRY_EVENT)
events.sctp_sender_dry_event =
esock_setopt_sctp_event(env, eVal, atom_sender_dry, &error);
+#if defined(__linux__)
+ last_opt = offsetof(struct sctp_event_subscribe, sctp_sender_dry_event) + 1;
+#endif
#endif
if (error) {
goto invalid;
} else {
ERL_NIF_TERM result;
+#if defined(__linux__)
+ int arg_sz = last_opt;
+#else
+ int arg_sz = sizeof(events);
+#endif
result = esock_setopt_level_opt(env, descP, level, opt,
- &events, sizeof(events));
+ &events, arg_sz);
SSDBG( descP,
("SOCKET",
"esock_setopt_sctp_events {%d} -> set events -> %T\r\n",
--
2.51.0