mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-10-15 18:27:12 +00:00
lksctp-tools: fix sctp_connectx() and ptests on musl
Three func_tests failed on musl: - test_1_to_1_sendmsg and test_1_to_1_recvmsg died with SIGSEGV. They pass (struct msghdr *)-1 and expect EFAULT, but on 64-bit musl the sendmsg()/recvmsg() wrappers copy the msghdr to clear its padding before making the syscall. Issue those two calls with syscall(2) so they test the kernel's handling of the bad pointer. - test_connectx reported "Association id mismatch: connectx returned 3, notification returned:240". libsctp exports an unversioned sctp_connectx alias of the original API next to the VERS_1..VERS_3 versions. musl's dynamic linker does not implement symbol versioning and binds that alias, so every sctp_connectx() call on musl ran the old API, which never returns the association id. The alias only serves binaries linked before libsctp was versioned, so only emit it on glibc; sctp_connectx@@VERS_3 is then the one musl resolves. Tested with meta-networking-image-ptest-lksctp-tools on qemux86-64 with yoe-musl-systemd-wayland: TOTAL: 1 FAIL: 0. AI-Generated: Uses Claude Code Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
This commit is contained in:
3 files changed
+123
No files matched your search
+72
@@ -0,0 +1,72 @@
|
||||
From 5402bce533c3ba8dae022eded7c6ffe7967b7248 Mon Sep 17 00:00:00 2001
|
||||
From: Khem Raj <khem.raj@oss.qualcomm.com>
|
||||
Date: Sun, 27 Sep 2026 15:52:39 -0700
|
||||
Subject: [PATCH 2/3] func_tests: pass invalid msghdr pointers straight to the
|
||||
kernel
|
||||
|
||||
test_1_to_1_sendmsg TEST6 and test_1_to_1_recvmsg TEST4 hand
|
||||
(struct msghdr *)-1 to sendmsg()/recvmsg() and expect EFAULT from the
|
||||
kernel. Passing an invalid pointer to a libc function is undefined, and
|
||||
on 64-bit musl both wrappers copy the msghdr first to clear its padding
|
||||
fields, so the tests die with SIGSEGV before reaching the syscall.
|
||||
|
||||
Use syscall(2) for these two cases so they test what they mean to: the
|
||||
kernel's handling of a bad msghdr pointer.
|
||||
|
||||
Upstream-Status: Pending
|
||||
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
|
||||
---
|
||||
src/func_tests/test_1_to_1_recvmsg.c | 7 ++++++-
|
||||
src/func_tests/test_1_to_1_sendmsg.c | 7 ++++++-
|
||||
2 files changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/func_tests/test_1_to_1_recvmsg.c b/src/func_tests/test_1_to_1_recvmsg.c
|
||||
index 962b7b5..0ccf087 100644
|
||||
--- a/src/func_tests/test_1_to_1_recvmsg.c
|
||||
+++ b/src/func_tests/test_1_to_1_recvmsg.c
|
||||
@@ -56,6 +56,7 @@
|
||||
#include <sys/uio.h>
|
||||
#include <linux/socket.h>
|
||||
#include <sctputil.h>
|
||||
+#include <sys/syscall.h>
|
||||
|
||||
char *TCID = __FILE__;
|
||||
int TST_TOTAL = 8;
|
||||
@@ -158,7 +159,11 @@ main(int argc, char *argv[])
|
||||
inmessage.msg_iov = &iov_rcv;
|
||||
|
||||
/*recvmsg () TEST4: Invalid msghdr pointer EFAULT, Expected error*/
|
||||
- count = recvmsg(acpt_sk, (struct msghdr *)-1, flag);
|
||||
+ /* Call the kernel directly: libc wrappers may read the msghdr
|
||||
+ * themselves (musl copies it to clear padding on 64-bit), which
|
||||
+ * crashes instead of returning EFAULT.
|
||||
+ */
|
||||
+ count = syscall(SYS_recvmsg, acpt_sk, (struct msghdr *)-1, flag);
|
||||
if (count != -1 || errno != EFAULT)
|
||||
tst_brkm(TBROK, tst_exit, "recvmsg with invalid msghdr "
|
||||
"pointer count:%d, errno:%d", count, errno);
|
||||
diff --git a/src/func_tests/test_1_to_1_sendmsg.c b/src/func_tests/test_1_to_1_sendmsg.c
|
||||
index f2949e7..4f46c78 100644
|
||||
--- a/src/func_tests/test_1_to_1_sendmsg.c
|
||||
+++ b/src/func_tests/test_1_to_1_sendmsg.c
|
||||
@@ -63,6 +63,7 @@
|
||||
#include <sys/uio.h>
|
||||
#include <linux/socket.h>
|
||||
#include <sctputil.h>
|
||||
+#include <sys/syscall.h>
|
||||
|
||||
char *TCID = __FILE__;
|
||||
int TST_TOTAL = 14;
|
||||
@@ -200,7 +201,11 @@ main(int argc, char *argv[])
|
||||
outmessage.msg_iovlen = 1;
|
||||
|
||||
/*sendmsg () TEST6: Invalid msghdr pointer EFAULT, Expected error*/
|
||||
- count = sendmsg(sk, (struct msghdr *)-1, flag);
|
||||
+ /* Call the kernel directly: libc wrappers may read the msghdr
|
||||
+ * themselves (musl copies it to clear padding on 64-bit), which
|
||||
+ * crashes instead of returning EFAULT.
|
||||
+ */
|
||||
+ count = syscall(SYS_sendmsg, sk, (struct msghdr *)-1, flag);
|
||||
if (count != -1 || errno != EFAULT)
|
||||
tst_brkm(TBROK, tst_exit, "sendmsg with invalid msghdr "
|
||||
"pointer count:%d, errno:%d", count, errno);
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
From fb2fa4a7af169878f7e7cb2fbf3dba00639d73ed Mon Sep 17 00:00:00 2001
|
||||
From: Khem Raj <khem.raj@oss.qualcomm.com>
|
||||
Date: Sun, 27 Sep 2026 15:52:39 -0700
|
||||
Subject: [PATCH 3/3] connectx: only export the unversioned sctp_connectx alias
|
||||
on glibc
|
||||
|
||||
libsctp exports sctp_connectx four times: an unversioned alias of the
|
||||
original three-argument API plus the VERS_1, VERS_2 and default VERS_3
|
||||
versions. glibc honours the version recorded in the caller, but musl's
|
||||
dynamic linker does not implement symbol versioning: it skips the
|
||||
hidden VERS_1/VERS_2 entries yet accepts both the unversioned alias and
|
||||
sctp_connectx@@VERS_3, and whichever comes first in the hash chain wins.
|
||||
That is the unversioned alias, so on musl every sctp_connectx() call
|
||||
runs the old API, which ignores the association id argument. The caller
|
||||
then reads an uninitialised id, e.g. test_connectx:
|
||||
|
||||
test_connectx.c 3 BROK : Association id mismatch: connectx returned 3,
|
||||
notification returned:240
|
||||
|
||||
The alias only exists for binaries linked before libsctp was versioned,
|
||||
which is a glibc concern. Emit it only when building against glibc, so
|
||||
sctp_connectx@@VERS_3 is the only visible definition elsewhere.
|
||||
|
||||
Upstream-Status: Pending
|
||||
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
|
||||
---
|
||||
src/lib/connectx.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/src/lib/connectx.c b/src/lib/connectx.c
|
||||
index 2a21e3a..119f6c9 100644
|
||||
--- a/src/lib/connectx.c
|
||||
+++ b/src/lib/connectx.c
|
||||
@@ -76,7 +76,15 @@ static int __connectx_addrsize(const struct sockaddr *addrs,
|
||||
}
|
||||
|
||||
|
||||
+/* The unversioned alias lets glibc resolve references from binaries
|
||||
+ * built before libsctp had symbol versions. Dynamic linkers without
|
||||
+ * symbol versioning, such as musl's, pick the first matching name
|
||||
+ * instead and would bind every sctp_connectx() call to this old API,
|
||||
+ * which never reports the association id.
|
||||
+ */
|
||||
+#ifdef __GLIBC__
|
||||
SYMVER(__sctp_connectx, sctp_connectx@)
|
||||
+#endif
|
||||
int __sctp_connectx(int fd, struct sockaddr *addrs, int addrcnt)
|
||||
{
|
||||
int addrs_size = __connectx_addrsize(addrs, addrcnt);
|
||||
@@ -13,6 +13,8 @@ SRCREV = "37d5f1225573b91d706a5e547d081f79963a9deb"
|
||||
SRC_URI = " \
|
||||
git://github.com/sctp/lksctp-tools.git;branch=master;protocol=https \
|
||||
file://0001-func_tests-disable-FORTIFY_SOURCE-for-test_1_to_1_re.patch \
|
||||
file://0002-func_tests-pass-invalid-msghdr-pointers-straight-to-.patch \
|
||||
file://0003-connectx-only-export-the-unversioned-sctp_connectx-a.patch \
|
||||
file://run-ptest \
|
||||
file://v4test.sh \
|
||||
file://v6test.sh \
|
||||
|
||||
Reference in new issue
Block a user