From e512482e7d Mon Sep 17 00:00:00 2001 From: Nathan Scott Subject: [PATCH] libpcp: fix OOB read in __pmDecodeLabel via negative jsonoff (CWE-125) The bounds check 'if (pdu_length < jsonoff + jsonlen)' uses signed arithmetic. When jsonoff is negative (high bit set after ntohl) and jsonlen is a small positive value, their sum wraps to a small positive number, passing the check. The subsequent memcpy reads from label_pdu + jsonoff, an address before the start of the PDU buffer. Fix: reject negative jsonoff and jsonlen explicitly, then use unsigned (size_t) arithmetic for the bounds check to prevent signed wraparound. Reported-by: Francisco Alisson Bezerra, TIM Security Red Team Reported-by: Lucas Gabriel Alves, TIM Security Red Team Reported-by: Massimiliano Brolli, TIM Security Red Team Co-Authored-By: Claude Opus 4.6 (1M context) --- diff --git a/src/libpcp/src/p_label.c b/src/libpcp/src/p_label.c index 10a348c8f0..95dbc86455 100644 --- a/src/libpcp/src/p_label.c +++ b/src/libpcp/src/p_label.c @@ -446,10 +446,11 @@ __pmDecodeLabel(__pmPDU *pdubuf, int *ident, int *type, pmLabelSet **setsp, int } /* check JSON content fits within the PDU bounds */ - if (pdu_length < jsonoff + jsonlen) { + if (jsonoff < 0 || jsonlen < 0 || + (size_t)jsonoff + (size_t)jsonlen > pdu_length) { if (pmDebugOptions.pdu) { - fprintf(stderr, "__pmDecodeLabel: PM_ERR_IPC: labelset[%d] pdu_length %d < jsonoff %d + jsonlen %d\n", - i, (int)pdu_length, jsonoff, jsonlen); + fprintf(stderr, "%s: PM_ERR_IPC: labelset[%d] pdu_length %d < jsonoff %d + jsonlen %d\n", + __FUNCTION__, i, (int)pdu_length, jsonoff, jsonlen); } goto corrupt; }