From e186f4ea5300e34791f5b3c444adacc0277ec02e Mon Sep 17 00:00:00 2001 From: Sertonix Date: Wed, 16 Apr 2025 23:31:17 +0200 Subject: [PATCH 1/3] druntime: set __USE_FILE_OFFSET64=true for musl off_t needs to be 64-bits on all arches Reverts b31aa942a27e fix: mmap64 error (#16361) --- druntime/src/core/sys/posix/config.d | 4 ++-- druntime/src/core/sys/posix/sys/types.d | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/druntime/src/core/sys/posix/config.d b/druntime/src/core/sys/posix/config.d index 6b80d1ff0e6c..235ce328e4bd 100644 --- a/druntime/src/core/sys/posix/config.d +++ b/druntime/src/core/sys/posix/config.d @@ -87,8 +87,8 @@ else version (CRuntime_Musl) // Not present in Musl sources enum __REDIRECT = false; - // Those three are irrelevant for Musl as it always uses 64 bits off_t - enum __USE_FILE_OFFSET64 = false; + // Always use code paths that are compatible with 64 bits off_t + enum __USE_FILE_OFFSET64 = true; enum __USE_LARGEFILE = __USE_FILE_OFFSET64 && !__REDIRECT; enum __USE_LARGEFILE64 = __USE_FILE_OFFSET64 && !__REDIRECT; diff --git a/druntime/src/core/sys/posix/sys/types.d b/druntime/src/core/sys/posix/sys/types.d index 081748ac608d..4b8e4071b630 100644 --- a/druntime/src/core/sys/posix/sys/types.d +++ b/druntime/src/core/sys/posix/sys/types.d @@ -124,6 +124,7 @@ version (linux) version (CRuntime_Musl) { + static assert(off_t.sizeof == 8); /** * Musl versions before v1.2.0 (up to v1.1.24) had different * definitions for `time_t` for 32 bits. From 0307cefd7c563aaaf86eccedd56b8b872f8566c3 Mon Sep 17 00:00:00 2001 From: Sertonix Date: Wed, 16 Apr 2025 23:59:37 +0200 Subject: [PATCH 2/3] druntime: fix timespec size on musl The struct is passed to the kernel by musl which causes out of bounds memory access when the struct isn't padded correctly. Ref https://git.musl-libc.org/cgit/musl/commit/?id=9b2921bea1d5017832e1b45d1fd64220047a9802 --- druntime/src/core/sys/posix/time.d | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/druntime/src/core/sys/posix/time.d b/druntime/src/core/sys/posix/time.d index f49764d1964a..fdd6b0a88809 100644 --- a/druntime/src/core/sys/posix/time.d +++ b/druntime/src/core/sys/posix/time.d @@ -16,6 +16,7 @@ module core.sys.posix.time; import core.sys.posix.config; +import core.sys.posix.endian; public import core.stdc.time; public import core.sys.posix.sys.types; public import core.sys.posix.signal; // for sigevent @@ -201,7 +202,11 @@ version (linux) struct timespec { time_t tv_sec; + version (CRuntime_Musl) + int : 8 * (time_t.sizeof - c_long.sizeof) * (BYTE_ORDER == BIG_ENDIAN); c_long tv_nsec; + version (CRuntime_Musl) + int : 8 * (time_t.sizeof - c_long.sizeof) * (BYTE_ORDER != BIG_ENDIAN); } } else version (Darwin) @@ -461,6 +466,8 @@ else version (CRuntime_Bionic) } else version (CRuntime_Musl) { + static assert(timespec.sizeof == 16); + alias int clockid_t; alias void* timer_t; From 8a95b3b912f425df5c3ba1b849be838dde03a6a2 Mon Sep 17 00:00:00 2001 From: Sertonix Date: Thu, 17 Apr 2025 00:07:42 +0200 Subject: [PATCH 3/3] druntime: fix stat_t on arm/x86/mips musl --- druntime/src/core/sys/posix/sys/stat.d | 441 ++++++++++++++++--------- 1 file changed, 280 insertions(+), 161 deletions(-) diff --git a/druntime/src/core/sys/posix/sys/stat.d b/druntime/src/core/sys/posix/sys/stat.d index 0dbf4ebb7b6b..03989149170c 100644 --- a/druntime/src/core/sys/posix/sys/stat.d +++ b/druntime/src/core/sys/posix/sys/stat.d @@ -72,29 +72,38 @@ version (linux) { version (X86) { - struct stat_t + version (CRuntime_Musl) { - dev_t st_dev; - ushort __pad1; - static if (!__USE_FILE_OFFSET64) + struct stat_t { + dev_t st_dev; + ushort __pad1; + static if (!__USE_FILE_OFFSET64) + { + ino_t st_ino; + } + else + { + uint __st_ino; + } + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + ushort __pad2; + off_t st_size; + blksize_t st_blksize; + blkcnt_t st_blocks; + private struct __timespec32 + { + c_long tv_sec; + c_long tv_nsec; + } + __timespec32 __st_atim32; + __timespec32 __st_mtim32; + __timespec32 __st_ctim32; ino_t st_ino; - } - else - { - uint __st_ino; - } - mode_t st_mode; - nlink_t st_nlink; - uid_t st_uid; - gid_t st_gid; - dev_t st_rdev; - ushort __pad2; - off_t st_size; - blksize_t st_blksize; - blkcnt_t st_blocks; - static if (_DEFAULT_SOURCE || _XOPEN_SOURCE >= 700) - { timespec st_atim; timespec st_mtim; timespec st_ctim; @@ -105,23 +114,61 @@ version (linux) ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } } } - else - { - time_t st_atime; - ulong_t st_atimensec; - time_t st_mtime; - ulong_t st_mtimensec; - time_t st_ctime; - ulong_t st_ctimensec; - } - static if (__USE_FILE_OFFSET64) - { - ino_t st_ino; - } - else + static assert(stat_t.sizeof == 144); + } + else + { + struct stat_t { - c_ulong __unused4; - c_ulong __unused5; + dev_t st_dev; + ushort __pad1; + static if (!__USE_FILE_OFFSET64) + { + ino_t st_ino; + } + else + { + uint __st_ino; + } + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + ushort __pad2; + off_t st_size; + blksize_t st_blksize; + blkcnt_t st_blocks; + static if (_DEFAULT_SOURCE || _XOPEN_SOURCE >= 700) + { + timespec st_atim; + timespec st_mtim; + timespec st_ctim; + extern(D) @safe @property inout pure nothrow + { + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } + } + } + else + { + time_t st_atime; + ulong_t st_atimensec; + time_t st_mtime; + ulong_t st_mtimensec; + time_t st_ctime; + ulong_t st_ctimensec; + } + static if (__USE_FILE_OFFSET64) + { + ino_t st_ino; + } + else + { + c_ulong __unused4; + c_ulong __unused5; + } } } } @@ -261,37 +308,31 @@ version (linux) } else version (MIPS_O32) { - struct stat_t + version (CRuntime_Musl) { - version (CRuntime_Musl) + struct stat_t { dev_t st_dev; - c_long[2] st_pad1; - } - else - { - c_ulong st_dev; - c_long[3] st_pad1; - } - ino_t st_ino; - mode_t st_mode; - nlink_t st_nlink; - uid_t st_uid; - gid_t st_gid; - c_ulong st_rdev; - static if (!__USE_FILE_OFFSET64) - { - c_long[2] st_pad2; - off_t st_size; - c_long st_pad3; - } - else - { - c_long[3] st_pad2; + c_long[2] __pad1; + ino_t st_ino; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + c_long[2] __pad2; off_t st_size; - } - static if (_DEFAULT_SOURCE || _XOPEN_SOURCE >= 700) - { + private struct __timespec32 + { + c_long tv_sec; + c_long tv_nsec; + } + __timespec32 __st_atim32; + __timespec32 __st_mtim32; + __timespec32 __st_ctim32; + blksize_t st_blksize; + c_long __pad3; + blkcnt_t st_blocks; timespec st_atim; timespec st_mtim; timespec st_ctim; @@ -301,27 +342,65 @@ version (linux) ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } } + c_long[2] __pad4; } - else - { - time_t st_atime; - c_ulong st_atimensec; - time_t st_mtime; - c_ulong st_mtimensec; - time_t st_ctime; - c_ulong st_ctimensec; - } - blksize_t st_blksize; - static if (!__USE_FILE_OFFSET64) - { - blkcnt_t st_blocks; - } - else + } + else + { + struct stat_t { - c_long st_pad4; - blkcnt_t st_blocks; + c_ulong st_dev; + c_long[3] st_pad1; + ino_t st_ino; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + c_ulong st_rdev; + static if (!__USE_FILE_OFFSET64) + { + c_long[2] st_pad2; + off_t st_size; + c_long st_pad3; + } + else + { + c_long[3] st_pad2; + off_t st_size; + } + static if (_DEFAULT_SOURCE || _XOPEN_SOURCE >= 700) + { + timespec st_atim; + timespec st_mtim; + timespec st_ctim; + extern(D) @safe @property inout pure nothrow + { + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } + } + } + else + { + time_t st_atime; + c_ulong st_atimensec; + time_t st_mtime; + c_ulong st_mtimensec; + time_t st_ctime; + c_ulong st_ctimensec; + } + blksize_t st_blksize; + static if (!__USE_FILE_OFFSET64) + { + blkcnt_t st_blocks; + } + else + { + c_long st_pad4; + blkcnt_t st_blocks; + } + c_long[14] st_pad6; } - c_long[14] st_pad5; } static if (!__USE_FILE_OFFSET64) static assert(stat_t.sizeof == 144); @@ -572,67 +651,34 @@ version (linux) } else version (ARM) { - private + version (CRuntime_Musl) { - alias __dev_t = ulong; - alias __ino_t = c_ulong; - alias __ino64_t = ulong; - alias __mode_t = uint; - alias __nlink_t = size_t; - alias __uid_t = uint; - alias __gid_t = uint; - alias __off_t = c_long; - alias __off64_t = long; - alias __blksize_t = c_long; - alias __blkcnt_t = c_long; - alias __blkcnt64_t = long; - alias __timespec = timespec; - alias __time_t = time_t; - } - struct stat_t - { - __dev_t st_dev; - ushort __pad1; - - static if (!__USE_FILE_OFFSET64) - { - __ino_t st_ino; - } - else - { - __ino_t __st_ino; - } - __mode_t st_mode; - __nlink_t st_nlink; - __uid_t st_uid; - __gid_t st_gid; - __dev_t st_rdev; - ushort __pad2; - - static if (!__USE_FILE_OFFSET64) - { - __off_t st_size; - } - else - { - __off64_t st_size; - } - __blksize_t st_blksize; - - static if (!__USE_FILE_OFFSET64) - { - __blkcnt_t st_blocks; - } - else - { - __blkcnt64_t st_blocks; - } - - static if ( _DEFAULT_SOURCE || _XOPEN_SOURCE >= 700) + struct stat_t { - __timespec st_atim; - __timespec st_mtim; - __timespec st_ctim; + dev_t st_dev; + ushort __pad1; + c_long __st_ino; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + ushort __pad2; + off_t st_size; + blksize_t st_blksize; + blkcnt_t st_blocks; + private struct __timespec32 + { + c_long tv_sec; + c_long tv_nsec; + } + __timespec32 __st_atim32; + __timespec32 __st_mtim32; + __timespec32 __st_ctim32; + ino_t st_ino; + timespec st_atim; + timespec st_mtim; + timespec st_ctim; extern(D) @safe @property inout pure nothrow { ref inout(time_t) st_atime() return { return st_atim.tv_sec; } @@ -640,30 +686,103 @@ version (linux) ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } } } - else - { - __time_t st_atime; - c_ulong st_atimensec; - __time_t st_mtime; - c_ulong st_mtimensec; - __time_t st_ctime; - c_ulong st_ctimensec; - } + static assert(stat_t.sizeof == 152); + } + else + { + private + { + alias __dev_t = ulong; + alias __ino_t = c_ulong; + alias __ino64_t = ulong; + alias __mode_t = uint; + alias __nlink_t = size_t; + alias __uid_t = uint; + alias __gid_t = uint; + alias __off_t = c_long; + alias __off64_t = long; + alias __blksize_t = c_long; + alias __blkcnt_t = c_long; + alias __blkcnt64_t = long; + alias __timespec = timespec; + alias __time_t = time_t; + } + struct stat_t + { + __dev_t st_dev; + ushort __pad1; - static if (!__USE_FILE_OFFSET64) - { - c_ulong __unused4; - c_ulong __unused5; - } - else - { - __ino64_t st_ino; + static if (!__USE_FILE_OFFSET64) + { + __ino_t st_ino; + } + else + { + __ino_t __st_ino; + } + __mode_t st_mode; + __nlink_t st_nlink; + __uid_t st_uid; + __gid_t st_gid; + __dev_t st_rdev; + ushort __pad2; + + static if (!__USE_FILE_OFFSET64) + { + __off_t st_size; + } + else + { + __off64_t st_size; + } + __blksize_t st_blksize; + + static if (!__USE_FILE_OFFSET64) + { + __blkcnt_t st_blocks; + } + else + { + __blkcnt64_t st_blocks; + } + + static if ( _DEFAULT_SOURCE || _XOPEN_SOURCE >= 700) + { + __timespec st_atim; + __timespec st_mtim; + __timespec st_ctim; + extern(D) @safe @property inout pure nothrow + { + ref inout(time_t) st_atime() return { return st_atim.tv_sec; } + ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } + ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } + } + } + else + { + __time_t st_atime; + c_ulong st_atimensec; + __time_t st_mtime; + c_ulong st_mtimensec; + __time_t st_ctime; + c_ulong st_ctimensec; + } + + static if (!__USE_FILE_OFFSET64) + { + c_ulong __unused4; + c_ulong __unused5; + } + else + { + __ino64_t st_ino; + } } + static if (__USE_FILE_OFFSET64) + static assert(stat_t.sizeof == 104); + else + static assert(stat_t.sizeof == 88); } - static if (__USE_FILE_OFFSET64) - static assert(stat_t.sizeof == 104); - else - static assert(stat_t.sizeof == 88); } else version (AArch64) {