Bug 115957 - Questionable ownership and security on mail/dspam
Summary: Questionable ownership and security on mail/dspam
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: Normal Affects Only Me
Assignee: Jason Unovitch
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-08-31 01:20 UTC by tedm
Modified: 2016-05-01 19:55 UTC (History)
4 users (show)

See Also:


Attachments
pr_115957-2016041000.patch (7.10 KB, patch)
2016-04-11 01:12 UTC, danny
no flags Details | Diff
pr_115957-2016041001.patch (8.49 KB, patch)
2016-04-11 05:31 UTC, danny
no flags Details | Diff
poudriere-10.3-amd64.log (151.22 KB, text/plain)
2016-04-11 05:34 UTC, danny
no flags Details
pr_115957-20160426.patch (10.37 KB, patch)
2016-04-27 01:51 UTC, Jason Unovitch
no flags Details | Diff
pr_115957-2016042900 (14.77 KB, patch)
2016-04-30 08:26 UTC, danny
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description tedm 2007-08-31 01:20:01 UTC
 
The Dspam port in /usr/ports/mail/dspam by default installs with the following options:
Comment 1 support 2007-08-31 22:19:20 UTC
send-pr ate the first part of this PR so here's the rest:

The Dspam port in /usr/ports/mail/dspam by default installs with the
following options:

DSPAM_HOME_OWNER=root
DSPAM_HOME_OWNER=mail

It also sets up the webUI to run suexec.

THe problem here is that under Apache 1.3 the suexec header has a minimum
UID and GIU in it's header of 100

This makes it impossible to run the dspam webUI. If you try running the
webUI
under a dspam user above 100, then it can't read /var/db/dspam/data
directories.
If you try running the webUI under a GID of mail, suexec won't allow it to
run.

The ideal thing from a security standpoint would be for the dspam port to
install with DSPAM_HOME_OWNER and DSPAM_HOME_OWNER both set to username
dspam, and have the port create that UID and GID on the system.  That is how
the port USED to work.  I don't know why the maintainer changed it.

If for some reason dspam must run with root UID in order to work with mail,
then the port should check the minimum GID in suexec with a test program,
and
issue an error to the admin to recompile suexec with a minimum GID of 5,
then
the apache entry for the port then runs the dspam vhost web UI under the
mail group.
Comment 2 Edwin Groothuis freebsd_committer 2007-09-01 07:15:18 UTC
Responsible Changed
From-To: freebsd-ports-bugs->itetcu

Over to maintainer
Comment 3 Carlo Strub freebsd_committer 2014-08-29 21:56:59 UTC
back to pool -- no maintainer anymore
Comment 4 Carlo Strub freebsd_committer 2014-08-31 20:15:44 UTC
Is this PR still relevant or shall I close it?
Comment 5 danny 2014-09-17 06:48:31 UTC
Reviewing as per bug #193693, I propose we postpone this bug until after merging mail/dspam-devel in to mail/dspam.

This is definitely still relevant and is important to fix for security reasons.

I tried to go back through the commit history and find where it was changed to get some sort of backstory on why, but I must not have gone back far enough.

There is some interesting semi-related stuff in bug #191797 applied to mail/dspam-devel, so we need to make sure that stuff survives the mail/dspam merge.

Once the mail/dspam merge is done, we can try and figure out exactly *why* the default permissions are set this way.  Someone must have been bumped up against something that failed when run as an unpriv'd user, right?

We should also probably discuss what the most appropriate user/group would be.  Do we create a new dspam/dspam?  Do we use the sorta-standard vmail/vmail?
Comment 6 Jason Unovitch freebsd_committer 2015-12-24 22:05:43 UTC
(In reply to danny from comment #5)

Are all actions for this PR done with now?

Noting bug 193693 and the following MOVED entry as discussed in the comment:
mail/dspam-devel|mail/dspam|2014-10-20|Merged into mail/dspam
Comment 7 danny 2015-12-25 05:49:24 UTC
(In reply to Jason Unovitch from comment #6)
I think this might have been taken care of when we merged the two ports together, but let me do an audit to make sure.

I'll let you know in a few days (away for the holidays right now).
Comment 8 danny 2016-01-12 08:46:31 UTC
Apologies for the delay, I've been under the weather since the holidays.

I dug a little deeper in to the issue reported by the original PR submitter, and I'm having some difficulty correlating what the submitter is saying with what I see in svn.

From what I can see, both the mail/dspam and the (now obsoleted) mail/dspam-devel have always installed with "root:mail" ownership.  This is also the default behavior of upstream dspam as well.

The DSPAM_OWNER and DSPAM_GROUP flags were added to the Makefile here:

  http://svnweb.freebsd.org/ports?view=revision&revision=125128 (dspam)
  http://svnweb.freebsd.org/ports?view=revision&revision=126208 (dspam-devel)

...but those flags were added with "root:mail" set in the Makefile to match the dspam defaults.  I can't find any history of either port installing as "dspam:dspam".

There *is* an entry for dspam in both ports/UIDs and ports/GIDs, but the history doesn't go back far enough to see when they were added:

  http://svnweb.freebsd.org/ports?view=revision&revision=168311

However, I was able to find PR #115957 from 2005, where the previous maintainer requested dspam be added to UIDs/GIDs:

  https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=77800
 
...but it seems like the mentioned changes never made it over to mail/dspam or mail/dspam-devel.  The mail/dspampd port mentioned seems to have been obsoleted, but it predates ports/MOVED.  The uid/gid 202 isn't standard to dspam either, that seems to have been grabbed at random.

Phew.  I'm at a loss as to why the history of this issue isn't adding up, but that doesn't change the fact that running as an unpriv'd user is probably the right thing to do.  Unless it's bad practice to stray that far from upstream behavior on this type of thing?  OpenBSD runs dspam with "_dspam:daemon", so I'm assuming there won't be any lurking problems.

I'll prepare a patch.
Comment 9 Jason Unovitch freebsd_committer 2016-04-03 02:56:05 UTC
(In reply to danny from comment #8)
>I'll prepare a patch.

Any update?
Comment 10 danny 2016-04-03 04:03:00 UTC
(In reply to Jason Unovitch from comment #9)
Sorry for letting this drop, I got wrapped up in a few months of heavy day job work.

I have a patch and was in the middle of testing it before I got pulled off.  Will wrap that up and get it out by the end of the week.
Comment 11 Jason Unovitch freebsd_committer 2016-04-03 16:12:12 UTC
(In reply to danny from comment #10)
No worries. Same here with heavy day job work. I won't have time until next weekend to review the patch so if you get to it anytime this week I'll try to commit it during the weekend.
Comment 12 danny 2016-04-09 09:56:59 UTC
(In reply to Jason Unovitch from comment #11)
I still plan on getting this to you by the end of the weekend, sorry again for the delays.
Comment 13 danny 2016-04-11 01:12:53 UTC
Created attachment 169168 [details]
pr_115957-2016041000.patch

Attached is a patch that changes mail/dspam so that it runs as dspam:dspam out of the box.  A few other changes were required to make things work as an unprivileged user, see CHANGELOG below.

CHANGELOG:

https://github.com/dannywarren/FreeBSD-Ports/compare/master...pr_115957

Changing mail/dspam to install as dspam:dspam instead of root:mail

  * dspam uid = 202
  * dspam gid = 202
  * these values are provided by the ports UIDs and GIDs file, and must have been previously used by dspam a long time ago (I can't find any historical evidence of when they were used, so it's possible they belonged to the dev release or never made it in to dspam proper)
  * a little research shows that these values are not standard to dspam, but have historically been blocked out for a long time so should be safe to use
  * for example, OpenBSD's _dspam:_dspam is 509:509
  * now that we are using the ports standard method of assigning uid:gid to a package, we can easily change the values later if needed

Moving dspam run directory to /var/run/dspam

  * this is the default behavior of upstream dspam
  * dspam starts as dspam:dspam now, so it can't drop files in /var/run any more
  * removing dspam.c patch, since we can just use the default upstream pidfile location
  * adjusting config to use /var/run/dspam/dspam.pid as default
  * adjusting config to use /var/run/dspam/dspam.sock as default
  * adjusting makefile and plist to use /var/run/dspam

Changing default port for dspam daemon/client communication from 24 to 2424

  * by default, dspam tries to use a privileged port for internal communication between itself and any client instances
  * since we are now running dspam as an unprivileged user, this prevents dspam from starting with the default configs
  * dspam probably shouldn't be using a privileged port for internal communication, anyhow
  * we will instead use port 2424 by default, updated daemon and client defaults, updated sample config
  * this is also how OpenBSD handles the issue
Comment 14 danny 2016-04-11 01:18:20 UTC
I'm going to run this through poudriere to make sure everything looks OK.  Additionally, I've been running this on my own mailserver all day with no issues.

Also, this change is probably going to break most people's dspam setups, so we should probably add a note to ports/UPDATING.  I can write up a blurb if you like.
Comment 15 danny 2016-04-11 05:31:10 UTC
Created attachment 169173 [details]
pr_115957-2016041001.patch

Updating Makefile to use "USES=sqlite" instead of "USE_SQLITE" as per pkg-check complaints.

Poudriere tests now passing, will attach those next.
Comment 16 danny 2016-04-11 05:34:36 UTC
Created attachment 169174 [details]
poudriere-10.3-amd64.log

Attaching successful poudriere log for 10.3-amd64.  

10.3-i386 and CURRENT-amd64 are also passing, but won't upload those unless requested as they are just more of the same.
Comment 17 Jason Unovitch freebsd_committer 2016-04-27 01:51:32 UTC
Created attachment 169737 [details]
pr_115957-20160426.patch

Hi.

I just wanted to say thanks up front for the thorough work improving the port.  I've attached a slight revision with an UPDATING entry.  Also since mat@ swept through the tree in a commit to clean up the USE_SQLITE -> USES=sqlite that portion of the patch wasn't relevant.

I'm not familiar with any of the code here but see that it just does setuid to use the dspam user.  So it doesn't *completely* take effect.

# procstat -s `pgrep dspam`                                                     
  PID COMM              EUID  RUID SVUID  EGID  RGID SVGID UMASK FLAGS GROUPS         
19703 dspam              202     0   202     0     0     0   006 -     0,5

I was curious your thoughts on the best way ahead here.  This certainly is a big improvement but it would feel best to be 100% or at least have a talk on why we can't.  Any comments on if anything extra for the UPDATING entry would be helpful as well.

Thanks again Danny!
Comment 18 danny 2016-04-27 07:36:27 UTC
(In reply to Jason Unovitch from comment #17)
UPDATING entry looks good, exactly what I would expect to see as someone who runs a dspam server.

There is a small typo in the UPDATING entry, priveleged->privileged. :)

Hrm, good point on the setuid use.  From what I can see in the README, there are a few corner case features which require setuid and root to run.  The standard usage of dspam doesn't need it at all though, so I agree that it would be best to avoid setuid in the defaults if possible.

I just did a quick and dirty test of yanking the setuid bit and setting user/group to dspam/dspam in the init script...

# procstat -s `pgrep dspam`
  PID COMM              EUID  RUID SVUID  EGID  RGID SVGID UMASK FLAGS GROUPS
79669 dspam              202   202   202   202   202   202   006 -     202,500

Much better!  Didn't bump in to any issues with permissions on existing files or communicating via sockets to other mail services, so I think we are good to go here.

I'll get a patch together and tested tomorrow.  Thanks again for all your help here!
Comment 19 danny 2016-04-27 07:41:11 UTC
Also, do you feel it would be useful to provide a config option to install dspam as root with setuid if the user intends to use any of the obscure features that require it?

Or is that overkill for something that has been mostly abandoned upstream?
Comment 20 Jason Unovitch freebsd_committer 2016-04-27 11:45:04 UTC
(In reply to danny from comment #19)
I'd say it's maintainer's call. You can make the case it's worth removing since it's too obscure and not worth the effort to support. You can also make the case it's only a few extra lines of nondefault config that would be worth keeping around to cover 100% of use cases. Both are reasonable.
Comment 21 danny 2016-04-28 06:57:10 UTC
It's worth a shot then I suppose, especially since the plist now respects the makefile settings and all that.

I'll give a shot and if it's easy, we can throw that in.  If not, let's just push forward without the option.  I'll have that to you by Friday at the latest.
Comment 22 Jason Unovitch freebsd_committer 2016-04-29 01:44:35 UTC
(In reply to danny from comment #21)
Super. I'll commit the update once I get the final notice from you.

Thanks!
Comment 23 danny 2016-04-30 05:55:02 UTC
Alright!  Got both the new behavior and the old insecure behavior working with a config option.

However, I found a bug in the new SQLITE changes, so I'm going to fix that real fast before submitting a patch.  In the meantime, here is what the final permissions and setuid behavior looks like.

# New SETUID config option...

  SETUID           Run as root:mail with setuid (insecure)


# UPDATING now reads...

  20160427:
    AFFECTS: Users of mail/dspam
    AUTHOR: junovitch@FreeBSD.org

    dspam has been modified to no longer run as root:mail by default.
    Existing configuration must be adjusted to reflect using a non-privileged
    port and the /var/run/dspam directory for PID and socket files.  If you
    need dspam to run as root for your mail setup, you can use the SETUID
    config option to enable the old insecure behavior.


# Example of default behavior (SETUID=off)

  # procstat -s `pgrep dspam`
    PID COMM              EUID  RUID SVUID  EGID  RGID SVGID UMASK FLAGS GROUPS
  38554 dspam              202   202   202   202   202   202   006 -     202

  # ls -al /usr/local/bin/dspam*
  -r-xr-xr-x  1 root  wheel  205034 Apr 29 22:34 /usr/local/bin/dspam
  -r-xr-xr-x  1 root  wheel   35258 Apr 29 22:34 /usr/local/bin/dspam_2sql
  -r-xr-xr-x  1 root  wheel   36767 Apr 29 22:34 /usr/local/bin/dspam_admin
  -r-xr-xr-x  1 root  wheel   43630 Apr 29 22:34 /usr/local/bin/dspam_clean
  -r-xr-xr-x  1 root  wheel    9284 Apr 29 22:34 /usr/local/bin/dspam_crc
  -r-xr-xr-x  1 root  wheel   36854 Apr 29 22:34 /usr/local/bin/dspam_dump
  -r-xr-xr-x  1 root  wheel    4274 Apr 29 22:34 /usr/local/bin/dspam_logrotate
  -r-xr-xr-x  1 root  wheel   38585 Apr 29 22:34 /usr/local/bin/dspam_merge
  -r-xr-xr-x  1 root  wheel    9893 Apr 29 22:34 /usr/local/bin/dspam_notify
  -r-xr-xr-x  1 root  wheel   43354 Apr 29 22:34 /usr/local/bin/dspam_stats
  -r-xr-xr-x  1 root  wheel    6881 Apr 29 22:34 /usr/local/bin/dspam_train
  -r-xr-xr-x  1 root  wheel  122562 Apr 29 22:34 /usr/local/bin/dspamc

  # ls -al /var/db/dspam
  drwxrwx---   2 dspam   dspam  5 Apr 29 22:35 dspam

  # ls -al /var/run/dspam
  drwxr-xr-x   2 dspam   dspam  3 Apr 29 22:37 dspam

  # ls -al /var/log/dspam
  drwxrwx---   2 dspam   dspam  2 Apr 29 22:34 dspam


# Example of optional insecure behavior (SETUID=on)

  # procstat -s `pgrep dspam`
    PID COMM              EUID  RUID SVUID  EGID  RGID SVGID UMASK FLAGS GROUPS
  43978 dspam                0     0     0     0     0     0   006 -     0,5

  # ls -al /usr/local/bin/dspam*
  -r-s--x---  1 root  mail   205026 Apr 29 22:41 /usr/local/bin/dspam
  -r-xr-xr-x  1 root  wheel   35258 Apr 29 22:41 /usr/local/bin/dspam_2sql
  -r-xr-xr-x  1 root  wheel   36767 Apr 29 22:41 /usr/local/bin/dspam_admin
  -r-xr-xr-x  1 root  wheel   43630 Apr 29 22:41 /usr/local/bin/dspam_clean
  -r-xr-xr-x  1 root  wheel    9284 Apr 29 22:41 /usr/local/bin/dspam_crc
  -r-xr-xr-x  1 root  wheel   36854 Apr 29 22:41 /usr/local/bin/dspam_dump
  -r-xr-xr-x  1 root  wheel    4274 Apr 29 22:41 /usr/local/bin/dspam_logrotate
  -r-xr-xr-x  1 root  wheel   38585 Apr 29 22:41 /usr/local/bin/dspam_merge
  -r-xr-xr-x  1 root  wheel    9893 Apr 29 22:41 /usr/local/bin/dspam_notify
  -r-xr-xr-x  1 root  wheel   43354 Apr 29 22:41 /usr/local/bin/dspam_stats
  -r-xr-xr-x  1 root  wheel    6881 Apr 29 22:41 /usr/local/bin/dspam_train
  -r-xr-xr-x  1 root  wheel  122554 Apr 29 22:41 /usr/local/bin/dspamc

  # ls -al /var/db/dspam
  drwxrwx---   2 root    mail   5 Apr 29 22:41 dspam

  # ls -al /var/run/dspam
  drwxr-xr-x   2 root    mail   2 Apr 29 22:41 dspam

  # ls -al /var/log/dspam
  drwxrwx---   2 root    mail   2 Apr 29 22:41 dspam
Comment 24 danny 2016-04-30 08:26:19 UTC
Created attachment 169822 [details]
pr_115957-2016042900

Updated patch, tested most of the options and ran everything through portlint/poudriere.  Looking good!  Thanks again for all your help with this.

Changes since your last patch:

* tweak UPDATING entry and add a blurb about the new SETUID option
* new non-default SETUID config option to allow the use of the old insecure behavior of running as root:mail with setuid, also creates /var/*/dspam dirs owned by root:mail
* fixed mistake of having /usr/local/bin/dspam owned by dspam:dspam when running with unprivileged used (it should run as dspam:dspam but be owned by root:wheel, like other bin files)
* fixed problem with SQLITE2 vs SQLITE3 lib files in plist, that must have been broken for a while
* fixed USE_MYSQL=yes -> USES=mysql to make portlint happy
Comment 25 commit-hook freebsd_committer 2016-05-01 01:13:31 UTC
A commit references this bug:

Author: junovitch
Date: Sun May  1 01:13:07 UTC 2016
New revision: 414374
URL: https://svnweb.freebsd.org/changeset/ports/414374

Log:
  mail/dspam: implement privilege separation (resolves bug running with suexec)

  - Runs as dspam:dspam instead of root:mail. The dspam UID/GID were created
    in r168311 when the UIDs/GIDs files were added but the port had always
    used root:mail. This had prevented running the dspam webUI under Apache
    with suexec due to a minimal requirement of UID/GID of 100. The original
    unsecure behavior is available with the SETUID option.
  - Default run directory is now /var/run/dspam. This follows the default
    upstream behavior and removes the patch to dspam.c as a result. Use
    RUN_DIR and correct the dspam.conf.sample file accordingly.
  - Default daemon/client communication port is now 2424.
  - Regen patches while here (portlint)

  UPDATING: Document privilege separated dspam

  PR:		115957
  Reported by:	tedm@ipinc.net, support@ipinc.net
  Submitted by:	Danny Warren <danny@dannywarren.com> (maintainer)

Changes:
  head/UPDATING
  head/mail/dspam/Makefile
  head/mail/dspam/files/UPDATING
  head/mail/dspam/files/dspam.in
  head/mail/dspam/files/patch-src__Makefile.in
  head/mail/dspam/files/patch-src__client.c
  head/mail/dspam/files/patch-src__daemon.c
  head/mail/dspam/files/patch-src__dspam.c
  head/mail/dspam/files/patch-src__dspam.conf.in
  head/mail/dspam/pkg-plist
Comment 26 Jason Unovitch freebsd_committer 2016-05-01 01:15:43 UTC
(In reply to danny from comment #24)
Super!  Thanks Danny!  It's good to finally get this closed all these years later.
Comment 27 danny 2016-05-01 01:31:37 UTC
Thanks for all your help pushing this out the door!  Good job condensing down the history in the commit message, too. :)
Comment 28 Jason Unovitch freebsd_committer 2016-05-01 01:36:18 UTC
(In reply to danny from comment #27)
All the nitty gritty details are above if needed.  Thanks for your efforts as well going through the history and SVN revisions to get that detail!
Comment 29 danny 2016-05-01 19:55:42 UTC
Hi Jason!  Looks like there was a problem regenerating the patch files in commit r414374, and mail/dspam isn't building.

I can't reopen this but, so I've filed a new one: 

  https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=209184

Thanks!