[Nut-upsdev] Re: [nut-commits] svn commit r731

Peter Selinger selinger at mathstat.dal.ca
Wed Jan 24 20:13:13 CET 2007


Arjen de Korte wrote:
>
>
> >> I don't see it as a security risk. Ditto for packet
> >> filters. As I understand you, port ownership will affect whether
> >> people connecting to that port can gain root access.
> > err, no, not directly.
> > opening the socket as root however leaves a window (until dropping
> > privs) where a bug might allow remote attackers to gain root access,
> > yes.
>
> Since the privileges are dropped immediately after opening the sockets,
> the chances are small that there is a usable attack window (in the latest
> version in the trunk that is). Especially since this is a one-time
> opportunity without any external trigger (restarting upsd) to reopen it.
> So one would need to be hammering a system with attack packets
> continuously in the hope that the server is restarted.
>
> I don't think this is a viable attack vector, since by the time we
> start to handle incoming packets, privileges are dropped
> anyway. What remains is the socket ownership. I agree that opening
> the sockets as the upsd user is probably better than as root, since
> there will be no surprises as to the ownership of the socket and/or
> preferential treatment in case of memory starvation.
>
> Maybe we should just open the server sockets after dropping
> privileges and allow people to override this behavior with a command
> line switch (I would prefer to parse upsd.conf after dropping
> privileges too, so automatic detection is not an option).

Ah yes, I agree. Sorry, I just sent my previous email without having
seen this one.

You have to drop privileges after reading upsd.conf though, because as
you pointed out, the user to become could be defined in upsd.conf.

Here is my more detailed analysis of possible event sequences for upsd:

Tasks:

0 read command line
1 set up signal handlers
2 open syslog
3 chroot()
4 read upsd.conf as root
5 look up user id
6 set up the network sockets
7 drop privileges
8 read ups.conf
9 chdir() to STATEPATH
10 open the local driver sockets
11 fork into background

Dependencies:

I can see the following dependencies [X < Y means X has to happen
before Y]:

0 < 3: chroot depends on -r command line option
2 < 3: syslog needs to be written in un-chroot()ed environment (is this true?)
3 < 4: location of upsd.conf is in chroot()ed filesystem
4 < 5: need to know user name
5 < 3: /etc/passwd probably lives in un-chroot()ed environment (CIRCULARITY!)
4 < 6: LISTEN addresses specified in upsd.conf
5 < 7: need to know what user to become
6 < 7: only root can open potentially privileged ports
7 < 8: permissions
7 < 9: permissions
8 < 10: need to know drivers
9 < 10: need to know socket location
10 < 11: useful error message on failure

I don't know if there are any dependencies for step 1; but it probably
should happen ASAP. Also, I might have missed some other dependencies
among the steps. 

Note that there is a circularity in the constraints: 3 < 4 < 5 < 3.
I am not sure how to resolve this.

Ignoring the circularity, there are several possible sequences that
satisfy these dependencies. The code (r782) currently uses this
sequence:

  0 - 1 - 2 - 5 - 3 - 4 - 6 - 7 - 9 - 8 - 10 - ... - 11.

It appears that 1 is independent of everything, 0 and 2 are
independent of each other, 5 and 6 are independent, and 8 and 9 are
independent. Here is a picture:

       	       	  1     0   2
		       	 \ /
		       	  3  <-
		   	  |    |
		   	  4    |circular
		   	 / \   |
		   	6   5--
		   	 \ /
		   	  7
		   	 / \
		   	8   9
		   	 \ /
		   	 10
		   	  |
		   	 11

An interesting consequence is that even if you drop the dependency 
6 < 7 (open sockets before dropping privileges), you still have to
have  5 < 7, so all of 0, 2, 3, 4, 5 have to be done as root anyway. 
So there is no additional gain in dropping root "as early as
possible".

-- Peter



More information about the Nut-upsdev mailing list