Subject: bin/8163: sendmail calls qsort(3) with a NULL list
To: None <>
From: Luke Mewburn <>
List: netbsd-bugs
Date: 08/07/1999 07:35:52
>Number:         8163
>Category:       bin
>Synopsis:       sendmail calls qsort(3) with a NULL list
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Aug  7 07:35:00 1999
>Originator:     Luke Mewburn
FTP Hackers R Us.
>Release:        Sun Aug  8 00:26:30 EST 1999
System: NetBSD 1.4J NetBSD 1.4J (LUKEM) #151: Fri Aug 6 12:46:15 EST 1999 i386

	as part of a project i'm doing i've added some assert(3) style
	functionality to various libc functions to ensure that they're
	called with correct pointers (as appropriate).

	i noticed that i was getting a bunch of syslog messages about
	qsort(3) being called by sendmail with a NULL pointer for the
	base arg.

	a quick troll through sendmail's src/queue.c file reveals that
	there is a condition where qsort may be called with base == NULL
	and nelems == 0. whilst I can't find anything specific in the
	Single Unix Specification about the behaviour of qsort when
	base == NULL, i don't think it's a great idea.

	still, as i'm not a standards guru, i'm filing a PR rather
	than making the simple change to sendmail to prevent this.
	(I also have a patch which adds a quick check to qsort() to
	return immediately if nelems == 0; this is a separate issue).

	put an assert(base != NULL) in qsort(3) which logs to the syslog,
	and wait until sendmail runs with an empty queue.

	here's the proposed fix to sendmail. should i commit this,
	or is it something to not bother with?

Index: src/queue.c
RCS file: /cvsroot/basesrc/usr.sbin/sendmail/src/queue.c,v
retrieving revision 1.24
diff -p -r1.24 queue.c
*** queue.c	1998/01/09 08:11:24	1.24
--- queue.c	1999/08/07 14:24:22
*************** orderq(doall)
*** 1072,1077 ****
--- 1072,1079 ----
  	(void) closedir(f);
+ 	if (WorkList == NULL)
+ 		return (0);
  	wc = min(wn, WorkListSize);
  	if (wc > MaxQueueRun && MaxQueueRun > 0)
  		wc = MaxQueueRun;