-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Profiling results publish script with improved checks #5923
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -125,18 +125,30 @@ | |
| echo "INFO: waiting for valgrind to exit" | ||
| VALGRIND_STATUS=0 | ||
| wait ${VALGRIND_PID} 2>/dev/null || VALGRIND_STATUS=$? | ||
| echo "${VALGRIND_STATUS}" > /etc/prof-results/valgrind-exit-status | ||
|
|
||
| if [ "${VALGRIND_STATUS}" -ne 0 ]; then | ||
| # Over 128 means a signal. 139 is SIGSEGV, which is how valgrind exiting on | ||
| # its 8 MB brk segment ceiling presents; valgrind.log names the real reason | ||
| # on the line above its backtrace. | ||
| # Over 128 means a signal. Valgrind passes the profiled server's exit | ||
| # status through (verified: freeradius's own _EXIT(134) matched the 134 | ||
| # recorded here on the e26e348 ldap run), so a signal status usually | ||
| # means FREERADIUS died of that signal - an assert or crash logged in | ||
|
Check warning on line 134 in src/tests/multi-server/scripts/profiling/start_valgrind_profiling.sh
|
||
|
Comment on lines
128
to
+134
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 The comment above this block (start_valgrind_profiling.sh:119-124) still says the publish step 'refuses to upload an unclean run' — this same PR rewrote publish-profiling-results.sh so it now only prunes the unclean test's own directory and publishes the clean remainder, refusing the whole run only when every test is unclean. The PR updated the parallel comments in publish-profiling-results.sh itself but missed this sibling description of the same cross-script contract. Extended reasoning...The bug: The comment at What changed under it: This exact PR rewrites Why existing code doesn't catch this: Nothing enforces comment/behavior consistency automatically; this is purely a documentation-drift issue caught by manual review. The PR author clearly tracked this same contract change in the sibling file: the header doc-comment in Impact: None on runtime behavior — this is a comment inside Step-by-step proof:
Fix: Reword the trailing clause, e.g.: "...so the status has to survive to the publish step, which prunes this test's directory if the run was unclean rather than publishing truncated data. The status is recorded for clean runs too, so an absent file means 'the wrapper did not get this far' rather than 'the run was fine'." matching the phrasing already used in the updated |
||
| # freeradius.log - rather than valgrind itself being killed. | ||
| # valgrind.log's "brk segment overflow" warning is NOT the reason: clean | ||
| # runs carry it too (glibc falls back to mmap when brk cannot grow). | ||
| if [ "${VALGRIND_STATUS}" -gt 128 ]; then | ||
| echo "ERROR: valgrind was killed by signal $((VALGRIND_STATUS - 128)); profiling data is truncated" >&2 | ||
| SIG=$((VALGRIND_STATUS - 128)) | ||
| case ${SIG} in | ||
| 6) SIGNAME="SIGABRT (abort/assertion)" ;; | ||
| 9) SIGNAME="SIGKILL (OOM killer or forced teardown)" ;; | ||
| 11) SIGNAME="SIGSEGV (crash)" ;; | ||
| 15) SIGNAME="SIGTERM" ;; | ||
| *) SIGNAME="signal ${SIG}" ;; | ||
| esac | ||
| echo "ERROR: exit status ${VALGRIND_STATUS}: ${SIGNAME}; freeradius likely died of that signal (see freeradius.log for asserts/backtraces)" >&2 | ||
| else | ||
| echo "ERROR: valgrind exited ${VALGRIND_STATUS}; profiling data may be truncated" >&2 | ||
| fi | ||
| echo "ERROR: see valgrind.log for the reason; these results will not be published" >&2 | ||
| echo "ERROR: these results will not be published" >&2 | ||
| fi | ||
|
|
||
| # Signal that valgrind has finished writing all profiling data | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 In
publish-profiling-results.shthis script runs under#!/bin/sh(dash on the CI runners), whoseechobuiltin interprets backslash escapes by default — soecho "...: ${diag}"at lines 121/124 can mangle or truncate the diagnostic line (a trailing\cdrops the rest of the line and its newline) since$diagis untrusted, grep-captured log content that can contain backslashes (e.g. LDAP DN escapes,DOMAIN\\user). The sibling script touched by this same PR (start_valgrind_profiling.sh) already avoids this exact issue by usingprintf '%s\n' "$var"for variable content — the same pattern should be used here, e.g.printf ' freeradius.log: %s\n' "${diag}" >&2.Extended reasoning...
The bug:
publish-profiling-results.shdeclares#!/bin/sh, which on the FreeRADIUS CI runners resolves to dash. Unlike bash, dash'sechobuiltin interprets backslash escape sequences unconditionally (XSI-style behavior, no-eneeded) — POSIX explicitly leaves this implementation-defined, and dash chooses to always expand escapes. The new diagnostic lines added by this PR are:$diagis not a fixed string — it is captured viagrep -E -m1 ... "$dir/freeradius.log"(orvalgrind.log), i.e. arbitrary, attacker/environment-controlled log content (assert messages, panic messages, signal-related text). FreeRADIUS fault messages routinely embed backslashes: LDAP DN/filter escaping uses sequences like\\28/\\29, and Windows/NTLM/Kerberos identities appear asDOMAIN\\user. If such a backslash sequence lands in the matched line, dash'sechowill reinterpret it as an escape rather than printing it literally.Concrete proof (verified by two independent verifiers running dash):
$ dash -c 'diag="some text\\ctrailing"; echo "line: ${diag}"' line: some textThe
\\csequence causes dash'sechoto suppress all further output including the trailing newline — the diagnostic is truncated mid-line and the nextecho's output gets concatenated onto the same terminal/log line. Other sequences like\\nor\\tinsert literal control characters into the CI log instead of printing the log line as-is.Why nothing today prevents this: the value flows straight from
grepoutput intoechowith no sanitization, and there is no guarantee the shell interpreting the script is a POSIX/bash-onlyecho— the shebang is#!/bin/sh, and CI runners for this repo use dash for/bin/sh.Established precedent in this very PR:
start_valgrind_profiling.sh, modified by this same PR, already prints variable/log-derived content ($CTRL_OUT) viaprintf '%s\n' "$CTRL_OUT"specifically to sidestep this exact class of shell-dependentechobehavior. The new diagnostic code inpublish-profiling-results.shdoesn't follow that established, safer pattern.Impact: this is diagnostic output written to stderr in the CI log only — it does not influence the unclean-detection logic, the prune/refuse-to-publish decision, or the exit code, all of which are driven by the
valgrind-exit-statusfile contents, not this echoed string. Worst case is a garbled or truncated hint line in the CI log, occasionally running into the next line's output, which makes the diagnostic harder to read right when someone is debugging a CI failure — mildly self-defeating for a change whose whole purpose is improving diagnostics, but not something that breaks the pipeline.Fix: swap both
echocalls forprintf, matching the sibling script's pattern: