Subject: Re: bug#59821: 9.1: du Aborted (corrupt filesystem)

From: Luke Dashjr <[email-masked]>
Date: Tue, 6 Dec 2022 23:41:16 +0000

On Tuesday 06 December 2022 19:08:57 Paul Eggert wrote:
> On 2022-12-04 10:07, Luke Dashjr wrote:
> > Version: sys-apps/coreutils-9.1-r1 (Gentoo)
> >
> > Context: Linux has a long-standing bug which leads to ext4 RAM dishs
> > (zram specifically) getting corrupted randomly. This manifests as various
> > newfstatat calls returning -1 errno=EUCLEAN (Structure needs cleaning).
> >
> > The `du` tool, when it encounters them, prints an error as expected, but
> > later on aborts...
> >
> > (I am not certain if the fstatat return value is related to the later
> > abort, because I couldn't find a way to get gdb to break only when
> > fstatat returns nonzero)
>
> Thanks, your diagnosis looks like it's on the right track. I attempted
> to fix the bug that leads to the abort by installing the following patch
> into Gnulib:
>
> https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=440b528b1d81dd31b2a
>2e4dde20d5c837c147811
>
> and then propagating that into coreutils so that this should appear in
> the next coreutils release. Although this patch fixes two obvious bugs
> in the area, I can't easily test the patch in your situation, so please
> give it a try.

Unfortunately, it does not appear to fix the bug.

I have reduced the test case to a single directory, which interestingly does
not appear to trigger the EUCLEAN error at all (though I expect it would soon,
had du not aborted).

Here's a full strace (hopefully enough to reproduce):

execve("./du", ["./du", "/tmp/bitcoin_func_test_m00g94yx/"...], 0x7fffe2b3c430 /* 54 vars */) = 0
brk(NULL)                               = 0x12bb30000
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
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=145836, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 145836, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fff93360000
close(3)                                = 0
openat(AT_FDCWD, "/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0\25\0\1\0\0\0\214\322\2\0\0\0\0\0"..., 832) = 832
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=2307000, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 2396704, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fff93110000
mmap(0x7fff93340000, 131072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x220000) = 0x7fff93340000
close(3)                                = 0
set_tid_address(0x7fff93402f10)         = 57893
set_robust_list(0x7fff93402f20, 24)     = 0
rseq(0x7fff934035e0, 0x20, 0, 0xfe5000b) = 0
mprotect(0x7fff93340000, 65536, PROT_READ) = 0
mprotect(0x100d60000, 65536, PROT_READ) = 0
mprotect(0x7fff933f0000, 65536, PROT_READ) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
munmap(0x7fff93360000, 145836)          = 0
getrandom("\x16\x55\x93\x1c\xf3\xba\xcc\x11", 8, GRND_NONBLOCK) = 8
brk(NULL)                               = 0x12bb30000
brk(0x12bb60000)                        = 0x12bb60000
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=7408528, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 7408528, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fff929f0000
close(3)                                = 0
newfstatat(AT_FDCWD, "/tmp/bitcoin_func_test_m00g94yx/node2/regtest/", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(AT_FDCWD, "/tmp/bitcoin_func_test_m00g94yx/node2/regtest/", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = 3
newfstatat(3, "", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_EMPTY_PATH) = 0
fcntl(3, F_GETFL)                       = 0x1c800 (flags O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_NOFOLLOW|O_DIRECTORY)
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
newfstatat(3, "", {st_mode=S_IFDIR|0755, st_size=4096, ...}, AT_EMPTY_PATH) = 0
fstatfs64(3, 120, {f_type=EXT2_SUPER_MAGIC, f_bsize=4096, f_blocks=16113571, f_bfree=10323875, f_bavail=10319779, f_files=4096000, f_ffree=4069261, 
f_fsid={val=[0x53d01241, 0x5136a981]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID}) = 0
fcntl(3, F_DUPFD_CLOEXEC, 3)            = 4
getdents64(3, 0x12bb34170 /* 3 entries */, 32768) = 80
getdents64(3, 0x12bb34170 /* 0 entries */, 32768) = 0
close(3)                                = 0
newfstatat(4, "banlist.json", {st_mode=S_IFDIR|0700, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(4, "banlist.json", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = 3
newfstatat(3, "", {st_mode=S_IFDIR|0700, st_size=4096, ...}, AT_EMPTY_PATH) = 0
fcntl(3, F_GETFL)                       = 0x1c800 (flags O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_NOFOLLOW|O_DIRECTORY)
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
gettid()                                = 57893
getpid()                                = 57893
tgkill(57893, 57893, SIGABRT)           = 0
--- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=57893, si_uid=0} ---
+++ killed by SIGABRT +++
Aborted