]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: phy: micrel: Fix potential null pointer dereference
authorAleksandr Mishin <amishin@t-argos.ru>
Fri, 29 Mar 2024 06:16:31 +0000 (09:16 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 10 Apr 2024 14:35:52 +0000 (16:35 +0200)
commit 96c155943a703f0655c0c4cab540f67055960e91 upstream.

In lan8814_get_sig_rx() and lan8814_get_sig_tx() ptp_parse_header() may
return NULL as ptp_header due to abnormal packet type or corrupted packet.
Fix this bug by adding ptp_header check.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: ece19502834d ("net: phy: micrel: 1588 support for LAN8814 phy")
Signed-off-by: Aleksandr Mishin <amishin@t-argos.ru>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/20240329061631.33199-1-amishin@t-argos.ru
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/phy/micrel.c

index c44b29c4a3dc6f0ae8cffeac8ee655570b520300..cbd98ea4a84afc167358f92194d1b44b50314fb3 100644 (file)
@@ -2503,7 +2503,7 @@ static void lan8814_txtstamp(struct mii_timestamper *mii_ts,
        }
 }
 
-static void lan8814_get_sig_rx(struct sk_buff *skb, u16 *sig)
+static bool lan8814_get_sig_rx(struct sk_buff *skb, u16 *sig)
 {
        struct ptp_header *ptp_header;
        u32 type;
@@ -2513,7 +2513,11 @@ static void lan8814_get_sig_rx(struct sk_buff *skb, u16 *sig)
        ptp_header = ptp_parse_header(skb, type);
        skb_pull_inline(skb, ETH_HLEN);
 
+       if (!ptp_header)
+               return false;
+
        *sig = (__force u16)(ntohs(ptp_header->sequence_id));
+       return true;
 }
 
 static bool lan8814_match_rx_skb(struct kszphy_ptp_priv *ptp_priv,
@@ -2525,7 +2529,8 @@ static bool lan8814_match_rx_skb(struct kszphy_ptp_priv *ptp_priv,
        bool ret = false;
        u16 skb_sig;
 
-       lan8814_get_sig_rx(skb, &skb_sig);
+       if (!lan8814_get_sig_rx(skb, &skb_sig))
+               return ret;
 
        /* Iterate over all RX timestamps and match it with the received skbs */
        spin_lock_irqsave(&ptp_priv->rx_ts_lock, flags);
@@ -2805,7 +2810,7 @@ static int lan8814_ptpci_adjfine(struct ptp_clock_info *ptpci, long scaled_ppm)
        return 0;
 }
 
-static void lan8814_get_sig_tx(struct sk_buff *skb, u16 *sig)
+static bool lan8814_get_sig_tx(struct sk_buff *skb, u16 *sig)
 {
        struct ptp_header *ptp_header;
        u32 type;
@@ -2813,7 +2818,11 @@ static void lan8814_get_sig_tx(struct sk_buff *skb, u16 *sig)
        type = ptp_classify_raw(skb);
        ptp_header = ptp_parse_header(skb, type);
 
+       if (!ptp_header)
+               return false;
+
        *sig = (__force u16)(ntohs(ptp_header->sequence_id));
+       return true;
 }
 
 static void lan8814_match_tx_skb(struct kszphy_ptp_priv *ptp_priv,
@@ -2827,7 +2836,8 @@ static void lan8814_match_tx_skb(struct kszphy_ptp_priv *ptp_priv,
 
        spin_lock_irqsave(&ptp_priv->tx_queue.lock, flags);
        skb_queue_walk_safe(&ptp_priv->tx_queue, skb, skb_tmp) {
-               lan8814_get_sig_tx(skb, &skb_sig);
+               if (!lan8814_get_sig_tx(skb, &skb_sig))
+                       continue;
 
                if (memcmp(&skb_sig, &seq_id, sizeof(seq_id)))
                        continue;
@@ -2881,7 +2891,8 @@ static bool lan8814_match_skb(struct kszphy_ptp_priv *ptp_priv,
 
        spin_lock_irqsave(&ptp_priv->rx_queue.lock, flags);
        skb_queue_walk_safe(&ptp_priv->rx_queue, skb, skb_tmp) {
-               lan8814_get_sig_rx(skb, &skb_sig);
+               if (!lan8814_get_sig_rx(skb, &skb_sig))
+                       continue;
 
                if (memcmp(&skb_sig, &rx_ts->seq_id, sizeof(rx_ts->seq_id)))
                        continue;