Package: sbuild
Version: 0.85.7
Severity: normal

When running sbuild in unshare chroot mode, /dev is provided by creating
all the entries as regular files, and then the entries from the host
/dev are bind-mounted to the container. This causes readdir(), which
maps to the getdents64 syscall, to return the underlying files in the
/dev directory instead of the bind-mounted files. Although the names are
correct, the d_ino, d_off and d_type values are incorrect. For instance
/dev/null is reported as regular file instead of a character device.

This can be demonstrated by this simple C code:

| #include <dirent.h>
| #include <stdio.h>
| #include <sys/types.h>
| 
| int main()
| {
|   struct dirent *entry;
|   DIR *dp;
| 
|   dp = opendir("/dev");
|   if (dp == NULL) { 
|     perror("opendir");
|     return -1;
|   }
| 
|   while((entry = readdir(dp))) {
|     printf("%s: type %d\n", entry->d_name, entry->d_type);
|   }
| 
|   closedir(dp);
| 
|   return 0;
| }

This is the reason of the FTBFS of at least glibc and libwibble when
using the unshare chroot mode of sbuild.

That said, this seems to be the standard way to provide /dev entries on
a non-privileged user namespace, for instance podman has the same issue.
Docker does not have the issue, but on the other hand requires root.

There might be no way to fix the issue, in that case we should consider
this a limitation of the unshare chroot mode, document it, and add
debian specific workarounds to the affected packages.

Reply via email to