[PATCH v8] connect03: New test case for EPROTOTYPE and EACCES errors
Wei Gao via ltp <[email protected]>
| Newsgroups | gmane.linux.ltp |
|---|---|
| Message-ID | <[email protected]> |
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