Bernhard Übelacker dixit: > On Thu, 4 Apr 2024 21:00:59 +0000 (UTC) Thorsten Glaser <t...@mirbsd.de> > wrote: >> Sometimes, it does not crash with a smashed stack but instead: >> >> Setting up sasl2-bin (2.1.28+dfsg1-6+b1) ... >> BDB0002 __fop_file_setup: Retry limit (100) exceeded >> saslpasswd2: generic failure > > This looks to be a result of the pre-existing /etc/__db.sasldb2. > If this file gets removed the stack smashing occurs again.
Right, I got there as well but not any further. > By some experimenting I could convince gdb to load the debug symbols. Massive detective work, thanks! > And the stack seems to point into function __os_unique_id from libdb-5.3.so. > > Unfortunately I am not sure where the canary gets overwritten. I had an immediate hunch as I saw this: > 38 __os_gettime(env, &v, 1); And: > (gdb) ptype /o v > type = struct { > /* 0 | 8 */ time_t tv_sec; > /* 8 | 4 */ long tv_nsec; > > /* total size (bytes): 12 */ > } This is, in the source: typedef struct { time_t tv_sec; /* seconds */ #ifdef HAVE_MIXED_SIZE_ADDRESSING int32_t tv_nsec; #else long tv_nsec; /* nanoseconds */ #endif } db_timespec; Compare the newer system header: struct timespec { #ifdef __USE_TIME_BITS64 __time64_t tv_sec; /* Seconds. */ #else __time_t tv_sec; /* Seconds. */ #endif #if __WORDSIZE == 64 \ || (defined __SYSCALL_WORDSIZE && __SYSCALL_WORDSIZE == 64) \ || (__TIMESIZE == 32 && !defined __USE_TIME_BITS64) __syscall_slong_t tv_nsec; /* Nanoseconds. */ #else # if __BYTE_ORDER == __BIG_ENDIAN int: 32; /* Padding. */ long int tv_nsec; /* Nanoseconds. */ # else long int tv_nsec; /* Nanoseconds. */ int: 32; /* Padding. */ # endif #endif }; This is actually longer and (IMHO) really stupid. But Linux has: struct __kernel_timespec { __kernel_time64_t tv_sec; /* seconds */ long long tv_nsec; /* nanoseconds */ }; So this is actually expected. *checks POSIX* which says: | The <time.h> header shall declare the timespec structure, which shall | include at least the following members: | | time_t tv_sec Whole seconds. | long tv_nsec Nanoseconds [0, 999 999 999]. So both the kernel definition (tv_nsec must be long, not long long, which is incompatible on ILP32 big endian platforms) and the one by db5.3 (struct timespec may include extra members and be in any order) actually violate POSIX… *sigh* And yes, it does cast to struct timespec and passes it to clock_gettime(). But it does give us a possible fix, which I’ll be testing. bye, //mirabilos -- 22:20⎜<asarch> The crazy that persists in his craziness becomes a master 22:21⎜<asarch> And the distance between the craziness and geniality is only measured by the success 18:35⎜<asarch> "Psychotics are consistently inconsistent. The essence of sanity is to be inconsistently inconsistent