Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  1// SPDX-License-Identifier: GPL-2.0
  2#include <test_progs.h>
  3#include "bind_perm.skel.h"
  4
  5#include <sys/types.h>
  6#include <sys/socket.h>
  7#include <sys/capability.h>
  8
  9static int duration;
 10
 11void try_bind(int family, int port, int expected_errno)
 12{
 13	struct sockaddr_storage addr = {};
 14	struct sockaddr_in6 *sin6;
 15	struct sockaddr_in *sin;
 16	int fd = -1;
 17
 18	fd = socket(family, SOCK_STREAM, 0);
 19	if (CHECK(fd < 0, "fd", "errno %d", errno))
 20		goto close_socket;
 21
 22	if (family == AF_INET) {
 23		sin = (struct sockaddr_in *)&addr;
 24		sin->sin_family = family;
 25		sin->sin_port = htons(port);
 26	} else {
 27		sin6 = (struct sockaddr_in6 *)&addr;
 28		sin6->sin6_family = family;
 29		sin6->sin6_port = htons(port);
 30	}
 31
 32	errno = 0;
 33	bind(fd, (struct sockaddr *)&addr, sizeof(addr));
 34	ASSERT_EQ(errno, expected_errno, "bind");
 35
 36close_socket:
 37	if (fd >= 0)
 38		close(fd);
 39}
 40
 41bool cap_net_bind_service(cap_flag_value_t flag)
 42{
 43	const cap_value_t cap_net_bind_service = CAP_NET_BIND_SERVICE;
 44	cap_flag_value_t original_value;
 45	bool was_effective = false;
 46	cap_t caps;
 47
 48	caps = cap_get_proc();
 49	if (CHECK(!caps, "cap_get_proc", "errno %d", errno))
 50		goto free_caps;
 51
 52	if (CHECK(cap_get_flag(caps, CAP_NET_BIND_SERVICE, CAP_EFFECTIVE,
 53			       &original_value),
 54		  "cap_get_flag", "errno %d", errno))
 55		goto free_caps;
 56
 57	was_effective = (original_value == CAP_SET);
 58
 59	if (CHECK(cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_net_bind_service,
 60			       flag),
 61		  "cap_set_flag", "errno %d", errno))
 62		goto free_caps;
 63
 64	if (CHECK(cap_set_proc(caps), "cap_set_proc", "errno %d", errno))
 65		goto free_caps;
 66
 67free_caps:
 68	CHECK(cap_free(caps), "cap_free", "errno %d", errno);
 69	return was_effective;
 70}
 71
 72void test_bind_perm(void)
 73{
 74	bool cap_was_effective;
 75	struct bind_perm *skel;
 76	int cgroup_fd;
 77
 78	cgroup_fd = test__join_cgroup("/bind_perm");
 79	if (CHECK(cgroup_fd < 0, "cg-join", "errno %d", errno))
 80		return;
 81
 82	skel = bind_perm__open_and_load();
 83	if (!ASSERT_OK_PTR(skel, "skel"))
 84		goto close_cgroup_fd;
 85
 86	skel->links.bind_v4_prog = bpf_program__attach_cgroup(skel->progs.bind_v4_prog, cgroup_fd);
 87	if (!ASSERT_OK_PTR(skel, "bind_v4_prog"))
 88		goto close_skeleton;
 89
 90	skel->links.bind_v6_prog = bpf_program__attach_cgroup(skel->progs.bind_v6_prog, cgroup_fd);
 91	if (!ASSERT_OK_PTR(skel, "bind_v6_prog"))
 92		goto close_skeleton;
 93
 94	cap_was_effective = cap_net_bind_service(CAP_CLEAR);
 95
 96	try_bind(AF_INET, 110, EACCES);
 97	try_bind(AF_INET6, 110, EACCES);
 98
 99	try_bind(AF_INET, 111, 0);
100	try_bind(AF_INET6, 111, 0);
101
102	if (cap_was_effective)
103		cap_net_bind_service(CAP_SET);
104
105close_skeleton:
106	bind_perm__destroy(skel);
107close_cgroup_fd:
108	close(cgroup_fd);
109}