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

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.ru


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 365af7ac
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -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;
	u32 type;
@@ -2547,7 +2547,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,
@@ -2559,7 +2563,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);
@@ -2834,7 +2839,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;
@@ -2842,7 +2847,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,
@@ -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);
	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;
@@ -2910,7 +2920,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;