Subject: [bug#43591] [PATCH core-updates v2 0/5] gnu: glibc-final: Catch all cases of a glibc user not requesting 64-bit offsets and then using readdir.

From: Danny Milosavljevic <[email-masked]>
Date: Wed, 30 Sep 2020 10:45:07 +0200

Linux kernel file offsets are always 64 bits.
But userspace can be built to use 32 bit offsets.

"struct dirent", returned by readdir, uses d_off to store
such an "offset" that it got from the Linux kernel.
In the case of ext4 that "offset" is actually a 64 bit
hash value.

Therefore, there are cases where such an offset that it got
from the Linux kernel does not fit in the "struct dirent"
field "d_off".

If the guest system's glibc is 32 bit AND uses 32 bit
file offsets it is going to be very confused.
It does check whether d_off fits into the structure
it gives back to the user--and it doesn't fit.  Hence readdir
fails, with errno == EOVERFLOW (which is undocumented and thus
an API error).
This manifests itself in simple directory reads not working
anymore in parts of cmake, for example.

This happened in Guix when building stuff for
ARMHF on a x86_64 build host using QEMU transparent emulation.

There is a very simple and complete way to avoid this problem:
Just always use 64 bit offsets in user space programs (also
on 32 bit machines).

Danny Milosavljevic (5):
  gnu: glibc-final: Catch all cases of a glibc user not requesting
    64-bit offsets and then using readdir regardless.
  build-system/gnu: Explicity declare the _FILE_OFFSET_BITS we want.
  gnu: glibc: Do not explicitly set _FILE_OFFSET_BITS.
  gnu: glibc-mesboot0: Do not explicitly set _FILE_OFFSET_BITS.
  gnu: rhash: Explicity declare the _FILE_OFFSET_BITS we want.

 gnu/packages/base.scm           |  2 +
 gnu/packages/commencement.scm   | 70 ++++++++++++++++++++++++++++++++-
 gnu/packages/crypto.scm         |  9 ++++-
 guix/build/gnu-build-system.scm | 13 +++++-
 4 files changed, 90 insertions(+), 4 deletions(-)