Skip to content

Conversation

@remexre
Copy link

@remexre remexre commented Feb 6, 2025

I'm trying to run debootstrap under proot, and it uses mknod(1) (with -m) to create the device nodes it needs.

  • mknod(1) tries to use lchmod(3) on the device node after creating it
  • glibc implements lchmod in terms of fchmodat(3)
  • fchmodat(3) has to use fchmodat2(2), because fchmodat(2) doesn't accept AT_SYMLINK_NOFOLLOW
  • fchmodat2(2) is not supported by proot, so we call fchmodat_fallback
  • fchmodat_fallback tries to open the file (with O_PATH)
  • Because we didn't actually create the file, or otherwise remember it, we return ENOENT.

My inclination would be to fix this by emulating the device node's "deviceness" for the purposes of stat:

  • mknod(2) would creat a regular file instead, and keep it around in a table (indexed by its st_dev and st_ino)
  • fstatat64, newfstatat, etc. would look the file up in the table, and replace its st_mode and st_rdev if it matched.

This is enough to get mknod(1) to work, and stat(1) to report the file's specialness:

$ ./src/proot -S / sh -c 'mknod -m 123 foo c 6 1 && stat foo; rm foo'
  File: foo
  Size: 0               Blocks: 1          IO Block: 131072 character special file
Device: 0,41    Inode: 5715306     Links: 1     Device type: 6,1
Access: (0123/c--x-w--wx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2025-02-06 17:05:54.528052661 -0600
Modify: 2025-02-06 17:05:54.528052661 -0600
Change: 2025-02-06 17:05:54.528052661 -0600
 Birth: 2025-02-06 17:05:54.528052661 -0600

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