diff mbox series

connect: Add negative tests for connect

Message ID 20240412080739.18933-1-xuyang2018.jy@fujitsu.com
State New
Headers show
Series connect: Add negative tests for connect | expand

Commit Message

Yang Xu April 12, 2024, 8:07 a.m. UTC
Add negative cases for connect(), when errno is EACCES and EPROTOTYPE

Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com>
---
 runtest/syscalls                              |   1 +
 testcases/kernel/syscalls/connect/.gitignore  |   1 +
 testcases/kernel/syscalls/connect/connect03.c | 121 ++++++++++++++++++
 3 files changed, 123 insertions(+)
 create mode 100644 testcases/kernel/syscalls/connect/connect03.c
diff mbox series

Patch

diff --git a/runtest/syscalls b/runtest/syscalls
index 71579cde4..cb2c001a0 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -131,6 +131,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..367b9d172
--- /dev/null
+++ b/testcases/kernel/syscalls/connect/connect03.c
@@ -0,0 +1,121 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2024 FUJITSU LIMITED. All Rights Reserved.
+ * Author: Yang Xu <xuyang2018.jy@fujitsu.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * Verify that connect(2) fails with
+ *
+ * - EACCES when write permission is denied on the socket file
+ * - EPROTOTYPE when socket type does not support the protocol
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <pwd.h>
+#include "tst_test.h"
+
+#define CLIENT_EACCES "client_eacces"
+#define SERVER_EACCES "server_eacces"
+#define CLIENT_EPROTOTYPE "client_eprototype"
+#define SERVER_EPROTOTYPE "server_eprototype"
+
+static struct passwd *pw;
+
+static struct sockaddr_un client_eacces;
+static struct sockaddr_un server_eacces;
+static struct sockaddr_un client_eprototype;
+static struct sockaddr_un server_eprototype;
+
+static struct test_case_t {
+	struct sockaddr *client;
+	socklen_t len_client;
+	int type_client;
+	int protocol_client;
+	struct sockaddr *server;
+	socklen_t len_server;
+	char *file_server;
+	int type_server;
+	int protocol_server;
+	int expected_errno;
+	char *desc;
+} tcases[] = {
+	{(struct sockaddr *)&client_eacces, sizeof(client_eacces),
+		SOCK_STREAM, 0, (struct sockaddr *)&server_eacces,
+		sizeof(server_eacces), SERVER_EACCES, SOCK_STREAM, 0, EACCES,
+		"connect() write permission is denied on the socket file"},
+	{(struct sockaddr *)&client_eprototype, sizeof(client_eprototype),
+		SOCK_DGRAM, 0, (struct sockaddr *)&server_eprototype,
+		sizeof(server_eprototype), SERVER_EPROTOTYPE, SOCK_STREAM, 0,
+		EPROTOTYPE,
+		"connect() socket type does not support the protocol"},
+};
+
+static void setup(void)
+{
+	pw = SAFE_GETPWNAM("nobody");
+
+	client_eacces.sun_family = AF_UNIX;
+	strncpy(client_eacces.sun_path, CLIENT_EACCES,
+		sizeof(client_eacces.sun_path));
+
+	server_eacces.sun_family = AF_UNIX;
+	strncpy(server_eacces.sun_path, SERVER_EACCES,
+		sizeof(server_eacces.sun_path));
+
+	client_eprototype.sun_family = AF_UNIX;
+	strncpy(client_eprototype.sun_path, CLIENT_EPROTOTYPE,
+		sizeof(client_eprototype.sun_path));
+
+	server_eprototype.sun_family = AF_UNIX;
+	strncpy(server_eprototype.sun_path, SERVER_EPROTOTYPE,
+		sizeof(server_eprototype.sun_path));
+}
+
+static void verify_connect(unsigned int i)
+{
+	struct test_case_t *tc = &tcases[i];
+	pid_t pid;
+
+	int fd_server = SAFE_SOCKET(tc->server->sa_family, tc->type_server,
+		tc->protocol_server);
+	int fd_client = SAFE_SOCKET(tc->client->sa_family, tc->type_client,
+		tc->protocol_client);
+
+	SAFE_BIND(fd_server, tc->server, tc->len_server);
+	SAFE_LISTEN(fd_server, 5);
+
+	if (tc->expected_errno == EACCES) {
+		pid = SAFE_FORK();
+		if (!pid) {
+			SAFE_SETUID(pw->pw_uid);
+			TST_EXP_FAIL(connect(fd_client, tc->server,
+				tc->len_server), tc->expected_errno,
+				"%s", tc->desc);
+			exit(0);
+		}
+		SAFE_WAITPID(pid, NULL, 0);
+	} else {
+		TST_EXP_FAIL(connect(fd_client, tc->server, tc->len_server),
+			tc->expected_errno, "%s", tc->desc);
+	}
+
+	if (fd_client > 0)
+		SAFE_CLOSE(fd_client);
+	if (fd_server > 0)
+		SAFE_CLOSE(fd_server);
+	SAFE_UNLINK(tc->file_server);
+}
+
+static struct tst_test test = {
+	.setup = setup,
+	.tcnt = ARRAY_SIZE(tcases),
+	.test = verify_connect,
+	.needs_tmpdir = 1,
+	.needs_root = 1,
+	.forks_child = 1,
+};