[net.bugs.4bsd] sendmail bug

jeff@fluke.UUCP (Jeff Stearns) (12/10/83)

Subject: sendmail can trash its alias database

Index:	usr.lib/sendmail 4.2BSD

Description:
	If the sendmail alias database is out of date, two concurrent
	invocations of sendmail could each begin to update it in parallel.
	The resultant database may be garbaged.

Repeat-By:
	The following procedure is slightly non-deterministic, but it has
	been effective for us in provoking the problem 50% of the time:
	    Configure /usr/lib/sendmail.cf for automatic database rebuilding:
		# rebuild alias database if out-of-date:
		OD
	    Create /usr/lib/aliases.{dir,pag}
	    % touch /usr/lib/aliases.
	    % mail root </dev/null &
	    % mail root </dev/null &
	Now the tricky part -- test for bad aliases.  A short C program using
	the dbm(3) routines may be helpful.
	
Fix:
	----- /usr/src/usr.lib/sendmail/alias.c -----
1a2
> # include <sys/file.h>
155a157
> 	int aliaslock;
218a221,256
> 	**
> 	**  FLUKE jps 28-sept-83 - Modified to provide some file locking
> 	**	on the alias database:
> 	**
> 	**	We have observed that concurrent sendmail's will rebuild
> 	**	the database in parallel, leading to trashed .{dir,pag} files.
> 	**	This code seeks to prevent that by using file locking as a
> 	**	semaphore.
> 	**
> 	**	Ideally we would like to lock the dbm version of the
> 	**	database - either the .dir or .pag file (or both).
> 	**	The database routines should always open the .pag file
> 	**	with an advisory lock, which would be upgraded to an
> 	**	exclusive one while the database is being updated.
> 	**	Unfortunately that's difficult because the file is opened
> 	**	by dbminit and we never see the file descriptor.  We could
> 	**	open it a second time ourself solely for locking purposes,
> 	**	but there's an alternative.  We lock the unencoded alias
> 	**	file instead.  If you think about it, it really doesn't
> 	**	matter *what* file we lock, so long as all instantiations
> 	**	of sendmail agree upon it (and we retain the convention of
> 	**	having a distinguished alias for "@").
> 	**
> 	**	Note that we open the alias file here solely for the purposes
> 	**	of hanging a lock around it.  Within readaliases() it will
> 	**	be opened a second time for actual processing.  I did it this
> 	**	way to minimize the amount of modified code.
> 	**
> 	**	Note also that this code could be better written to save
> 	**	sequential updatings.  As it is, several concurrent sendmails
> 	**	could each see the need for rebuilding the database, and each
> 	**	will do so, but now they'll do it sequentially, not in parallel.
> 	**	With a bit more smarts, we could prevent that, but it's not
> 	**	worth the bother to save *work*.  We're trying to prevent
> 	**	trashed alias files.
> 	**
222a261,263
> 		if(((aliaslock = open(aliasfile, O_RDONLY)) < 0) ||
> 			flock(aliaslock, LOCK_EX) < 0)
> 			syserr("can't lock alias file for rebuilding");
256a298
> 		(void) close(aliaslock);

		Jeff Stearns,  John Fluke Mfg. Co., Inc.
		P.O. Box C9090, Everett WA  98043
		...!decvax!microsoft!fluke!jeff

chris@umcp-cs.UUCP (Chris Torek) (10/20/85)

The true fix, it seems to me, is to replace the `freeze' and `thaw'
code with a compiled .cf format, easily read but independent of
the exact binary version of sendmail and not containing all sorts
of random things that should *not* be saved.

At the same time, the uncompiled format of the configuration file
should be redesigned.  And sendmail should be split into many
programs---five at the very least:  two queue drivers (one for
input and one for output), an SMTP receiver, an SMTP sender, and
an address rewriter.  But I am not about to attempt this myself.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu

campbell@maynard.UUCP (Larry Campbell) (10/21/85)

Mark Twain's comment about the weather seems to be appropriate
to sendmail as well:

    "Everyone complains about it but nobody does anything about it."
-- 
Larry Campbell                     decvax!genrad
The Boston Software Works, Inc.                 \
120 Fulton St.                 seismo!harvard!wjh12!maynard!campbell
Boston MA 02109                         /       /
                                   ihnp4  cbosgd

ARPA: campbell%maynard.uucp@harvard.ARPA  (broken because of bugs at Harvard)
  or: maynard.UUCP:campbell@harvard.ARPA  (works now but try above if no joy)

scott@cstvax.UUCP (Scott Larnach) (10/24/85)

In the article referred to above, Stephen Muir notes that freezing his
sendmail configuration file causes sendmail to blow up.
(Sun Unix 4.2 Release 2)

This is apparently due to the business of the VAX storing bytes on
the disk in reverse order. I noticed this on our Gould. On swapping
alternate bytes in the freeze file it works perfectly. And Stephen tells
me this cures the sun problem too. So if you have the same problem
run your freeze file through the following little program.
[ I was going to post my byteswapping program but someone has
pointed out to me that dd does that. How dare it?!? ]

Of course the best idea would be to do a proper fix to sendmail. I had
a wee shufty at the code and it seems to be just doing bog standard
raw read/write the memory area to/from the disk. Any takers? The code
is in <sendmail source>/main.c, functions freeze & thaw.

-- 
Scott Larnach			Janet: scott@uk.ac.ed.cstvax
Edinburgh Unix Support		Arpa:  scott@cstvax.ed.ac.uk
Tel:	+44 31 667 1081 x2629	Uucp:  scott@cstvax.uucp