Commit Graph
7 Commits
Author SHA1 Message Date
James Stringer 9f1772ce60 Add MIT LICENSE and third-party license notices
- LICENSE: MIT, Copyright (c) 2026 James Stringer.
- THIRD-PARTY-NOTICES.md: scopes the MIT grant around bundled third-party
  components, documenting each one's license/copyright:
    dxgkrnl (Microsoft WSL2 GPU driver) GPL-2.0; iso-patch/engine/xz 0BSD;
    wsl-mesa prebuilt (Mesa 25.3.6) MIT; WDF SDK, WebView2 SDK, DevCon (Microsoft).
- tools/linux/dxgkrnl/COPYING: verbatim GPL-2.0 text shipped with the GPL'd
  driver source.
- tools/linux/wsl-mesa/prebuilt/MESA-LICENSE.txt: Mesa's headline MIT license,
  shipped next to the prebuilt binary.
- README: license section points to LICENSE + THIRD-PARTY-NOTICES.
- Info.plist: copyright string now names the holder and notes MIT.

The asb_drm Linux kernel module keeps its existing dual (GPL-2.0 OR MIT)
licensing; vendored sources keep their own SPDX headers.
2026-06-03 21:47:02 -04:00
James Stringer a2a3c0920a Fix Linux guest agent clipboard/display/audio bugs
- C10 appsandbox-clipboard.c: the host->guest INCR accumulator doubled
  accum_cap *before* realloc, so on realloc failure it memcpy'd into the
  un-enlarged buffer (heap overflow). Grow into a temp, commit the cap
  only on a successful realloc, and append only when the buffer has room.
- L11 appsandbox-clipboard.c: reject FORMAT_LIST frames with data_size<4
  before reading the 4-byte count (OOB read; Linux analog of H4/C9).
- L18 appsandbox-clipboard.c: host->guest folder paste flattened — the
  text/uri-list builder listed every nested file and no directory, so the
  file manager pasted the files flat with no folder. List top-level items
  only (a top-level dir contributes its own URI; nested entries none),
  guarded on the dir actually existing.
- L12 appsandbox-display.c: use-after-free reading p->plane_id after
  drmModeFreePlane(p) in cursor_init; log the cached cur->plane_id.
- L13 appsandbox-audio.c: idle silence paced at 10ms < the ~21.3ms packet
  duration, overrunning the host render ring; pace at the true packet
  duration (FRAMES_PER_PACKET * 1000000000 / SAMPLE_RATE).

Built in-VM and validated on a live Ubuntu VM (folder/sub-item paste;
audio/display/clipboard daemons healthy after redeploy).
2026-06-02 23:30:55 -04:00
James Stringer 5a3494501c Scrub remaining cloud-image/cidata references from comments (comments only)
The cloud-image install flow is gone; reword the last comments that still
referenced it:
  - asb_core.c: "Linux cloud-image creates" -> "Linux ISO creates"
  - disk_util.c: drop the "Ubuntu cloud-image parent ~2.5 GB" rationale
    from vhdx_create_differencing_resized (now describes the generic
    inherit-then-resize behavior)
  - disk_util.h: stage_linux_agent_and_extras doc no longer says "same
    content the cidata builder used to ship"
  - appsandbox-agent.c: "autoinstall lets the user pick" -> "the create-VM
    modal lets the user pick"
2026-05-30 14:49:35 -04:00
James Stringer 52f71115ea Pre-merge cleanup: remove dead cidata/cloud-image flow + fix stale comments
Delete the abandoned cloud-image/cidata Linux install path (zero live
callers — linux_create_thread builds the VHDX directly from the ISO):
  - disk_util.c: drop iso_create_resources_ubuntu, generate_autoinstall_*,
    generate_network_config, generate_ubuntu_setup_sh, find_repo_root +
    copy helpers, the DEAD_ #if0 block, and the entire qcow2/VHD/inflate/
    cloud-image converter incl. ensure_ubuntu_cloud_image_cached
    (4492 -> 2315 lines). Shared helpers kept (create_iso_from_dir,
    remove_staging_dir, unix_password_hash, stage_linux_agent_and_extras).
  - disk_util.h: drop the two now-dead prototypes.

Rename the guest first-boot identifier poc-firstboot -> appsandbox-firstboot
(service/script/marker) in ubuntu_vhdx.c and reword stale "POC gpt.c"/
"f361def"/"old flow"/"subiquity"/"cidata" comment references to describe
the current direct-ISO->VHDX flow.

Fix factually-wrong comments found in a line-by-line audit:
  - asb_core.c: NAT comment claimed DHCP; it's a static IP baked into the
    HCN endpoint + pushed by the agent. SHA-512-crypt / Secure Boot /
    create-path comments reworded off the removed flow.
  - appsandbox-agent.c: gdm UID-range claim (gdm is <1000); netplan
    "renderer detect" actually probes the NetworkManager service.
  - appsandbox-display.c: cursor cadence said 30fps (TARGET_FPS is 60);
    card-selection "connected output" claim corrected (driver-name match).
  - appsandbox-audio.c: wire-proto doc said 16-bit/4-align (it's 32/8);
    snd-aloop subdev comment.

Move the internal IMPLEMENTATION_PLAN.md design doc out of the repo
(it now lives in the gitignored docs/).
2026-05-30 14:36:56 -04:00
James Stringer 45285394d9 Fix capture daemons hanging guest shutdown when IDD is disconnected
appsandbox-display / -audio / -input installed SIGINT/SIGTERM via
signal(), which on glibc carries BSD SA_RESTART semantics. With the
listen socket blocking and no SO_RCVTIMEO, a SIGTERM at poweroff ran
the handler (set g_stop=1) but the kernel auto-restarted the blocking
accept() instead of returning EINTR — so the existing
`if (errno == EINTR) continue;` re-check never fired and the daemon sat
blocked in accept(). systemd then waited the full TimeoutStopSec (~90s)
per unit before SIGKILL, which presented as the VM hanging at shutdown.
Reconnecting the IDD display made accept() return a real connection, the
loop re-evaluated g_stop, and shutdown finally completed — the tell.

Switch all three to sigaction() with sa_flags=0 (no SA_RESTART), exactly
matching appsandbox-agent.c, which already shuts down promptly for this
reason. accept() now returns EINTR on SIGTERM and the loop exits cleanly.
2026-05-30 12:59:02 -04:00
James Stringer 194cadeaa6 NVENC/NVDEC userspace path + nvidia-smi shortcut
- systemd-user environment generator and appsandbox-gpu wrapper both
  append /usr/lib/wsl/lib to LD_LIBRARY_PATH. ldconfig has the .so.1
  entries cached, but the 9P mount is read-only so the unversioned
  symlinks ldconfig wants to create can't be written. dlopen() of
  unversioned names (libcuda.so, libnvidia-encode.so, libnvcuvid.so)
  needs the path on LD_LIBRARY_PATH — without it ffmpeg's h264_nvenc /
  h264_cuvid plugins fail with 'Cannot load libcuda.so.1'.

- setup.sh: symlink /usr/lib/wsl/lib/nvidia-smi to /usr/local/bin so
  the bare command works without env tweaks. Created unconditionally
  because the symlink target is resolved at exec time — the file
  appears under the agent's 9P mount on first boot regardless of when
  the symlink was created.
2026-05-19 22:09:52 -04:00
James Stringer 2309cec029 Add Linux VM support with GPU-PV
Ubuntu 26.04 LTS guest end-to-end:

- cidata-driven autoinstall pipeline (subiquity user-data + nested
  cloud-init bootcmd) in disk_util.c. Static NAT IP, ssh-via-vsock
  marker, serial-debug kernel cmdline injected into ESP grub.cfg by
  iso-patch.exe. Five separate firstboot pipeline fixes get the VM
  to GDM unattended on Hyper-V Gen 2.

- Linux guest stack under tools/linux/:
    - appsandbox-agent  (vsock :1 control + clipboard helper spawn)
    - appsandbox-audio  (snd-aloop -> vsock :4)
    - appsandbox-display (KMS framebuffer capture -> vsock :2)
    - appsandbox-input  (uinput injection <- vsock :3)
    - appsandbox-clipboard (XCB selection bridge <-> vsock :5/:6)
  Helper binaries staged via release/resources/linux/.

- asb_drm DRM module: virtual single-CRTC display sink the host
  captures over vsock. Platform-bus, DRIVER_GEM/MODESET/ATOMIC/RENDER,
  linear shmem framebuffers. asb-evict-simpledrm.service unbinds the
  EFI simple-framebuffer before display-manager so mutter binds
  asb_drm as the sole DRM card.

- dxgkrnl vendored byte-identical from microsoft/WSL2-Linux-Kernel
  linux-msft-wsl-6.18.y with our DKMS/out-of-tree shim (dxgkrnl_compat.h
  + Kbuild + dkms.conf). Autoinstall late-commands dkms-builds against
  every /target/lib/modules/<kver> so kernel-version drift between ISO
  and post-update reboot still leaves a working .ko.

- wsl-mesa custom build (Mesa 25.3 + d3d12 gallium + microsoft-
  experimental dzn Vulkan). Installs to /opt/wsl-mesa parallel to
  Ubuntu's stock Mesa. Prebuilt tarball for ubuntu-26.04-amd64
  shipped under tools/linux/wsl-mesa/prebuilt/ (21 MB).

- Per-VM GPU acceleration policy:
    - /etc/systemd/user-environment-generators/50-appsandbox-gpu
      emits GALLIUM_DRIVER=d3d12 + LD_LIBRARY_PATH + VK_DRIVER_FILES
      into the user@1000 systemd-user environment when /dev/dxg and
      /opt/wsl-mesa are present. Inherited by every app-*.scope a
      .desktop launch creates.
    - /etc/systemd/user/org.gnome.Shell@.service.d/no-gpu.conf
      UnsetEnvironment= strips these for the compositor — mutter
      stays on llvmpipe so asb_drm scanout works (the d3d12 pipe has
      no GBM compatibility with asb_drm).
    - /usr/local/bin/appsandbox-gpu wrapper for terminal-launched
      opt-in GPU acceleration (probes /dev/dxg; no-op on no-GPU VMs).

- Host changes:
    - vm_display_idd.c, vm_clipboard.c, vm_agent.c, vm_ssh_proxy.c,
      asb_display.c: hcs_service_guid(os_type, port) so the same code
      paths reach the per-OS service identifiers (HV_GUID for Windows,
      vsock template for Linux).
    - asb_core.c: linux_create_thread builds an empty VHDX, cidata
      ISO with extras (agent ELFs, dxgkrnl src, asb_drm src, wsl-mesa
      tarball, wsl-deps libs), and boots the desktop ISO + cidata.
    - hcs_vm.c: HostLxssLib Plan9 share appended for Linux VMs;
      VideoMonitor + ComPorts retained for serial debug.
    - gpu_enum.c/h: gpu_append_lxsslib_share helper.
    - vm_clipboard.c file-drop support (CF_HDROP / x-special/gnome-
      copied-files round-trip).
    - vm_display_idd.c: 32-bit S32_LE PCM audio path matches the
      Linux daemon's snd-aloop capture format.

- iso-patch.c gains a patch_ubuntu_esp_grub_for_debug pass that
  rewrites /EFI/ubuntu/grub.cfg via the FAT32 ESP, plus a qcow2->
  vhdx converter with a RFC 1951 DEFLATE inflater for compressed
  cluster handling.

- wsl-deps: Microsoft's libd3d12.so / libd3d12core.so / libdxcore.so
  fetched on demand from the public NuGet feed
  pkgs.dev.azure.com/shine-oss/wsl (no auth). Staged at
  /opt/appsandbox/wsl-deps on the guest and put on /etc/ld.so.conf.d
  rather than /usr/lib/wsl/lib (which is overlaid by the agent's
  9P mount).

UI: web/{app.js,index.html} expose Linux VM creation + GPU selection,
distribution dropdown for cached Ubuntu ISOs, and the ISO picker for
custom images.
2026-05-19 20:21:43 -04:00