net: remove CONFIG_MCAST_TFTP
authorChris Packham <judge.packham@gmail.com>
Mon, 26 Nov 2018 08:00:29 +0000 (21:00 +1300)
committerJoe Hershberger <joe.hershberger@ni.com>
Thu, 24 Jan 2019 17:35:30 +0000 (11:35 -0600)
No mainline board enables CONFIG_MCAST_TFTP and there have been
compilation issues with the code for some time. Additionally, it has a
potential buffer underrun issue (reported as a side note in
CVE-2018-18439).

Remove the multicast TFTP code but keep the driver API for the future
addition of IPv6.

Cc: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
Signed-off-by: Chris Packham <judge.packham@gmail.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
README
drivers/net/rtl8139.c
drivers/net/tsec.c
drivers/usb/gadget/ether.c
include/net.h
net/eth-uclass.c
net/eth_legacy.c
net/net.c
net/tftp.c
scripts/config_whitelist.txt

diff --git a/README b/README
index 17d56b80349a7a97e847e30ab197e768e502b268..aed6b96b57ec3fecca99271aa250a0f7e4131a12 100644 (file)
--- a/README
+++ b/README
@@ -1429,15 +1429,6 @@ The following options need to be configured:
                forwarded through a router.
                (Environment variable "netmask")
 
-- Multicast TFTP Mode:
-               CONFIG_MCAST_TFTP
-
-               Defines whether you want to support multicast TFTP as per
-               rfc-2090; for example to work with atftp.  Lets lots of targets
-               tftp down the same boot image concurrently.  Note: the Ethernet
-               driver in use must provide a function: mcast() to join/leave a
-               multicast group.
-
 - BOOTP Recovery Mode:
                CONFIG_BOOTP_RANDOM_DELAY
 
index 590f8ce154264a01ee8a3ee68e15a1beab6aaab2..13309970e2c4b72617907de1d0d06b65185ea258 100644 (file)
@@ -183,12 +183,10 @@ static void rtl_reset(struct eth_device *dev);
 static int rtl_transmit(struct eth_device *dev, void *packet, int length);
 static int rtl_poll(struct eth_device *dev);
 static void rtl_disable(struct eth_device *dev);
-#ifdef CONFIG_MCAST_TFTP/*  This driver already accepts all b/mcast */
-static int rtl_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, u8 set)
+static int rtl_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, int join)
 {
        return (0);
 }
-#endif
 
 static struct pci_device_id supported[] = {
        {PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139},
@@ -229,9 +227,7 @@ int rtl8139_initialize(bd_t *bis)
                dev->halt = rtl_disable;
                dev->send = rtl_transmit;
                dev->recv = rtl_poll;
-#ifdef CONFIG_MCAST_TFTP
                dev->mcast = rtl_bcast_addr;
-#endif
 
                eth_register (dev);
 
index 9a4fab85e928361fa51ee2c4f75f97eef9695add..06a9b4fb03cefeedc0bb0d4e78cc8a5065019983 100644 (file)
@@ -78,8 +78,6 @@ static void tsec_configure_serdes(struct tsec_private *priv)
                              0, TBI_CR, CONFIG_TSEC_TBICR_SETTINGS);
 }
 
-#ifdef CONFIG_MCAST_TFTP
-
 /* the 'way' for ethernet-CRC-32. Spliced in from Linux lib/crc32.c
  * and this is the ethernet-crc method needed for TSEC -- and perhaps
  * some other adapter -- hash tables
@@ -124,9 +122,10 @@ static u32 ether_crc(size_t len, unsigned char const *p)
  * the entry.
  */
 #ifndef CONFIG_DM_ETH
-static int tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, u8 set)
+static int tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac,
+                          int join)
 #else
-static int tsec_mcast_addr(struct udevice *dev, const u8 *mcast_mac, int set)
+static int tsec_mcast_addr(struct udevice *dev, const u8 *mcast_mac, int join)
 #endif
 {
        struct tsec_private *priv = (struct tsec_private *)dev->priv;
@@ -140,14 +139,13 @@ static int tsec_mcast_addr(struct udevice *dev, const u8 *mcast_mac, int set)
 
        value = BIT(31 - whichbit);
 
-       if (set)
+       if (join)
                setbits_be32(&regs->hash.gaddr0 + whichreg, value);
        else
                clrbits_be32(&regs->hash.gaddr0 + whichreg, value);
 
        return 0;
 }
-#endif /* Multicast TFTP ? */
 
 /*
  * Initialized required registers to appropriate values, zeroing
@@ -745,9 +743,7 @@ static int tsec_initialize(bd_t *bis, struct tsec_info_struct *tsec_info)
        dev->halt = tsec_halt;
        dev->send = tsec_send;
        dev->recv = tsec_recv;
-#ifdef CONFIG_MCAST_TFTP
        dev->mcast = tsec_mcast_addr;
-#endif
 
        /* Tell U-Boot to get the addr from the env */
        for (i = 0; i < 6; i++)
@@ -887,9 +883,7 @@ static const struct eth_ops tsec_ops = {
        .recv = tsec_recv,
        .free_pkt = tsec_free_pkt,
        .stop = tsec_halt,
-#ifdef CONFIG_MCAST_TFTP
        .mcast = tsec_mcast_addr,
-#endif
 };
 
 static const struct udevice_id tsec_ids[] = {
index 3b3d9af681034d73a869e30b1dad278ffa61c4c5..e4993dc6e62c7d93ee12a0260336fb4d4bdd10c5 100644 (file)
@@ -2579,9 +2579,6 @@ int usb_eth_initialize(bd_t *bi)
        netdev->halt = usb_eth_halt;
        netdev->priv = l_priv;
 
-#ifdef CONFIG_MCAST_TFTP
-  #error not supported
-#endif
        eth_register(netdev);
        return 0;
 }
index 359bfb5ef69f659cbd757dff8c4f270001c8e433..dd52ed3f476c156c0528a7cbc3ed1ea153ad1493 100644 (file)
@@ -140,9 +140,7 @@ struct eth_ops {
        int (*recv)(struct udevice *dev, int flags, uchar **packetp);
        int (*free_pkt)(struct udevice *dev, uchar *packet, int length);
        void (*stop)(struct udevice *dev);
-#ifdef CONFIG_MCAST_TFTP
        int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join);
-#endif
        int (*write_hwaddr)(struct udevice *dev);
        int (*read_rom_hwaddr)(struct udevice *dev);
 };
@@ -175,9 +173,7 @@ struct eth_device {
        int (*send)(struct eth_device *, void *packet, int length);
        int (*recv)(struct eth_device *);
        void (*halt)(struct eth_device *);
-#ifdef CONFIG_MCAST_TFTP
-       int (*mcast)(struct eth_device *, const u8 *enetaddr, u8 set);
-#endif
+       int (*mcast)(struct eth_device *, const u8 *enetaddr, int join);
        int (*write_hwaddr)(struct eth_device *);
        struct eth_device *next;
        int index;
@@ -286,11 +282,7 @@ extern void (*push_packet)(void *packet, int length);
 int eth_rx(void);                      /* Check for received packets */
 void eth_halt(void);                   /* stop SCC */
 const char *eth_get_name(void);                /* get name of current device */
-
-#ifdef CONFIG_MCAST_TFTP
 int eth_mcast_join(struct in_addr mcast_addr, int join);
-#endif
-
 
 /**********************************************************************/
 /*
@@ -577,10 +569,6 @@ extern struct in_addr      net_ntp_server;         /* the ip address to NTP */
 extern int net_ntp_time_offset;                        /* offset time from UTC */
 #endif
 
-#if defined(CONFIG_MCAST_TFTP)
-extern struct in_addr net_mcast_addr;
-#endif
-
 /* Initialize the network adapter */
 void net_init(void);
 int net_loop(enum proto_t);
index 91d861be41365459a7bd5c114376b59b8c5a7652..2ef20df19203767a89896c6089193706c135a32a 100644 (file)
@@ -476,10 +476,8 @@ static int eth_post_probe(struct udevice *dev)
                        ops->free_pkt += gd->reloc_off;
                if (ops->stop)
                        ops->stop += gd->reloc_off;
-#ifdef CONFIG_MCAST_TFTP
                if (ops->mcast)
                        ops->mcast += gd->reloc_off;
-#endif
                if (ops->write_hwaddr)
                        ops->write_hwaddr += gd->reloc_off;
                if (ops->read_rom_hwaddr)
index d2e16b8fa3da63beb44653a2838c228979ee5be0..e250a430f333aa66d1774346377efdc93b908d3f 100644 (file)
@@ -291,7 +291,6 @@ int eth_initialize(void)
        return num_devices;
 }
 
-#ifdef CONFIG_MCAST_TFTP
 /* Multicast.
  * mcast_addr: multicast ipaddr from which multicast Mac is made
  * join: 1=join, 0=leave.
@@ -310,9 +309,6 @@ int eth_mcast_join(struct in_addr mcast_ip, int join)
        return eth_current->mcast(eth_current, mcast_mac, join);
 }
 
-#endif
-
-
 int eth_init(void)
 {
        struct eth_device *old_current;
index e9f7a7d85e7365d574850b8426b18b4df2813e88..58b0417cbe9401a7e267d73b286bdfc9dd04cbdb 100644 (file)
--- a/net/net.c
+++ b/net/net.c
@@ -131,10 +131,6 @@ struct in_addr net_dns_server;
 struct in_addr net_dns_server2;
 #endif
 
-#ifdef CONFIG_MCAST_TFTP       /* Multicast TFTP */
-struct in_addr net_mcast_addr;
-#endif
-
 /** END OF BOOTP EXTENTIONS **/
 
 /* Our ethernet address */
@@ -1216,9 +1212,6 @@ void net_process_received_packet(uchar *in_packet, int len)
                dst_ip = net_read_ip(&ip->ip_dst);
                if (net_ip.s_addr && dst_ip.s_addr != net_ip.s_addr &&
                    dst_ip.s_addr != 0xFFFFFFFF) {
-#ifdef CONFIG_MCAST_TFTP
-                       if (net_mcast_addr != dst_ip)
-#endif
                                return;
                }
                /* Read source IP address for later use */
index a9335b1b7e0b2a20ccb0757e5c3b81edc7e1a2c2..8fab6d2650f77c49b788c41f67d1b754b479c1df 100644 (file)
@@ -140,36 +140,6 @@ static char tftp_filename[MAX_LEN];
 static unsigned short tftp_block_size = TFTP_BLOCK_SIZE;
 static unsigned short tftp_block_size_option = TFTP_MTU_BLOCKSIZE;
 
-#ifdef CONFIG_MCAST_TFTP
-#include <malloc.h>
-#define MTFTP_BITMAPSIZE       0x1000
-static unsigned *tftp_mcast_bitmap;
-static int tftp_mcast_prev_hole;
-static int tftp_mcast_bitmap_size = MTFTP_BITMAPSIZE;
-static int tftp_mcast_disabled;
-static int tftp_mcast_master_client;
-static int tftp_mcast_active;
-static int tftp_mcast_port;
-/* can get 'last' block before done..*/
-static ulong tftp_mcast_ending_block;
-
-static void parse_multicast_oack(char *pkt, int len);
-
-static void mcast_cleanup(void)
-{
-       if (net_mcast_addr)
-               eth_mcast_join(net_mcast_addr, 0);
-       if (tftp_mcast_bitmap)
-               free(tftp_mcast_bitmap);
-       tftp_mcast_bitmap = NULL;
-       net_mcast_addr.s_addr = 0;
-       tftp_mcast_active = 0;
-       tftp_mcast_port = 0;
-       tftp_mcast_ending_block = -1;
-}
-
-#endif /* CONFIG_MCAST_TFTP */
-
 static inline int store_block(int block, uchar *src, unsigned int len)
 {
        ulong offset = block * tftp_block_size + tftp_block_wrap_offset;
@@ -211,10 +181,6 @@ static inline int store_block(int block, uchar *src, unsigned int len)
                memcpy(ptr, src, len);
                unmap_sysmem(ptr);
        }
-#ifdef CONFIG_MCAST_TFTP
-       if (tftp_mcast_active)
-               ext2_set_bit(block, tftp_mcast_bitmap);
-#endif
 
        if (net_boot_file_size < newsize)
                net_boot_file_size = newsize;
@@ -292,9 +258,6 @@ static void show_block_marker(void)
 static void restart(const char *msg)
 {
        printf("\n%s; starting again\n", msg);
-#ifdef CONFIG_MCAST_TFTP
-       mcast_cleanup();
-#endif
        net_start_again();
 }
 
@@ -349,12 +312,6 @@ static void tftp_send(void)
        int len = 0;
        ushort *s;
 
-#ifdef CONFIG_MCAST_TFTP
-       /* Multicast TFTP.. non-MasterClients do not ACK data. */
-       if (tftp_mcast_active && tftp_state == STATE_DATA &&
-           tftp_mcast_master_client == 0)
-               return;
-#endif
        /*
         *      We will always be sending some sort of packet, so
         *      cobble together the packet headers now.
@@ -389,30 +346,10 @@ static void tftp_send(void)
                /* try for more effic. blk size */
                pkt += sprintf((char *)pkt, "blksize%c%d%c",
                                0, tftp_block_size_option, 0);
-#ifdef CONFIG_MCAST_TFTP
-               /* Check all preconditions before even trying the option */
-               if (!tftp_mcast_disabled) {
-                       tftp_mcast_bitmap = malloc(tftp_mcast_bitmap_size);
-                       if (tftp_mcast_bitmap && eth_get_dev()->mcast) {
-                               free(tftp_mcast_bitmap);
-                               tftp_mcast_bitmap = NULL;
-                               pkt += sprintf((char *)pkt, "multicast%c%c",
-                                       0, 0);
-                       }
-               }
-#endif /* CONFIG_MCAST_TFTP */
                len = pkt - xp;
                break;
 
        case STATE_OACK:
-#ifdef CONFIG_MCAST_TFTP
-               /* My turn!  Start at where I need blocks I missed. */
-               if (tftp_mcast_active)
-                       tftp_cur_block = ext2_find_next_zero_bit(
-                               tftp_mcast_bitmap,
-                               tftp_mcast_bitmap_size * 8, 0);
-               /* fall through */
-#endif
 
        case STATE_RECV_WRQ:
        case STATE_DATA:
@@ -482,10 +419,6 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
        int i;
 
        if (dest != tftp_our_port) {
-#ifdef CONFIG_MCAST_TFTP
-               if (tftp_mcast_active &&
-                   (!tftp_mcast_port || dest != tftp_mcast_port))
-#endif
                        return;
        }
        if (tftp_state != STATE_SEND_RRQ && src != tftp_remote_port &&
@@ -566,12 +499,6 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
                        }
 #endif
                }
-#ifdef CONFIG_MCAST_TFTP
-               parse_multicast_oack((char *)pkt, len - 1);
-               if ((tftp_mcast_active) && (!tftp_mcast_master_client))
-                       tftp_state = STATE_DATA;        /* passive.. */
-               else
-#endif
 #ifdef CONFIG_CMD_TFTPPUT
                if (tftp_put_active) {
                        /* Get ready to send the first block */
@@ -599,11 +526,6 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
                        tftp_remote_port = src;
                        new_transfer();
 
-#ifdef CONFIG_MCAST_TFTP
-                       if (tftp_mcast_active) { /* start!=1 common if mcast */
-                               tftp_prev_block = tftp_cur_block - 1;
-                       } else
-#endif
                        if (tftp_cur_block != 1) {      /* Assertion */
                                puts("\nTFTP error: ");
                                printf("First block is not block 1 (%ld)\n",
@@ -633,44 +555,8 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
                 *      Acknowledge the block just received, which will prompt
                 *      the remote for the next one.
                 */
-#ifdef CONFIG_MCAST_TFTP
-               /* if I am the MasterClient, actively calculate what my next
-                * needed block is; else I'm passive; not ACKING
-                */
-               if (tftp_mcast_active) {
-                       if (len < tftp_block_size)  {
-                               tftp_mcast_ending_block = tftp_cur_block;
-                       } else if (tftp_mcast_master_client) {
-                               tftp_mcast_prev_hole = ext2_find_next_zero_bit(
-                                       tftp_mcast_bitmap,
-                                       tftp_mcast_bitmap_size * 8,
-                                       tftp_mcast_prev_hole);
-                               tftp_cur_block = tftp_mcast_prev_hole;
-                               if (tftp_cur_block >
-                                   ((tftp_mcast_bitmap_size * 8) - 1)) {
-                                       debug("tftpfile too big\n");
-                                       /* try to double it and retry */
-                                       tftp_mcast_bitmap_size <<= 1;
-                                       mcast_cleanup();
-                                       net_start_again();
-                                       return;
-                               }
-                               tftp_prev_block = tftp_cur_block;
-                       }
-               }
-#endif
                tftp_send();
 
-#ifdef CONFIG_MCAST_TFTP
-               if (tftp_mcast_active) {
-                       if (tftp_mcast_master_client &&
-                           (tftp_cur_block >= tftp_mcast_ending_block)) {
-                               puts("\nMulticast tftp done\n");
-                               mcast_cleanup();
-                               net_set_state(NETLOOP_SUCCESS);
-                       }
-               } else
-#endif
                if (len < tftp_block_size)
                        tftp_complete();
                break;
@@ -693,9 +579,6 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
                case TFTP_ERR_FILE_ALREADY_EXISTS:
                default:
                        puts("Starting again\n\n");
-#ifdef CONFIG_MCAST_TFTP
-                       mcast_cleanup();
-#endif
                        net_start_again();
                        break;
                }
@@ -873,9 +756,6 @@ void tftp_start(enum proto_t protocol)
        memset(net_server_ethaddr, 0, 6);
        /* Revert tftp_block_size to dflt */
        tftp_block_size = TFTP_BLOCK_SIZE;
-#ifdef CONFIG_MCAST_TFTP
-       mcast_cleanup();
-#endif
 #ifdef CONFIG_TFTP_TSIZE
        tftp_tsize = 0;
        tftp_tsize_num_hash = 0;
@@ -924,102 +804,3 @@ void tftp_start_server(void)
 }
 #endif /* CONFIG_CMD_TFTPSRV */
 
-#ifdef CONFIG_MCAST_TFTP
-/*
- * Credits: atftp project.
- */
-
-/*
- * Pick up BcastAddr, Port, and whether I am [now] the master-client.
- * Frame:
- *    +-------+-----------+---+-------~~-------+---+
- *    |  opc  | multicast | 0 | addr, port, mc | 0 |
- *    +-------+-----------+---+-------~~-------+---+
- * The multicast addr/port becomes what I listen to, and if 'mc' is '1' then
- * I am the new master-client so must send ACKs to DataBlocks.  If I am not
- * master-client, I'm a passive client, gathering what DataBlocks I may and
- * making note of which ones I got in my bitmask.
- * In theory, I never go from master->passive..
- * .. this comes in with pkt already pointing just past opc
- */
-static void parse_multicast_oack(char *pkt, int len)
-{
-       int i;
-       struct in_addr addr;
-       char *mc_adr;
-       char *port;
-       char *mc;
-
-       mc_adr = NULL;
-       port = NULL;
-       mc = NULL;
-       /* march along looking for 'multicast\0', which has to start at least
-        * 14 bytes back from the end.
-        */
-       for (i = 0; i < len - 14; i++)
-               if (strcmp(pkt + i, "multicast") == 0)
-                       break;
-       if (i >= (len - 14)) /* non-Multicast OACK, ign. */
-               return;
-
-       i += 10; /* strlen multicast */
-       mc_adr = pkt + i;
-       for (; i < len; i++) {
-               if (*(pkt + i) == ',') {
-                       *(pkt + i) = '\0';
-                       if (port) {
-                               mc = pkt + i + 1;
-                               break;
-                       } else {
-                               port = pkt + i + 1;
-                       }
-               }
-       }
-       if (!port || !mc_adr || !mc)
-               return;
-       if (tftp_mcast_active && tftp_mcast_master_client) {
-               printf("I got a OACK as master Client, WRONG!\n");
-               return;
-       }
-       /* ..I now accept packets destined for this MCAST addr, port */
-       if (!tftp_mcast_active) {
-               if (tftp_mcast_bitmap) {
-                       printf("Internal failure! no mcast.\n");
-                       free(tftp_mcast_bitmap);
-                       tftp_mcast_bitmap = NULL;
-                       tftp_mcast_disabled = 1;
-                       return;
-               }
-               /* I malloc instead of pre-declare; so that if the file ends
-                * up being too big for this bitmap I can retry
-                */
-               tftp_mcast_bitmap = malloc(tftp_mcast_bitmap_size);
-               if (!tftp_mcast_bitmap) {
-                       printf("No bitmap, no multicast. Sorry.\n");
-                       tftp_mcast_disabled = 1;
-                       return;
-               }
-               memset(tftp_mcast_bitmap, 0, tftp_mcast_bitmap_size);
-               tftp_mcast_prev_hole = 0;
-               tftp_mcast_active = 1;
-       }
-       addr = string_to_ip(mc_adr);
-       if (net_mcast_addr.s_addr != addr.s_addr) {
-               if (net_mcast_addr.s_addr)
-                       eth_mcast_join(net_mcast_addr, 0);
-               net_mcast_addr = addr;
-               if (eth_mcast_join(net_mcast_addr, 1)) {
-                       printf("Fail to set mcast, revert to TFTP\n");
-                       tftp_mcast_disabled = 1;
-                       mcast_cleanup();
-                       net_start_again();
-               }
-       }
-       tftp_mcast_master_client = simple_strtoul((char *)mc, NULL, 10);
-       tftp_mcast_port = (unsigned short)simple_strtoul(port, NULL, 10);
-       printf("Multicast: %s:%d [%d]\n", mc_adr, tftp_mcast_port,
-              tftp_mcast_master_client);
-       return;
-}
-
-#endif /* Multicast TFTP */
index e6ac098e279cac1895cfa0b4a861215546059a09..d03ddd876ff697341c88e1d208d3e04e7c305398 100644 (file)
@@ -1198,7 +1198,6 @@ CONFIG_MAX_FPGA_DEVICES
 CONFIG_MAX_MEM_MAPPED
 CONFIG_MAX_PKT
 CONFIG_MAX_RAM_BANK_SIZE
-CONFIG_MCAST_TFTP
 CONFIG_MCF5249
 CONFIG_MCF5253
 CONFIG_MCFFEC