aboutsummaryrefslogtreecommitdiff
path: root/net
AgeCommit message (Collapse)AuthorFilesLines
2022-12-05net: ping6: Add ping6 commandViacheslav Mitrofanov4-0/+136
Implement ping6 command to ping hosts using IPv6. It works the same way as an ordinary ping command. There is no ICMP request so it is not possible to ping our host. This patch adds options in Kconfig and Makefile to build ping6 command. Series-changes: 3 - Added structures and functions descriptions - Added to ping6_receive() return value instead of void Series-changes: 4 - Fixed structures and functions description style Signed-off-by: Viacheslav Mitrofanov <v.v.mitrofanov@yadro.com> Reviewed-by: Ramon Fried <rfried.dev@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2022-12-05net: tftp: Add IPv6 support for tftpbootViacheslav Mitrofanov2-7/+68
The command tftpboot uses IPv4 by default. Add the possibility to use IPv6 instead. If an address in the command is an IPv6 address it will use IPv6 to boot or if there is a suffix -ipv6 in the end of the command it also force using IPv6. All other tftpboot features and parameters are left the same. Signed-off-by: Viacheslav Mitrofanov <v.v.mitrofanov@yadro.com> Reviewed-by: Ramon Fried <rfried.dev@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2022-12-05net: ipv6: Incorporate IPv6 support into u-boot net subsystemViacheslav Mitrofanov1-1/+22
Add net_ip6_handler (an IPv6 packet handler) into net_loop. Add neighbor discovery mechanism into network init process. That is the main step to run IPv6 in u-boot. Now u-boot is capable to use NDP and handle IPv6 packets. Signed-off-by: Viacheslav Mitrofanov <v.v.mitrofanov@yadro.com> Reviewed-by: Ramon Fried <rfried.dev@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2022-12-05net: ipv6: Add implementation of main IPv6 functionsViacheslav Mitrofanov1-0/+362
Functions that were exposed in "net: ipv6: Add IPv6 basic primitives" had only empty implementations and were exposed as API for futher patches. This patch add implementation of these functions. Main functions are: net_ip6_handler() - IPv6 packet handler for incoming packets; net_send_udp_packet6() - make up and send an UDP packet; csum_ipv6_magic() - compute checksum of IPv6 "psuedo-header" per RFC2460 section 8.1; ip6_addr_in_subnet() - check if an address is in our subnet. Other functions are auxiliary. Series-changes: 3 - Added comments - Fixed style problems - Fixed return codes instead of -1 Signed-off-by: Viacheslav Mitrofanov <v.v.mitrofanov@yadro.com> Reviewed-by: Ramon Fried <rfried.dev@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2022-12-05net: ipv6: Add ip6addr, gatewayip6, serverip6 variables callbacksViacheslav Mitrofanov1-0/+48
Implement actions on ip6addr, gatewayip6, serverip6 varaibles. on_ip6addr - convert IPv6 string addr to struct ip6_addr on_gatewayip6 - convert IPv6 string addr to struct ip6_addr on_serverip6 - convert IPv6 string addr to struct ip6_addr Series-changes: 3 - Removed memory allocation - Substituted -1 for error code Signed-off-by: Viacheslav Mitrofanov <v.v.mitrofanov@yadro.com> Reviewed-by: Ramon Fried <rfried.dev@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2022-12-05net: ipv6: Add Neighbor Discovery Protocol (NDP)Viacheslav Mitrofanov2-0/+290
Implement basic of NDP. It doesn't include such things as Router Solicitation, Router Advertisement and Redirect. It just has Neighbor Solicitation and Neighbor Advertisement. Only these two features are used in u-boot IPv6. Implementation of some NDP functions uses API that was exposed in "net: ipv6: Add IPv6 basic primitives". Also this patch inlcudes update in Makefile to build NDP. Series-changes: 3 - Added structures and functions descriptions - Fixed style problems Series-changes: 4 - Fixed structures and functions description style Signed-off-by: Viacheslav Mitrofanov <v.v.mitrofanov@yadro.com> Reviewed-by: Ramon Fried <rfried.dev@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2022-12-05net: ipv6: Add IPv6 build optionsViacheslav Mitrofanov2-0/+11
Add options to Makefile and Kconfig file to build IPv6 Series-changes: 3 - Added help for IPv6 support Signed-off-by: Viacheslav Mitrofanov <v.v.mitrofanov@yadro.com> Reviewed-by: Ramon Fried <rfried.dev@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2022-12-05net: ipv6: Add IPv6 basic primitivesViacheslav Mitrofanov1-0/+31
This patch is a collection of basic primitives that are prerequisite for further IPv6 implementation. There are structures definition such as IPv6 header, UDP header (for TFTP), ICMPv6 header. There are auxiliary defines such as protocol codes, padding, struct size and etc. Also here are functions prototypes and its empty implementation that will be used as API for further patches. Here are variables declaration such as IPv6 address of our host, gateway, ipv6 server. Series-changes: 3 - Added functions and structures descriptions - Removed enums ND_OPT_*. It will be moved into further patches - Substituted -1 for error codes Series-changes: 4 - Changed functions and structures description style Signed-off-by: Viacheslav Mitrofanov <v.v.mitrofanov@yadro.com> Reviewed-by: Ramon Fried <rfried.dev@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2022-12-02net: CONFIG_NET_DEVICES in dhcp_handler()Heinrich Schuchardt1-1/+1
The symbol CONFIG_NET_DEVICES does not exist. The correct name is CONFIG_NETDEVICES. Fixes: 77b5c4a5b1dc ("efi_loader: Let networking support depend on NETDEVICES") Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
2022-11-28net: Add wget applicationYing-Chun Liu (PaulLiu)3-0/+445
This commit adds a simple wget command that can download files from http server. The command syntax is wget ${loadaddr} <path of the file from server> Signed-off-by: Duncan Hare <DuncanCHare@yahoo.com> Signed-off-by: Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org> Reviewed-by: Simon Glass <sjg@chromium.org> Cc: Christian Gmeiner <christian.gmeiner@gmail.com> Cc: Joe Hershberger <joe.hershberger@ni.com> Cc: Michal Simek <michal.simek@xilinx.com> Cc: Ramon Fried <rfried.dev@gmail.com> Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
2022-11-28net: Add TCP protocolYing-Chun Liu (PaulLiu)4-0/+767
Currently file transfers are done using tftp or NFS both over udp. This requires a request to be sent from client (u-boot) to the boot server. The current standard is TCP with selective acknowledgment. Signed-off-by: Duncan Hare <DH@Synoia.com> Signed-off-by: Duncan Hare <DuncanCHare@yahoo.com> Signed-off-by: Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org> Reviewed-by: Simon Glass <sjg@chromium.org> Cc: Christian Gmeiner <christian.gmeiner@gmail.com> Cc: Joe Hershberger <joe.hershberger@ni.com> Cc: Michal Simek <michal.simek@xilinx.com> Cc: Ramon Fried <rfried.dev@gmail.com> Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
2022-11-28net: deal with fragment-overlapping-two-holes caseRasmus Villemoes1-3/+7
With a suitable sequence of malicious packets, it's currently possible to get a hole descriptor to contain arbitrary attacker-controlled contents, and then with one more packet to use that as an arbitrary write vector. While one could possibly change the algorithm so we instead loop over all holes, and in each hole puts as much of the current fragment as belongs there (taking care to carefully update the hole list as appropriate), it's not worth the complexity: In real, non-malicious scenarios, one never gets overlapping fragments, and certainly not fragments that would be supersets of one another. So instead opt for this simple protection: Simply don't allow the eventual memcpy() to write beyond the last_byte of the current hole. Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
2022-11-28net: tftp: sanitize tftp block size, especially for TXRasmus Villemoes1-0/+47
U-Boot does not support IP fragmentation on TX (and unless CONFIG_IP_DEFRAG is set, neither on RX). So the blocks we send must fit in a single ethernet packet. Currently, if tftpblocksize is set to something like 5000 and I tftpput a large enough file, U-Boot crashes because we overflow net_tx_packet (which only has room for 1500 bytes plus change). Similarly, if tftpblocksize is set to something larger than what we can actually receive (e.g. 50000, with NET_MAXDEFRAG being 16384), any tftp get just hangs because we never receive any packets. Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk> Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
2022-11-28net: tftp: use IS_ENABLED(CONFIG_NET_TFTP_VARS) instead of #ifRasmus Villemoes1-28/+28
Nothing inside this block depends on NET_TFTP_VARS to be set to parse correctly. Switch to C if() in preparation for adding code before this (to avoid a declaration-after-statement warning). Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk> [trini: Update to cover CONFIG_TFTP_PORT case as well] Signed-off-by: Tom Rini <trini@konsulko.com>
2022-11-28net: fix ip_len in reassembled IP datagramRasmus Villemoes1-2/+2
For some reason, the ip_len field in a reassembled IP datagram is set to just the size of the payload, but it should be set to the value it would have had if the datagram had never been fragmented in the first place, i.e. size of payload plus size of IP header. That latter value is currently returned correctly via the "len" variable. And before entering net_defragment(), len does have the value ntohs(ip->ip_len), so if we're not dealing with a fragment (so net_defragment leaves *len alone), that relationship of course also holds after the net_defragment() call. The only use I can find of ip->ip_len after the net_defragment call is the ntohs(ip->udp_len) > ntohs(ip->ip_len) sanity check - none of the functions that are passed the "ip" pointer themselves inspect ->ip_len but instead use the passed len. But that sanity check is a bit odd, since the RHS really should be "ntohs(ip->ip_len) - 20", i.e. the IP payload size. Now that we've fixed things so that len == ntohs(ip->ip_len) in all cases, change that sanity check to use len-20 as the RHS. Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
2022-11-28net: (actually/better) deal with CVE-2022-{30790,30552}Rasmus Villemoes1-1/+9
I hit a strange problem with v2022.10: Sometimes my tftp transfer would seemingly just hang. It only happened for some files. Moreover, changing tftpblocksize from 65464 to 65460 or 65000 made it work again for all the files I tried. So I started suspecting it had something to do with the file sizes and in particular the way the tftp blocks get fragmented and reassembled. v2022.01 showed no problems with any of the files or any value of tftpblocksize. Looking at what had changed in net.c or tftp.c since January showed only one remotely interesting thing, b85d130ea0ca. So I fired up wireshark on my host to see if somehow one of the packets would be too small. But no, with both v2022.01 and v2022.10, the exact same sequence of packets were sent, all but the last of size 1500, and the last being 1280 bytes. But then it struck me that 1280 is 5*256, so one of the two bytes on-the-wire is 0 and the other is 5, and when then looking at the code again the lack of endianness conversion becomes obvious. [ntohs is both applied to ip->ip_off just above, as well as to ip->ip_len just a little further down when the "len" is actually computed]. IOWs the current code would falsely reject any packet which happens to be a multiple of 256 bytes in size, breaking tftp transfers somewhat randomly, and if it did get one of those "malicious" packets with ip_len set to, say, 27, it would be seen by this check as being 6912 and hence not rejected. ==== Now, just adding the missing ntohs() would make my initial problem go away, in that I can now download the file where the last fragment ends up being 1280 bytes. But there's another bug in the code and/or analysis: The right-hand side is too strict, in that it is ok for the last fragment not to have a multiple of 8 bytes as payload - it really must be ok, because nothing in the IP spec says that IP datagrams must have a multiple of 8 bytes as payload. And comments in the code also mention this. To fix that, replace the comparison with <= IP_HDR_SIZE and add another check that len is actually a multiple of 8 when the "more fragments" bit is set - which it necessarily is for the case where offset8 ends up being 0, since we're only called when (ip_off & (IP_OFFS | IP_FLAGS_MFRAG)). ==== So, does this fix CVE-2022-30790 for real? It certainly correctly rejects the POC code which relies on sending a packet of size 27 with the MFRAG flag set. Can the attack be carried out with a size 27 packet that doesn't set MFRAG (hence must set a non-zero fragment offset)? I dunno. If we get a packet without MFRAG, we update h->last_byte in the hole we've found to be start+len, hence we'd enter one of if ((h >= thisfrag) && (h->last_byte <= start + len)) { or } else if (h->last_byte <= start + len) { and thus won't reach any of the /* overlaps with initial part of the hole: move this hole */ newh = thisfrag + (len / 8); /* fragment sits in the middle: split the hole */ newh = thisfrag + (len / 8); IOW these division are now guaranteed to be exact, and thus I think the scenario in CVE-2022-30790 cannot happen anymore. ==== However, there's a big elephant in the room, which has always been spelled out in the comments, and which makes me believe that one can still cause mayhem even with packets whose payloads are all 8-byte aligned: This code doesn't deal with a fragment that overlaps with two different holes (thus being a superset of a previously-received fragment). Suppose each character below represents 8 bytes, with D being already received data, H being a hole descriptor (struct hole), h being non-populated chunks, and P representing where the payload of a just received packet should go: DDDHhhhhDDDDHhhhDDDD PPPPPPPPP I'm pretty sure in this case we'd end up with h being the first hole, enter the simple } else if (h->last_byte <= start + len) { /* overlaps with final part of the hole: shorten this hole */ h->last_byte = start; case, and thus in the memcpy happily overwrite the second H with our chosen payload. This is probably worth fixing... Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
2022-11-28net: compare received length to sizeof(ip_hdr), not sizeof(ip_udp_hdr)Rasmus Villemoes1-2/+6
While the code mostly/only handles UDP packets, it's possible for the last fragment of a fragmented UDP packet to be smaller than 28 bytes; it can be as small as 21 bytes (an IP header plus one byte of payload). So until we've performed the defragmentation step and thus know whether we're now holding a full packet, we should only check for the existence of the fields in the ip header, i.e. that there are at least 20 bytes present. In practice, we always seem to be handed a "len" of minimum 60 from the device layer, i.e. minimal ethernet frame length minus FCS, so this is mostly theoretical. After we've fetched the header's claimed length and used that to update the len variable, check that the header itself claims to be the minimal possible length. This is probably how CVE-2022-30552 should have been dealt with in the first place, because net_defragment() is not the only place that wants to know the size of the IP datagram payload: If we receive a non-fragmented ICMP packet, we pass "len" to receive_icmp() which in turn may pass it to ping_receive() which does compute_ip_checksum(icmph, len - IP_HDR_SIZE) and due to the signature of compute_ip_checksum(), that would then lead to accessing ~4G of address space, very likely leading to a crash. Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
2022-11-28net: improve check for no IP optionsRasmus Villemoes1-1/+1
There's no reason we should accept an IP packet with a malformed IHL field. So ensure that it is exactly 5, not just <= 5. Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk> Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
2022-11-06efi_loader: Let networking support depend on NETDEVICESJan Kiszka1-1/+3
CONFIG_NET does not imply that there are actually network devices available, only CONFIG_NETDEVICES does. Changing to this dependency obsoletes the check in Kconfig because NETDEVICES means DM_ETH. Fixes: 0efe1bcf5c2c ("efi_loader: Add network access support") Suggested-by: Tom Rini <trini@konsulko.com> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2022-10-21cmd: Add ncsi commandSamuel Mendoza-Jonas1-0/+1
Adds an "ncsi" command to manually start NC-SI configuration. Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com> Signed-off-by: Joel Stanley <joel@jms.id.au> Reviewed-by: Cédric Le Goater <clg@kaod.org>
2022-10-21net: NC-SI setup and handlingSamuel Mendoza-Jonas1-1/+25
Add the handling of NC-SI ethernet frames, and add a check at the start of net_loop() to configure NC-SI before starting other network commands. Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com> Signed-off-by: Joel Stanley <joel@jms.id.au> Reviewed-by: Cédric Le Goater <clg@kaod.org> Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
2022-10-17net: eth-uclass: Do not set device on errorMichal Suchanek1-0/+2
eth_get_dev relies on the broken behavior that returns an error but not the device on which the error happened which gives the caller no reasonable way to report or handle the error. In a later patch uclass_first_device_err will be changed to return the device on error but eth_get_dev stores the returned device pointer directly in a global state without checking the return value. Unset the pointer again in the error case. Signed-off-by: Michal Suchanek <msuchanek@suse.de> Reviewed-by: Simon Glass <sjg@chromium.org>
2022-10-17dm: treewide: Use uclass_first_device_err when accessing one deviceMichal Suchanek1-2/+2
There is a number of users that use uclass_first_device to access the first and (assumed) only device in uclass. Some check the return value of uclass_first_device and also that a device was returned which is exactly what uclass_first_device_err does. Some are not checking that a device was returned and can potentially crash if no device exists in the uclass. Finally there is one that returns NULL on error either way. Convert all of these to use uclass_first_device_err instead, the return value will be removed from uclass_first_device in a later patch. Signed-off-by: Michal Suchanek <msuchanek@suse.de> Reviewed-by: Simon Glass <sjg@chromium.org>
2022-09-29dm: core: Drop ofnode_is_available()Simon Glass1-1/+1
This function is also available as ofnode_is_enabled(), so use that instead. Signed-off-by: Simon Glass <sjg@chromium.org>
2022-09-18cyclic: Use schedule() instead of WATCHDOG_RESET()Stefan Roese1-1/+1
Globally replace all occurances of WATCHDOG_RESET() with schedule(), which handles the HW_WATCHDOG functionality and the cyclic infrastructure. Signed-off-by: Stefan Roese <sr@denx.de> Reviewed-by: Simon Glass <sjg@chromium.org> Tested-by: Tom Rini <trini@konsulko.com> [am335x_evm, mx6cuboxi, rpi_3,dra7xx_evm, pine64_plus, am65x_evm, j721e_evm]
2022-08-10common: Drop display_options.h from common headerSimon Glass2-0/+2
Move this out of the common header and include it only where needed. Signed-off-by: Simon Glass <sjg@chromium.org>
2022-08-08net: bootp: Make root path (option 17) length configurableAndre Kalb2-1/+7
to adjust the root path length. Eg to 256 from Linux Kernel Signed-off-by: Andre Kalb <andre.kalb@sma.de> Reviewed-by: Ramon Fried <rfried.dev@gmail.com> [trini: Guard extern so that !CONFIG_NET platforms will build] Signed-off-by: Tom Rini <trini@konsulko.com>
2022-08-04Audit <flash.h> inclusionTom Rini1-0/+2
A large number of files include <flash.h> as it used to be how various SPI flash related functions were found, or for other reasons entirely. In order to migrate some further CONFIG symbols to Kconfig we need to not include flash.h in cases where we don't have a NOR flash of some sort enabled. Furthermore, in cases where we are in common code and it doesn't make sense to try and further refactor the code itself in to new files we need to guard this inclusion. Signed-off-by: Tom Rini <trini@konsulko.com>
2022-08-04net: Remove CONFIG_SYS_DIRECT_FLASH_TFTPTom Rini1-39/+13
No platforms enable the functionality to tftp directly to NOR flash, and this is discouraged by the documentation. Remove this code. Further, this highlights an oddity of the code. Un-indent the start of this function. Cc: Joe Hershberger <joe.hershberger@ni.com> Cc: Ramon Fried <rfried.dev@gmail.com> Signed-off-by: Tom Rini <trini@konsulko.com>
2022-06-20Merge branch 'master' into nextTom Rini1-1/+1
Merge in v2022.07-rc5.
2022-06-16net: Fix discuss discard typoMarek Vasut1-1/+1
Replace discuss with discard, that is what happens with packet with incorrect checksum. Fix the typo. Fixes: 4b37fd146bb ("Convert CONFIG_UDP_CHECKSUM to Kconfig") Signed-off-by: Marek Vasut <marex@denx.de> Cc: Ramon Fried <rfried.dev@gmail.com> Cc: Simon Glass <sjg@chromium.org>
2022-06-08net: Add support for reading mac addresses from nvmem cellsSean Anderson1-4/+9
This adds support for reading mac addresses from the "mac-address" nvmem cell. If there is no (local-)mac-address property, then we will try reading from an nvmem cell. For some existing examples of this property, refer to imx8mn.dtsi and imx8mp.dtsi. Unfortunately, fuse drivers have not yet been converted to DM. Signed-off-by: Sean Anderson <sean.anderson@seco.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2022-06-08net: dsa: Fix segmentation fault if master fails to probeSean Anderson1-2/+4
If the DSA master fails to probe for whatever reason, then DSA devices will continue on as if nothing is wrong. This can cause incorrect behavior. In particular, on sandbox, dsa_sandbox_probe attempts to access the master's private data. This is only safe to do if the master has been probed first. Fix this by probing the master after we look it up, and bailing out if we get an error. Fixes: fc054d563b ("net: Introduce DSA class for Ethernet switches") Signed-off-by: Sean Anderson <sean.anderson@seco.com> Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
2022-06-03net: Check for the minimum IP fragmented datagram sizeFabio Estevam1-0/+3
Nicolas Bidron and Nicolas Guigo reported the two bugs below: " ----------BUG 1---------- In compiled versions of U-Boot that define CONFIG_IP_DEFRAG, a value of `ip->ip_len` (IP packet header's Total Length) higher than `IP_HDR_SIZE` and strictly lower than `IP_HDR_SIZE+8` will lead to a value for `len` comprised between `0` and `7`. This will ultimately result in a truncated division by `8` resulting value of `0` forcing the hole metadata and fragment to point to the same location. The subsequent memcopy will overwrite the hole metadata with the fragment data. Through a second fragment, this can be exploited to write to an arbitrary offset controlled by that overwritten hole metadata value. This bug is only exploitable locally as it requires crafting two packets the first of which would most likely be dropped through routing due to its unexpectedly low Total Length. However, this bug can potentially be exploited to root linux based embedded devices locally. ```C static struct ip_udp_hdr *__net_defragment(struct ip_udp_hdr *ip, int *lenp) { static uchar pkt_buff[IP_PKTSIZE] __aligned(PKTALIGN); static u16 first_hole, total_len; struct hole *payload, *thisfrag, *h, *newh; struct ip_udp_hdr *localip = (struct ip_udp_hdr *)pkt_buff; uchar *indata = (uchar *)ip; int offset8, start, len, done = 0; u16 ip_off = ntohs(ip->ip_off); /* payload starts after IP header, this fragment is in there */ payload = (struct hole *)(pkt_buff + IP_HDR_SIZE); offset8 = (ip_off & IP_OFFS); thisfrag = payload + offset8; start = offset8 * 8; len = ntohs(ip->ip_len) - IP_HDR_SIZE; ``` The last line of the previous excerpt from `u-boot/net/net.c` shows how the attacker can control the value of `len` to be strictly lower than `8` by issuing a packet with `ip_len` between `21` and `27` (`IP_HDR_SIZE` has a value of `20`). Also note that `offset8` here is `0` which leads to `thisfrag = payload`. ```C } else if (h >= thisfrag) { /* overlaps with initial part of the hole: move this hole */ newh = thisfrag + (len / 8); *newh = *h; h = newh; if (h->next_hole) payload[h->next_hole].prev_hole = (h - payload); if (h->prev_hole) payload[h->prev_hole].next_hole = (h - payload); else first_hole = (h - payload); } else { ``` Lower down the same function, execution reaches the above code path. Here, `len / 8` evaluates to `0` leading to `newh = thisfrag`. Also note that `first_hole` here is `0` since `h` and `payload` point to the same location. ```C /* finally copy this fragment and possibly return whole packet */ memcpy((uchar *)thisfrag, indata + IP_HDR_SIZE, len); ``` Finally, in the above excerpt the `memcpy` overwrites the hole metadata since `thisfrag` and `h` both point to the same location. The hole metadata is effectively overwritten with arbitrary data from the fragmented IP packet data. If `len` was crafted to be `6`, `last_byte`, `next_hole`, and `prev_hole` of the `first_hole` can be controlled by the attacker. Finally the arbitrary offset write occurs through a second fragment that only needs to be crafted to write data in the hole pointed to by the previously controlled hole metadata (`next_hole`) from the first packet. ### Recommendation Handle cases where `len` is strictly lower than 8 by preventing the overwrite of the hole metadata during the memcpy of the fragment. This could be achieved by either: * Moving the location where the hole metadata is stored when `len` is lower than `8`. * Or outright rejecting fragmented IP datagram with a Total Length (`ip_len`) lower than 28 bytes which is the minimum valid fragmented IP datagram size (as defined as the minimum fragment of 8 octets in the IP Specification Document: [RFC791](https://datatracker.ietf.org/doc/html/rfc791) page 25). ----------BUG 2---------- In compiled versions of U-Boot that define CONFIG_IP_DEFRAG, a value of `ip->ip_len` (IP packet header's Total Length) lower than `IP_HDR_SIZE` will lead to a negative value for `len` which will ultimately result in a buffer overflow during the subsequent `memcpy` that uses `len` as it's `count` parameter. This bug is only exploitable on local ethernet as it requires crafting an invalid packet to include an unexpected `ip_len` value in the IP UDP header that's lower than the minimum accepted Total Length of a packet (21 as defined in the IP Specification Document: [RFC791](https://datatracker.ietf.org/doc/html/rfc791)). Such packet would in all likelihood be dropped while being routed to its final destination through most routing equipment and as such requires the attacker to be in a local position in order to be exploited. ```C static struct ip_udp_hdr *__net_defragment(struct ip_udp_hdr *ip, int *lenp) { static uchar pkt_buff[IP_PKTSIZE] __aligned(PKTALIGN); static u16 first_hole, total_len; struct hole *payload, *thisfrag, *h, *newh; struct ip_udp_hdr *localip = (struct ip_udp_hdr *)pkt_buff; uchar *indata = (uchar *)ip; int offset8, start, len, done = 0; u16 ip_off = ntohs(ip->ip_off); /* payload starts after IP header, this fragment is in there */ payload = (struct hole *)(pkt_buff + IP_HDR_SIZE); offset8 = (ip_off & IP_OFFS); thisfrag = payload + offset8; start = offset8 * 8; len = ntohs(ip->ip_len) - IP_HDR_SIZE; ``` The last line of the previous excerpt from `u-boot/net/net.c` shows where the underflow to a negative `len` value occurs if `ip_len` is set to a value strictly lower than 20 (`IP_HDR_SIZE` being 20). Also note that in the above excerpt the `pkt_buff` buffer has a size of `CONFIG_NET_MAXDEFRAG` which defaults to 16 KB but can range from 1KB to 64 KB depending on configurations. ```C /* finally copy this fragment and possibly return whole packet */ memcpy((uchar *)thisfrag, indata + IP_HDR_SIZE, len); ``` In the above excerpt the `memcpy` overflows the destination by attempting to make a copy of nearly 4 gigabytes in a buffer that's designed to hold `CONFIG_NET_MAXDEFRAG` bytes at most which leads to a DoS. ### Recommendation Stop processing of the packet if `ip_len` is lower than 21 (as defined by the minimum length of a data carrying datagram in the IP Specification Document: [RFC791](https://datatracker.ietf.org/doc/html/rfc791) page 34)." Add a check for ip_len lesser than 28 and stop processing the packet in this case. Such a check covers the two reported bugs. Reported-by: Nicolas Bidron <nicolas.bidron@nccgroup.com> Signed-off-by: Fabio Estevam <festevam@denx.de>
2022-05-26net: nfs: Fix CVE-2022-30767 (old CVE-2019-14196)Andrea zi0Black Cappa1-3/+1
This patch mitigates the vulnerability identified via CVE-2019-14196. The previous patch was bypassed/ineffective, and now the vulnerability is identified via CVE-2022-30767. The patch removes the sanity check introduced to mitigate CVE-2019-14196 since it's ineffective. filefh3_length is changed to unsigned type integer, preventing negative numbers from being used during comparison with positive values during size sanity checks. Signed-off-by: Andrea zi0Black Cappa <zi0Black@protonmail.com>
2022-05-04net: mdio-uclass: add dm_phy_find_by_ofnode() helperMarek Behún1-0/+22
Add helper to resolve PHY node from it's ofnode via DM MDIO subsystem. Signed-off-by: Marek Behún <marek.behun@nic.cz> Reviewed-by: Ramon Fried <rfried.dev@gmail.com> Reviewed-by: Stefan Roese <sr@denx.de>
2022-04-25bootstd: ethernet: Add a bootdev driverSimon Glass4-0/+119
Add a bootdev driver for Ethernet. It can use the PXE boot mechanism to locate a file, added later. Signed-off-by: Simon Glass <sjg@chromium.org>
2022-04-22Allow colon in PXE bootfile URLsLyle Franklin1-2/+7
- U-boot's PXE flow supports prefixing your bootfile name with an IP address to fetch from a server other than the DHCP server, e.g. `hostIPaddr:bootfilename`: https://github.com/u-boot/u-boot/commit/a93907c43f847f076dd0e34ee3b69b5e8e6d0d29 - However, this breaks bootfile paths which contain a colon, e.g. `f0:ad:4e:10:1b:87/7/pxelinux.cfg/default` - This patch checks whether the `hostIPaddr` prefix is a valid IP address before overriding the serverIP otherwise the whole bootfile path is preserved Signed-off-by: Lyle Franklin <lylejfranklin@gmail.com>
2022-04-12net: tftp: fix tftp server initializationArjan Minzinga Zijlstra1-0/+2
Some globals where not properly initialized causing timeouts as data packets where not immediately acknowledged. Fixes: cc6b87ecaa96 ("net: tftp: Add client support for RFC 7440") Signed-off-by: Arjan Minzinga Zijlstra <arjan.minzingazijlstra@fox-it.com> Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
2022-04-10treewide: Rename PHY_INTERFACE_MODE_NONE to PHY_INTERFACE_MODE_NAMarek Behún1-2/+2
Rename constant PHY_INTERFACE_MODE_NONE to PHY_INTERFACE_MODE_NA to make it compatible with Linux' naming. Signed-off-by: Marek Behún <marek.behun@nic.cz> Reviewed-by: Stefan Roese <sr@denx.de> Reviewed-by: Ramon Fried <rfried.dev@gmail.com> Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
2022-04-10net: introduce helpers to get PHY interface mode from a device/ofnodeMarek Behún1-17/+1
Add helpers ofnode_read_phy_mode() and dev_read_phy_mode() to parse the "phy-mode" / "phy-connection-type" property. Add corresponding UT test. Use them treewide. This allows us to inline the phy_get_interface_by_name() into ofnode_read_phy_mode(), since the former is not used anymore. Signed-off-by: Marek Behún <marek.behun@nic.cz> Reviewed-by: Ramon Fried <rfried.dev@gmail.com> Tested-by: Patrice Chotard <patrice.chotard@foss.st.com>
2022-04-10treewide: use dm_mdio_read/write/reset() wrappersMarek Behún2-27/+8
Use the new dm_mdio_read/write/reset() wrappers treewide, instead of always getting and dereferencing MDIO operations structure pointer. Signed-off-by: Marek Behún <marek.behun@nic.cz> Reviewed-by: Ramon Fried <rfried.dev@gmail.com> Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
2022-04-10net: mdio-uclass: add wrappers for read/write/reset operationsMarek Behún1-0/+31
Add wrappers dm_mdio_read(), dm_mdio_write() and dm_mdio_reset() for DM MDIO's .read(), .write() and .reset() operations. Signed-off-by: Marek Behún <marek.behun@nic.cz> Reviewed-by: Ramon Fried <rfried.dev@gmail.com> Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
2022-04-10net: introduce helpers to get PHY ofnode from MACMarek Behún1-18/+6
Add helpers ofnode_get_phy_node() and dev_get_phy_node() and use it in net/mdio-uclass.c function dm_eth_connect_phy_handle(). Also add corresponding UT test. This is useful because other part's of U-Boot may want to get PHY ofnode without connecting a PHY. Signed-off-by: Marek Behún <marek.behun@nic.cz> Reviewed-by: Ramon Fried <rfried.dev@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
2022-04-10net: mdio-uclass: use ARRAY_SIZE()Marek Behún1-6/+5
Use the ARRAY_SIZE() macro instead of hardcoding sizes of arrays in macros. Signed-off-by: Marek Behún <marek.behun@nic.cz> Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
2022-04-10net: mdio-uclass: fix type for phy_mode_str and phy_handle_strMarek Behún1-5/+6
These global variables should both have type static const char * const Signed-off-by: Marek Behún <marek.behun@nic.cz> Reviewed-by: Ramon Fried <rfried.dev@gmail.com> Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
2022-03-25Convert CONFIG_SYS_RX_ETH_BUFFER to KconfigTom Rini1-0/+9
This converts the following to Kconfig: CONFIG_SYS_RX_ETH_BUFFER Cc: Ramon Fried <rfried.dev@gmail.com> Signed-off-by: Tom Rini <trini@konsulko.com>
2022-03-25Convert CONFIG_TFTP_PORT to KconfigTom Rini1-0/+18
This converts the following to Kconfig: CONFIG_TFTP_PORT Cc: Ramon Fried <rfried.dev@gmail.com> Signed-off-by: Tom Rini <trini@konsulko.com>
2022-03-25Convert CONFIG_SYS_FAULT_ECHO_LINK_DOWN to KconfigTom Rini1-0/+7
This converts the following to Kconfig: CONFIG_SYS_FAULT_ECHO_LINK_DOWN Cc: Ramon Fried <rfried.dev@gmail.com> Signed-off-by: Tom Rini <trini@konsulko.com>
2022-03-18Convert CONFIG_NFS_TIMEOUT to KconfigTom Rini1-7/+2
This converts the following to Kconfig: CONFIG_NFS_TIMEOUT Cc: Ramon Fried <rfried.dev@gmail.com> Signed-off-by: Tom Rini <trini@konsulko.com>