net: ar8216: address security vulnerabilities in swconfig & ar8216
[openwrt/staging/yousong.git] / target / linux / generic / files / drivers / net / phy / ar8216.c
index 6c670dd75f18c64ae9a48c64fcf17d60904cab9a..746d8e6c3dcc312b03f851901b0c4d9ec8edfa96 100644 (file)
@@ -536,7 +536,7 @@ ar8216_mangle_rx(struct net_device *dev, struct sk_buff *skb)
        if ((buf[12 + 2] != 0x81) || (buf[13 + 2] != 0x00))
                return;
 
-       port = buf[0] & 0xf;
+       port = buf[0] & 0x7;
 
        /* no need to fix up packets coming from a tagged source */
        if (priv->vlan_tagged & (1 << port))
@@ -949,7 +949,8 @@ ar8xxx_sw_set_pvid(struct switch_dev *dev, int port, int vlan)
 
        /* make sure no invalid PVIDs get set */
 
-       if (vlan >= dev->vlans)
+       if (vlan < 0 || vlan >= dev->vlans ||
+           port < 0 || port >= AR8X16_MAX_PORTS)
                return -EINVAL;
 
        priv->pvid[port] = vlan;
@@ -960,6 +961,10 @@ int
 ar8xxx_sw_get_pvid(struct switch_dev *dev, int port, int *vlan)
 {
        struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
+
+       if (port < 0 || port >= AR8X16_MAX_PORTS)
+               return -EINVAL;
+
        *vlan = priv->pvid[port];
        return 0;
 }
@@ -969,6 +974,10 @@ ar8xxx_sw_set_vid(struct switch_dev *dev, const struct switch_attr *attr,
                  struct switch_val *val)
 {
        struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
+
+       if (val->port_vlan >= AR8X16_MAX_PORTS)
+               return -EINVAL;
+
        priv->vlan_id[val->port_vlan] = val->value.i;
        return 0;
 }
@@ -996,9 +1005,13 @@ static int
 ar8xxx_sw_get_ports(struct switch_dev *dev, struct switch_val *val)
 {
        struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
-       u8 ports = priv->vlan_table[val->port_vlan];
+       u8 ports;
        int i;
 
+       if (val->port_vlan >= AR8X16_MAX_VLANS)
+               return -EINVAL;
+
+       ports = priv->vlan_table[val->port_vlan];
        val->len = 0;
        for (i = 0; i < dev->ports; i++) {
                struct switch_port *p;
@@ -1378,7 +1391,7 @@ ar8xxx_sw_get_port_mib(struct switch_dev *dev,
        struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
        const struct ar8xxx_chip *chip = priv->chip;
        u64 *mib_stats, mib_data;
-       int port;
+       unsigned int port;
        int ret;
        char *buf = priv->buf;
        char buf1[64];