Pull request net-20260813.

net:
- phy: dp83867: enable extended read / write for driver
- phy: fix duplicate eth_phy binding
- Drop unnecessary device_set_name
- dwc_eth_xgmac: Return -ENODEV when phy_connect() fails
- nfs: clean up bounds checks in nfs_readlink_reply()
- rtl8169: add support for RTL8126A and RTL8127A
- srand_mac(): fix -ENODEV crash with CONFIG_DM_RNG

net-legacy:
- Fix out-of-bounds write in IP fragment reassembly
- test: net: add regression test for IP reassembly overflow

net-lwip:
- Add tftpsrv command
- Handle chained pbufs in transmit path
- sntp: fix netif leak when ntpserverip is unset
- wget: free mbedtls x509 cert context to avoid memory leak
- Fix DHCP fine timer interval
This commit is contained in:
Tom Rini
2026-08-13 08:58:29 -06:00
26 changed files with 613 additions and 65 deletions
+36
View File
@@ -80,3 +80,39 @@ static int dm_test_net_ip_defrag_dup_last(struct unit_test_state *uts)
}
DM_TEST(dm_test_net_ip_defrag_dup_last, 0);
/*
* A fragment placed at the very top of the reassembly buffer takes the
* split-hole branch, which writes an 8-byte "struct hole" at
* pkt_buff + IP_HDR_SIZE + (offset8 + len / 8) * 8. With start + len equal to
* IP_MAXUDP that write reaches the end of pkt_buff and spills past it. pkt_buff
* is a static array, so this is flagged under AddressSanitizer; the fix rejects
* such a fragment instead. The datagram is incomplete, so nothing is delivered
* either way.
*/
static int dm_test_net_ip_defrag_oob(struct unit_test_state *uts)
{
rxhand_f *saved_handler = net_get_udp_handler();
uchar frame[FRAME_LEN];
struct ip_udp_hdr *ip = (struct ip_udp_hdr *)(frame + ETHER_HDR_SIZE);
u16 payload[4] = { 0, 0, 0, 0 };
/* Offset (8-byte units) so that start + FRAG_LEN == IP_MAXUDP. */
u16 off8 = (CONFIG_NET_MAXDEFRAG - IP_HDR_SIZE - FRAG_LEN) / 8;
udp_rx_count = 0;
net_set_udp_handler(defrag_udp_handler);
build_frag(frame, IP_FLAGS_MFRAG | off8, payload);
/* A distinct id forces a fresh reassembly independent of earlier tests. */
ip->ip_id = htons(0x7abc);
ip->ip_sum = 0;
ip->ip_sum = compute_ip_checksum(ip, IP_HDR_SIZE);
net_process_received_packet(frame, FRAME_LEN);
ut_asserteq(0, udp_rx_count);
net_set_udp_handler(saved_handler);
return 0;
}
DM_TEST(dm_test_net_ip_defrag_oob, 0);
+94
View File
@@ -59,6 +59,19 @@ For example:
'fnu': 'ubtest-upload.bin',
}
# Details regarding a file that may be written to U-Boot using the tftpsrv
# command. This variable may be omitted or set to None if tftpsrv testing
# is not possible or desired. The test uses host-side curl TFTP support to
# upload a generated file to U-Boot. The optional tftpsrv_url entry may be
# used when the host must use a forwarded address instead of U-Boot's
# ipaddr value.
env__net_tftpsrv_file = {
'fn': 'ubtest-tftpsrv.bin',
'addr': 0x10000000,
'size': 4096,
'timeout': 50000,
}
# Details regarding a file that may be read from a NFS server. This variable
# may be omitted or set to None if NFS testing is not possible or desired.
env__net_nfs_readable_file = {
@@ -89,6 +102,8 @@ import utils
import uuid
import datetime
import re
import tempfile
import zlib
net_set_up = False
net6_set_up = False
@@ -460,3 +475,82 @@ def test_net_tftpput(ubman):
output = ubman.run_command("crc32 $fileaddr $filesize")
assert expected_tftpb_crc in output
@pytest.mark.buildconfigspec("cmd_crc32")
@pytest.mark.buildconfigspec("cmd_tftpsrv")
@pytest.mark.requiredtool("curl")
def test_net_tftpsrv(ubman):
"""Test the tftpsrv command.
A file is generated on the host, uploaded to U-Boot using TFTP and then
validated in U-Boot using its size and CRC32.
The details of the file to upload are provided by the boardenv_* file;
see the comment at the beginning of this file.
"""
if not net_set_up:
pytest.skip("Network not initialized")
f = ubman.config.env.get("env__net_tftpsrv_file", None)
if not f:
pytest.skip("No tftpsrv file to write")
curl_version = utils.run_and_log(ubman, ["curl", "--version"])
if "tftp" not in curl_version.split():
pytest.skip("curl does not support TFTP")
addr = f.get("addr", None)
if not addr:
addr = utils.find_ram_base(ubman)
timeout = f.get("timeout", ubman.p.timeout)
timeout_secs = max(1, (timeout + 999) // 1000)
size = f.get("size", 4096)
fn = f.get("fn", "ubtest-tftpsrv.bin")
url = f.get("tftpsrv_url", None)
data = bytes([i % 251 for i in range(size)])
crc = "%08x" % (zlib.crc32(data) & 0xffffffff)
ip = ubman.run_command("echo $ipaddr").strip()
if not ip:
pytest.skip("No U-Boot IP address")
if not url:
url = "tftp://%s/%s" % (ip, fn)
with tempfile.NamedTemporaryFile() as tmp:
tmp.write(data)
tmp.flush()
done = False
with ubman.temporary_timeout(timeout):
try:
ubman.run_command("tftpsrv %x" % addr,
wait_for_prompt=False)
ubman.wait_for("Listening for TFTP transfer")
utils.run_and_log(
ubman,
[
"curl",
"--fail",
"--max-time",
str(timeout_secs),
"--upload-file",
tmp.name,
url,
],
)
ubman.wait_for("Bytes transferred = %d" % size)
ubman.wait_for(ubman.prompt)
done = True
finally:
if not done:
ubman.ctrlc()
ubman.drain_console()
output = ubman.run_command("echo $filesize")
assert "%x" % size in output
output = ubman.run_command("crc32 $fileaddr $filesize")
assert crc in output