* gnu/packages/qt.scm (qtwebengine): Backport fix for text rendering. --- gnu/packages/qt.scm | 286 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 286 insertions(+) diff --git a/gnu/packages/qt.scm b/gnu/packages/qt.scm index ca97725052..111e068094 100644 --- a/gnu/packages/qt.scm +++ b/gnu/packages/qt.scm @@ -1878,6 +1878,292 @@ (define (delete-unwanted-files child stat flag base level) ;; Respect the '--cores' option of 'guix build'. " -j" (number->string (parallel-job-count)))) #t)) + ;; Backport + ;; https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/374232 + ;; to fix broken text rendering. + ;; The patch couldn't be applied directly as it does not apply to + ;; the source code of our qtwebengine package + (add-before 'configure 'fix-text-rendering + (lambda _ + (let ((output-port (open-file "src/3rdparty/chromium/sandbox/linux/system_headers/linux_stat.h" "a"))) + (display "// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_STAT_H_ +#define SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_STAT_H_ + +#include + +#include \"build/build_config.h\" +#include \"sandbox/linux/system_headers/linux_syscalls.h\" + +#if defined(ARCH_CPU_MIPS_FAMILY) +#if defined(ARCH_CPU_64_BITS) +struct kernel_stat { +#else +struct kernel_stat64 { +#endif + unsigned st_dev; + unsigned __pad0[3]; + unsigned long long st_ino; + unsigned st_mode; + unsigned st_nlink; + unsigned st_uid; + unsigned st_gid; + unsigned st_rdev; + unsigned __pad1[3]; + long long st_size; + unsigned st_atime_; + unsigned st_atime_nsec_; + unsigned st_mtime_; + unsigned st_mtime_nsec_; + unsigned st_ctime_; + unsigned st_ctime_nsec_; + unsigned st_blksize; + unsigned __pad2; + unsigned long long st_blocks; +}; +#else +struct kernel_stat64 { + unsigned long long st_dev; + unsigned char __pad0[4]; + unsigned __st_ino; + unsigned st_mode; + unsigned st_nlink; + unsigned st_uid; + unsigned st_gid; + unsigned long long st_rdev; + unsigned char __pad3[4]; + long long st_size; + unsigned st_blksize; + unsigned long long st_blocks; + unsigned st_atime_; + unsigned st_atime_nsec_; + unsigned st_mtime_; + unsigned st_mtime_nsec_; + unsigned st_ctime_; + unsigned st_ctime_nsec_; + unsigned long long st_ino; +}; +#endif + +#if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) +struct kernel_stat { + /* The kernel headers suggest that st_dev and st_rdev should be 32bit + * quantities encoding 12bit major and 20bit minor numbers in an interleaved + * format. In reality, we do not see useful data in the top bits. So, + * we'll leave the padding in here, until we find a better solution. + */ + unsigned short st_dev; + short pad1; + unsigned st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + short pad2; + unsigned st_size; + unsigned st_blksize; + unsigned st_blocks; + unsigned st_atime_; + unsigned st_atime_nsec_; + unsigned st_mtime_; + unsigned st_mtime_nsec_; + unsigned st_ctime_; + unsigned st_ctime_nsec_; + unsigned __unused4; + unsigned __unused5; +}; +#elif defined(__x86_64__) +struct kernel_stat { + uint64_t st_dev; + uint64_t st_ino; + uint64_t st_nlink; + unsigned st_mode; + unsigned st_uid; + unsigned st_gid; + unsigned __pad0; + uint64_t st_rdev; + int64_t st_size; + int64_t st_blksize; + int64_t st_blocks; + uint64_t st_atime_; + uint64_t st_atime_nsec_; + uint64_t st_mtime_; + uint64_t st_mtime_nsec_; + uint64_t st_ctime_; + uint64_t st_ctime_nsec_; + int64_t __unused4[3]; +}; +#elif (defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_32_BITS)) +struct kernel_stat { + unsigned st_dev; + int st_pad1[3]; + unsigned st_ino; + unsigned st_mode; + unsigned st_nlink; + unsigned st_uid; + unsigned st_gid; + unsigned st_rdev; + int st_pad2[2]; + long st_size; + int st_pad3; + long st_atime_; + long st_atime_nsec_; + long st_mtime_; + long st_mtime_nsec_; + long st_ctime_; + long st_ctime_nsec_; + int st_blksize; + int st_blocks; + int st_pad4[14]; +}; +#elif defined(__aarch64__) +struct kernel_stat { + unsigned long st_dev; + unsigned long st_ino; + unsigned int st_mode; + unsigned int st_nlink; + unsigned int st_uid; + unsigned int st_gid; + unsigned long st_rdev; + unsigned long __pad1; + long st_size; + int st_blksize; + int __pad2; + long st_blocks; + long st_atime_; + unsigned long st_atime_nsec_; + long st_mtime_; + unsigned long st_mtime_nsec_; + long st_ctime_; + unsigned long st_ctime_nsec_; + unsigned int __unused4; + unsigned int __unused5; +}; +#endif + +#if !defined(AT_EMPTY_PATH) +#define AT_EMPTY_PATH 0x1000 +#endif + +// On 32-bit systems, we default to the 64-bit stat struct like libc +// implementations do. Otherwise we default to the normal stat struct which is +// already 64-bit. +// These defines make it easy to call the right syscall to fill out a 64-bit +// stat struct, which is the default in libc implementations but requires +// different syscall names on 32 and 64-bit platforms. +#if defined(__NR_fstatat64) + +namespace sandbox { +using default_stat_struct = struct kernel_stat64; +} // namespace sandbox + +#define __NR_fstatat_default __NR_fstatat64 +#define __NR_fstat_default __NR_fstat64 + +#elif defined(__NR_newfstatat) + +namespace sandbox { +using default_stat_struct = struct kernel_stat; +} // namespace sandbox + +#define __NR_fstatat_default __NR_newfstatat +#define __NR_fstat_default __NR_fstat + +#else +#error \"one of fstatat64 and newfstatat must be defined\" +#endif + +#endif // SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_STAT_H_ +" output-port) + + (close output-port)) + + (substitute* "src/3rdparty/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc" + (("#include \"sandbox/linux/services/syscall_wrappers\\.h\"") + "#include \"sandbox/linux/services/syscall_wrappers.h\" +#include \"sandbox/linux/system_headers/linux_stat.h\"") + (("if [(]SyscallSets::IsFileSystem[(]sysno[)] [|][|]") + "if (sysno == __NR_fstatat_default) { + return RewriteFstatatSIGSYS(fs_denied_errno); + } + + if (SyscallSets::IsFileSystem(sysno) ||")) + + (substitute* "src/3rdparty/chromium/sandbox/linux/seccomp-bpf-helpers/baseline_policy_unittest.cc" + (("BPF_ASSERT[(]S_ISFIFO[(]stat_buf\\.st_mode[)] [|][|] S_ISSOCK[(]stat_buf\\.st_mode[)][)];") + "BPF_ASSERT(S_ISFIFO(stat_buf.st_mode) || S_ISSOCK(stat_buf.st_mode)); + + sys_ret = fstatat(read_end.get(), \"\", &stat_buf, AT_EMPTY_PATH); + BPF_ASSERT_EQ(0, sys_ret); + BPF_ASSERT(S_ISFIFO(stat_buf.st_mode) || S_ISSOCK(stat_buf.st_mode)); + + // Make sure fstatat with anything other than an empty string is denied. + sys_ret = fstatat(read_end.get(), \"/\", &stat_buf, AT_EMPTY_PATH); + BPF_ASSERT_EQ(sys_ret, -1); + BPF_ASSERT_EQ(EPERM, errno); + + // Make sure fstatat without AT_EMPTY_PATH is denied. + sys_ret = fstatat(read_end.get(), \"\", &stat_buf, 0); + BPF_ASSERT_EQ(sys_ret, -1); + BPF_ASSERT_EQ(EPERM, errno);")) + + (substitute* "src/3rdparty/chromium/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" + (("// Variants of the above functions for use with bpf_dsl\\.") + "SANDBOX_EXPORT intptr_t +SIGSYSFstatatHandler(const struct arch_seccomp_data& args, + void* fs_denied_errno); + +// Variants of the above functions for use with bpf_dsl.") + (("SANDBOX_EXPORT bpf_dsl::ResultExpr RewriteSchedSIGSYS[(][)];") + "SANDBOX_EXPORT bpf_dsl::ResultExpr RewriteSchedSIGSYS(); +SANDBOX_EXPORT bpf_dsl::ResultExpr RewriteFstatatSIGSYS(int fs_denied_errno);")) + + (substitute* "src/3rdparty/chromium/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc" + (("#include ") + "#include +#include ") + (("#include \"sandbox/linux/system_headers/linux_syscalls\\.h\"") + "#include \"sandbox/linux/system_headers/linux_stat.h\" +#include \"sandbox/linux/system_headers/linux_syscalls.h\"") + (("bpf_dsl::ResultExpr CrashSIGSYS[(][)] [{]") + "intptr_t SIGSYSFstatatHandler(const struct arch_seccomp_data& args, + void* fs_denied_errno) { + if (args.nr == __NR_fstatat_default) { + if (*reinterpret_cast(args.args[1]) == '\0' && + args.args[3] == static_cast(AT_EMPTY_PATH)) { + return syscall(__NR_fstat_default, static_cast(args.args[0]), + reinterpret_cast(args.args[2])); + } + return -reinterpret_cast(fs_denied_errno); + } + + CrashSIGSYS_Handler(args, fs_denied_errno); + + // Should never be reached. + RAW_CHECK(false); + return -ENOSYS; +} + +bpf_dsl::ResultExpr CrashSIGSYS() {") + (("void AllocateCrashKeys[(][)] [{]") + "bpf_dsl::ResultExpr RewriteFstatatSIGSYS(int fs_denied_errno) { + return bpf_dsl::Trap(SIGSYSFstatatHandler, + reinterpret_cast(fs_denied_errno)); +} + +void AllocateCrashKeys() {")) + + (substitute* "src/3rdparty/chromium/sandbox/linux/syscall_broker/broker_process.cc" + (("#if !defined[(]__aarch64__[)]") + "#if !defined(__aarch64__) && !defined(OS_ANDROID)")) + + (substitute* "src/3rdparty/chromium/sandbox/linux/syscall_broker/broker_process_unittest.cc" + (("#if !defined[(]__aarch64__[)]") + "#if !defined(__aarch64__) && !defined(OS_ANDROID)")))) (replace 'configure (lambda _ ;; Valid QT_BUILD_PARTS variables are: