Camera Control Helper (PipeWire / V4L2)

1. Overview

This component is a privileged command-line helper designed to block or unblock local camera devices as part of BastionGuard hardening and privacy controls. It supports two execution paths depending on the active multimedia stack:

  • PipeWire path – disables/enables video device nodes via pw-cli
  • V4L2 fallback – restricts access to camera device files under /dev using chmod

The helper is intended to run with root privileges (e.g., setuid root or equivalent controlled privilege escalation). It performs early environment hardening and uses a minimal command interface:

helper block
helper unblock

2. Security Model and Hardening

2.1 Root-Only Enforcement

The helper explicitly requires effective root privileges:

  • If geteuid() != 0, execution is aborted with an error and exit code 10.

This requirement is mandatory because the helper modifies system device access and may interact with system-level PipeWire configuration.


2.2 Environment Sanitization

Before any operation, the helper performs defensive hardening to reduce attack surface in privileged execution contexts:

  • clearenv() – clears all environment variables
  • setenv("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1) – enforces a trusted PATH

This limits the risk of environment-based privilege escalation (e.g., malicious PATH, injected variables affecting subprocesses).


3. Command Interface

3.1 Accepted Arguments

The helper expects exactly one argument:

  • block – disables camera access
  • unblock – re-enables camera access

If the argument count is invalid, it prints usage and exits with code 1. If the argument is unsupported, it exits with code 2.


4. Runtime Detection: PipeWire vs V4L2

4.1 PipeWire Presence Check

The helper detects PipeWire availability by executing:

/usr/bin/pw-cli info 0

The command output is suppressed. A successful exit status indicates PipeWire is available and the helper will use the PipeWire path for camera control.


5. PipeWire Camera Control Path

5.1 Shell Output Capture

The helper uses exec_shell(cmd) to run a command and capture standard output as a string. It is implemented via popen() and reads output incrementally into a buffer.

This is used to enumerate PipeWire nodes:

/usr/bin/pw-cli ls Node

5.2 Node Enumeration and Filtering

The helper parses the output of pw-cli ls Node and identifies candidate node IDs whose metadata indicates a video device:

  • Lines containing id are treated as potential node identifiers
  • Subsequent lines are scanned for:
    • media.class
    • Video/Device

Only node IDs classified as Video/Device are collected for modification.


5.3 Disable / Enable Operations

For each selected PipeWire node ID, the helper executes:

  • Disable: /usr/bin/pw-cli set-param <id> Device/Disabled true
  • Enable: pw-cli set-param <id> Device/Disabled false

The helper aggregates success across all affected nodes. Any failure logs a localized error message and causes the helper to return a failure code.


6. V4L2 Fallback Path

6.1 Device File Enumeration

If PipeWire is not available, the helper falls back to direct device file permission changes. It enumerates entries in:

/dev

Any path with the prefix:

/dev/video

is considered a V4L2 camera device and is modified.


6.2 Block / Unblock Semantics

The fallback mechanism implements:

  • Block – remove access by setting permissions to: 0000
  • Unblock – restore access by setting permissions to: 0660

This approach is simple and effective, but it assumes the system’s device ownership and group policies are consistent with the restored mode (0660).


7. Exit Codes and Result Semantics

The helper returns:

  • 0 – operation completed successfully
  • 5 – operation attempted but failed (e.g., PipeWire node modification failure)
  • 10 – not executed with root privileges
  • 1 – invalid argument count / usage error
  • 2 – invalid command argument

8. Runtime and Security Considerations

  • Privilege minimization: the helper sanitizes the environment and restricts PATH before any privileged action.
  • Operational safety: PipeWire operations are scoped to nodes tagged as Video/Device.
  • Fallback robustness: V4L2 chmod blocking works without PipeWire, but may not handle udev re-permissioning unless integrated with rules or a persistent mechanism.
  • Restore assumptions: restoring to 0660 assumes the correct device owner/group are already set by the OS.
  • Attack surface: popen()/system() calls are protected partially by environment hardening; further hardening can include absolute paths everywhere (currently mixed: some PipeWire enable calls omit /usr/bin/).
  • Localization: user-visible error messages are wrapped for translation using glib/gi18n.