summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-06-03 12:21:24 -0600
committerTom Rini <[email protected]>2026-06-03 12:21:24 -0600
commita4c8728f225b0d7d591fb9199ce7efb72f48290e (patch)
tree295234d16bbf194c171484835ef7ff1a99cb0eba
parent5188b96cdb7884cdcad2a068450e66516edf74f9 (diff)
parentfac46e5aa7c448444764044467e0cceb9d12f3f0 (diff)
Merge tag 'net-20260603' of https://source.denx.de/u-boot/custodians/u-boot-net
Pull request net-20260603. net: - ti: icssg: Fix portname buffer overflow - pxe: Fix potential initrd_filesize buffer overflow net-legacy: - bootp, dhcpv6: Prevent out-of-bound reads and buffer overflow - sntp: Check packet length in sntp_handler
-rw-r--r--boot/pxe_utils.c2
-rw-r--r--drivers/net/ti/icssg_prueth.c5
-rw-r--r--net/bootp.c8
-rw-r--r--net/dhcpv6.c32
-rw-r--r--net/sntp.c3
5 files changed, 43 insertions, 7 deletions
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index 419ab1f1b0e..8c1310dabeb 100644
--- a/boot/pxe_utils.c
+++ b/boot/pxe_utils.c
@@ -546,7 +546,7 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
char *zboot_argv[] = { "zboot", NULL, "0", NULL, NULL };
char *kernel_addr = NULL;
char *initrd_addr_str = NULL;
- char initrd_filesize[10];
+ char initrd_filesize[17];
char initrd_str[28];
char mac_str[29] = "";
char ip_str[68] = "";
diff --git a/drivers/net/ti/icssg_prueth.c b/drivers/net/ti/icssg_prueth.c
index 12a162b9d68..4796d0d67cd 100644
--- a/drivers/net/ti/icssg_prueth.c
+++ b/drivers/net/ti/icssg_prueth.c
@@ -496,14 +496,15 @@ static int prueth_port_probe(struct udevice *dev)
{
struct prueth_priv *priv = dev_get_priv(dev);
struct prueth *prueth;
- char portname[15];
+ char portname[64];
int ret;
priv->dev = dev;
prueth = dev_get_priv(dev->parent);
priv->prueth = prueth;
- sprintf(portname, "%s-%s", dev->parent->name, dev->name);
+ snprintf(portname, sizeof(portname), "%s-%s", dev->parent->name, dev->name);
+ portname[sizeof(portname) - 1] = '\0';
device_set_name(dev, portname);
diff --git a/net/bootp.c b/net/bootp.c
index 8976936b184..f0dc329d6e4 100644
--- a/net/bootp.c
+++ b/net/bootp.c
@@ -997,13 +997,13 @@ static void dhcp_packet_process_options(struct bootp_hdr *bp)
}
}
-static int dhcp_message_type(unsigned char *popt)
+static int dhcp_message_type(unsigned char *popt, unsigned char *end)
{
if (net_read_u32((u32 *)popt) != htonl(BOOTP_VENDOR_MAGIC))
return -1;
popt += 4;
- while (*popt != 0xff) {
+ while (popt < end && *popt != 0xff) {
if (*popt == 53) /* DHCP Message Type */
return *(popt + 2);
if (*popt == 0) {
@@ -1120,7 +1120,7 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0) {
#endif /* CONFIG_SYS_BOOTFILE_PREFIX */
if (CONFIG_IS_ENABLED(UNIT_TEST) &&
- dhcp_message_type((u8 *)bp->bp_vend) == -1) {
+ dhcp_message_type((u8 *)bp->bp_vend, (u8 *)pkt + len) == -1) {
debug("got BOOTP response; transitioning to BOUND\n");
goto dhcp_got_bootp;
}
@@ -1149,7 +1149,7 @@ static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
case REQUESTING:
debug("DHCP State: REQUESTING\n");
- if (dhcp_message_type((u8 *)bp->bp_vend) == DHCP_ACK) {
+ if (dhcp_message_type((u8 *)bp->bp_vend, (u8 *)pkt + len) == DHCP_ACK) {
dhcp_got_bootp:
dhcp_packet_process_options(bp);
/* Store net params from reply */
diff --git a/net/dhcpv6.c b/net/dhcpv6.c
index 5bf935cb6a3..640f089a2e1 100644
--- a/net/dhcpv6.c
+++ b/net/dhcpv6.c
@@ -339,6 +339,11 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
break;
case DHCP6_OPTION_IA_TA:
case DHCP6_OPTION_IA_NA:
+ if (option_len < sizeof(u32)) {
+ debug("Invalid IA_NA/IA_TA option length\n");
+ break;
+ }
+
/* check the IA_ID */
if (*((u32 *)option_ptr) != htonl(sm_params.ia_id)) {
debug("IA_ID mismatch 0x%08x 0x%08x\n",
@@ -347,6 +352,10 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
}
if (ntohs(option_hdr->option_id) == DHCP6_OPTION_IA_NA) {
+ if (option_len < 3 * sizeof(u32)) {
+ debug("Invalid IA_NA option length\n");
+ break;
+ }
/* skip past IA_ID/T1/T2 */
option_ptr += 3 * sizeof(u32);
} else if (ntohs(option_hdr->option_id) == DHCP6_OPTION_IA_TA) {
@@ -358,12 +367,20 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
break;
case DHCP6_OPTION_STATUS_CODE:
debug("DHCP6_OPTION_STATUS_CODE FOUND\n");
+ if (option_len < sizeof(u16)) {
+ debug("Invalid status code option length\n");
+ break;
+ }
sm_params.rx_status.status_code = ntohs(*((u16 *)option_ptr));
debug("DHCP6 top-level status code %d\n", sm_params.rx_status.status_code);
debug("DHCP6 status message: %.*s\n", len, option_ptr + 2);
break;
case DHCP6_OPTION_SOL_MAX_RT:
debug("DHCP6_OPTION_SOL_MAX_RT FOUND\n");
+ if (option_len != sizeof(u32)) {
+ debug("Invalid SOL_MAX_RT option length\n");
+ break;
+ }
sol_max_rt_sec = ntohl(*((u32 *)option_ptr));
/* A DHCP client MUST ignore any SOL_MAX_RT option values that are less
@@ -377,6 +394,11 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
break;
case DHCP6_OPTION_OPT_BOOTFILE_URL:
debug("DHCP6_OPTION_OPT_BOOTFILE_URL FOUND\n");
+ if (option_len >= sizeof(net_boot_file_name)) {
+ debug("Option length for BOOTFILE_URL is greater or equal than %zu. Skipping\n",
+ sizeof(net_boot_file_name));
+ break;
+ }
copy_filename(net_boot_file_name, option_ptr, option_len + 1);
debug("net_boot_file_name: %s\n", net_boot_file_name);
@@ -389,6 +411,12 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
case DHCP6_OPTION_OPT_BOOTFILE_PARAM:
if (IS_ENABLED(CONFIG_DHCP6_PXE_DHCP_OPTION)) {
debug("DHCP6_OPTION_OPT_BOOTFILE_PARAM FOUND\n");
+
+ if (option_len < sizeof(u16)) {
+ debug("Invalid BOOTFILE_PARAM option length\n");
+ break;
+ }
+
/* if CONFIG_DHCP6_PXE_DHCP_OPTION is set the PXE config file path
* is contained in the first OPT_BOOTFILE_PARAM argument
*/
@@ -414,6 +442,10 @@ static void dhcp6_parse_options(uchar *rx_pkt, unsigned int len)
break;
case DHCP6_OPTION_PREFERENCE:
debug("DHCP6_OPTION_PREFERENCE FOUND\n");
+ if (option_len != 1) {
+ debug("Invalid preference option length\n");
+ break;
+ }
sm_params.rx_status.preference = *option_ptr;
break;
default:
diff --git a/net/sntp.c b/net/sntp.c
index 77cee0046bd..4b3dc675bab 100644
--- a/net/sntp.c
+++ b/net/sntp.c
@@ -64,6 +64,9 @@ static void sntp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
if (dest != sntp_our_port)
return;
+ if (len < SNTP_PACKET_LEN)
+ return;
+
/*
* As the RTC's used in U-Boot support second resolution only
* we simply ignore the sub-second field.