[exim-dev] [Bug 927] segfault around group_list

Top Page
Delete this message
Reply to this message
Author: Phil Pennock
Date:  
To: exim-dev
Subject: [exim-dev] [Bug 927] segfault around group_list
------- You are receiving this mail because: -------
You are on the CC list for the bug.

http://bugs.exim.org/show_bug.cgi?id=927

Phil Pennock <exim-dev@???> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |exim-dev@???





--- Comment #1 from Phil Pennock <exim-dev@???> 2009-12-05 10:20:43 ---
[ sorry, don't have a Debian BTS account to comment there ]

How many groups is the Exim user a member of? What is the value of NGROUPS_MAX
on the OS?

It's true that the call to getgroups(2) is not checked for a failure return,
but this is a syscall, not a library call, no memory needs to be alloced and
the setup of the call does not allow for any of the possible documented errno
values to be set. However, if the OS allows more members to be in a group than
NGROUPS_MAX, then that would be one explanation. But that would be a
consistent failure.

I note that someone in the referenced bug noted that the problem arrived with a
new kernel version. Is there a new undocumented error return possible from
getgroups() in the updated kernel?

Exim should check that return value and panic/exit on failure, rather than
crash. It's a simple 2-line patch, you can shove that into a debug build and
see if Exim aborts?

The referenced long list of values in the array is rather suspicious. The
groups_list has a defined fixed length. I'm not currently seeing why that
would happen, other than lack of sufficient typing available to gdb. Any
chance of getting a reproduction with a version of Exim built with -ggdb, which
I'm guessing might provide enough type information to prevent this?

I notice that as well as being used for setgroups(), the getgroups() data is
used in two loops for checking for an admin/trusted user. The loops iterate,
stopping once the index no is no longer less than the group count, so if
group_count (the return value from getgroups()) is -1, then it will still go
through the loop once. If the first sizeof(gid_t) bytes from the thus
unitialised memory matches a value configured as an admin_groups or a
trusted_groups gid, then the process will grant the user too many privileges.

So it's a good thing this is crashing, otherwise it would risk being a security
hole (which would let the user, at most, issue an Exim admin command, no
running of arbitrary code). Note though that the reported crashing processes
are running as the exim user, so are already entitled to these privileges. Oh,
and Exim will already have dropped privileges if invoked with an option which
would change the default config (-D, -C) which somewhat limits the possibility
for mischief.

However, although this is uninitialised memory (if getgroups() failed), it's
also memory on the stack frame in main(), so it's not like a previous call will
have let an attacker put whatever data they want there. Linux distributions
don't tend to use "wheel" as group 0, so the fairly common "admin_groups =
wheel" config would not let (gid_t)0 match. On configurations where
admin_groups or trusted_groups contains a group whose gid is 0, this could be
more problematic.

(I'm about to go to sleep, 2.14am, so can't chase this up further tonight).


--
Configure bugmail: http://bugs.exim.org/userprefs.cgi?tab=email