6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Tristan Madani [ Upstream commit 1e860f42f41c6fbf3304f6a52be38245b9394982 ] ppp_ccp_peek() caches a pointer to skb->data in dp after the first pskb_may_pull(), then uses dp after a second pskb_may_pull(skb, len + 2) in the CCP_CONFACK handler. If the second pull triggers pskb_expand_head() due to a cloned skb or frag linearization, skb->head is freed and reallocated, leaving dp stale. The stale dp is subsequently used in CCP_OPT_LENGTH() and passed to decomp_init()/comp_init() which read from the freed memory. Re-derive dp from skb->data after the second pskb_may_pull. Fixes: 1da177e4c3f41 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Tristan Madani Signed-off-by: Dave Miller Signed-off-by: Sasha Levin --- drivers/net/ppp/ppp_generic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 14fa87a8e0834..61c240d846ee2 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -3204,6 +3204,7 @@ ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound) len = CCP_LENGTH(dp); if (!pskb_may_pull(skb, len + 2)) return; /* too short */ + dp = skb->data + 2; dp += CCP_HDRLEN; len -= CCP_HDRLEN; if (len < CCP_OPT_MINLEN || len < CCP_OPT_LENGTH(dp)) -- 2.53.0