156 lines
4.4 KiB
Diff
156 lines
4.4 KiB
Diff
From 33a21d3552ba59889654c53dfc41c385180dcc6a Mon Sep 17 00:00:00 2001
|
|
From: Ken McDonell <kenj@kenj.id.au>
|
|
Date: Thu, 8 Aug 2024 18:58:23 +1000
|
|
Subject: [PATCH 13/19] src/libpcp/src/p_result.c: correct buffer over-run test
|
|
in __pmDecodeValueSet()
|
|
|
|
Addresses SUSE Issue A.
|
|
|
|
Also new qa/1518 to verify fix.
|
|
|
|
(cherry picked from commit 3fc59861174ac0bbb08f5fa98cadb0d206f5cc60)
|
|
[ddiss: rebase without 48ee02dc6 ("libpcp: extra diagnostics associated
|
|
with PM_ERR_IPC")]
|
|
Acked-by: David Disseldorp <ddiss@suse.de>
|
|
---
|
|
qa/1518 | 75 +++++++++++++++++++++++++++++++++++++++
|
|
qa/1518.out | 11 ++++++
|
|
qa/group | 1 +
|
|
src/libpcp/src/p_result.c | 7 ++--
|
|
4 files changed, 90 insertions(+), 4 deletions(-)
|
|
create mode 100755 qa/1518
|
|
create mode 100644 qa/1518.out
|
|
|
|
diff --git a/qa/1518 b/qa/1518
|
|
new file mode 100755
|
|
index 000000000..aee12567e
|
|
--- /dev/null
|
|
+++ b/qa/1518
|
|
@@ -0,0 +1,75 @@
|
|
+#!/bin/sh
|
|
+# PCP QA Test No. 1518
|
|
+# SUSE Issue A)
|
|
+# __pmDecodeValueSet() Miscalculates Available Buffer Space
|
|
+# Leading to a Possible Heap Corruption
|
|
+#
|
|
+# Copyright (c) 2024 Ken McDonell. All Rights Reserved.
|
|
+# Copyright (c) 2024 Matthias Gerstner. All Rights Reserved.
|
|
+#
|
|
+
|
|
+if [ $# -eq 0 ]
|
|
+then
|
|
+ seq=`basename $0`
|
|
+ echo "QA output created by $seq"
|
|
+else
|
|
+ # use $seq from caller, unless not set
|
|
+ [ -n "$seq" ] || seq=`basename $0`
|
|
+ echo "QA output created by `basename $0` $*"
|
|
+fi
|
|
+
|
|
+# get standard environment, filters and checks
|
|
+. ./common.product
|
|
+. ./common.filter
|
|
+. ./common.check
|
|
+
|
|
+$sudo rm -rf $tmp $tmp.* $seq.full
|
|
+
|
|
+which nc >/dev/null 2>&1 || _notrun "no nc executable installed"
|
|
+_check_valgrind
|
|
+
|
|
+_cleanup()
|
|
+{
|
|
+ cat pmcd.log >>$here/$seq.full
|
|
+ cd $here
|
|
+ $sudo rm -rf $tmp $tmp.*
|
|
+}
|
|
+
|
|
+status=0 # success is the default!
|
|
+trap "_cleanup; exit \$status" 0 1 2 3 15
|
|
+
|
|
+_filter()
|
|
+{
|
|
+ sed \
|
|
+ -e '/^Command: /d' \
|
|
+ # end
|
|
+}
|
|
+
|
|
+mkdir $tmp || exit 1
|
|
+cd $tmp
|
|
+grep sampledso $PCP_PMCDCONF_PATH >pmcd.conf
|
|
+cat pmcd.conf >>$here/$seq.full
|
|
+port=`_find_free_port`
|
|
+echo "port=$port" >>$here/$seq.full
|
|
+
|
|
+# real QA test starts here
|
|
+valgrind $PCP_BINADM_DIR/pmcd -f -Dpdu -c ./pmcd.conf -s ./pmcd.socket -p $port >out 2>err &
|
|
+valgrind_pid=$!
|
|
+sleep 2
|
|
+pmcd_pid=`$PCP_PS_PROG $PCP_PS_ALL_FLAGS | grep '[p]mcd -f -Dpdu' | $PCP_AWK_PROG '{ print $2 }'`
|
|
+echo "pmcd_pid=$pmcd_pid" >>$here/$seq.full
|
|
+nc -N -U ./pmcd.socket <$here/binary/decode-value-set-out-of-bound-write 2>&1 \
|
|
+| od -c >>$here/$seq.full
|
|
+sleep 2
|
|
+kill -TERM $pmcd_pid
|
|
+wait
|
|
+
|
|
+echo "expect error to be logged ..."
|
|
+grep __pmDecodeValueSet pmcd.log
|
|
+
|
|
+echo
|
|
+echo "and no valgrind badness ..."
|
|
+cat out err | _filter_valgrind | _filter
|
|
+
|
|
+# success, all done
|
|
+exit
|
|
diff --git a/qa/1518.out b/qa/1518.out
|
|
new file mode 100644
|
|
index 000000000..3e9282414
|
|
--- /dev/null
|
|
+++ b/qa/1518.out
|
|
@@ -0,0 +1,11 @@
|
|
+QA output created by 1518
|
|
+expect error to be logged ...
|
|
+__pmDecodeValueSet: PM_ERR_IPC: pmid[0] value[0] vindex=1020 (max=255)
|
|
+
|
|
+and no valgrind badness ...
|
|
+Memcheck, a memory error detector
|
|
+LEAK SUMMARY:
|
|
+definitely lost: 0 bytes in 0 blocks
|
|
+indirectly lost: 0 bytes in 0 blocks
|
|
+Rerun with --leak-check=full to see details of leaked memory
|
|
+ERROR SUMMARY: 0 errors from 0 contexts ...
|
|
diff --git a/qa/group b/qa/group
|
|
index 98c371201..ffe0c5d92 100644
|
|
--- a/qa/group
|
|
+++ b/qa/group
|
|
@@ -1951,6 +1951,7 @@ x11
|
|
1503 pcp pidstat ps python local
|
|
1511 pmcd local pmda.sample
|
|
1515 pmda.denki local valgrind
|
|
+1518 pmcd libpcp local
|
|
1530 pmda.zfs local valgrind
|
|
1531 pmda.zfs local valgrind
|
|
1532 pmda.zfs local
|
|
diff --git a/src/libpcp/src/p_result.c b/src/libpcp/src/p_result.c
|
|
index 8826b5317..1500fe97c 100644
|
|
--- a/src/libpcp/src/p_result.c
|
|
+++ b/src/libpcp/src/p_result.c
|
|
@@ -414,11 +414,10 @@ __pmDecodeValueSet(__pmPDU *pdubuf, int pdulen, __pmPDU *data, char *pduend,
|
|
return PM_ERR_IPC;
|
|
}
|
|
vindex = ntohl(pduvp->value.lval);
|
|
- if (vindex < 0 || vindex > pdulen) {
|
|
+ if (vindex < 0 || (char *)&pdubuf[vindex] >= pduend) {
|
|
if (pmDebugOptions.pdu && pmDebugOptions.desperate)
|
|
- fprintf(stderr, "%s: Bad: pmid[%d] value[%d] "
|
|
- "vindex=%d\n",
|
|
- "__pmDecodeValueSet", i, j, vindex);
|
|
+ fprintf(stderr, "__pmDecodeValueSet: PM_ERR_IPC: pmid[%d] value[%d] vindex=%d (max=%ld)\n",
|
|
+ i, j, vindex, (long)((pduend-(char *)pdubuf) / sizeof(pdubuf[0])-1));
|
|
return PM_ERR_IPC;
|
|
}
|
|
pduvbp = (pmValueBlock *)&pdubuf[vindex];
|
|
--
|
|
2.43.0
|
|
|