Commit 96c15594 authored by Aleksandr Mishin's avatar Aleksandr Mishin Committed by Jakub Kicinski

net: phy: micrel: Fix potential null pointer dereference

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: ece19502 ("net: phy: micrel: 1588 support for LAN8814 phy")
Signed-off-by: default avatarAleksandr Mishin <amishin@t-argos.ru>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/20240329061631.33199-1-amishin@t-argos.ruSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 365af7ac
...@@ -2537,7 +2537,7 @@ static void lan8814_txtstamp(struct mii_timestamper *mii_ts, ...@@ -2537,7 +2537,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; struct ptp_header *ptp_header;
u32 type; u32 type;
...@@ -2547,7 +2547,11 @@ static void lan8814_get_sig_rx(struct sk_buff *skb, u16 *sig) ...@@ -2547,7 +2547,11 @@ static void lan8814_get_sig_rx(struct sk_buff *skb, u16 *sig)
ptp_header = ptp_parse_header(skb, type); ptp_header = ptp_parse_header(skb, type);
skb_pull_inline(skb, ETH_HLEN); skb_pull_inline(skb, ETH_HLEN);
if (!ptp_header)
return false;
*sig = (__force u16)(ntohs(ptp_header->sequence_id)); *sig = (__force u16)(ntohs(ptp_header->sequence_id));
return true;
} }
static bool lan8814_match_rx_skb(struct kszphy_ptp_priv *ptp_priv, static bool lan8814_match_rx_skb(struct kszphy_ptp_priv *ptp_priv,
...@@ -2559,7 +2563,8 @@ static bool lan8814_match_rx_skb(struct kszphy_ptp_priv *ptp_priv, ...@@ -2559,7 +2563,8 @@ static bool lan8814_match_rx_skb(struct kszphy_ptp_priv *ptp_priv,
bool ret = false; bool ret = false;
u16 skb_sig; 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 */ /* Iterate over all RX timestamps and match it with the received skbs */
spin_lock_irqsave(&ptp_priv->rx_ts_lock, flags); spin_lock_irqsave(&ptp_priv->rx_ts_lock, flags);
...@@ -2834,7 +2839,7 @@ static int lan8814_ptpci_adjfine(struct ptp_clock_info *ptpci, long scaled_ppm) ...@@ -2834,7 +2839,7 @@ static int lan8814_ptpci_adjfine(struct ptp_clock_info *ptpci, long scaled_ppm)
return 0; 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; struct ptp_header *ptp_header;
u32 type; u32 type;
...@@ -2842,7 +2847,11 @@ static void lan8814_get_sig_tx(struct sk_buff *skb, u16 *sig) ...@@ -2842,7 +2847,11 @@ static void lan8814_get_sig_tx(struct sk_buff *skb, u16 *sig)
type = ptp_classify_raw(skb); type = ptp_classify_raw(skb);
ptp_header = ptp_parse_header(skb, type); ptp_header = ptp_parse_header(skb, type);
if (!ptp_header)
return false;
*sig = (__force u16)(ntohs(ptp_header->sequence_id)); *sig = (__force u16)(ntohs(ptp_header->sequence_id));
return true;
} }
static void lan8814_match_tx_skb(struct kszphy_ptp_priv *ptp_priv, static void lan8814_match_tx_skb(struct kszphy_ptp_priv *ptp_priv,
...@@ -2856,7 +2865,8 @@ static void lan8814_match_tx_skb(struct kszphy_ptp_priv *ptp_priv, ...@@ -2856,7 +2865,8 @@ static void lan8814_match_tx_skb(struct kszphy_ptp_priv *ptp_priv,
spin_lock_irqsave(&ptp_priv->tx_queue.lock, flags); spin_lock_irqsave(&ptp_priv->tx_queue.lock, flags);
skb_queue_walk_safe(&ptp_priv->tx_queue, skb, skb_tmp) { 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))) if (memcmp(&skb_sig, &seq_id, sizeof(seq_id)))
continue; continue;
...@@ -2910,7 +2920,8 @@ static bool lan8814_match_skb(struct kszphy_ptp_priv *ptp_priv, ...@@ -2910,7 +2920,8 @@ static bool lan8814_match_skb(struct kszphy_ptp_priv *ptp_priv,
spin_lock_irqsave(&ptp_priv->rx_queue.lock, flags); spin_lock_irqsave(&ptp_priv->rx_queue.lock, flags);
skb_queue_walk_safe(&ptp_priv->rx_queue, skb, skb_tmp) { 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))) if (memcmp(&skb_sig, &rx_ts->seq_id, sizeof(rx_ts->seq_id)))
continue; continue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment