[Date Prev][Date Next] [Chronological] [Thread] [Top]

sl_malloc is unportable (ITS#2551)

Full_Name: Hallvard B Furuseth
Version: HEAD
Submission from: (NULL) (
Submitted by: hallvard

This test in sl_realloc() and sl_free() yields undefined behaviour:
	/* Not our memory? */
	if ( !sh || ptr < sh->h_base || ptr >= sh->h_end ) {
Also this in sl_release() and sl_context():
	if ( sh && ptr >= sh->h_base && ptr <= sh->h_end ) {
The operators < <= > >= are only defined between two pointers into the
same block of memory.  An example of how they can fail with pointers
to different blocks of memory is if a pointer consists of a segment
number and an offset into the segment, and an object cannot cross a
segment boundary.  Then these operators need only compare the offsets,
they can ignore the segment numbers.

So slapd needs an `#ifdef USE_SL_MALLOC' to be defined for architectures
or architecture/compiler combinations where sl_malloc works.
Unfortunately I cannot think of a reliable configure test for this,
the best I can think of is to collect information about where it works,
and hard-code #if tests for that into the code.

Another non-portability is this code:
	int pad = 2*sizeof(int)-1;
	/* round up to doubleword boundary */
	size += pad;
	size &= ~pad;
Some types may need stricter alignment than that.  A better way to find
the required alignment is:
	#include <stddef.h>
	struct align_test {
		char c;
		union {
			long l;
			double d;
			void *vp;
			struct align_test *sp;
			int (*ifp)(int);
			void (*vfp)(void);
			/* ...other types used by the program... */
		} align;
	#define ALIGN_MAX offsetof(struct align_test, align)