tools/testing/selftests/landlock/net_test.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/landlock/net_test.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/landlock/net_test.c
Extension
.c
Size
85463 bytes
Lines
3192
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (srv->protocol.domain) {
		case AF_UNSPEC:
		case AF_INET:
			dst = (const struct sockaddr *)&srv->ipv4_addr;
			break;

		case AF_INET6:
			dst = (const struct sockaddr *)&srv->ipv6_addr;
			break;

		case AF_UNIX:
			dst = (const struct sockaddr *)&srv->unix_addr;
			break;

		default:
			errno = EAFNOSUPPORT;
			return -errno;
		}
	}

	ret = sendto(sock_fd, buf, len, flags, dst, addrlen);
	if (ret < 0)
		return -errno;

	/* errno is not set in cases of partial writes. */
	if (ret != len)
		return -EINTR;

	return 0;
}

static int sendto_variant(const int sock_fd,
			  const struct service_fixture *const srv, void *buf,
			  size_t len, size_t flags)
{
	socklen_t addrlen = 0;

	if (srv != NULL)
		addrlen = get_addrlen(srv, false);

	return sendto_variant_addrlen(sock_fd, srv, addrlen, buf, len, flags);
}

static int test_sendmsg(struct __test_metadata *const _metadata,
			const struct protocol_variant *prot, int client_fd,
			int server_fd, const struct service_fixture *srv,
			bool bind_denied, bool send_denied)
{
	int ret;
	socklen_t opt_len;
	int sock_type;
	int addr_family;
	struct sockaddr_storage peer_addr = { 0 };
	bool has_remote_port;
	bool needs_autobind;
	char read_buf[1] = { 0 };

	/*
	 * Prepare the test by inspecting the socket type and whether it has a
	 * local/remote address set (all of which determine the expected
	 * outcomes).
	 */
	opt_len = sizeof(sock_type);
	ASSERT_EQ(0, getsockopt(client_fd, SOL_SOCKET, SO_TYPE, &sock_type,
				&opt_len));
	opt_len = sizeof(addr_family);
	ASSERT_EQ(0, getsockopt(client_fd, SOL_SOCKET, SO_DOMAIN, &addr_family,
				&opt_len));
	opt_len = sizeof(peer_addr);
	has_remote_port = (getpeername(client_fd, (struct sockaddr *)&peer_addr,
				       &opt_len) == 0);
	needs_autobind = (addr_family == AF_INET || addr_family == AF_INET6) &&
			 get_binded_port(client_fd, prot) == 0;

	/* First, check error code with truncated explicit address. */
	if (srv != NULL) {
		ret = sendto_variant_addrlen(
			client_fd, srv, get_addrlen(srv, true) - 1, "A", 1, 0);
		if (sock_type == SOCK_STREAM && !has_remote_port) {
			EXPECT_EQ(-EPIPE, ret)
			{
				return -1;
			}
		} else if (bind_denied && needs_autobind) {
			EXPECT_EQ(-EACCES, ret)
			{
				return -1;
			}
		} else {
			EXPECT_EQ(-EINVAL, ret)

Annotation

Implementation Notes