cloud-hypervisor/scripts/gitlint/rules/TitleStartsWithComponent.py
Philipp Schuster d580ed55c6 seccomp: add SYS_getcwd (79) to support proper Rust backtraces
When a proper Rust backtrace is printed, the Rust std wants to use the
SYS_getcwd(79) system call to prettify some paths while printing. In
Cloud Hypervisor, this is at least relevant for printing panics or if
a `anyhow::Error` value is printed using `{e:?}` (but not `{e:#?}`).

The syscall cause can be found in `impl fmt::Display for Backtrace {}`
in `library/std/src/backtrace.rs`.

Without this addition, the seccomp violation of the SYS_getcwd (79)
hinders the proper error message including a full backtrace from showing
up. This annoying behaviour already delayed many debugging efforts. With
this fix, things just work. The new syscall itself should be pretty
harmless for normal operation.

```
thread 'vmm' panicked at virtio-devices/src/rng.rs:224:9:
Yikes, things went horribly wrong!

==== Possible seccomp violation ====
Try running with `strace -ff` to identify the cause and open an issue: https://github.com/cloud-hypervisor/cloud-hypervisor/issues/new
[1]    287683 invalid system call (core dumped)  RUST_BACKTRACE=full cargo run --bin cloud-hypervisor -- --api-socket  --kerne
```

```
thread 'vmm' panicked at virtio-devices/src/rng.rs:224:9:
Yikes, things went horribly wrong!
stack backtrace:
   0:     0x557d91286b62 - std::backtrace_rs::backtrace::libunwind::trace::hc20b48b31ee52608
                               at /rustc/17067e9ac6d7ecb70e50f92c1944e545188d2359/library/std/src/../../backtrace/src/backtrace/libunwind.rs:117:9
   1:     0x557d91286b62 - std::backtrace_rs::backtrace::trace_unsynchronized::h5d207cd20f193d88
                               at /rustc/17067e9ac6d7ecb70e50f92c1944e545188d2359/library/std/src/../../backtrace/src/backtrace/mod.rs:66:14

...

  67:                0x0 - <unknown>
Error: Cloud Hypervisor exited with the following error:
  Failed to join on VMM thread: Any { .. }

Debug Info: ThreadJoin(Any { .. })
```

- add any panic, for example into the create or drop function of a
  device
- add --seccomp=true|log to analyze the situation

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-06-26 20:50:57 +00:00

95 lines
2.8 KiB
Python

# SPDX-License-Identifier: Apache-2.0
from gitlint.rules import LineRule, RuleViolation, CommitMessageTitle
import re
class TitleStartsWithComponent(LineRule):
"""A rule to enforce valid commit message title
Valid title format:
component1[, component2, componentN]: submodule: summary
Title should have at least one component
Components are separated by comma+space: ", "
Components are validated to be in valid_components
Components list is ended by a colon
Submodules are not validated
"""
# A rule MUST have a human friendly name
name = "title-has-valid-component"
# A rule MUST have a *unique* id.
# We recommend starting with UL (for User-defined Line-rule)
id = "UL1"
# A line-rule MUST have a target (not required for CommitRules).
target = CommitMessageTitle
def validate(self, line, _commit):
valid_components = (
'api_client',
'arch',
'block',
'build',
'ch-remote',
'ci',
'devices',
'docs',
'event_monitor',
'fuzz',
'github',
'gitignore',
'gitlint',
'hypervisor',
'main',
'misc',
'net_gen',
'net_util',
'openapi',
'option_parser',
'pci',
'performance-metrics',
'rate_limiter',
'README',
'resources',
'scripts',
'seccomp',
'serial_buffer',
'test_data',
'test_infra',
'tests',
'tpm',
'tracer',
'vhost_user_block',
'vhost_user_net',
'virtio-devices',
'vm-allocator',
'vm-device',
'vmm',
'vm-migration',
'vm-virtio')
ptrn_title = re.compile(r'^(.+?):\s(.+)$')
match = ptrn_title.match(line)
if not match:
self.log.debug("Invalid commit title {}", line)
return [RuleViolation(self.id, "Commit title does not comply with "
"rule: 'component: change summary'")]
components = match.group(1)
summary = match.group(2)
self.log.debug(f"\nComponents: {components}\nSummary: {summary}")
ptrn_components = re.compile(r',\s')
components_list = re.split(ptrn_components, components)
self.log.debug("components list: %s" % components_list)
for component in components_list:
if component not in valid_components:
return [RuleViolation(self.id,
f"Invalid component: {component}, "
"\nValid components are: {}".format(
" ".join(valid_components)))]