Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 3 Apr 2006 21:07:23 -0300 (ADT)
From:      "Marc G. Fournier" <scrappy@postgresql.org>
To:        Robert Watson <rwatson@FreeBSD.org>
Cc:        Daniel Eischen <deischen@freebsd.org>, "Marc G. Fournier" <scrappy@postgresql.org>, freebsd-stable@freebsd.org, Andrew Thompson <thompsa@freebsd.org>, Kris Kennaway <kris@obsecurity.org>
Subject:   Re: [HACKERS] semaphore usage "port based"?
Message-ID:  <20060403205630.N947@ganymede.hub.org>
In-Reply-To: <20060403230850.P76562@fledge.watson.org>
References:  <Pine.GSO.4.43.0604030817090.21105-100000@sea.ntplx.net> <20060403140902.C947@ganymede.hub.org> <20060403182504.S76562@fledge.watson.org> <20060403144916.J947@ganymede.hub.org> <20060403230850.P76562@fledge.watson.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 3 Apr 2006, Robert Watson wrote:

>
> On Mon, 3 Apr 2006, Marc G. Fournier wrote:
>
>>> The problem here is actually that two postgres instances are trying to use 
>>> the same sempahore when they are actually different postgres instances.
>> 
>> No, the problem here is that kill(PID, 0) reports that a PID is 'not in 
>> use' when, in fact, it is, but in a different jail ... can someone explain 
>> to me how 'not hiding that fact' increases information leakage, or causes a 
>> security problem?  I could see it if I could then proceed to kill that 
>> process from a seperate jail, but I don't see what as possible ...
>
> So if it's using a different semaphore, why is it finding the semaphore 
> of another Postgres session and trying to use that?  The problem you're 
> describing is a property of a collision on a semaphore.  If there's no 
> semaphore collision, how would it ever find the pid from another jail?

All PostgreSQL processes use "port * 1000" as their starting port for 
semId ... if "port * 1000" is reported as in use, the first thing that the 
PostgreSQL process does is kill(PID, 0) the PID returned by semctl(GETPID) 
to see if, in fact, there is a process running ... if not, PostgreSQL 
reuses that semaphore, if not, it goes to (port*1000)+1, and tries again 
... until it can find a free semaphore that isn't in use ...

Now, it doesn't care if PID does exist, but isn't a postgresql process, it 
will just move on to the next (errors on the side of caution) ... so it 
doesn't need to know anything, other then that PID is 'in use' ... 
basically, if the OS reports it as being in use, even if that 'in use' 
happened to be a 1 second perl script running, we don't care, we just move 
to the next semId ...

So, without kill(PID,0) returning that the process is 'in use', we can't 
move onto the next semId to find one not in use :(

Now, there are two ways around that from a 'non-coding' perspective ... 
one is to change the port that the PostgreSQL daemon runs on, which is 
inconvient, since then ppl need ot know to change their applications 
accordingly ... the other is to setup the pgsql "superuser" in the vServer 
to be a different uid in each one, so that even if the process is reported 
as 'not in use', it can't attach to the existing semaphore, since its 
owned by another user ... slightly inconvient from a 'setup perspective', 
but at least then its a one time only thing, so I livable solution ...

... and a solution that doesn't require anyone but me to change :)


----
Marc G. Fournier           Hub.Org Networking Services (http://www.hub.org)
Email: scrappy@hub.org           Yahoo!: yscrappy              ICQ: 7615664



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