Summary
When extracting an ext4 disk image (handled by the unblob backend), fw2tar loses the source filesystem's permission bits — every directory and file in the produced .rootfs.tar.gz comes out as 0700 (owner-only), except the top-level ./ which is forced to 0755. The real modes in the source ext4 inodes (e.g. 0755 for /bin, /usr, /etc, /www) are not preserved.
This silently breaks rehosting: any service that enforces permission checks fails. Concretely, it made an OpenWrt x86-64 rehosting's uhttpd return 403 Forbidden to every request because its /www docroot was 0700 instead of 0755 (uhttpd refuses to serve a docroot that isn't world-traversable, even as root). It would equally affect dropbear host-key perm checks, anything that drops privileges, etc.
Reproduce
wget https://downloads.openwrt.org/releases/23.05.5/targets/x86/64/openwrt-23.05.5-x86-64-generic-ext4-combined.img.gz
gunzip openwrt-23.05.5-x86-64-generic-ext4-combined.img.gz
fakeroot fw2tar openwrt-23.05.5-x86-64-generic-ext4-combined.img # -> unblob backend
(binwalk finds no filesystem in this image; fw2tar selects the unblob extractor.)
Evidence
Source ext4 rootfs (read directly from the image's rootfs partition with debugfs, no mount):
/ Mode: 0755
/bin Mode: 0755
/usr Mode: 0755
/etc Mode: 0755
/sbin Mode: 0755
/www Mode: 0755
fw2tar output (*.rootfs.tar.gz): everything collapsed to 0700.
$ find . -type d -printf '%m\n' | sort | uniq -c
111 700
1 755 # only ./ (the forced top-level)
$ stat -c '%a %n' bin usr etc sbin www www/index.html bin/busybox sbin/init
700 bin
700 usr
700 etc
700 sbin
700 www
700 www/index.html
700 bin/busybox
700 sbin/init
So the source is 0755 but the extracted tar is 0700 for all 111 non-root directories (and files).
Likely cause
src/archive.rs:104-110 copies each entry's mode verbatim from the on-disk extracted tree and only special-cases the root:
header.set_metadata_in_mode(&metadata, tar::HeaderMode::Deterministic);
header.set_mode(metadata.permissions().mode());
if entry_path == "./" {
header.set_mode(0o755);
}
The ./-only 0o755 override is exactly what produces the observed "root is 0755, everything else is 0700" pattern — the extracted tree already has 0700 everywhere, and fw2tar reflects it. The mode loss happens upstream in the extraction step (the unblob ext4 extractor isn't preserving the source inode modes; they end up 0700 on disk before archiving).
Suggested directions
- Preserve real modes through the unblob ext4 extraction (so
archive.rs reflects correct perms), or
- Have fw2tar re-derive modes from the source filesystem rather than trusting the extracted tree's on-disk perms when the extractor is known to drop them.
A blanket "everything 0700" is never a faithful rootfs (a real Linux rootfs needs 0755 on /bin, /usr, etc. or nothing works for non-root), so this is safe to treat as an extraction-fidelity bug.
Environment
- fw2tar image
rehosting/fw2tar:latest digest sha256:7f1bb5d5f798597b98d936146716c2aec5adee098503a2b6c8854b0d05a40302 (built 2026-05-15, repo HEAD 2723ef0).
- Also relevant to the pinned
f44361d4c64e9e6f54d940cb2637bf9283961a29 used by the rehostings corpus.
- Extractor selected: unblob (binwalk found no filesystem in this ext4 image).
Summary
When extracting an ext4 disk image (handled by the unblob backend), fw2tar loses the source filesystem's permission bits — every directory and file in the produced
.rootfs.tar.gzcomes out as0700(owner-only), except the top-level./which is forced to0755. The real modes in the source ext4 inodes (e.g.0755for/bin,/usr,/etc,/www) are not preserved.This silently breaks rehosting: any service that enforces permission checks fails. Concretely, it made an OpenWrt x86-64 rehosting's uhttpd return
403 Forbiddento every request because its/wwwdocroot was0700instead of0755(uhttpd refuses to serve a docroot that isn't world-traversable, even as root). It would equally affect dropbear host-key perm checks, anything that drops privileges, etc.Reproduce
wget https://downloads.openwrt.org/releases/23.05.5/targets/x86/64/openwrt-23.05.5-x86-64-generic-ext4-combined.img.gz gunzip openwrt-23.05.5-x86-64-generic-ext4-combined.img.gz fakeroot fw2tar openwrt-23.05.5-x86-64-generic-ext4-combined.img # -> unblob backend(binwalk finds no filesystem in this image; fw2tar selects the unblob extractor.)
Evidence
Source ext4 rootfs (read directly from the image's rootfs partition with
debugfs, no mount):fw2tar output (
*.rootfs.tar.gz): everything collapsed to0700.So the source is
0755but the extracted tar is0700for all 111 non-root directories (and files).Likely cause
src/archive.rs:104-110copies each entry's mode verbatim from the on-disk extracted tree and only special-cases the root:The
./-only0o755override is exactly what produces the observed "root is 0755, everything else is 0700" pattern — the extracted tree already has0700everywhere, and fw2tar reflects it. The mode loss happens upstream in the extraction step (the unblob ext4 extractor isn't preserving the source inode modes; they end up0700on disk before archiving).Suggested directions
archive.rsreflects correct perms), orA blanket "everything 0700" is never a faithful rootfs (a real Linux rootfs needs
0755on/bin,/usr, etc. or nothing works for non-root), so this is safe to treat as an extraction-fidelity bug.Environment
rehosting/fw2tar:latestdigestsha256:7f1bb5d5f798597b98d936146716c2aec5adee098503a2b6c8854b0d05a40302(built 2026-05-15, repo HEAD2723ef0).f44361d4c64e9e6f54d940cb2637bf9283961a29used by the rehostings corpus.