Thread: BUG #5275: validate_exec in port/exec.c only reads u/g/o, not ACLs

BUG #5275: validate_exec in port/exec.c only reads u/g/o, not ACLs

From
"James Bellinger"
Date:
The following bug has been logged online:

Bug reference:      5275
Logged by:          James Bellinger
Email address:      jfb@zer7.com
PostgreSQL version: 8.4.2
Operating system:   Ubuntu 9.10
Description:        validate_exec in port/exec.c only reads u/g/o, not ACLs
Details:

Howdy,

I'm not certain of the actual *purpose* for this function even checking in
the first place, but the result is that, if Postgres gets its access via an
ACL, it will say 'invalid binary' here and there, will not be able to find
its own executables, etc. I can see no purpose for this function.

That said, currently, the reason it gives these errors is that it only
checks user/group/other. Linux ACLs are not checked. If this function really
needs to exist as is, this ought to be fixed.

Thanks

James

Re: BUG #5275: validate_exec in port/exec.c only reads u/g/o, not ACLs

From
Tom Lane
Date:
"James Bellinger" <jfb@zer7.com> writes:
> I'm not certain of the actual *purpose* for this function even checking in
> the first place, but the result is that, if Postgres gets its access via an
> ACL, it will say 'invalid binary' here and there, will not be able to find
> its own executables, etc. I can see no purpose for this function.

Hmm.  I wonder why we have all that complexity at all, rather than using
access(2).  The man page says it checks against real not effective uid,
but since we don't run setuid I think there's no difference.

[ pokes in CVS history ... ]  Oh, this is interesting: this code looks
like this clear back to the original Berkeley import, and back then it
had this comment:

    * We use the effective uid here because the backend will not have
    * executed setuid() by the time it calls this routine.

So once upon a time there was a reason to try to implement access()
for ourselves, but it's long gone.  Comments?

            regards, tom lane

Re: BUG #5275: validate_exec in port/exec.c only reads u/g/o, not ACLs

From
Bruce Momjian
Date:
Tom Lane wrote:
> "James Bellinger" <jfb@zer7.com> writes:
> > I'm not certain of the actual *purpose* for this function even checking in
> > the first place, but the result is that, if Postgres gets its access via an
> > ACL, it will say 'invalid binary' here and there, will not be able to find
> > its own executables, etc. I can see no purpose for this function.
>
> Hmm.  I wonder why we have all that complexity at all, rather than using
> access(2).  The man page says it checks against real not effective uid,
> but since we don't run setuid I think there's no difference.
>
> [ pokes in CVS history ... ]  Oh, this is interesting: this code looks
> like this clear back to the original Berkeley import, and back then it
> had this comment:
>
>     * We use the effective uid here because the backend will not have
>     * executed setuid() by the time it calls this routine.
>
> So once upon a time there was a reason to try to implement access()
> for ourselves, but it's long gone.  Comments?

I am not sure of its purpose either.  I remember having to call it in
the old postmaster code before /port was added, but again, I am not sure
why we didn't use access().

I think access's reputation as something to avoid caused us not to look
at it.  My old BSD manual says about access():

CAVEAT
     The access() function should be used rarely, if ever.  Specifically,
     access() should never be used by any program whose user real and effec-
     tive IDs, or group real and effective IDs, differ.  At best, using
     access() in this situation can produce a misleading result, because the
     system call permission checks are based on effective IDs.  Thus, access()
     might return that the file is accessible, when the corresponding open(2)
     or exec(2) call would fail, or vice-versa.  In addition, the permissions
     on the file, or the path leading to the file, may change between the time
     access() makes its test and the eventual system call.  This timing race
     applies to all uses of access(), so it is better to attempt the operation
     itself to see if it will succeed.  (Processes designed to run setuid or
     setgid should call seteuid(2) or setegid(2) as needed to suspend their
     special privileges.)

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

Re: BUG #5275: validate_exec in port/exec.c only reads u/g/o, not ACLs

From
Tom Lane
Date:
Bruce Momjian <bruce@momjian.us> writes:
> I think access's reputation as something to avoid caused us not to look
> at it.  My old BSD manual says about access():

> CAVEAT
>      The access() function should be used rarely, if ever.  Specifically,
>      access() should never be used by any program whose user real and effec-
>      tive IDs, or group real and effective IDs, differ.

But we force those to be the same in main.c.  Anyway there are several
other uses of access() in the code ...

            regards, tom lane

Re: BUG #5275: validate_exec in port/exec.c only reads u/g/o, not ACLs

From
Bruce Momjian
Date:
Tom Lane wrote:
> Bruce Momjian <bruce@momjian.us> writes:
> > I think access's reputation as something to avoid caused us not to look
> > at it.  My old BSD manual says about access():
>
> > CAVEAT
> >      The access() function should be used rarely, if ever.  Specifically,
> >      access() should never be used by any program whose user real and effec-
> >      tive IDs, or group real and effective IDs, differ.
>
> But we force those to be the same in main.c.  Anyway there are several
> other uses of access() in the code ...

Yea, I am not saying the text is right, but rather why it was not
considered for use in that case.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

Re: BUG #5275: validate_exec in port/exec.c only reads u/g/o, not ACLs

From
Tom Lane
Date:
Bruce Momjian <bruce@momjian.us> writes:
> Tom Lane wrote:
>> But we force those to be the same in main.c.  Anyway there are several
>> other uses of access() in the code ...

> Yea, I am not saying the text is right, but rather why it was not
> considered for use in that case.

Actually, since that code has been untouched since Berkeley days,
my bet is that we just never considered changing it at all.

            regards, tom lane