3
0
mirror of https://github.com/Qortal/Brooklyn.git synced 2025-01-30 14:52:17 +00:00

If you are friends with T3Q or Mike, you need a prostate exam

This commit is contained in:
Scare Crowe 2021-11-02 22:34:48 +05:00
parent 159f821fa8
commit 443f7c2f4b
14 changed files with 460 additions and 65 deletions

View File

@ -742,7 +742,7 @@ class DebugfsProvider(Provider):
The fields are all available KVM debugfs files
"""
exempt_list = ['halt_poll_fail_ns', 'halt_poll_success_ns']
exempt_list = ['halt_poll_fail_ns', 'halt_poll_success_ns', 'halt_wait_ns']
fields = [field for field in self.walkdir(PATH_DEBUGFS_KVM)[2]
if field not in exempt_list]

View File

@ -949,7 +949,6 @@ static void redir_to_connected(int family, int sotype, int sock_mapfd,
int err, n;
u32 key;
char b;
int retries = 100;
zero_verdict_count(verd_mapfd);
@ -1002,17 +1001,11 @@ static void redir_to_connected(int family, int sotype, int sock_mapfd,
goto close_peer1;
if (pass != 1)
FAIL("%s: want pass count 1, have %d", log_prefix, pass);
again:
n = read(c0, &b, 1);
if (n < 0) {
if (errno == EAGAIN && retries--) {
usleep(1000);
goto again;
}
FAIL_ERRNO("%s: read", log_prefix);
}
n = recv_timeout(c0, &b, 1, 0, IO_TIMEOUT_SEC);
if (n < 0)
FAIL_ERRNO("%s: recv_timeout", log_prefix);
if (n == 0)
FAIL("%s: incomplete read", log_prefix);
FAIL("%s: incomplete recv", log_prefix);
close_peer1:
xclose(p1);
@ -1571,7 +1564,6 @@ static void unix_redir_to_connected(int sotype, int sock_mapfd,
const char *log_prefix = redir_mode_str(mode);
int c0, c1, p0, p1;
unsigned int pass;
int retries = 100;
int err, n;
int sfd[2];
u32 key;
@ -1606,17 +1598,11 @@ static void unix_redir_to_connected(int sotype, int sock_mapfd,
if (pass != 1)
FAIL("%s: want pass count 1, have %d", log_prefix, pass);
again:
n = read(mode == REDIR_INGRESS ? p0 : c0, &b, 1);
if (n < 0) {
if (errno == EAGAIN && retries--) {
usleep(1000);
goto again;
}
FAIL_ERRNO("%s: read", log_prefix);
}
n = recv_timeout(mode == REDIR_INGRESS ? p0 : c0, &b, 1, 0, IO_TIMEOUT_SEC);
if (n < 0)
FAIL_ERRNO("%s: recv_timeout", log_prefix);
if (n == 0)
FAIL("%s: incomplete read", log_prefix);
FAIL("%s: incomplete recv", log_prefix);
close:
xclose(c1);
@ -1748,7 +1734,6 @@ static void udp_redir_to_connected(int family, int sock_mapfd, int verd_mapfd,
const char *log_prefix = redir_mode_str(mode);
int c0, c1, p0, p1;
unsigned int pass;
int retries = 100;
int err, n;
u32 key;
char b;
@ -1781,17 +1766,11 @@ static void udp_redir_to_connected(int family, int sock_mapfd, int verd_mapfd,
if (pass != 1)
FAIL("%s: want pass count 1, have %d", log_prefix, pass);
again:
n = read(mode == REDIR_INGRESS ? p0 : c0, &b, 1);
if (n < 0) {
if (errno == EAGAIN && retries--) {
usleep(1000);
goto again;
}
FAIL_ERRNO("%s: read", log_prefix);
}
n = recv_timeout(mode == REDIR_INGRESS ? p0 : c0, &b, 1, 0, IO_TIMEOUT_SEC);
if (n < 0)
FAIL_ERRNO("%s: recv_timeout", log_prefix);
if (n == 0)
FAIL("%s: incomplete read", log_prefix);
FAIL("%s: incomplete recv", log_prefix);
close_cli1:
xclose(c1);
@ -1841,7 +1820,6 @@ static void inet_unix_redir_to_connected(int family, int type, int sock_mapfd,
const char *log_prefix = redir_mode_str(mode);
int c0, c1, p0, p1;
unsigned int pass;
int retries = 100;
int err, n;
int sfd[2];
u32 key;
@ -1876,17 +1854,11 @@ static void inet_unix_redir_to_connected(int family, int type, int sock_mapfd,
if (pass != 1)
FAIL("%s: want pass count 1, have %d", log_prefix, pass);
again:
n = read(mode == REDIR_INGRESS ? p0 : c0, &b, 1);
if (n < 0) {
if (errno == EAGAIN && retries--) {
usleep(1000);
goto again;
}
FAIL_ERRNO("%s: read", log_prefix);
}
n = recv_timeout(mode == REDIR_INGRESS ? p0 : c0, &b, 1, 0, IO_TIMEOUT_SEC);
if (n < 0)
FAIL_ERRNO("%s: recv_timeout", log_prefix);
if (n == 0)
FAIL("%s: incomplete read", log_prefix);
FAIL("%s: incomplete recv", log_prefix);
close_cli1:
xclose(c1);
@ -1932,7 +1904,6 @@ static void unix_inet_redir_to_connected(int family, int type, int sock_mapfd,
int sfd[2];
u32 key;
char b;
int retries = 100;
zero_verdict_count(verd_mapfd);
@ -1963,17 +1934,11 @@ static void unix_inet_redir_to_connected(int family, int type, int sock_mapfd,
if (pass != 1)
FAIL("%s: want pass count 1, have %d", log_prefix, pass);
again:
n = read(mode == REDIR_INGRESS ? p0 : c0, &b, 1);
if (n < 0) {
if (errno == EAGAIN && retries--) {
usleep(1000);
goto again;
}
FAIL_ERRNO("%s: read", log_prefix);
}
n = recv_timeout(mode == REDIR_INGRESS ? p0 : c0, &b, 1, 0, IO_TIMEOUT_SEC);
if (n < 0)
FAIL_ERRNO("%s: recv_timeout", log_prefix);
if (n == 0)
FAIL("%s: incomplete read", log_prefix);
FAIL("%s: incomplete recv", log_prefix);
close:
xclose(c1);

View File

@ -43,3 +43,4 @@ CONFIG_NET_ACT_TUNNEL_KEY=m
CONFIG_NET_ACT_MIRRED=m
CONFIG_BAREUDP=m
CONFIG_IPV6_IOAM6_LWTUNNEL=y
CONFIG_CRYPTO_SM4=y

View File

@ -289,6 +289,12 @@ set_sysctl()
run_cmd sysctl -q -w $*
}
# get sysctl values in NS-A
get_sysctl()
{
${NSA_CMD} sysctl -n $*
}
################################################################################
# Setup for tests
@ -439,10 +445,13 @@ cleanup()
ip -netns ${NSA} link set dev ${NSA_DEV} down
ip -netns ${NSA} link del dev ${NSA_DEV}
ip netns pids ${NSA} | xargs kill 2>/dev/null
ip netns del ${NSA}
fi
ip netns pids ${NSB} | xargs kill 2>/dev/null
ip netns del ${NSB}
ip netns pids ${NSC} | xargs kill 2>/dev/null
ip netns del ${NSC} >/dev/null 2>&1
}
@ -1003,6 +1012,60 @@ ipv4_tcp_md5()
run_cmd nettest -s -I ${NSA_DEV} -M ${MD5_PW} -m ${NS_NET}
log_test $? 1 "MD5: VRF: Device must be a VRF - prefix"
test_ipv4_md5_vrf__vrf_server__no_bind_ifindex
test_ipv4_md5_vrf__global_server__bind_ifindex0
}
test_ipv4_md5_vrf__vrf_server__no_bind_ifindex()
{
log_start
show_hint "Simulates applications using VRF without TCP_MD5SIG_FLAG_IFINDEX"
run_cmd nettest -s -I ${VRF} -M ${MD5_PW} -m ${NS_NET} --no-bind-key-ifindex &
sleep 1
run_cmd_nsb nettest -r ${NSA_IP} -X ${MD5_PW}
log_test $? 0 "MD5: VRF: VRF-bound server, unbound key accepts connection"
log_start
show_hint "Binding both the socket and the key is not required but it works"
run_cmd nettest -s -I ${VRF} -M ${MD5_PW} -m ${NS_NET} --force-bind-key-ifindex &
sleep 1
run_cmd_nsb nettest -r ${NSA_IP} -X ${MD5_PW}
log_test $? 0 "MD5: VRF: VRF-bound server, bound key accepts connection"
}
test_ipv4_md5_vrf__global_server__bind_ifindex0()
{
# This particular test needs tcp_l3mdev_accept=1 for Global server to accept VRF connections
local old_tcp_l3mdev_accept
old_tcp_l3mdev_accept=$(get_sysctl net.ipv4.tcp_l3mdev_accept)
set_sysctl net.ipv4.tcp_l3mdev_accept=1
log_start
run_cmd nettest -s -M ${MD5_PW} -m ${NS_NET} --force-bind-key-ifindex &
sleep 1
run_cmd_nsb nettest -r ${NSA_IP} -X ${MD5_PW}
log_test $? 2 "MD5: VRF: Global server, Key bound to ifindex=0 rejects VRF connection"
log_start
run_cmd nettest -s -M ${MD5_PW} -m ${NS_NET} --force-bind-key-ifindex &
sleep 1
run_cmd_nsc nettest -r ${NSA_IP} -X ${MD5_PW}
log_test $? 0 "MD5: VRF: Global server, key bound to ifindex=0 accepts non-VRF connection"
log_start
run_cmd nettest -s -M ${MD5_PW} -m ${NS_NET} --no-bind-key-ifindex &
sleep 1
run_cmd_nsb nettest -r ${NSA_IP} -X ${MD5_PW}
log_test $? 0 "MD5: VRF: Global server, key not bound to ifindex accepts VRF connection"
log_start
run_cmd nettest -s -M ${MD5_PW} -m ${NS_NET} --no-bind-key-ifindex &
sleep 1
run_cmd_nsc nettest -r ${NSA_IP} -X ${MD5_PW}
log_test $? 0 "MD5: VRF: Global server, key not bound to ifindex accepts non-VRF connection"
# restore value
set_sysctl net.ipv4.tcp_l3mdev_accept="$old_tcp_l3mdev_accept"
}
ipv4_tcp_novrf()

View File

@ -9,6 +9,7 @@ TEST_PROGS = bridge_igmp.sh \
gre_inner_v4_multipath.sh \
gre_inner_v6_multipath.sh \
gre_multipath.sh \
ip6_forward_instats_vrf.sh \
ip6gre_inner_v4_multipath.sh \
ip6gre_inner_v6_multipath.sh \
ipip_flat_gre_key.sh \

View File

@ -39,3 +39,5 @@ NETIF_CREATE=yes
# Timeout (in seconds) before ping exits regardless of how many packets have
# been sent or received
PING_TIMEOUT=5
# IPv6 traceroute utility name.
TROUTE6=traceroute6

View File

@ -0,0 +1,172 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Test ipv6 stats on the incoming if when forwarding with VRF
ALL_TESTS="
ipv6_ping
ipv6_in_too_big_err
ipv6_in_hdr_err
ipv6_in_addr_err
ipv6_in_discard
"
NUM_NETIFS=4
source lib.sh
h1_create()
{
simple_if_init $h1 2001:1:1::2/64
ip -6 route add vrf v$h1 2001:1:2::/64 via 2001:1:1::1
}
h1_destroy()
{
ip -6 route del vrf v$h1 2001:1:2::/64 via 2001:1:1::1
simple_if_fini $h1 2001:1:1::2/64
}
router_create()
{
vrf_create router
__simple_if_init $rtr1 router 2001:1:1::1/64
__simple_if_init $rtr2 router 2001:1:2::1/64
mtu_set $rtr2 1280
}
router_destroy()
{
mtu_restore $rtr2
__simple_if_fini $rtr2 2001:1:2::1/64
__simple_if_fini $rtr1 2001:1:1::1/64
vrf_destroy router
}
h2_create()
{
simple_if_init $h2 2001:1:2::2/64
ip -6 route add vrf v$h2 2001:1:1::/64 via 2001:1:2::1
mtu_set $h2 1280
}
h2_destroy()
{
mtu_restore $h2
ip -6 route del vrf v$h2 2001:1:1::/64 via 2001:1:2::1
simple_if_fini $h2 2001:1:2::2/64
}
setup_prepare()
{
h1=${NETIFS[p1]}
rtr1=${NETIFS[p2]}
rtr2=${NETIFS[p3]}
h2=${NETIFS[p4]}
vrf_prepare
h1_create
router_create
h2_create
forwarding_enable
}
cleanup()
{
pre_cleanup
forwarding_restore
h2_destroy
router_destroy
h1_destroy
vrf_cleanup
}
ipv6_in_too_big_err()
{
RET=0
local t0=$(ipv6_stats_get $rtr1 Ip6InTooBigErrors)
local vrf_name=$(master_name_get $h1)
# Send too big packets
ip vrf exec $vrf_name \
$PING6 -s 1300 2001:1:2::2 -c 1 -w $PING_TIMEOUT &> /dev/null
local t1=$(ipv6_stats_get $rtr1 Ip6InTooBigErrors)
test "$((t1 - t0))" -ne 0
check_err $?
log_test "Ip6InTooBigErrors"
}
ipv6_in_hdr_err()
{
RET=0
local t0=$(ipv6_stats_get $rtr1 Ip6InHdrErrors)
local vrf_name=$(master_name_get $h1)
# Send packets with hop limit 1, easiest with traceroute6 as some ping6
# doesn't allow hop limit to be specified
ip vrf exec $vrf_name \
$TROUTE6 2001:1:2::2 &> /dev/null
local t1=$(ipv6_stats_get $rtr1 Ip6InHdrErrors)
test "$((t1 - t0))" -ne 0
check_err $?
log_test "Ip6InHdrErrors"
}
ipv6_in_addr_err()
{
RET=0
local t0=$(ipv6_stats_get $rtr1 Ip6InAddrErrors)
local vrf_name=$(master_name_get $h1)
# Disable forwarding temporary while sending the packet
sysctl -qw net.ipv6.conf.all.forwarding=0
ip vrf exec $vrf_name \
$PING6 2001:1:2::2 -c 1 -w $PING_TIMEOUT &> /dev/null
sysctl -qw net.ipv6.conf.all.forwarding=1
local t1=$(ipv6_stats_get $rtr1 Ip6InAddrErrors)
test "$((t1 - t0))" -ne 0
check_err $?
log_test "Ip6InAddrErrors"
}
ipv6_in_discard()
{
RET=0
local t0=$(ipv6_stats_get $rtr1 Ip6InDiscards)
local vrf_name=$(master_name_get $h1)
# Add a policy to discard
ip xfrm policy add dst 2001:1:2::2/128 dir fwd action block
ip vrf exec $vrf_name \
$PING6 2001:1:2::2 -c 1 -w $PING_TIMEOUT &> /dev/null
ip xfrm policy del dst 2001:1:2::2/128 dir fwd
local t1=$(ipv6_stats_get $rtr1 Ip6InDiscards)
test "$((t1 - t0))" -ne 0
check_err $?
log_test "Ip6InDiscards"
}
ipv6_ping()
{
RET=0
ping6_test $h1 2001:1:2::2
}
trap cleanup EXIT
setup_prepare
setup_wait
tests_run
exit $EXIT_STATUS

View File

@ -751,6 +751,14 @@ qdisc_parent_stats_get()
| jq '.[] | select(.parent == "'"$parent"'") | '"$selector"
}
ipv6_stats_get()
{
local dev=$1; shift
local stat=$1; shift
cat /proc/net/dev_snmp6/$dev | grep "^$stat" | cut -f2
}
humanize()
{
local speed=$1; shift

View File

@ -28,6 +28,7 @@
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include <getopt.h>
#include <linux/xfrm.h>
#include <linux/ipsec.h>
@ -101,6 +102,8 @@ struct sock_args {
struct sockaddr_in6 v6;
} md5_prefix;
unsigned int prefix_len;
/* 0: default, -1: force off, +1: force on */
int bind_key_ifindex;
/* expected addresses and device index for connection */
const char *expected_dev;
@ -271,11 +274,14 @@ static int tcp_md5sig(int sd, void *addr, socklen_t alen, struct sock_args *args
}
memcpy(&md5sig.tcpm_addr, addr, alen);
if (args->ifindex) {
if ((args->ifindex && args->bind_key_ifindex >= 0) || args->bind_key_ifindex >= 1) {
opt = TCP_MD5SIG_EXT;
md5sig.tcpm_flags |= TCP_MD5SIG_FLAG_IFINDEX;
md5sig.tcpm_ifindex = args->ifindex;
log_msg("TCP_MD5SIG_FLAG_IFINDEX set tcpm_ifindex=%d\n", md5sig.tcpm_ifindex);
} else {
log_msg("TCP_MD5SIG_FLAG_IFINDEX off\n", md5sig.tcpm_ifindex);
}
rc = setsockopt(sd, IPPROTO_TCP, opt, &md5sig, sizeof(md5sig));
@ -1822,6 +1828,14 @@ static int ipc_parent(int cpid, int fd, struct sock_args *args)
}
#define GETOPT_STR "sr:l:c:p:t:g:P:DRn:M:X:m:d:I:BN:O:SCi6xL:0:1:2:3:Fbq"
#define OPT_FORCE_BIND_KEY_IFINDEX 1001
#define OPT_NO_BIND_KEY_IFINDEX 1002
static struct option long_opts[] = {
{"force-bind-key-ifindex", 0, 0, OPT_FORCE_BIND_KEY_IFINDEX},
{"no-bind-key-ifindex", 0, 0, OPT_NO_BIND_KEY_IFINDEX},
{0, 0, 0, 0}
};
static void print_usage(char *prog)
{
@ -1858,6 +1872,10 @@ static void print_usage(char *prog)
" -M password use MD5 sum protection\n"
" -X password MD5 password for client mode\n"
" -m prefix/len prefix and length to use for MD5 key\n"
" --no-bind-key-ifindex: Force TCP_MD5SIG_FLAG_IFINDEX off\n"
" --force-bind-key-ifindex: Force TCP_MD5SIG_FLAG_IFINDEX on\n"
" (default: only if -I is passed)\n"
"\n"
" -g grp multicast group (e.g., 239.1.1.1)\n"
" -i interactive mode (default is echo and terminate)\n"
"\n"
@ -1893,7 +1911,7 @@ int main(int argc, char *argv[])
* process input args
*/
while ((rc = getopt(argc, argv, GETOPT_STR)) != -1) {
while ((rc = getopt_long(argc, argv, GETOPT_STR, long_opts, NULL)) != -1) {
switch (rc) {
case 'B':
both_mode = 1;
@ -1966,6 +1984,12 @@ int main(int argc, char *argv[])
case 'M':
args.password = optarg;
break;
case OPT_FORCE_BIND_KEY_IFINDEX:
args.bind_key_ifindex = 1;
break;
case OPT_NO_BIND_KEY_IFINDEX:
args.bind_key_ifindex = -1;
break;
case 'X':
args.client_pw = optarg;
break;

View File

@ -199,7 +199,6 @@ fi
# test basic connectivity
if ! ip netns exec ns1 ping -c 1 -q 10.0.2.99 > /dev/null; then
echo "ERROR: ns1 cannot reach ns2" 1>&2
bash
exit 1
fi

View File

@ -741,6 +741,149 @@ EOF
return $lret
}
# test port shadowing.
# create two listening services, one on router (ns0), one
# on client (ns2), which is masqueraded from ns1 point of view.
# ns2 sends udp packet coming from service port to ns1, on a highport.
# Later, if n1 uses same highport to connect to ns0:service, packet
# might be port-forwarded to ns2 instead.
# second argument tells if we expect the 'fake-entry' to take effect
# (CLIENT) or not (ROUTER).
test_port_shadow()
{
local test=$1
local expect=$2
local daddrc="10.0.1.99"
local daddrs="10.0.1.1"
local result=""
local logmsg=""
echo ROUTER | ip netns exec "$ns0" nc -w 5 -u -l -p 1405 >/dev/null 2>&1 &
nc_r=$!
echo CLIENT | ip netns exec "$ns2" nc -w 5 -u -l -p 1405 >/dev/null 2>&1 &
nc_c=$!
# make shadow entry, from client (ns2), going to (ns1), port 41404, sport 1405.
echo "fake-entry" | ip netns exec "$ns2" nc -w 1 -p 1405 -u "$daddrc" 41404 > /dev/null
# ns1 tries to connect to ns0:1405. With default settings this should connect
# to client, it matches the conntrack entry created above.
result=$(echo "" | ip netns exec "$ns1" nc -w 1 -p 41404 -u "$daddrs" 1405)
if [ "$result" = "$expect" ] ;then
echo "PASS: portshadow test $test: got reply from ${expect}${logmsg}"
else
echo "ERROR: portshadow test $test: got reply from \"$result\", not $expect as intended"
ret=1
fi
kill $nc_r $nc_c 2>/dev/null
# flush udp entries for next test round, if any
ip netns exec "$ns0" conntrack -F >/dev/null 2>&1
}
# This prevents port shadow of router service via packet filter,
# packets claiming to originate from service port from internal
# network are dropped.
test_port_shadow_filter()
{
local family=$1
ip netns exec "$ns0" nft -f /dev/stdin <<EOF
table $family filter {
chain forward {
type filter hook forward priority 0; policy accept;
meta iif veth1 udp sport 1405 drop
}
}
EOF
test_port_shadow "port-filter" "ROUTER"
ip netns exec "$ns0" nft delete table $family filter
}
# This prevents port shadow of router service via notrack.
test_port_shadow_notrack()
{
local family=$1
ip netns exec "$ns0" nft -f /dev/stdin <<EOF
table $family raw {
chain prerouting {
type filter hook prerouting priority -300; policy accept;
meta iif veth0 udp dport 1405 notrack
udp dport 1405 notrack
}
chain output {
type filter hook output priority -300; policy accept;
udp sport 1405 notrack
}
}
EOF
test_port_shadow "port-notrack" "ROUTER"
ip netns exec "$ns0" nft delete table $family raw
}
# This prevents port shadow of router service via sport remap.
test_port_shadow_pat()
{
local family=$1
ip netns exec "$ns0" nft -f /dev/stdin <<EOF
table $family pat {
chain postrouting {
type nat hook postrouting priority -1; policy accept;
meta iif veth1 udp sport <= 1405 masquerade to : 1406-65535 random
}
}
EOF
test_port_shadow "pat" "ROUTER"
ip netns exec "$ns0" nft delete table $family pat
}
test_port_shadowing()
{
local family="ip"
ip netns exec "$ns0" sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null
ip netns exec "$ns0" sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null
ip netns exec "$ns0" nft -f /dev/stdin <<EOF
table $family nat {
chain postrouting {
type nat hook postrouting priority 0; policy accept;
meta oif veth0 masquerade
}
}
EOF
if [ $? -ne 0 ]; then
echo "SKIP: Could not add add $family masquerade hook"
return $ksft_skip
fi
# test default behaviour. Packet from ns1 to ns0 is redirected to ns2.
test_port_shadow "default" "CLIENT"
# test packet filter based mitigation: prevent forwarding of
# packets claiming to come from the service port.
test_port_shadow_filter "$family"
# test conntrack based mitigation: connections going or coming
# from router:service bypass connection tracking.
test_port_shadow_notrack "$family"
# test nat based mitigation: fowarded packets coming from service port
# are masqueraded with random highport.
test_port_shadow_pat "$family"
ip netns exec "$ns0" nft delete table $family nat
}
# ip netns exec "$ns0" ping -c 1 -q 10.0.$i.99
for i in 0 1 2; do
@ -861,6 +1004,8 @@ reset_counters
$test_inet_nat && test_redirect inet
$test_inet_nat && test_redirect6 inet
test_port_shadowing
if [ $ret -ne 0 ];then
echo -n "FAIL: "
nft --version

View File

@ -341,7 +341,7 @@ void split_file_backed_thp(void)
}
/* write something to the file, so a file-backed THP can be allocated */
num_written = write(fd, tmpfs_loc, sizeof(tmpfs_loc));
num_written = write(fd, tmpfs_loc, strlen(tmpfs_loc) + 1);
close(fd);
if (num_written < 1) {

View File

@ -414,9 +414,6 @@ static void uffd_test_ctx_init_ext(uint64_t *features)
uffd_test_ops->allocate_area((void **)&area_src);
uffd_test_ops->allocate_area((void **)&area_dst);
uffd_test_ops->release_pages(area_src);
uffd_test_ops->release_pages(area_dst);
userfaultfd_open(features);
count_verify = malloc(nr_pages * sizeof(unsigned long long));
@ -437,6 +434,26 @@ static void uffd_test_ctx_init_ext(uint64_t *features)
*(area_count(area_src, nr) + 1) = 1;
}
/*
* After initialization of area_src, we must explicitly release pages
* for area_dst to make sure it's fully empty. Otherwise we could have
* some area_dst pages be errornously initialized with zero pages,
* hence we could hit memory corruption later in the test.
*
* One example is when THP is globally enabled, above allocate_area()
* calls could have the two areas merged into a single VMA (as they
* will have the same VMA flags so they're mergeable). When we
* initialize the area_src above, it's possible that some part of
* area_dst could have been faulted in via one huge THP that will be
* shared between area_src and area_dst. It could cause some of the
* area_dst won't be trapped by missing userfaults.
*
* This release_pages() will guarantee even if that happened, we'll
* proactively split the thp and drop any accidentally initialized
* pages within area_dst.
*/
uffd_test_ops->release_pages(area_dst);
pipefd = malloc(sizeof(int) * nr_cpus * 2);
if (!pipefd)
err("pipefd");

View File

@ -332,8 +332,6 @@ static void test_no_sockets(const struct test_opts *opts)
read_vsock_stat(&sockets);
check_no_sockets(&sockets);
free_sock_stat(&sockets);
}
static void test_listen_socket_server(const struct test_opts *opts)