Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 17 Dec 1996 23:01:30 +1100 (EST)
From:      proff@suburbia.net
To:        ley@cert.dfn.de (Wolfgang Ley)
Cc:        vitjok@fasts.com, freebsd-security@freebsd.org
Subject:   Re: sendmail...
Message-ID:  <19961217120130.4779.qmail@suburbia.net>
In-Reply-To: <199612170931.KAA05839@tiger.cert.dfn.de> from Wolfgang Ley at "Dec 17, 96 10:31:24 am"

next in thread | previous in thread | raw e-mail | index | archive | help
-- Start of PGP signed section.
> Victor Rotanov wrote:
> >
> > Hello.
> >
> > Why sendmail can't be replaced with something more secure by default?
> > I'd suggest Zmailer which can be fount at
> > ftp://ftp.funet.fi/pub/unix/mail/zmailer
> > It is also seems to be faster than sendmail on high loads.
> 
> Proof that Zmailer ist more secure than sendmail (note: "there are no/less
> *known* security bugs" doesn't count because people most probably haven't
> bothered to investigate Zmailer/Smail/Qmail/... in the same depth as
> sendmail).
> 
> Bye,
>   Wolfgang.
> --
> Wolfgang Ley, DFN-CERT, Vogt-Koelln-Str. 30, 22527 Hamburg,    Germany

Proof that you haven't investigated Qmail (I can't comment on
Zmailer, and I wouldn't trust Smail any more than sendmail, although
apparently Debian linux does) - Qmail is a well thought out example
of functional compartmentalisation and least-privilege. I strongly
suggest people take a good look at the code, and consider making
qmail the default MTA for FreeBSD.  Qmail handles virtual domains,
mail-tables etc, without any sendmail.cf trickery, which even
after 10 years and m4 is not something I do in my sleep. Sendmail is a
monolithic suid patchwork quilt. Qmail is very much in keeping with
the unix paradigm of division of labours and despite it's strong
security stance actually seems more efficient than sendmail.

Someone suggested on this subject that FreeBSD would be the laughing
stock of the network community if it dropped sendmail8(!). This is
strange perspective. I had thought *sendmail* was the laughing
stock of the networking, security and cracker communities.

-Julian (proff@suburbia.net) // attached: qmail/SECURITY

Background: Every few months CERT announces Yet Another Security Hole In
Sendmail---something that lets local or even remote users take complete
control of the machine. I'm sure there are many more holes waiting to be
discovered; sendmail's design means that any minor bug in 46000 lines of
code is a major security risk. Other popular mailers, such as Smail, and
even mailing-list managers, such as Majordomo, seem just as bad.

I started working on qmail because I was sick of this cycle of doom.
Here are some of the things I did to make sure that qmail will never let
an intruder into your machine.


1. Programs and files are not addresses. Don't treat them as addresses.

sendmail treats programs and files as addresses. Obviously random people
can't be allowed to execute arbitrary programs or write to arbitrary
files, so sendmail goes through horrendous contortions trying to keep
track of whether a local user was ``responsible'' for an address. This
has proven to be an unmitigated disaster.

In qmail, programs and files are not addresses. The local delivery
agent, qmail-alias, can run programs or write to files as directed by
~user/.qmail, but it's always running as that user. (The notion of
``user'' is configurable, but root is never a user. To prevent silly
mistakes, qmail-alias makes sure that neither ~user nor ~user/.qmail is
group-writable or world-writable.)

Security impact: .qmail, like .cshrc and .exrc and various other files,
means that anyone who can write arbitrary files as a user can execute
arbitrary programs as that user. That's it.


2. Do as little as possible in setuid programs.

A setuid program must operate in a very dangerous environment: a user is
under complete control of its fds, args, environ, cwd, tty, rlimits,
timers, signals, and more. Even worse, the list of controlled items
varies from one vendor's UNIX to the next, so it is very difficult to
write portable code that cleans up everything.

Of the twelve most recent sendmail security holes, six worked only
because the entire sendmail system is setuid.

Only one qmail program is setuid: qmail-queue. Its only purpose is to
add a new mail message to the outgoing queue.


3. Do as little as possible as root.

The entire sendmail system runs as root, so there's no way that its
mistakes can be caught by the operating system's built-in protections.
In contrast, only two qmail programs, qmail-start and qmail-lspawn,
run as root.


4. Move separate functions into mutually untrusting programs.

Five of the qmail programs---qmail-smtpd, qmail-send, qmail-rspawn,
qmail-remote, and tcp-env---are not security-critical. Even if all of
these programs are completely compromised, so that an intruder has
control over the qmaild, qmails, and qmailr accounts and the mail queue,
he still can't take over your system. None of the other programs trust
the results from these five.

In fact, these programs don't even trust each other. They are in three
groups: tcp-env and qmail-smtpd, which run as qmaild; qmail-rspawn and
qmail-remote, which run as qmailr; and qmail-send, the queue manager,
which runs as qmails. Each group is immune from attacks by the others.

(From root's point of view, as long as root doesn't send any mail, only
qmail-start and qmail-lspawn are security-critical. They don't write any
files or start any other programs as root.)


5. Don't parse.

I have discovered that there are two types of command interfaces in the
world of computing: good interfaces and user interfaces.

The essence of user interfaces is _parsing_---converting an unstructured
sequence of commands, in a format usually determined more by psychology
than by solid engineering, into structured data.

When another programmer wants to talk to a user interface, he has to
_quote_: convert his structured data into an unstructured sequence of
commands that the parser will, he hopes, convert back into the original
structured data.

This situation is a recipe for disaster. The parser often has bugs: it
fails to handle some inputs according to the documented interface. The
quoter often has bugs: it produces outputs that do not have the right
meaning. Only on rare joyous occasions does it happen that the parser
and the quoter both misinterpret the interface in the same way.

When the original data is controlled by a malicious user, many of these
bugs translate into security holes. Some examples: the Linux login
-froot security hole; the classic find | xargs rm security hole; the
recent Majordomo security hole. Even a simple parser like getopt is
complicated enough for people to screw up the quoting.

In qmail, all the internal file structures are incredibly simple: text0
lines beginning with single-character commands. (text0 format means that
lines are separated by a 0 byte instead of line feed.) The program-level
interfaces don't take options.

All the complexity of parsing RFC 822 address lists and rewriting
headers is in the qmail-inject program, which runs without privileges
and is essentially part of the UA.

The only nasty case is .qmail, qmail's answer to .forward. I tried to
make this as simple as possible, but unfortunately it still has to be
edited by users. As a result, the qlist mailing-list-management program
has to be careful to exclude subscriber addresses that contain newlines.


6. Keep it simple, stupid.

See BLURB for some of the reasons that qmail is so much smaller than
sendmail. There's nothing inherently complicated about writing a mailer.
(Except RFC 822 support; but that's only in qmail-inject.) Security
holes can't show up in features that don't exist.


7. Write bug-free code.

I've mostly given up on the standard C library. Many of its facilities,
particularly stdio, seem designed to encourage bugs. A big chunk of
qmail is stolen from a basic C library that I've been developing for
several years for a variety of applications. The stralloc concept and
getline2() make it very easy to avoid buffer overruns, memory leaks,
and artificial line length limits.




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19961217120130.4779.qmail>