Impossible to enable `%set_verify_elf_method strict` for Rust packages because rustc builds with non-LFS functions on 32-bit architectures. For example Firefox: https://git.altlinux.org/beehive/logs/Sisyphus-i586/latest/success/firefox-97.0-alt1 verify-elf: WARNING: ./usr/lib/firefox/libxul.so: uses non-LFS functions: fallocate fcntl fopen fstat fstatfs ftruncate getrlimit glob globfree lseek lstat mkstemp mmap open openat posix_fadvise posix_fallocate pread pwrite readdir setrlimit stat statfs
Ничего не понятно, но спасибо на багрепорт.
$ rustc -vV rustc 1.58.1 binary: rustc commit-hash: unknown commit-date: unknown host: i686-unknown-linux-gnu release: 1.58.1 LLVM version: 12.0.1 $ cat >main.rs use std::fs; fn main() -> std::io::Result<()> { let metadata = match fs::metadata("foo.txt") { Err(why) => panic!("couldn't open: {}", why), Ok(file) => file, }; print!("len: {}\n", metadata.len()); Ok(()) } $ rustc main.rs $ truncate -s 6E foo.txt $ ./main len: 6917529027641081856 $ nm main |grep -o 'U open.*' U open64@GLIBC_2.1 U open@GLIBC_2.0 $ nm main |grep -o 'U .*stat.*' U fstat64@GLIBC_2.33 U stat64@GLIBC_2.33
$ strace -f -e trace=file ./main execve("./main", ["./main"], 0xffa21b1c /* 17 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_LARGEFILE|O_CLOEXEC) = 3 statx(3, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0644, stx_size=5695, ...}) = 0 openat(AT_FDCWD, "/lib/libgcc_s.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3 statx(3, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0644, stx_size=127880, ...}) = 0 openat(AT_FDCWD, "/lib/libc.so.6", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3 statx(3, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0755, stx_size=2002476, ...}) = 0 openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 3 statx(3, "", AT_STATX_SYNC_AS_STAT|AT_NO_AUTOMOUNT|AT_EMPTY_PATH, STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0444, stx_size=0, ...}) = 0 statx(0, NULL, AT_STATX_SYNC_AS_STAT, STATX_ALL, NULL) = -1 EFAULT (Bad address) statx(AT_FDCWD, "foo.txt", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0644, stx_size=6917529027641081856, ...}) = 0 len: 6917529027641081856 +++ exited with 0 +++ $ grep -c statx /usr/lib/rpm/verify-elf-non-lfs-funcs.list 0
Ещё для наглядности: $ cat main.rs use std::fs::File; fn main() { let file = match File::open("foo.txt") { Err(why) => panic!("couldn't open: {}", why), Ok(file) => file, }; let metadata = match file.metadata() { Err(why) => panic!("couldn't get metadata: {}", why), Ok(file) => file, }; print!("len: {}\n", metadata.len()); } $ strace -f ./main 2>&1 |grep foo.txt openat(AT_FDCWD, "foo.txt", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
$ for f in /usr/lib/rustlib/i686-unknown-linux-gnu/lib/lib*.rlib; do nm "$f" 2>/dev/null |grep -E "U ($(tr '\n' '|' < /usr/lib/rpm/verify-elf-non-lfs-funcs.list))$" && echo "$f"; done U fcntl U mmap U sendfile U fcntl U mmap U open U openat /usr/lib/rustlib/i686-unknown-linux-gnu/lib/libstd-689d71722d0c29bf.rlib $ rpmquery -f /usr/lib/rustlib/i686-unknown-linux-gnu/lib/libstd-689d71722d0c29bf.rlib rust-1.58.1-alt1.i586