public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Ondrej Mosnacek <omosnace@redhat.com>
To: git-commits@fedoraproject.org
Subject: [tests/selinux] pr775-checkpolicy-revdeps: Add a test for two-way SCTP association setup
Date: Fri, 11 Sep 2026 13:21:55 GMT [thread overview]
Message-ID: <178913291533.1.9711287180412306592.tests-selinux-5e03405ed4f7@fedoraproject.org> (raw)
A new commit has been pushed.
Repo : tests/selinux
Branch : pr775-checkpolicy-revdeps
Commit : 5e03405ed4f761adcf79e479ebf33c0dc76e4ad5
Author : Ondrej Mosnacek <omosnace@redhat.com>
Date : 2024-08-29T10:06:21+00:00
Stats : +312/-0 in 3 file(s)
URL : https://src.fedoraproject.org/tests/selinux/c/5e03405ed4f761adcf79e479ebf33c0dc76e4ad5?branch=pr775-checkpolicy-revdeps
Log:
Add a test for two-way SCTP association setup
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
---
diff --git a/kernel/sctp_peeloff_corner_case/main.fmf b/kernel/sctp_peeloff_corner_case/main.fmf
new file mode 100644
index 0000000..582248e
--- /dev/null
+++ b/kernel/sctp_peeloff_corner_case/main.fmf
@@ -0,0 +1,25 @@
+summary: Verify that two-way SCTP association setup doesn't trigger AVCs
+description: |
+ When two SCTP endpoints try to initiate an association
+ simultaneously with each other, they may hit various corner cases.
+ This test verifies that this scenario works correctly and that the
+ resulting association is properly labeled (by peeling it off, which
+ transfers the label onto the new socket).
+contact: Ondrej Mosnacek <omosnace@redhat.com>
+component:
+ - kernel
+framework: beakerlib
+require:
+ - make
+ - gcc
+ - lksctp-tools-devel
+ - audit
+duration: 10m
+tier: 2
+enabled: true
+adjust:
+ - enabled: false
+ when: distro < rhel-8
+ because: RHEL-7 and below don't have SCTP SELinux support
+link:
+ - verifies: https://issues.redhat.com/browse/RHEL-48647
diff --git a/kernel/sctp_peeloff_corner_case/reproducer.c b/kernel/sctp_peeloff_corner_case/reproducer.c
new file mode 100644
index 0000000..de6cedb
--- /dev/null
+++ b/kernel/sctp_peeloff_corner_case/reproducer.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPLv2
+/*
+ * Copyright (c) 2024 Red Hat, Inc.
+ * Author: Ondrej Mosnacek <omosnace@redhat.com>
+ */
+
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/sctp.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <netdb.h>
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+static const char * const TEST_PORTS[] = { "9998", "9999" };
+
+#define ITERATIONS 1000
+
+#define member_size(type, member) sizeof(((type *)0)->member)
+#define sizeof_up_to(type, member) (offsetof(type, member) + member_size(type, member))
+
+enum {
+ PIPE_R = 0,
+ PIPE_W,
+};
+
+int main(int argc, char **argv)
+{
+ int sock, psock, result, flags, index, i, pipefd[2], pipes[2][2];
+ struct addrinfo hints, *info;
+ struct sctp_event_subscribe subscr_events;
+ pid_t fork_pid;
+ char byte = 0x41, data[1024];
+ sctp_assoc_t assoc_id;
+ union sctp_notification *notif;
+
+ result = pipe(pipefd);
+ if (result < 0) {
+ perror("pipe");
+ return 1;
+ }
+ pipes[0][PIPE_R] = pipefd[0];
+ pipes[1][PIPE_W] = pipefd[1];
+
+ result = pipe(pipefd);
+ if (result < 0) {
+ perror("pipe");
+ return 1;
+ }
+ pipes[1][PIPE_R] = pipefd[0];
+ pipes[0][PIPE_W] = pipefd[1];
+
+ fork_pid = fork();
+ if (fork_pid < 0) {
+ perror("fork");
+ return 1;
+ }
+
+ index = !!fork_pid;
+ close(pipes[!index][PIPE_R]);
+ close(pipes[!index][PIPE_W]);
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_protocol = IPPROTO_SCTP;
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_SEQPACKET;
+
+ result = getaddrinfo(NULL, TEST_PORTS[index], &hints, &info);
+ if (result < 0) {
+ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(result));
+ return 1;
+ }
+
+ sock = socket(info->ai_family, info->ai_socktype, info->ai_protocol);
+ if (sock < 0) {
+ perror("socket");
+ return 1;
+ }
+
+ result = bind(sock, info->ai_addr, info->ai_addrlen);
+ if (result < 0) {
+ perror("bind");
+ return 1;
+ }
+
+ if (listen(sock, SOMAXCONN)) {
+ perror("listen");
+ return 1;
+ }
+
+ memset(&subscr_events, 0, sizeof(subscr_events));
+ subscr_events.sctp_association_event = 1;
+ result = setsockopt(sock, IPPROTO_SCTP, SCTP_EVENTS, &subscr_events,
+ sizeof_up_to(struct sctp_event_subscribe,
+ sctp_association_event));
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_protocol = IPPROTO_SCTP;
+ hints.ai_socktype = SOCK_SEQPACKET;
+
+ result = getaddrinfo("127.0.0.1", TEST_PORTS[!index], &hints, &info);
+ if (result < 0) {
+ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(result));
+ return 1;
+ }
+
+ for (i = 0; i < ITERATIONS; i++) {
+ printf("[%i] ITERATION %i...\n", index, i);
+
+ /* synchronize */
+ result = write(pipes[index][PIPE_W], &byte, 1);
+ if (result < 0) {
+ perror("pipe");
+ return 1;
+ }
+ result = read(pipes[index][PIPE_R], &byte, 1);
+ if (result < 0) {
+ perror("pipe");
+ return 1;
+ }
+
+ result = connect(sock, info->ai_addr, info->ai_addrlen);
+ if (result < 0 && errno != EISCONN) {
+ perror("connect");
+ return 1;
+ }
+
+ /* Get assoc_id for sctp_peeloff() */
+ flags = 0;
+ result = sctp_recvmsg(sock, data, sizeof(data),
+ NULL, 0, NULL, &flags);
+ if (result < 0) {
+ perror("sctp_recvmsg");
+ return 1;
+ }
+
+ if ((flags & (MSG_NOTIFICATION | MSG_EOR)) != (MSG_NOTIFICATION | MSG_EOR)) {
+ fprintf(stderr, "[%i] Invalid sctp_recvmsg response FLAGS: %x\n", index, flags);
+ return 1;
+ }
+
+ notif = (union sctp_notification *)data;
+ if (notif->sn_header.sn_type != SCTP_ASSOC_CHANGE) {
+ fprintf(stderr, "[%i] Invalid sctp_recvmsg response type: %x\n", index, notif->sn_header.sn_type);
+ return 1;
+ }
+ assoc_id = notif->sn_assoc_change.sac_assoc_id;
+ psock = sctp_peeloff(sock, assoc_id);
+ if (psock < 0) {
+ perror("sctp_peeloff");
+ return 1;
+ }
+
+ data[0] = 42;
+ result = sctp_sendmsg(psock, data, 1, NULL, 0,
+ 0, 0, 0, 0, 0);
+ if (result < 0) {
+ perror("sctp_sendmsg");
+ return 1;
+ }
+
+ result = sctp_recvmsg(psock, data, sizeof(data),
+ NULL, 0, NULL, NULL);
+ if (result < 0) {
+ perror("sctp_recvmsg");
+ return 1;
+ }
+
+ if (data[0] != 42) {
+ fprintf(stderr, "[%i] Invalid sctp_recvmsg response: %d\n", index, (int)data[0]);
+ return 1;
+ }
+
+ close(psock);
+ printf("[%i] ITERATION %i SUCCESS!\n", index, i);
+ }
+ close(sock);
+ return 0;
+}
diff --git a/kernel/sctp_peeloff_corner_case/runtest.sh b/kernel/sctp_peeloff_corner_case/runtest.sh
new file mode 100755
index 0000000..19649bd
--- /dev/null
+++ b/kernel/sctp_peeloff_corner_case/runtest.sh
@@ -0,0 +1,100 @@
+#!/bin/bash
+# vim: dict=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
+# SPDX-License-Identifier: GPLv2
+# Copyright (c) 2024 Red Hat, Inc.
+# Author: Ondrej Mosnacek <omosnace@redhat.com>
+
+# Include Beakerlib environment
+. /usr/share/beakerlib/beakerlib.sh || exit 1
+
+function installDepsYum() {
+ local yum="$1"; shift
+
+ if "$yum" install --help | grep -q -- --skip-unavailable; then
+ "$yum" install -y --skip-unavailable $*
+ elif "$yum" install --help | grep -q -- --skip-broken; then
+ "$yum" install -y --skip-broken $*
+ else
+ for req in $*; do
+ if ! rpm -q --quiet --whatprovides "$req"; then
+ "$yum" install -y "$req" || true
+ fi
+ done
+ fi
+}
+
+function installDeps() {
+ if [ -e /run/ostree-booted ]; then
+ for item in "$@"; do
+ if ! rpm -q --quiet --whatprovides "$item"; then
+ rpm-ostree --apply-live -y install "$item"
+ fi
+ done
+ elif type yum >/dev/null; then
+ installDepsYum yum "$@"
+ elif type dnf >/dev/null; then
+ installDepsYum dnf "$@"
+ fi
+}
+
+function check_avc_begin() {
+ sleep 1.1
+ date +'%x %T'
+ sleep 1.1
+}
+
+function check_avc_end() {
+ marker="marker-$RANDOM"
+
+ auditctl -m "$marker"
+
+ for (( i = 0; i < 100; i++ )); do
+ if ausearch -i -m user -ts $1 2>/dev/null </dev/null | \
+ grep -q "$marker"
+ then
+ echo $i
+ break
+ fi
+ sleep 0.1
+ done
+
+ ausearch -i -m avc -ts $1 </dev/null
+}
+
+rlJournalStart
+ rlPhaseStartSetup
+ rlRun "uname -r" 0 "Print kernel version"
+ # Determine the base kernel package name and version corresponding
+ # to the currently running kernel. Use this information to derive
+ # the correct kernel subpackages to install.
+ if KERNEL_CORE_NVRA="$(rpm -qf "/lib/modules/$(uname -r)/config")"; then
+ KERNEL_CORE_NV="${KERNEL_CORE_NVRA%-*}"
+ KERNEL_CORE_N="${KERNEL_CORE_NV%-*}"
+
+ KERNEL_PKG_VRA="${KERNEL_CORE_NVRA#$KERNEL_CORE_N-}"
+ KERNEL_PKG_BASE="${KERNEL_CORE_N%-core}"
+
+ rlLog "Detected kernel package base name '$KERNEL_PKG_BASE' and version-release.arch '$KERNEL_PKG_VRA'"
+ rlRun "installDeps $KERNEL_PKG_BASE-modules-extra-$KERNEL_PKG_VRA" 0 "Install extra kernel modules"
+ else
+ rlLog "Detected non-RPM running kernel - no extra kernel packages will be installed"
+ fi
+
+ rlRun "gcc -O2 -Wall -o reproducer reproducer.c -lsctp" 0 \
+ "Compile the reproducer"
+ rlRun "modprobe sctp" 0 "Ensure SCTP module is loaded"
+ rlPhaseEnd
+
+ rlPhaseStartTest
+ rlRun "audit_ts=\"\$(check_avc_begin)\""
+
+ rlRun "./reproducer" 0 "Run the reproducer"
+
+ rlRun "check_avc_end \"\$audit_ts\"" 1 "Check if there are AVC denials"
+ rlPhaseEnd
+
+ rlPhaseStartCleanup
+ rlRun "rm -f reproducer"
+ rlPhaseEnd
+rlJournalPrintText
+rlJournalEnd
next reply other threads:[~2026-09-11 13:21 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-11 13:21 Ondrej Mosnacek [this message]
-- strict thread matches above, loose matches on Subject: below --
2026-09-11 13:19 [tests/selinux] pr775-checkpolicy-revdeps: Add a test for two-way SCTP association setup Ondrej Mosnacek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=178913291533.1.9711287180412306592.tests-selinux-5e03405ed4f7@fedoraproject.org \
--to=omosnace@redhat.com \
--cc=git-commits@fedoraproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox