Skip to content

Commit 5238754

Browse files
committed
Merge branch 'netconsole-selftest-for-userdata-overflow'
Breno Leitao says: ==================== netconsole: selftest for userdata overflow Implement comprehensive testing for netconsole userdata entry handling, demonstrating correct behavior when creating maximum entries and preventing unauthorized overflow. Refactor existing test infrastructure to support modular, reusable helper functions that validate strict entry limit enforcement. Also, add a warning if update_userdata() sees more than MAX_USERDATA_ITEMS entries. This shouldn't happen and it is a bug that shouldn't be silently ignored. v2: https://lore.kernel.org/[email protected] v1: https://lore.kernel.org/[email protected] ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 14ea4cd + daea6d2 commit 5238754

File tree

6 files changed

+298
-219
lines changed

6 files changed

+298
-219
lines changed

MAINTAINERS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16170,7 +16170,8 @@ M: Breno Leitao <[email protected]>
1617016170
S: Maintained
1617116171
F: Documentation/networking/netconsole.rst
1617216172
F: drivers/net/netconsole.c
16173-
F: tools/testing/selftests/drivers/net/netcons_basic.sh
16173+
F: tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
16174+
F: tools/testing/selftests/drivers/net/netcons\*
1617416175

1617516176
NETDEVSIM
1617616177
M: Jakub Kicinski <[email protected]>

drivers/net/netconsole.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ static void update_userdata(struct netconsole_target *nt)
730730
struct userdatum *udm_item;
731731
struct config_item *item;
732732

733-
if (child_count >= MAX_USERDATA_ITEMS)
733+
if (WARN_ON_ONCE(child_count >= MAX_USERDATA_ITEMS))
734734
break;
735735
child_count++;
736736

tools/testing/selftests/drivers/net/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
# SPDX-License-Identifier: GPL-2.0
22

33
TEST_INCLUDES := $(wildcard lib/py/*.py) \
4+
$(wildcard lib/sh/*.sh) \
45
../../net/net_helper.sh \
56
../../net/lib.sh \
67

78
TEST_PROGS := \
89
netcons_basic.sh \
10+
netcons_overflow.sh \
911
ping.py \
1012
queues.py \
1113
stats.py \
Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
#!/usr/bin/env bash
2+
# SPDX-License-Identifier: GPL-2.0
3+
4+
# This file contains functions and helpers to support the netconsole
5+
# selftests
6+
#
7+
# Author: Breno Leitao <[email protected]>
8+
9+
set -euo pipefail
10+
11+
LIBDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")")
12+
13+
SRCIF="" # to be populated later
14+
SRCIP=192.0.2.1
15+
DSTIF="" # to be populated later
16+
DSTIP=192.0.2.2
17+
18+
PORT="6666"
19+
MSG="netconsole selftest"
20+
USERDATA_KEY="key"
21+
USERDATA_VALUE="value"
22+
TARGET=$(mktemp -u netcons_XXXXX)
23+
DEFAULT_PRINTK_VALUES=$(cat /proc/sys/kernel/printk)
24+
NETCONS_CONFIGFS="/sys/kernel/config/netconsole"
25+
NETCONS_PATH="${NETCONS_CONFIGFS}"/"${TARGET}"
26+
# NAMESPACE will be populated by setup_ns with a random value
27+
NAMESPACE=""
28+
29+
# IDs for netdevsim
30+
NSIM_DEV_1_ID=$((256 + RANDOM % 256))
31+
NSIM_DEV_2_ID=$((512 + RANDOM % 256))
32+
NSIM_DEV_SYS_NEW="/sys/bus/netdevsim/new_device"
33+
34+
# Used to create and delete namespaces
35+
source "${LIBDIR}"/../../../../net/lib.sh
36+
source "${LIBDIR}"/../../../../net/net_helper.sh
37+
38+
# Create netdevsim interfaces
39+
create_ifaces() {
40+
41+
echo "$NSIM_DEV_2_ID" > "$NSIM_DEV_SYS_NEW"
42+
echo "$NSIM_DEV_1_ID" > "$NSIM_DEV_SYS_NEW"
43+
udevadm settle 2> /dev/null || true
44+
45+
local NSIM1=/sys/bus/netdevsim/devices/netdevsim"$NSIM_DEV_1_ID"
46+
local NSIM2=/sys/bus/netdevsim/devices/netdevsim"$NSIM_DEV_2_ID"
47+
48+
# These are global variables
49+
SRCIF=$(find "$NSIM1"/net -maxdepth 1 -type d ! \
50+
-path "$NSIM1"/net -exec basename {} \;)
51+
DSTIF=$(find "$NSIM2"/net -maxdepth 1 -type d ! \
52+
-path "$NSIM2"/net -exec basename {} \;)
53+
}
54+
55+
link_ifaces() {
56+
local NSIM_DEV_SYS_LINK="/sys/bus/netdevsim/link_device"
57+
local SRCIF_IFIDX=$(cat /sys/class/net/"$SRCIF"/ifindex)
58+
local DSTIF_IFIDX=$(cat /sys/class/net/"$DSTIF"/ifindex)
59+
60+
exec {NAMESPACE_FD}</var/run/netns/"${NAMESPACE}"
61+
exec {INITNS_FD}</proc/self/ns/net
62+
63+
# Bind the dst interface to namespace
64+
ip link set "${DSTIF}" netns "${NAMESPACE}"
65+
66+
# Linking one device to the other one (on the other namespace}
67+
if ! echo "${INITNS_FD}:$SRCIF_IFIDX $NAMESPACE_FD:$DSTIF_IFIDX" > $NSIM_DEV_SYS_LINK
68+
then
69+
echo "linking netdevsim1 with netdevsim2 should succeed"
70+
cleanup
71+
exit "${ksft_skip}"
72+
fi
73+
}
74+
75+
function configure_ip() {
76+
# Configure the IPs for both interfaces
77+
ip netns exec "${NAMESPACE}" ip addr add "${DSTIP}"/24 dev "${DSTIF}"
78+
ip netns exec "${NAMESPACE}" ip link set "${DSTIF}" up
79+
80+
ip addr add "${SRCIP}"/24 dev "${SRCIF}"
81+
ip link set "${SRCIF}" up
82+
}
83+
84+
function set_network() {
85+
# setup_ns function is coming from lib.sh
86+
setup_ns NAMESPACE
87+
88+
# Create both interfaces, and assign the destination to a different
89+
# namespace
90+
create_ifaces
91+
92+
# Link both interfaces back to back
93+
link_ifaces
94+
95+
configure_ip
96+
}
97+
98+
function create_dynamic_target() {
99+
DSTMAC=$(ip netns exec "${NAMESPACE}" \
100+
ip link show "${DSTIF}" | awk '/ether/ {print $2}')
101+
102+
# Create a dynamic target
103+
mkdir "${NETCONS_PATH}"
104+
105+
echo "${DSTIP}" > "${NETCONS_PATH}"/remote_ip
106+
echo "${SRCIP}" > "${NETCONS_PATH}"/local_ip
107+
echo "${DSTMAC}" > "${NETCONS_PATH}"/remote_mac
108+
echo "${SRCIF}" > "${NETCONS_PATH}"/dev_name
109+
110+
echo 1 > "${NETCONS_PATH}"/enabled
111+
}
112+
113+
function cleanup() {
114+
local NSIM_DEV_SYS_DEL="/sys/bus/netdevsim/del_device"
115+
116+
# delete netconsole dynamic reconfiguration
117+
echo 0 > "${NETCONS_PATH}"/enabled
118+
# Remove all the keys that got created during the selftest
119+
find "${NETCONS_PATH}/userdata/" -mindepth 1 -type d -delete
120+
# Remove the configfs entry
121+
rmdir "${NETCONS_PATH}"
122+
123+
# Delete netdevsim devices
124+
echo "$NSIM_DEV_2_ID" > "$NSIM_DEV_SYS_DEL"
125+
echo "$NSIM_DEV_1_ID" > "$NSIM_DEV_SYS_DEL"
126+
127+
# this is coming from lib.sh
128+
cleanup_all_ns
129+
130+
# Restoring printk configurations
131+
echo "${DEFAULT_PRINTK_VALUES}" > /proc/sys/kernel/printk
132+
}
133+
134+
function set_user_data() {
135+
if [[ ! -d "${NETCONS_PATH}""/userdata" ]]
136+
then
137+
echo "Userdata path not available in ${NETCONS_PATH}/userdata"
138+
exit "${ksft_skip}"
139+
fi
140+
141+
KEY_PATH="${NETCONS_PATH}/userdata/${USERDATA_KEY}"
142+
mkdir -p "${KEY_PATH}"
143+
VALUE_PATH="${KEY_PATH}""/value"
144+
echo "${USERDATA_VALUE}" > "${VALUE_PATH}"
145+
}
146+
147+
function listen_port_and_save_to() {
148+
local OUTPUT=${1}
149+
# Just wait for 2 seconds
150+
timeout 2 ip netns exec "${NAMESPACE}" \
151+
socat UDP-LISTEN:"${PORT}",fork "${OUTPUT}"
152+
}
153+
154+
function validate_result() {
155+
local TMPFILENAME="$1"
156+
157+
# TMPFILENAME will contain something like:
158+
# 6.11.1-0_fbk0_rc13_509_g30d75cea12f7,13,1822,115075213798,-;netconsole selftest: netcons_gtJHM
159+
# key=value
160+
161+
# Check if the file exists
162+
if [ ! -f "$TMPFILENAME" ]; then
163+
echo "FAIL: File was not generated." >&2
164+
exit "${ksft_fail}"
165+
fi
166+
167+
if ! grep -q "${MSG}" "${TMPFILENAME}"; then
168+
echo "FAIL: ${MSG} not found in ${TMPFILENAME}" >&2
169+
cat "${TMPFILENAME}" >&2
170+
exit "${ksft_fail}"
171+
fi
172+
173+
if ! grep -q "${USERDATA_KEY}=${USERDATA_VALUE}" "${TMPFILENAME}"; then
174+
echo "FAIL: ${USERDATA_KEY}=${USERDATA_VALUE} not found in ${TMPFILENAME}" >&2
175+
cat "${TMPFILENAME}" >&2
176+
exit "${ksft_fail}"
177+
fi
178+
179+
# Delete the file once it is validated, otherwise keep it
180+
# for debugging purposes
181+
rm "${TMPFILENAME}"
182+
exit "${ksft_pass}"
183+
}
184+
185+
function check_for_dependencies() {
186+
if [ "$(id -u)" -ne 0 ]; then
187+
echo "This test must be run as root" >&2
188+
exit "${ksft_skip}"
189+
fi
190+
191+
if ! which socat > /dev/null ; then
192+
echo "SKIP: socat(1) is not available" >&2
193+
exit "${ksft_skip}"
194+
fi
195+
196+
if ! which ip > /dev/null ; then
197+
echo "SKIP: ip(1) is not available" >&2
198+
exit "${ksft_skip}"
199+
fi
200+
201+
if ! which udevadm > /dev/null ; then
202+
echo "SKIP: udevadm(1) is not available" >&2
203+
exit "${ksft_skip}"
204+
fi
205+
206+
if [ ! -f "${NSIM_DEV_SYS_NEW}" ]; then
207+
echo "SKIP: file ${NSIM_DEV_SYS_NEW} does not exist. Check if CONFIG_NETDEVSIM is enabled" >&2
208+
exit "${ksft_skip}"
209+
fi
210+
211+
if [ ! -d "${NETCONS_CONFIGFS}" ]; then
212+
echo "SKIP: directory ${NETCONS_CONFIGFS} does not exist. Check if NETCONSOLE_DYNAMIC is enabled" >&2
213+
exit "${ksft_skip}"
214+
fi
215+
216+
if ip link show "${DSTIF}" 2> /dev/null; then
217+
echo "SKIP: interface ${DSTIF} exists in the system. Not overwriting it." >&2
218+
exit "${ksft_skip}"
219+
fi
220+
221+
if ip addr list | grep -E "inet.*(${SRCIP}|${DSTIP})" 2> /dev/null; then
222+
echo "SKIP: IPs already in use. Skipping it" >&2
223+
exit "${ksft_skip}"
224+
fi
225+
}

0 commit comments

Comments
 (0)