[PATCH v9] connect03: New test case for EPROTOTYPE and EACCES errors

Wei Gao via ltp <[email protected]>
Newsgroups gmane.linux.ltp
Message-ID <[email protected]>
connect01/02 only cover generic socket error paths and do not test
AF_UNIX-specific errors.

Add a new connect03 test case targeting AF_UNIX-specific connect(2)
error paths, specifically EPROTOTYPE and EACCES.

- EPROTOTYPE is verified by attempting to connect a UNIX domain SOCK_DGRAM
  socket to a SOCK_STREAM listening server.
- EACCES is verified by modifying permissions on the socket file to 0700,
  spawning a child process, dropping privileges to the unprivileged "nobody"
  user, and attempting to connect.

Signed-off-by: Wei Gao <wegao-IBi9RG/[email protected]>
---
 runtest/syscalls                              |   1 +
 testcases/kernel/syscalls/connect/.gitignore  |   1 +
 testcases/kernel/syscalls/connect/connect03.c | 117 ++++++++++++++++++
 3 files changed, 119 insertions(+)
 create mode 100644 testcases/kernel/syscalls/connect/connect03.c

diff --git a/runtest/syscalls b/runtest/syscalls
index a021c79da..0fec2c6b5 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -142,6 +142,7 @@ confstr01 confstr01
 
 connect01 connect01
 connect02 connect02
+connect03 connect03
 
 creat01 creat01
 creat03 creat03
diff --git a/testcases/kernel/syscalls/connect/.gitignore b/testcases/kernel/syscalls/connect/.gitignore
index 0a3fc90bf..7ef5fef1a 100644
--- a/testcases/kernel/syscalls/connect/.gitignore
+++ b/testcases/kernel/syscalls/connect/.gitignore
@@ -1,2 +1,3 @@
 /connect01
 /connect02
+/connect03
diff --git a/testcases/kernel/syscalls/connect/connect03.c b/testcases/kernel/syscalls/connect/connect03.c
new file mode 100644
index 000000000..b576a10ce
--- /dev/null
+++ b/testcases/kernel/syscalls/connect/connect03.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Linux Test Project
+ */
+
+/*\
+ * Verify that :manpage:`connect(2)` with AF_UNIX fails with -1 and sets proper errno:
+ *
+ * - EPROTOTYPE: The socket type does not support the protocol (e.g.,
+ *   connecting a UNIX domain datagram socket to a stream socket)
+ * - EACCES: Write permission is denied on the socket file
+ *
+ * Requires root to test EACCES by dropping privileges to an
+ * unprivileged user.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <string.h>
+
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+
+#define SOCK_FILE "sock_file"
+
+static int fd_unix_server = -1;
+static int fd_unix_dgram = -1;
+static int fd_unix_stream = -1;
+
+static struct sockaddr_un sock_un;
+static struct passwd *pw;
+
+static struct test_case_t {
+	int *fd;
+	struct sockaddr_un *addr;
+	socklen_t salen;
+	int exp_errno;
+	const char *desc;
+} tcases[] = {
+	{
+		.fd = &fd_unix_dgram,
+		.addr = &sock_un,
+		.salen = sizeof(sock_un),
+		.exp_errno = EPROTOTYPE,
+		.desc = "socket type does not support the protocol"
+	},
+	{
+		.fd = &fd_unix_stream,
+		.addr = &sock_un,
+		.salen = sizeof(sock_un),
+		.exp_errno = EACCES,
+		.desc = "write permission is denied on the socket file"
+	},
+};
+
+static int sys_connect(int sockfd, const struct sockaddr *addr,
+		       socklen_t addrlen)
+{
+	return tst_syscall(__NR_connect, sockfd, addr, addrlen);
+}
+
+static void setup(void)
+{
+	sock_un.sun_family = AF_UNIX;
+	strncpy(sock_un.sun_path, SOCK_FILE, sizeof(sock_un.sun_path));
+
+	fd_unix_server = SAFE_SOCKET(AF_UNIX, SOCK_STREAM, 0);
+	SAFE_BIND(fd_unix_server, (struct sockaddr *)&sock_un, sizeof(sock_un));
+	SAFE_CHMOD(SOCK_FILE, 0700);
+	SAFE_LISTEN(fd_unix_server, 5);
+
+	fd_unix_dgram = SAFE_SOCKET(AF_UNIX, SOCK_DGRAM, 0);
+	fd_unix_stream = SAFE_SOCKET(AF_UNIX, SOCK_STREAM, 0);
+
+	pw = SAFE_GETPWNAM("nobody");
+}
+
+static void cleanup(void)
+{
+	if (fd_unix_dgram != -1)
+		SAFE_CLOSE(fd_unix_dgram);
+	if (fd_unix_stream != -1)
+		SAFE_CLOSE(fd_unix_stream);
+	if (fd_unix_server != -1)
+		SAFE_CLOSE(fd_unix_server);
+}
+
+static void verify_connect(unsigned int i)
+{
+	struct test_case_t *tc = &tcases[i];
+
+	if (tc->exp_errno == EACCES) {
+		if (!SAFE_FORK()) {
+			SAFE_SETUID(pw->pw_uid);
+			TST_EXP_FAIL(sys_connect(*tc->fd, (const struct sockaddr *)tc->addr, tc->salen),
+				     tc->exp_errno, "%s", tc->desc);
+			exit(0);
+		}
+		tst_reap_children();
+	} else {
+		TST_EXP_FAIL(sys_connect(*tc->fd, (const struct sockaddr *)tc->addr, tc->salen),
+			     tc->exp_errno, "%s", tc->desc);
+	}
+}
+
+static struct tst_test test = {
+	.setup = setup,
+	.cleanup = cleanup,
+	.tcnt = ARRAY_SIZE(tcases),
+	.test = verify_connect,
+	.forks_child = 1,
+	.needs_root = 1,
+	.needs_tmpdir = 1,
+};
-- 
2.54.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.