Skip to content

Commit

Permalink
add /scanning/oscap-debug for helping us debug oscap freezes
Browse files Browse the repository at this point in the history
Signed-off-by: Jiri Jaburek <[email protected]>
  • Loading branch information
comps committed Sep 18, 2024
1 parent 94defcb commit 44c7904
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 0 deletions.
29 changes: 29 additions & 0 deletions scanning/oscap-debug/main.fmf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
summary: Runs oscap many times to hopefully reproduce a freeze
test: python3 -m lib.runtest ./test.py
result: custom
environment+:
PYTHONPATH: ../..
duration: 1h
require+:
# virt library dependencies
- libvirt-daemon
- libvirt-daemon-driver-qemu
- libvirt-daemon-driver-storage-core
- libvirt-daemon-driver-network
- firewalld
- qemu-kvm
- libvirt-client
- virt-install
- rpm-build
- createrepo
extra-hardware: |
keyvalue = HVM=1
hostrequire = memory>=3720
adjust:
- when: arch != x86_64
enabled: false
because: we want to run virtualization on x86_64 only

/scan:

/remediate:
105 changes: 105 additions & 0 deletions scanning/oscap-debug/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#!/usr/bin/python3

import itertools
import subprocess
import tempfile

from lib import util, results, virt, oscap
from conf import remediation, partitions


profile = 'cis_workstation_l1'

extra_packages = [
'gdb',
#'@Server with GUI', # uncomment to test with GUI
]
extra_debuginfos = [
'glibc',
'openscap-scanner',
'xmlsec1',
'xmlsec1-openssl',
'libtool-ltdl',
]

oscap_timeout = 600 # 10 minutes should be enough for everybody


virt.Host.setup()
g = virt.Guest()
ks = virt.Kickstart(partitions=partitions.partitions)
ks.packages += extra_packages
g.install(kickstart=ks)

with g.booted(safe_shutdown=True):
# copy our datastreams to the guest
ds = util.get_datastream()
g.copy_to(ds, 'scan-ds.xml')
oscap.unselect_rules(ds, 'remediation-ds.xml', remediation.excludes())
g.copy_to('remediation-ds.xml')
# install debugsource / debuginfo
g.ssh(['dnf', 'debuginfo-install', *extra_debuginfos], check=True)
# prepare gdb script
with tempfile.NamedTemporaryFile(mode='w+t') as f:
f.write(util.dedent('''
generate-core-file oscap.core
set logging file oscap-bt.txt
set logging overwrite on
set logging redirect on
set logging enabled on
thread apply all bt
set logging enabled off
'''))
g.copy_to(f.name, '/root/gdb.script')

g.prepare_for_snapshot()


def run_oscap(attempt, cmd):
proc = g.ssh(' '.join(cmd), func=subprocess.Popen)

try:
proc.wait(oscap_timeout)
except subprocess.TimeoutExpired:
# figure out oscap PID on the remote system
pgrep = g.ssh(['pgrep', '-n', 'oscap'], stdout=subprocess.PIPE, universal_newlines=True)
if pgrep.returncode != 0:
results.report(
'warn',
f'attempt:{attempt}',
f"pgrep returned {pgrep.returncode}, oscap probably just finished "
"and we hit a rare race, moving on",
)
return
oscap_pid = pgrep.stdout.strip()

# attach gdb to that PID
g.ssh(['gdb', '-n', '-batch', '-x', '/root/gdb.script', '-p', oscap_pid], check=True)

# and download its results
g.copy_from('/root/oscap.core')
g.copy_from('/root/oscap-bt.txt')
util.subprocess_run(['xz', '-e', '-9', 'oscap.core'], check=True)
results.report(
'fail',
f'attempt:{attempt}',
"oscap froze, gdb output available",
logs=['oscap.core.xz', 'oscap-bt.txt'],
)

if proc.returncode not in [0,2]:
raise RuntimeError(f"oscap failed with {proc.returncode}")


testname = util.get_test_name().rpartition('/')[2]
cmd = ['oscap', 'xccdf', 'eval', '--profile', profile, '--progress']
if testname == 'remediate':
cmd += ['--remediate', 'remediation-ds.xml']
else:
cmd += ['scan-ds.xml']

for attempt in itertools.count(start=1):
with g.snapshotted():
run_oscap(attempt, cmd)

results.report_and_exit()

0 comments on commit 44c7904

Please sign in to comment.