From 7111d23ae409d8da76c85682b378e2e4f3aeabf8 Mon Sep 17 00:00:00 2001 From: Zhe Weng Date: Mon, 6 Mar 2023 17:30:25 +0800 Subject: [PATCH] net/arp: Only parse ioctl request for valid cmd. Signed-off-by: Zhe Weng --- net/netdev/netdev_ioctl.c | 54 +++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index 94df206ecc8..a2461522a1d 100644 --- a/net/netdev/netdev_ioctl.c +++ b/net/netdev/netdev_ioctl.c @@ -1219,6 +1219,40 @@ static int netdev_imsf_ioctl(FAR struct socket *psock, int cmd, } #endif +/**************************************************************************** + * Name: ioctl_arpreq_parse + * + * Description: + * Parse arpreq into netdev and sockaddr. + * + * Input Parameters: + * req The argument of the ioctl cmd + * dev The pointer to get ethernet driver device structure + * addr The pointer to get address in the request + * + * Returned Value: + * true on success and false on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_ARP +static bool ioctl_arpreq_parse(FAR struct arpreq *req, + FAR struct net_driver_s **dev, + FAR struct sockaddr_in **addr) +{ + if (req != NULL) + { + *addr = (FAR struct sockaddr_in *)&req->arp_pa; + *dev = req->arp_dev[0] != '\0' ? + netdev_findbyname((FAR const char *)req->arp_dev) : + netdev_findby_ripv4addr(INADDR_ANY, (*addr)->sin_addr.s_addr); + return true; + } + + return false; +} +#endif + /**************************************************************************** * Name: netdev_arp_ioctl * @@ -1241,25 +1275,17 @@ static int netdev_imsf_ioctl(FAR struct socket *psock, int cmd, static int netdev_arp_ioctl(FAR struct socket *psock, int cmd, FAR struct arpreq *req) { - FAR struct net_driver_s *dev = NULL; - FAR struct sockaddr_in *addr = NULL; + FAR struct net_driver_s *dev; + FAR struct sockaddr_in *addr; int ret; - if (req != NULL) - { - addr = (FAR struct sockaddr_in *)&req->arp_pa; - dev = req->arp_dev[0] ? - netdev_findbyname((FAR const char *)req->arp_dev) : - netdev_findby_ripv4addr(INADDR_ANY, addr->sin_addr.s_addr); - } - /* Execute the command */ switch (cmd) { case SIOCSARP: /* Set an ARP mapping */ { - if (dev != NULL && req != NULL && + if (ioctl_arpreq_parse(req, &dev, &addr) && dev != NULL && req->arp_pa.sa_family == AF_INET && req->arp_ha.sa_family == ARPHRD_ETHER) { @@ -1279,7 +1305,8 @@ static int netdev_arp_ioctl(FAR struct socket *psock, int cmd, case SIOCDARP: /* Delete an ARP mapping */ { - if (dev != NULL && req != NULL && req->arp_pa.sa_family == AF_INET) + if (ioctl_arpreq_parse(req, &dev, &addr) && dev != NULL && + req->arp_pa.sa_family == AF_INET) { /* Delete the ARP entry for this protocol address. */ @@ -1294,7 +1321,8 @@ static int netdev_arp_ioctl(FAR struct socket *psock, int cmd, case SIOCGARP: /* Get an ARP mapping */ { - if (req != NULL && req->arp_pa.sa_family == AF_INET) + if (ioctl_arpreq_parse(req, &dev, &addr) && + req->arp_pa.sa_family == AF_INET) { ret = arp_find(addr->sin_addr.s_addr, (FAR uint8_t *)req->arp_ha.sa_data, dev);