|
20 | 20 | #include <sys/syscall.h>
|
21 | 21 | #include <sys/un.h>
|
22 | 22 |
|
| 23 | +#include "audit.h" |
23 | 24 | #include "common.h"
|
24 | 25 |
|
25 | 26 | const short sock_port_start = (1 << 10);
|
@@ -1868,4 +1869,135 @@ TEST_F(port_specific, bind_connect_1023)
|
1868 | 1869 | EXPECT_EQ(0, close(bind_fd));
|
1869 | 1870 | }
|
1870 | 1871 |
|
| 1872 | +static int matches_log_tcp(const int audit_fd, const char *const blockers, |
| 1873 | + const char *const dir_addr, const char *const addr, |
| 1874 | + const char *const dir_port) |
| 1875 | +{ |
| 1876 | + static const char log_template[] = REGEX_LANDLOCK_PREFIX |
| 1877 | + " blockers=%s %s=%s %s=1024$"; |
| 1878 | + /* |
| 1879 | + * Max strlen(blockers): 16 |
| 1880 | + * Max strlen(dir_addr): 5 |
| 1881 | + * Max strlen(addr): 12 |
| 1882 | + * Max strlen(dir_port): 4 |
| 1883 | + */ |
| 1884 | + char log_match[sizeof(log_template) + 37]; |
| 1885 | + int log_match_len; |
| 1886 | + |
| 1887 | + log_match_len = snprintf(log_match, sizeof(log_match), log_template, |
| 1888 | + blockers, dir_addr, addr, dir_port); |
| 1889 | + if (log_match_len > sizeof(log_match)) |
| 1890 | + return -E2BIG; |
| 1891 | + |
| 1892 | + return audit_match_record(audit_fd, AUDIT_LANDLOCK_ACCESS, log_match, |
| 1893 | + NULL); |
| 1894 | +} |
| 1895 | + |
| 1896 | +FIXTURE(audit) |
| 1897 | +{ |
| 1898 | + struct service_fixture srv0; |
| 1899 | + struct audit_filter audit_filter; |
| 1900 | + int audit_fd; |
| 1901 | +}; |
| 1902 | + |
| 1903 | +FIXTURE_VARIANT(audit) |
| 1904 | +{ |
| 1905 | + const char *const addr; |
| 1906 | + const struct protocol_variant prot; |
| 1907 | +}; |
| 1908 | + |
| 1909 | +/* clang-format off */ |
| 1910 | +FIXTURE_VARIANT_ADD(audit, ipv4) { |
| 1911 | + /* clang-format on */ |
| 1912 | + .addr = "127\\.0\\.0\\.1", |
| 1913 | + .prot = { |
| 1914 | + .domain = AF_INET, |
| 1915 | + .type = SOCK_STREAM, |
| 1916 | + }, |
| 1917 | +}; |
| 1918 | + |
| 1919 | +/* clang-format off */ |
| 1920 | +FIXTURE_VARIANT_ADD(audit, ipv6) { |
| 1921 | + /* clang-format on */ |
| 1922 | + .addr = "::1", |
| 1923 | + .prot = { |
| 1924 | + .domain = AF_INET6, |
| 1925 | + .type = SOCK_STREAM, |
| 1926 | + }, |
| 1927 | +}; |
| 1928 | + |
| 1929 | +FIXTURE_SETUP(audit) |
| 1930 | +{ |
| 1931 | + ASSERT_EQ(0, set_service(&self->srv0, variant->prot, 0)); |
| 1932 | + setup_loopback(_metadata); |
| 1933 | + |
| 1934 | + set_cap(_metadata, CAP_AUDIT_CONTROL); |
| 1935 | + self->audit_fd = audit_init_with_exe_filter(&self->audit_filter); |
| 1936 | + EXPECT_LE(0, self->audit_fd); |
| 1937 | + disable_caps(_metadata); |
| 1938 | +}; |
| 1939 | + |
| 1940 | +FIXTURE_TEARDOWN(audit) |
| 1941 | +{ |
| 1942 | + set_cap(_metadata, CAP_AUDIT_CONTROL); |
| 1943 | + EXPECT_EQ(0, audit_cleanup(self->audit_fd, &self->audit_filter)); |
| 1944 | + clear_cap(_metadata, CAP_AUDIT_CONTROL); |
| 1945 | +} |
| 1946 | + |
| 1947 | +TEST_F(audit, bind) |
| 1948 | +{ |
| 1949 | + const struct landlock_ruleset_attr ruleset_attr = { |
| 1950 | + .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | |
| 1951 | + LANDLOCK_ACCESS_NET_CONNECT_TCP, |
| 1952 | + }; |
| 1953 | + struct audit_records records; |
| 1954 | + int ruleset_fd, sock_fd; |
| 1955 | + |
| 1956 | + ruleset_fd = |
| 1957 | + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); |
| 1958 | + ASSERT_LE(0, ruleset_fd); |
| 1959 | + enforce_ruleset(_metadata, ruleset_fd); |
| 1960 | + EXPECT_EQ(0, close(ruleset_fd)); |
| 1961 | + |
| 1962 | + sock_fd = socket_variant(&self->srv0); |
| 1963 | + ASSERT_LE(0, sock_fd); |
| 1964 | + EXPECT_EQ(-EACCES, bind_variant(sock_fd, &self->srv0)); |
| 1965 | + EXPECT_EQ(0, matches_log_tcp(self->audit_fd, "net\\.bind_tcp", "saddr", |
| 1966 | + variant->addr, "src")); |
| 1967 | + |
| 1968 | + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); |
| 1969 | + EXPECT_EQ(0, records.access); |
| 1970 | + EXPECT_EQ(1, records.domain); |
| 1971 | + |
| 1972 | + EXPECT_EQ(0, close(sock_fd)); |
| 1973 | +} |
| 1974 | + |
| 1975 | +TEST_F(audit, connect) |
| 1976 | +{ |
| 1977 | + const struct landlock_ruleset_attr ruleset_attr = { |
| 1978 | + .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | |
| 1979 | + LANDLOCK_ACCESS_NET_CONNECT_TCP, |
| 1980 | + }; |
| 1981 | + struct audit_records records; |
| 1982 | + int ruleset_fd, sock_fd; |
| 1983 | + |
| 1984 | + ruleset_fd = |
| 1985 | + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); |
| 1986 | + ASSERT_LE(0, ruleset_fd); |
| 1987 | + enforce_ruleset(_metadata, ruleset_fd); |
| 1988 | + EXPECT_EQ(0, close(ruleset_fd)); |
| 1989 | + |
| 1990 | + sock_fd = socket_variant(&self->srv0); |
| 1991 | + ASSERT_LE(0, sock_fd); |
| 1992 | + EXPECT_EQ(-EACCES, connect_variant(sock_fd, &self->srv0)); |
| 1993 | + EXPECT_EQ(0, matches_log_tcp(self->audit_fd, "net\\.connect_tcp", |
| 1994 | + "daddr", variant->addr, "dest")); |
| 1995 | + |
| 1996 | + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); |
| 1997 | + EXPECT_EQ(0, records.access); |
| 1998 | + EXPECT_EQ(1, records.domain); |
| 1999 | + |
| 2000 | + EXPECT_EQ(0, close(sock_fd)); |
| 2001 | +} |
| 2002 | + |
1871 | 2003 | TEST_HARNESS_MAIN
|
0 commit comments