Обсуждение: [HACKERS] CurrentUserId may be invalid during the rest of a session

Поиск
Список
Период
Сортировка

[HACKERS] CurrentUserId may be invalid during the rest of a session

От
Richard Guo
Дата:
Hi,

During the first transaction starting phase within a backend, if there is an 'ereport' after setting transaction state but before
saving CurrentUserId into 'prevUser' in 'TransactionStateData', CurrentUserId will be invalid in the rest of the session.

Take branch 'REL9_6_STABLE' for example:

1797 static void
1798 StartTransaction(void)
1799 {
1800     TransactionState s;

             ......

1822     s->state = TRANS_START;

                                                               <======= 'ereport' in this window
             ......

1909     GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext);

             ......

1927 }

If 'ereport' occurs in the described window, CurrentUserId will have no chance to be saved into 'prevUser' and 'prevUser' will remain to be InvalidOid as this is the first transaction of the session.

As transaction state has been set to be TRANS_START, 'AbortTransaction' will be called then and CurrentUserId will be restored with 'prevUser', which is InvalidOid. So in the rest of the session, CurrentUserId will be invalid.

The invalid CurrentUserId may cause assertion failure or other issues, for example:

(gdb) bt
#0  0x00007f3d8ced9495 in raise () from /lib64/libc.so.6
#1  0x00007f3d8cedac75 in abort () from /lib64/libc.so.6
#2  0x000000000095fdbd in ExceptionalCondition (conditionName=0xb72838 "!(((bool) ((CurrentUserId) != ((Oid) 0))))", errorType=0xb726ff "BadState",
    fileName=0xb726c0 "miscinit.c", lineNumber=284) at assert.c:54
#3  0x0000000000971b88 in GetUserId () at miscinit.c:284
#4  0x00000000005559c4 in recomputeNamespacePath () at namespace.c:3496
#5  0x0000000000551d53 in RelnameGetRelid (relname=0x1d3f288 "t1") at namespace.c:673
#6  0x00000000005514a7 in RangeVarGetRelidExtended (relation=0x1d3f2a8, lockmode=1, missing_ok=1 '\001', nowait=0 '\000', callback=0x0, callback_arg=0x0)
    at namespace.c:326

Is this expected behavior?

Thanks
-Richard

Re: [HACKERS] CurrentUserId may be invalid during the rest of a session

От
Robert Haas
Дата:
On Thu, Aug 31, 2017 at 6:02 AM, Richard Guo <guofenglinux@gmail.com> wrote:
> Is this expected behavior?

I don't think so.  My impression after brief research is that this is
a bug introduced here:

Author: Tom Lane <tgl@sss.pgh.pa.us>
Branch: master Release: REL8_3_0 [eedb068c0] 2008-01-03 21:23:15 +0000
Branch: REL8_2_STABLE Release: REL8_2_6 [3af35f8d4] 2008-01-03 21:23:45 +0000
Branch: REL8_1_STABLE Release: REL8_1_11 [46cf9c260] 2008-01-03 21:24:26 +0000
Branch: REL8_0_STABLE Release: REL8_0_15 [108b19d86] 2008-01-03 21:25:00 +0000
Branch: REL7_4_STABLE Release: REL7_4_19 [230d5cfc4] 2008-01-03 21:25:34 +0000
Branch: REL7_3_STABLE Release: REL7_3_21 [218cf59b6] 2008-01-03 21:25:58 +0000
   Make standard maintenance operations (including VACUUM, ANALYZE, REINDEX,   and CLUSTER) execute as the table owner
ratherthan the calling user, using   the same privilege-switching mechanism already used for SECURITY DEFINER
functions. The purpose of this change is to ensure that user-defined   functions used in index definitions cannot
acquirethe privileges of a   superuser account that is performing routine maintenance.  While a function   used in an
indexis supposed to be IMMUTABLE and thus not able to
 
do anything   very interesting, there are several easy ways around that restriction; and   even if we could plug them
all,there would remain a risk of
 
reading sensitive   information and broadcasting it through a covert channel such as CPU usage.
   To prevent bypassing this security measure, execution of SET SESSION   AUTHORIZATION and SET ROLE is now forbidden
withina SECURITY
 
DEFINER context.
   Thanks to Itagaki Takahiro for reporting this vulnerability.
   Security: CVE-2007-6600

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company