Skip to content

camera-check runs against a laptop's own USB camera with --hardware - #681

Open
DevomB wants to merge 2 commits into
zbook-batch-6from
camera-check-hardware
Open

DevomB wants to merge 2 commits into
zbook-batch-6from
camera-check-hardware

Conversation

@DevomB

@DevomB DevomB commented Oct 29, 2026

Copy link
Copy Markdown
Owner

This is the audit's camera:5.

Until now, nothing could check a real camera:

  • The zone probe took its frame with read(), which uvcvideo doesn't implement: uvc_fops has no .read, and the capture node has only VIDEO_CAPTURE and STREAMING (v6.18.56).
  • camera-check.sh always loaded vivid first, so a run on a laptop granted vivid's node.
  • The path a real camera takes when a program keeps its descriptor (uvcvideo pinned, "stayed", the next grant refused) was never exercised.

Probe, both modes. It lists the node's formats (VIDIOC_ENUM_FMT) and takes frames by mmap streaming: REQBUFS, QUERYBUF, mmap, QBUF, STREAMON, then select and DQBUF. That is the path a browser takes. A frame counts when bytesused is non-zero and the buffer isn't flagged as an error. While held, it prints DQBUF-FAILED errno once the node is gone. With keep, it then holds the descriptor two minutes more. The zone's allowlist already has select, mmap, dup and ioctl.

QEMU run (zones-test.sh, unchanged call and check names):

  • It refuses to start if a video-class USB interface is present, and names --hardware.
  • camera-granted also checks that the granted node's own device driver is vivid.
  • camera-zone-captures also asks for MJPG or YUYV among the formats (vivid offers YUYV).
  • camera-ends-with-zone-again also checks that uvcvideo unloaded.

camera-check.sh USER --hardware, run as root at a console of the installed laptop, never loads vivid:

  • camera-hardware: a video-class USB interface exists, uvcvideo isn't loaded, and kryptikd camera status reads exactly none, meaning no grant this boot.
  • The same grant, refusal and capture checks as the QEMU run, with uvcvideo as the driver. camera-other-zone-none runs only in QEMU, since it needs a passphrase file that run makes.
  • camera-revoked: with a program holding the node across k, the launcher prints untrusted stayed, uvcvideo stays loaded, and status reads none; its driver stayed loaded. The held descriptor's DQBUF fails.
  • camera-kept-refuses-grant: a grant while that descriptor is held is refused with camera.rs's "still holds the camera".
  • Once the holder is gone, the next grant captures. At its end status reads none and uvcvideo unloads.
  • camera-gone-ends-grant writes 0 to the USB device's authorized. That device is found from the granted node, so a separate infrared camera can't be taken by mistake. The grant ends through udev's kryptikd camera gone, and authorized is written back to 1.
  • camera-back-loads-nothing: the camera comes back, and uvcvideo isn't loaded.

docs/design/camera.md (Check) and docs/hardware.md gain a row that runs it before any k. That row comes after #674's camera usb listing row, which is why this is based on zbook-batch-6.

Testing on physical hardware is planned for October 2026.

The probe read a frame with read(), which uvcvideo does not implement,
and the check always loaded vivid first, so nothing could check a real
camera. The probe now lists the node's formats and takes frames by mmap
streaming, the path a browser takes, in both modes. A held probe reports
DQBUF-FAILED.

camera-check.sh USER --hardware runs at a console of the installed
laptop. It never loads vivid, and it requires a video-class USB interface
with uvcvideo not loaded and no grant since boot. It also checks what only
uvcvideo shows:
- a program keeping its descriptor past the revoke holds the driver,
  which stays loaded;
- a grant meanwhile is refused;
- the next grant captures again and unloads the driver at its end;
- deauthorizing the camera's USB device ends the grant, and the camera
  coming back loads nothing.

The QEMU run refuses to start when a USB camera is present, and keeps its
check names. Its capture check now also asks for MJPG or YUYV among the
formats, and that the granted node's own driver is the expected one.
…B device, and camera.md says an infrared camera goes with it

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant