I see a quite odd behaviour where "find ... -type f" inside a customize hook is matching device files.
As a simple test, "find /dev -type f" finds /dev/zero inside mmdebstrap, but not outside mmdebstrap.
The problem doesn't appear to be affecting stat, test, or python -- only find.
I haven't tested with bwrap or unshare(1) instead of mmdebstrap – I'm not sure exactly how.
If find fails for those, clearly this bug should be reassigned to findutils.
I speculate this is some interaction between unshare(2) and stat(2) that may be a bug in find.
I looked at the strace, but I can't see anything obvious.
Here is some basic investigation outside mmdebstrap:
bash5$ find /dev/ -type f
[no matches]
bash5$ strace -e trace=file find /dev/zero -type f -print -quit
execve("/usr/bin/find", ["find", "/dev/zero", "-type", "f", "-print", "-quit"], 0x7ffc1e9c8578 /* 72 vars */) = 0
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpcre2-8.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
statfs("/sys/fs/selinux", 0x7ffd464f5210) = -1 ENOENT (No such file or directory)
statfs("/selinux", 0x7ffd464f5210) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_CLOEXEC) = 3
access("/etc/selinux/config", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, ".", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/usr/share/locale/en_AU.UTF-8/LC_MESSAGES/findutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_AU.utf8/LC_MESSAGES/findutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_AU/LC_MESSAGES/findutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.UTF-8/LC_MESSAGES/findutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.utf8/LC_MESSAGES/findutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/findutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/dev/zero", {st_mode=S_IFCHR|0666, st_rdev=makedev(0x1, 0x5), ...}, AT_SYMLINK_NOFOLLOW) = 0
+++ exited with 0 +++
Here is some basic investigation inside mmdebstrap:
bash5$ mmdebstrap bullseye /dev/null --customize-hook='chroot $1 bash; false' --include=strace,findutils
I: automatically chosen mode: unshare
I: chroot architecture amd64 is equal to the host's architecture
I: automatically chosen format: tar
I: using /tmp/mmdebstrap.PqOlBcBbIw as tempdir
I: running apt-get update...
done
I: downloading packages with apt...
done
I: extracting archives...
done
I: installing essential packages...
done
I: downloading apt...
done
I: installing apt...
done
I: installing remaining packages inside the chroot...
done
done
I: running --customize-hook in shell: sh -c 'chroot $1 bash; false' exec /tmp/mmdebstrap.PqOlBcBbIw
root@hera:/# find /dev/ -type f
/dev/zero
/dev/urandom
/dev/tty
/dev/random
/dev/ptmx
/dev/null
/dev/full
/dev/console
root@hera:/# strace -e trace=file find /dev/zero -type f -print -quit
execve("/usr/bin/find", ["find", "/dev/zero", "-type", "f", "-print", "-quit"], 0x7fff5a33ba68 /* 79 vars */) = 0
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libpcre2-8.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
statfs("/sys/fs/selinux", 0x7ffe4aac8df0) = -1 ENOENT (No such file or directory)
statfs("/selinux", 0x7ffe4aac8df0) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_CLOEXEC) = 3
access("/etc/selinux/config", F_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, ".", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/locale/C.UTF-8/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache", O_RDONLY) = 4
openat(AT_FDCWD, "/usr/lib/locale/C.UTF-8/LC_MEASUREMENT", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/usr/lib/locale/C.UTF-8/LC_TELEPHONE", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/usr/lib/locale/C.UTF-8/LC_ADDRESS", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/usr/lib/locale/C.UTF-8/LC_NAME", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/usr/lib/locale/C.UTF-8/LC_PAPER", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/usr/lib/locale/C.UTF-8/LC_MESSAGES", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/usr/lib/locale/C.UTF-8/LC_MESSAGES/SYS_LC_MESSAGES", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/usr/lib/locale/C.UTF-8/LC_MONETARY", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/usr/lib/locale/C.UTF-8/LC_COLLATE", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/usr/lib/locale/C.UTF-8/LC_TIME", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/usr/lib/locale/C.UTF-8/LC_NUMERIC", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/usr/lib/locale/C.UTF-8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/usr/share/locale/C.UTF-8/LC_MESSAGES/findutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/C.utf8/LC_MESSAGES/findutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/C/LC_MESSAGES/findutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/dev/zero", {st_mode=S_IFCHR|0666, st_rdev=makedev(0x1, 0x5), ...}, AT_SYMLINK_NOFOLLOW) = 0
+++ exited with 0 +++
root@hera:/# stat /dev/zero
File: /dev/zero
Size: 0 Blocks: 0 IO Block: 4096 character special file
Device: 5h/5d Inode: 6 Links: 1 Device type: 1,5
Access: (0666/crw-rw-rw-) Uid: (65534/ nobody) Gid: (65534/ nogroup)
Access: 2022-03-25 00:22:02.702830832 +0000
Modify: 2022-03-25 00:22:02.702830832 +0000
Change: 2022-03-25 00:22:02.702830832 +0000
Birth: -
root@hera:/# if builtin test -f /dev/zero; then echo IS REGULAR; else echo NOT REGULAR; fi
NOT REGULAR
root@hera:/# apt install python3 -qq
⋮
root@hera:/# python3 -c 'import pathlib; print(pathlib.Path("/dev/zero").stat())'
os.stat_result(st_mode=8630, st_ino=6, st_dev=5, st_nlink=1, st_uid=65534, st_gid=65534, st_size=0, st_atime=1648167722, st_mtime=1648167722, st_ctime=1648167722)
root@hera:/# python3 -c 'import pathlib; print(pathlib.Path("/dev/zero").is_file())'
False
Oh also... SOME character devices are correctly detected.
bash$ mmdebstrap --aptopt='Acquire::http::Proxy "http://localhost:3142"' --dpkgopt=force-unsafe-io --variant=apt bullseye /dev/null --customize-hook='chroot $1 bash; false' --include=strace,findutils
⋮
root@hera:/# find /dev -type b -ls
root@hera:/# find /dev -type c -ls
14 0 crw--w---- 1 nobody nogroup 136, 11 Mar 25 04:10 /dev/pts/11
13 0 crw--w---- 1 nobody nogroup 136, 10 Mar 25 04:05 /dev/pts/10
12 0 crw--w---- 1 nobody nogroup 136, 9 Mar 25 04:11 /dev/pts/9
10 0 crw--w---- 1 nobody nogroup 136, 7 Mar 25 04:12 /dev/pts/7
9 0 crw--w---- 1 nobody nogroup 136, 6 Mar 25 04:12 /dev/pts/6
6 0 crw--w---- 1 nobody nogroup 136, 3 Mar 25 03:44 /dev/pts/3
8 0 crw--w---- 1 nobody nogroup 136, 5 Mar 25 03:38 /dev/pts/5
7 0 crw--w---- 1 nobody nogroup 136, 4 Mar 25 04:12 /dev/pts/4
5 0 crw--w---- 1 nobody nogroup 136, 2 Mar 25 03:42 /dev/pts/2
4 0 crw--w---- 1 nobody nogroup 136, 1 Mar 25 04:12 /dev/pts/1
3 0 crw------- 1 nobody nogroup 136, 0 Mar 25 04:12 /dev/pts/0
2 0 c--------- 1 nobody nogroup 5, 2 Mar 25 00:21 /dev/pts/ptmx
root@hera:/# find /dev -type f -ls
6 0 crw-rw-rw- 1 nobody nogroup 1, 5 Mar 25 00:22 /dev/zero
9 0 crw-rw-rw- 1 nobody nogroup 1, 9 Mar 25 00:22 /dev/urandom
11 0 crw-rw-rw- 1 nobody nogroup 5, 0 Mar 25 04:11 /dev/tty
8 0 crw-rw-rw- 1 nobody nogroup 1, 8 Mar 25 00:22 /dev/random
86 0 crw-rw-rw- 1 nobody nogroup 5, 2 Mar 25 04:12 /dev/ptmx
4 0 crw-rw-rw- 1 nobody nogroup 1, 3 Mar 25 00:22 /dev/null
7 0 crw-rw-rw- 1 nobody nogroup 1, 7 Mar 25 00:22 /dev/full
12 0 crw------- 1 nobody nogroup 5, 1 Mar 25 00:22 /dev/console