Backport applicable private-pcp security fixes to PCP 6.3.7 for RHEL 9.9. CVE-2026-16531 is not applicable because the pmproxy logger servlet is absent in this release. Resolves: RHEL-213747 CVE-2026-16530 Resolves: RHEL-213736 CVE-2026-16529 Resolves: RHEL-213711 CVE-2026-16527 Resolves: RHEL-213687 CVE-2026-16526 Resolves: RHEL-213658 CVE-2026-16524 Co-authored-by: Cursor <cursoragent@cursor.com>
143 lines
4.3 KiB
Diff
143 lines
4.3 KiB
Diff
From cdc9676ab6 Mon Sep 17 00:00:00 2001
|
|
From: Nathan Scott <nathans@redhat.com>
|
|
Subject: [PATCH] pmieconf: fix command injection via $HOME and -f (CWE-78)
|
|
|
|
The write_pmiefile() function constructed a shell command via
|
|
pmsprintf("/bin/mkdir -p %s", fname) and passed it to system().
|
|
The fname value derives from either $HOME or the -f command-line
|
|
argument without sanitization, enabling command injection through
|
|
shell metacharacters in the path.
|
|
|
|
Fix: replace system("/bin/mkdir -p ...") with __pmMakePath() which
|
|
creates directories recursively using mkdir() syscalls directly,
|
|
with no shell involvement.
|
|
|
|
Add qa/2103 verifying that legitimate directory creation works and
|
|
that shell metacharacters in -f and $HOME paths do not result in
|
|
command execution.
|
|
|
|
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) <noreply@anthropic.com>
|
|
|
|
---
|
|
diff --git a/qa/2103 b/qa/2103
|
|
new file mode 100755
|
|
index 0000000000..c068ae92f0
|
|
--- /dev/null
|
|
+++ b/qa/2103
|
|
@@ -0,0 +1,62 @@
|
|
+#!/bin/sh
|
|
+# PCP QA Test No. 2103
|
|
+# Verify pmieconf does not execute shell metacharacters in -f path
|
|
+# (CWE-78 fix verification)
|
|
+#
|
|
+# Copyright (c) 2026 Red Hat. All Rights Reserved.
|
|
+#
|
|
+
|
|
+seq=`basename $0`
|
|
+echo "QA output created by $seq"
|
|
+
|
|
+# get standard environment, filters and checks
|
|
+. ./common.product
|
|
+. ./common.filter
|
|
+. ./common.check
|
|
+
|
|
+which pmieconf >/dev/null 2>&1 || _notrun "pmieconf not installed"
|
|
+
|
|
+_cleanup()
|
|
+{
|
|
+ cd $here
|
|
+ $sudo rm -rf $tmp $tmp.*
|
|
+}
|
|
+
|
|
+status=0 # success is the default!
|
|
+trap "_cleanup; exit \$status" 0 1 2 3 15
|
|
+
|
|
+# real QA test starts here
|
|
+
|
|
+echo "=== normal -f path should work ==="
|
|
+mkdir -p $tmp.dir
|
|
+pmieconf -f $tmp.dir/subdir/test.pmie modify global delta "2min" >$tmp.out 2>&1
|
|
+_sts=$?
|
|
+if [ -f $tmp.dir/subdir/test.pmie ]; then
|
|
+ echo "directory creation and file write succeeded"
|
|
+else
|
|
+ echo "FAIL: file not created (exit=$_sts)"
|
|
+ cat $tmp.out
|
|
+fi
|
|
+
|
|
+echo
|
|
+echo "=== -f path with semicolon should not execute commands ==="
|
|
+_bad="$tmp.dir/bad;touch $tmp.dir/pwned"
|
|
+pmieconf -f "$_bad" modify global delta "2min" >$tmp.out 2>&1
|
|
+if [ -f "$tmp.dir/pwned" ]; then
|
|
+ echo "FAIL: shell metacharacter was executed"
|
|
+else
|
|
+ echo "no command execution from semicolon in path"
|
|
+fi
|
|
+
|
|
+echo
|
|
+echo "=== verify no injected file from HOME variable ==="
|
|
+_badhome="$tmp.dir/home;touch $tmp.dir/pwned2"
|
|
+HOME="$_badhome" pmieconf modify global delta "2min" >$tmp.out 2>&1
|
|
+if [ -f "$tmp.dir/pwned2" ]; then
|
|
+ echo "FAIL: shell metacharacter in HOME was executed"
|
|
+else
|
|
+ echo "no command execution from HOME injection"
|
|
+fi
|
|
+
|
|
+# success, all done
|
|
+exit
|
|
diff --git a/qa/2103.out b/qa/2103.out
|
|
new file mode 100644
|
|
index 0000000000..a5054675e2
|
|
--- /dev/null
|
|
+++ b/qa/2103.out
|
|
@@ -0,0 +1,9 @@
|
|
+QA output created by 2103
|
|
+=== normal -f path should work ===
|
|
+directory creation and file write succeeded
|
|
+
|
|
+=== -f path with semicolon should not execute commands ===
|
|
+no command execution from semicolon in path
|
|
+
|
|
+=== verify no injected file from HOME variable ===
|
|
+no command execution from HOME injection
|
|
diff --git a/qa/group b/qa/group
|
|
index 9c158034fd..c096e80cc8 100644
|
|
--- a/qa/group
|
|
+++ b/qa/group
|
|
@@ -2221,4 +2221,5 @@ pmcd.pdu
|
|
2104 libpcp local security
|
|
2101 linux_sockets local security
|
|
2102 pmlogmv local security
|
|
+2103 pmieconf local security
|
|
4751 libpcp threads valgrind local pcp helgrind
|
|
diff --git a/src/pmieconf/rules.c b/src/pmieconf/rules.c
|
|
index 4bd173fcfe..f0b3ce68c6 100644
|
|
--- a/src/pmieconf/rules.c
|
|
+++ b/src/pmieconf/rules.c
|
|
@@ -1805,7 +1805,6 @@ write_pmiefile(char *program, int autocreate)
|
|
{
|
|
time_t now = time(NULL);
|
|
char *p, *msg = NULL;
|
|
- char buf[MAXPATHLEN+10];
|
|
char *fname = get_pmiefile();
|
|
FILE *fp;
|
|
int i;
|
|
@@ -1816,9 +1815,8 @@ write_pmiefile(char *program, int autocreate)
|
|
|
|
*p = '\0'; /* p is the dirname of fname */
|
|
if (stat(fname, &sbuf) < 0) {
|
|
- pmsprintf(buf, sizeof(buf), "/bin/mkdir -p %s", fname);
|
|
- if (system(buf) < 0) {
|
|
- pmsprintf(errmsg, sizeof(errmsg), "failed to create directory \"%s\"", p);
|
|
+ if (__pmMakePath(fname, 0755) < 0) {
|
|
+ pmsprintf(errmsg, sizeof(errmsg), "failed to create directory \"%s\"", fname);
|
|
return errmsg;
|
|
}
|
|
}
|