2007-02-09 15:10:35 UTC
first my system configuration:
System: Ubuntu Linux 6.06 64bit on AMD x86_64
Compilers: gcc-3.4.6 and gcc-4.0.3
Libc: glibc-2.3.6 and dietlibc-0.31
dietlibc is available from: http://www.fefe.de/dietlibc/
I recommend to use the version from cvs.
When linking qmail against dietlibc, qmail, specifically qmail-rspawn,
becomes unreliable, segfaulting. Problem might appear with glibc to, or
on any other 64bit system, sooner or later, probably later.
compile and link qmail against dietlibc
[ in the qmail source directory you may need to do:
sed -i 's/extern int read();/#include <unistd.h>/' readwrite.h
sed -i 's/extern int write();//' readwrite.h
echo "diet -Os gcc -Os -D_BSD_SOURCE" > conf-cc
echo "diet gcc -s" > conf-ld
then execute qmail-rspawn:
line 194 in spawn.c:
d = (struct delivery *) alloc((auto_spawn + 10) * \
referencing d later results in Segmentation fault.
When compiling, gcc in this case assumes the return value of alloc() to
be an int, therefore the pointer which is meant to be returned is
truncated to an int.
This can be easily verified by removing the cast in line 194, so:
d = alloc((auto_spawn + 10) * sizeof(struct delivery));
Compilation now exhibits the message:
spawn.c:194: warning: assignment makes pointer from integer without a
The Problem did not show up when linking against glibc, because the
allocator of glibc in this case and on my system configuration returned
an address within the range of an int. However the dietlibc allocator
returned an address not fitting into int and so the address got
truncated resulting in segfault.
Simple, add an:
at the beginning of every file where alloc() is called.
Now gcc knows for sure that alloc returns char * and no more truncation
Looks like a time bomb to me :)