- C1/C2/H7/H8/H9 engine/squashfs.c: validate block_size (non-zero, power
of two, == 1<<block_log, <= 1 MiB); bound walk_directory to the dir
stream; bound the inode block_sizes[] list and each per-block write to
the output buffer.
- C6/H6 engine/ext4.c: cap inodes_per_group at BLOCK_SIZE*8 and size the
inode table by whole blocks so the bitmap/table buffers can't overrun.
- C7 + M8-sibling iso-patch.c: bound qcow2 l1_size (reject under/oversize,
avoid 32-bit length overflow) and propagate IStream::Read failures.
- H10/H11 prefetch_build_deps.c: reject an over-long Filename and clamp
WriteFile lengths derived from snprintf return values.
- L17 prefetch_wsl_deps.c: route download/extract/copy failures through a
cleanup label that removes the unique temp directory.
- M10/M11 ubuntu_vhdx.c: abort (don't finalize a partial VHDX) when the
squashfs walk reports errors; stop and join workers if a thread fails
to start so they can't touch the freed stack-local pipeline.
Replace the prebuilt-ELF/prebuilt-.ko shipping model with three
in-process prefetchers that populate per-VM staging from authoritative
sources at create time:
--prefetch-repo GitHub tarball (agent + DKMS sources, units)
--prefetch-build-deps archive.ubuntu.com Packages closure walk
(xz-embedded for Packages.xz, BCrypt SHA-256
verify, synthetic Packages file for offline apt)
--prefetch-wsl-deps Microsoft NuGet libd3d12*/libdxcore.so
The Ubuntu guest's firstboot script then builds the agent from source
(make + make install), installs both kernel modules via DKMS, and
optionally enables openssh-server — all offline, against an isolated
apt sources dir pinned to /opt/appsandbox/local-apt{,-extras}.
xz-embedded gained CRC64 support (XZ_USE_CRC64 + xz_crc64.c compiled in)
because Ubuntu's Packages.xz uses 0x04/CRC64 in its stream check; without
this the decoder bails at the first block header. Decompression also
streams to disk in 4 MiB chunks instead of buffering the whole ~50 MiB
output in RAM.
Linux VM credentials now flow from the create-VM modal:
- host hashes admin_pass into glibc $6$ SHA-512 (unix_password_hash,
same path Windows autounattend uses); plaintext is wiped immediately
- two marker files staged into the rootfs:
/etc/appsandbox-admin-user (UTF-8 username)
/etc/appsandbox-admin-hash (consumed and wiped by STEP 5)
- firstboot useradd + usermod -p so /etc/shadow gets the hash directly
- gdm autologin + GNOME OOBE skip now use $ASB_USER, not hardcoded test
- SSH gated on /etc/appsandbox-ssh-enabled marker; STEP 7.5 installs
openssh-server from local-apt-extras, enables ssh.service + ssh.socket,
opens ufw
ComPorts/com1 restored as a Linux-only debug pipe — systemd's
console output goes to \.\pipe\<vm>.com1 so the host can see firstboot
progress without an SSH session into the guest.
STEP 17 verification now resolves the asb_drm card by walking
/sys/class/drm/card*/device/driver instead of hardcoding card0 — with
efifb=off and asb-evict-simpledrm.service, asb_drm lands as card1.
iso-patch.exe gains a new --ubuntu-to-vhdx mode that produces a fully
installed, bootable Ubuntu VHDX in one shot:
- vendored xz-embedded + custom ext4 writer + squashfs reader
- mounts the ISO, partitions GPT (ESP + Linux root), streams
casper/minimal.squashfs into a freshly-built ext4 rootfs through
a producer/N-decompress-worker/single-writer pipeline
- installs signed shim + grub from the ISO's pool .debs onto ESP,
writes a redirect grub.cfg pointing at the rootfs by UUID
- plants a defensive one-shot first-boot systemd unit that runs
grub-install + update-grub + AppSandbox guest setup (agent ELFs,
kernel modules, systemd units, wsl-mesa, wsl-deps, ldconfig,
no-sleep dconf, etc.) and reboots
linux_create_thread now spawns iso-patch with --ubuntu-to-vhdx
and a --stage manifest covering the full extras tree (reuses
stage_linux_agent_and_extras to populate a staging dir then walks
it). image_path is cleared post-build so the ISO isn't re-attached
to the runtime VM. ComPorts/com1 named pipe and the do_connect_rdp
window path are dropped (IDD is the only live display path now).
VideoMonitor stays unconditional (vmwp.exe crashes 0xC0000005
without it) — but with no ConnectionOptions/named pipe, matching
master.
JS frontend: "Installing Linux" branch added so the spinner label
no longer says "Installing Windows" for Linux VMs. Progress %
now tracks ingest fraction (n_processed / total_inodes) mapped
into 10..75%, with post-ingest phases at 82..99%.