diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/Kconfig | 70 | ||||
| -rw-r--r-- | net/Makefile | 6 | ||||
| -rw-r--r-- | net/bootp.c | 8 | ||||
| -rw-r--r-- | net/cdp.c | 8 | ||||
| -rw-r--r-- | net/dhcpv6.c | 32 | ||||
| -rw-r--r-- | net/lwip/Kconfig | 2 | ||||
| -rw-r--r-- | net/lwip/dhcp.c | 15 | ||||
| -rw-r--r-- | net/lwip/dns.c | 7 | ||||
| -rw-r--r-- | net/lwip/net-lwip.c | 16 | ||||
| -rw-r--r-- | net/lwip/nfs.c | 4 | ||||
| -rw-r--r-- | net/lwip/tftp.c | 4 | ||||
| -rw-r--r-- | net/lwip/wget.c | 125 | ||||
| -rw-r--r-- | net/net.c | 9 | ||||
| -rw-r--r-- | net/nfs-common.c | 4 | ||||
| -rw-r--r-- | net/sntp.c | 3 |
15 files changed, 228 insertions, 85 deletions
diff --git a/net/Kconfig b/net/Kconfig index e45ceb25106..386376ce884 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -2,8 +2,45 @@ # Network configuration # +config NO_NET + bool "Disable networking" + help + Transitional variable. Equivalent to setting NET=n. + +menuconfig NET + bool "Networking" + depends on !NO_NET + default y + if NET +choice + prompt "Networking stack" + default NET_LEGACY + +config NET_LEGACY + bool "Legacy U-Boot networking stack" + select NETDEVICES + help + Include networking support with U-Boot's internal implementation of + the TCP/IP protocol stack. + +config NET_LWIP + bool "Use lwIP for networking stack" + select NETDEVICES + help + Include networking support based on the lwIP (lightweight IP) + TCP/IP stack (https://nongnu.org/lwip). This is a replacement for + the default U-Boot network stack and applications located in net/ + and enabled via CONFIG_NET_LEGACY as well as other pieces of code that + depend on CONFIG_NET_LEGACY (such as cmd/net.c enabled via CONFIG_CMD_NET). + Therefore the two symbols CONFIG_NET_LEGACY and CONFIG_NET_LWIP are mutually + exclusive. + +endchoice + +if NET_LEGACY + config ARP_TIMEOUT int "Milliseconds before trying ARP again" default 5000 @@ -77,15 +114,15 @@ config SERVERIP_FROM_PROXYDHCP bool "Get serverip value from Proxy DHCP response" help Allows bootfile config to be fetched from Proxy DHCP server - while IP is obtained from main DHCP server. + while IP is obtained from main DHCP server. config SERVERIP_FROM_PROXYDHCP_DELAY_MS int "# of additional milliseconds to wait for ProxyDHCP response" default 100 help Amount of additional time to wait for ProxyDHCP response after - receiving response from main DHCP server. Has no effect if - SERVERIP_FROM_PROXYDHCP is false. + receiving response from main DHCP server. Has no effect if + SERVERIP_FROM_PROXYDHCP is false. config KEEP_SERVERADDR bool "Write the server's MAC address to 'serveraddr'" @@ -195,12 +232,10 @@ config IPV6 ip6addr, serverip6. If a u-boot command is capable to parse an IPv6 address and find it, it will force using IPv6 in the network stack. -endif # if NET +endif # if NET_LEGACY source "net/lwip/Kconfig" -if NET || NET_LWIP - config BOOTDEV_ETH bool "Enable bootdev for ethernet" depends on BOOTSTD @@ -228,7 +263,7 @@ config DNS config WGET bool "Enable wget" - select PROT_TCP if NET + select PROT_TCP if NET_LEGACY select PROT_TCP_LWIP if NET_LWIP help Selecting this will enable wget, an interface to send HTTP requests @@ -244,13 +279,16 @@ config TFTP_BLOCKSIZE almost-MTU block sizes. You can also activate CONFIG_IP_DEFRAG to set a larger block. -endif # if NET || NET_LWIP - config SYS_RX_ETH_BUFFER - int "Number of receive packet buffers" - default 4 - help - Defines the number of Ethernet receive buffers. On some Ethernet - controllers it is recommended to set this value to 8 or even higher, - since all buffers can be full shortly after enabling the interface on - high Ethernet traffic. + int "Number of receive packet buffers" + default 8 if FSL_ENETC + default 4 + help + Defines the number of Ethernet receive buffers. On some Ethernet + controllers (e.g. FSL_ENETC) it is recommended to set this value to 8 + or even higher, since all buffers can be full shortly after enabling + the interface on high Ethernet traffic. + + FSL_ENETC requires this value to be a multiple of 8. + +endif # if NET diff --git a/net/Makefile b/net/Makefile index 3a32bc8b0e7..ceac6de6377 100644 --- a/net/Makefile +++ b/net/Makefile @@ -5,9 +5,9 @@ #ccflags-y += -DDEBUG -ifeq ($(CONFIG_NET),y) +ifeq ($(CONFIG_NET_LEGACY),y) -obj-$(CONFIG_NET) += arp.o +obj-$(CONFIG_NET_LEGACY) += arp.o obj-$(CONFIG_CMD_BOOTP) += bootp.o obj-$(CONFIG_CMD_CDP) += cdp.o obj-$(CONFIG_DNS) += dns.o @@ -37,7 +37,7 @@ CFLAGS_eth_common.o += -Wno-format-extra-args endif -ifeq ($(filter y,$(CONFIG_NET) $(CONFIG_NET_LWIP)),y) +ifeq ($(CONFIG_NET),y) obj-$(CONFIG_DM_DSA) += dsa-uclass.o obj-$(CONFIG_$(PHASE_)DM_ETH) += eth-uclass.o obj-$(CONFIG_$(PHASE_)BOOTDEV_ETH) += eth_bootdev.o 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/cdp.c b/net/cdp.c index 6e404981d4a..300b3d5c409 100644 --- a/net/cdp.c +++ b/net/cdp.c @@ -276,7 +276,13 @@ void cdp_receive(const uchar *pkt, unsigned len) ss = (const ushort *)pkt; type = ntohs(ss[0]); tlen = ntohs(ss[1]); - if (tlen > len) + /* + * tlen includes the 4-byte TLV header, so it must be at + * least 4. Without this check a crafted tlen < 4 makes the + * "tlen -= 4" below underflow (tlen is a ushort), and a tlen + * of 0 also fails to advance pkt/len, hanging the loop. + */ + if (tlen < 4 || tlen > len) goto pkt_short; pkt += tlen; 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/lwip/Kconfig b/net/lwip/Kconfig index 0cfd3eb2684..3beaf48ff2a 100644 --- a/net/lwip/Kconfig +++ b/net/lwip/Kconfig @@ -18,7 +18,7 @@ config LWIP_DEBUG bool "Enable debug traces in the lwIP library" help Prints messages to the console regarding network packets that go in - and out of the lwIP library. + and out of the lwIP library. config LWIP_DEBUG_RXTX bool "Dump packets sent and received by lwIP" diff --git a/net/lwip/dhcp.c b/net/lwip/dhcp.c index acdf601d7eb..18dc36ae7ca 100644 --- a/net/lwip/dhcp.c +++ b/net/lwip/dhcp.c @@ -138,18 +138,25 @@ int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) dev = eth_get_dev(); if (!dev) { log_err("No network device\n"); - return CMD_RET_FAILURE; + ret = CMD_RET_FAILURE; + goto out; } ret = dhcp_loop(dev); if (ret) - return ret; + goto out; if (argc > 1) { struct cmd_tbl cmdtp = {}; - return do_tftpb(&cmdtp, 0, argc, argv); + ret = do_tftpb(&cmdtp, 0, argc, argv); + goto out; } - return CMD_RET_SUCCESS; + ret = CMD_RET_SUCCESS; + +out: + net_lwip_eth_stop(); + + return ret; } diff --git a/net/lwip/dns.c b/net/lwip/dns.c index 8b7b3b7f970..b620b0611d6 100644 --- a/net/lwip/dns.c +++ b/net/lwip/dns.c @@ -91,6 +91,7 @@ int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { char *name; char *var = NULL; + int ret; if (argc == 1 || argc > 3) return CMD_RET_USAGE; @@ -103,5 +104,9 @@ int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (net_lwip_eth_start() < 0) return CMD_RET_FAILURE; - return dns_loop(eth_get_dev(), name, var); + ret = dns_loop(eth_get_dev(), name, var); + + net_lwip_eth_stop(); + + return ret; } diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c index 0c83c004cab..cfe5a6a640d 100644 --- a/net/lwip/net-lwip.c +++ b/net/lwip/net-lwip.c @@ -31,6 +31,7 @@ void (*push_packet)(void *, int len) = 0; int net_try_count; static int net_restarted; int net_restart_wrap; +static int net_lwip_eth_started; static uchar net_pkt_buf[(PKTBUFSRX) * PKTSIZE_ALIGN + PKTALIGN] __aligned(PKTALIGN); const u8 net_bcast_ethaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -180,11 +181,15 @@ int net_lwip_eth_start(void) { int ret; + if (net_lwip_eth_started++ > 0) + return 0; + net_init(); eth_halt(); eth_set_current(); ret = eth_init(); if (ret < 0) { + net_lwip_eth_started--; eth_halt(); return ret; } @@ -192,6 +197,17 @@ int net_lwip_eth_start(void) return 0; } +void net_lwip_eth_stop(void) +{ + if (!net_lwip_eth_started) + return; + + if (--net_lwip_eth_started) + return; + + eth_halt(); +} + static struct netif *new_netif(struct udevice *udev, bool with_ip) { unsigned char enetaddr[ARP_HLEN]; diff --git a/net/lwip/nfs.c b/net/lwip/nfs.c index 9e6b801e465..4cc36373fdd 100644 --- a/net/lwip/nfs.c +++ b/net/lwip/nfs.c @@ -187,6 +187,7 @@ static int nfs_loop(struct udevice *udev, ulong addr, char *fname, int do_nfs(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { int ret = CMD_RET_SUCCESS; + bool started = false; char *arg = NULL; char *words[2] = { }; char *fname = NULL; @@ -281,10 +282,13 @@ int do_nfs(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) ret = CMD_RET_FAILURE; goto out; } + started = true; if (nfs_loop(eth_get_dev(), laddr, fname, srvip) < 0) ret = CMD_RET_FAILURE; out: + if (started) + net_lwip_eth_stop(); if (arg != net_boot_file_name) free(arg); return ret; diff --git a/net/lwip/tftp.c b/net/lwip/tftp.c index 7f3b28b8507..571c38172f9 100644 --- a/net/lwip/tftp.c +++ b/net/lwip/tftp.c @@ -261,6 +261,7 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname, int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { int ret = CMD_RET_SUCCESS; + bool started = false; char *arg = NULL; char *words[3] = { }; char *fname = NULL; @@ -365,12 +366,15 @@ int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) ret = CMD_RET_FAILURE; goto out; } + started = true; if (tftp_loop(eth_get_dev(), laddr, fname, srvip, port) < 0) ret = CMD_RET_FAILURE; else image_load_addr = laddr; out: + if (started) + net_lwip_eth_stop(); if (arg != net_boot_file_name) free(arg); return ret; diff --git a/net/lwip/wget.c b/net/lwip/wget.c index 008f3b395e7..247ece18e2b 100644 --- a/net/lwip/wget.c +++ b/net/lwip/wget.c @@ -20,7 +20,6 @@ #define SERVER_NAME_SIZE 254 #define HTTP_PORT_DEFAULT 80 #define HTTPS_PORT_DEFAULT 443 -#define PROGRESS_PRINT_STEP_BYTES (100 * 1024) enum done_state { NOT_DONE = 0, @@ -178,6 +177,9 @@ static int store_block(struct wget_ctx *ctx, void *src, u16_t len) ctx->daddr += len; ctx->size += len; + if (wget_info->silent) + return 0; + pos = clamp(ctx->size, 0UL, ctx->content_len); while (ctx->hash_count < pos * 50 / ctx->content_len) { @@ -240,20 +242,18 @@ static void httpc_result_cb(void *arg, httpc_result_t httpc_result, } /* Print hash marks for the last packet received */ - while (ctx->hash_count < 49) { - putc('#'); - ctx->hash_count++; + if (!wget_info->silent) { + while (ctx->hash_count < 49) { + putc('#'); + ctx->hash_count++; + } } - puts(" "); - print_size(ctx->content_len, ""); elapsed = get_timer(ctx->start_time); if (!elapsed) elapsed = 1; if (!wget_info->silent) { - if (rx_content_len > PROGRESS_PRINT_STEP_BYTES) - printf("\n"); - printf("%u bytes transferred in %lu ms (", rx_content_len, + printf("\n%u bytes transferred in %lu ms (", rx_content_len, elapsed); print_size(rx_content_len / elapsed * 1000, "/s)\n"); printf("Bytes transferred = %lu (%lx hex)\n", ctx->size, @@ -292,46 +292,22 @@ static err_t httpc_headers_done_cb(httpc_state_t *connection, void *arg, struct #if CONFIG_IS_ENABLED(WGET_CACERT) #endif -int wget_do_request(ulong dst_addr, char *uri) +static int wget_handle_request(struct wget_ctx *ctx, bool is_https, + struct udevice *udev, struct netif *netif) { #if CONFIG_IS_ENABLED(WGET_HTTPS) altcp_allocator_t tls_allocator; #endif httpc_connection_t conn; httpc_state_t *state; - struct udevice *udev; - struct netif *netif; - struct wget_ctx ctx; - char *path; - bool is_https; - - ctx.daddr = dst_addr; - ctx.saved_daddr = dst_addr; - ctx.done = NOT_DONE; - ctx.size = 0; - ctx.prevsize = 0; - ctx.start_time = 0; - ctx.content_len = 0; - ctx.hash_count = 0; - - if (parse_url(uri, ctx.server_name, &ctx.port, &path, &is_https)) - return CMD_RET_USAGE; - - if (net_lwip_eth_start() < 0) - return CMD_RET_FAILURE; - - if (!wget_info) - wget_info = &default_wget_info; - - udev = eth_get_dev(); - - netif = net_lwip_new_netif(udev); - if (!netif) - return -1; + int ret; /* if URL with hostname init dns */ - if (!ipaddr_aton(ctx.server_name, NULL) && net_lwip_dns_init()) - return CMD_RET_FAILURE; + if (!ipaddr_aton(ctx->server_name, NULL)) { + ret = net_lwip_dns_init(); + if (ret) + return ret; + } memset(&conn, 0, sizeof(conn)); #if CONFIG_IS_ENABLED(WGET_HTTPS) @@ -353,7 +329,7 @@ int wget_do_request(ulong dst_addr, char *uri) printf("Error: cacert authentication " "mode is 'required' but no CA " "certificates given\n"); - return CMD_RET_FAILURE; + return -EINVAL; } } else if (cacert_auth_mode == AUTH_NONE) { ca = NULL; @@ -374,12 +350,11 @@ int wget_do_request(ulong dst_addr, char *uri) tls_allocator.alloc = &altcp_tls_alloc; tls_allocator.arg = altcp_tls_create_config_client(ca, ca_sz, - ctx.server_name); + ctx->server_name); if (!tls_allocator.arg) { log_err("error: Cannot create a TLS connection\n"); - net_lwip_remove_netif(netif); - return -1; + return -ENODEV; } conn.altcp_allocator = &tls_allocator; @@ -388,30 +363,70 @@ int wget_do_request(ulong dst_addr, char *uri) conn.result_fn = httpc_result_cb; conn.headers_done_fn = httpc_headers_done_cb; - ctx.path = path; - if (httpc_get_file_dns(ctx.server_name, ctx.port, path, &conn, httpc_recv_cb, - &ctx, &state)) { - net_lwip_remove_netif(netif); - return CMD_RET_FAILURE; + if (httpc_get_file_dns(ctx->server_name, ctx->port, ctx->path, &conn, + httpc_recv_cb, ctx, &state)) { + return -ENODEV; } errno = 0; - while (!ctx.done) { + while (!ctx->done) { net_lwip_rx(udev, netif); if (ctrlc()) break; } - net_lwip_remove_netif(netif); - - if (ctx.done == SUCCESS) + if (ctx->done == SUCCESS) return 0; if (errno == EPERM && !wget_info->silent) printf("Certificate verification failed\n"); - return -1; + return -errno ?: -EIO; +} + +int wget_do_request(ulong dst_addr, char *uri) +{ + struct udevice *udev; + struct wget_ctx ctx; + struct netif *netif; + bool is_https; + int ret; + + ctx.daddr = dst_addr; + ctx.saved_daddr = dst_addr; + ctx.done = NOT_DONE; + ctx.size = 0; + ctx.prevsize = 0; + ctx.start_time = 0; + ctx.content_len = 0; + ctx.hash_count = 0; + + ret = parse_url(uri, ctx.server_name, &ctx.port, &ctx.path, &is_https); + if (ret) + return ret; + + ret = net_lwip_eth_start(); + if (ret) + return ret; + + if (!wget_info) + wget_info = &default_wget_info; + + udev = eth_get_dev(); + + netif = net_lwip_new_netif(udev); + if (!netif) { + net_lwip_eth_stop(); + return -ENODEV; + } + + ret = wget_handle_request(&ctx, is_https, udev, netif); + + net_lwip_remove_netif(netif); + net_lwip_eth_stop(); + + return ret; } /** diff --git a/net/net.c b/net/net.c index ae3b977781f..61c5a6ef6c4 100644 --- a/net/net.c +++ b/net/net.c @@ -1103,6 +1103,15 @@ static struct ip_udp_hdr *__net_defragment(struct ip_udp_hdr *ip, int *lenp) *lenp = total_len + IP_HDR_SIZE; localip->ip_len = htons(*lenp); + + /* + * Mark the reassembly state empty so that any further + * fragment goes through the normal re-init path and + * rebuilds a clean hole list + */ + total_len = 0; + first_hole = 0; + return localip; } diff --git a/net/nfs-common.c b/net/nfs-common.c index 4fbde67a760..72d8fd823e3 100644 --- a/net/nfs-common.c +++ b/net/nfs-common.c @@ -674,11 +674,15 @@ static int nfs_readlink_reply(uchar *pkt, unsigned int len) strcat(nfs_path, "/"); pathlen = strlen(nfs_path); + if (pathlen + rlen >= sizeof(nfs_path_buff)) + return -NFS_RPC_DROP; memcpy(nfs_path + pathlen, (uchar *)&rpc_pkt.u.reply.data[2 + nfsv3_data_offset], rlen); nfs_path[pathlen + rlen] = 0; } else { + if (rlen >= sizeof(nfs_path_buff)) + return -NFS_RPC_DROP; memcpy(nfs_path, (uchar *)&rpc_pkt.u.reply.data[2 + nfsv3_data_offset], rlen); 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. |
