diff options
| author | Tom Rini <[email protected]> | 2026-06-03 12:21:24 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2026-06-03 12:21:24 -0600 |
| commit | a4c8728f225b0d7d591fb9199ce7efb72f48290e (patch) | |
| tree | 295234d16bbf194c171484835ef7ff1a99cb0eba | |
| parent | 5188b96cdb7884cdcad2a068450e66516edf74f9 (diff) | |
| parent | fac46e5aa7c448444764044467e0cceb9d12f3f0 (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.c | 2 | ||||
| -rw-r--r-- | drivers/net/ti/icssg_prueth.c | 5 | ||||
| -rw-r--r-- | net/bootp.c | 8 | ||||
| -rw-r--r-- | net/dhcpv6.c | 32 | ||||
| -rw-r--r-- | net/sntp.c | 3 |
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. |
