~ubuntu-branches/ubuntu/oneiric/postgresql-9.1/oneiric-security

« back to all changes in this revision

Viewing changes to src/pl/plperl/plperl.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2013-02-05 18:13:52 UTC
  • mfrom: (1.1.10) (10.1.5 oneiric-proposed)
  • Revision ID: package-import@ubuntu.com-20130205181352-3kw4f94ilqklzm7c
Tags: 9.1.8-0ubuntu11.10
* New upstream security/bug fix release: (LP: #1116336)
  - Prevent execution of enum_recv from SQL
    The function was misdeclared, allowing a simple SQL command to crash the
    server.  In principle an attacker might be able to use it to examine the
    contents of server memory.  Our thanks to Sumit Soni (via Secunia SVCRP)
    for reporting this issue. (CVE-2013-0255)
  - See HISTORY/changelog.gz for the other bug fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include "commands/trigger.h"
24
24
#include "executor/spi.h"
25
25
#include "funcapi.h"
 
26
#include "libpq/pqsignal.h"
26
27
#include "mb/pg_wchar.h"
27
28
#include "miscadmin.h"
28
29
#include "nodes/makefuncs.h"
29
30
#include "parser/parse_type.h"
30
31
#include "storage/ipc.h"
 
32
#include "tcop/tcopprot.h"
31
33
#include "utils/builtins.h"
32
34
#include "utils/fmgroids.h"
33
35
#include "utils/guc.h"
66
68
 *
67
69
 * The plperl_interp_desc structs are kept in a Postgres hash table indexed
68
70
 * by userid OID, with OID 0 used for the single untrusted interpreter.
 
71
 * Once created, an interpreter is kept for the life of the process.
69
72
 *
70
73
 * We start out by creating a "held" interpreter, which we initialize
71
74
 * only as far as we can do without deciding if it will be trusted or
91
94
 
92
95
/**********************************************************************
93
96
 * The information we cache about loaded procedures
 
97
 *
 
98
 * The refcount field counts the struct's reference from the hash table shown
 
99
 * below, plus one reference for each function call level that is using the
 
100
 * struct.  We can release the struct, and the associated Perl sub, when the
 
101
 * refcount goes to zero.
94
102
 **********************************************************************/
95
103
typedef struct plperl_proc_desc
96
104
{
97
105
        char       *proname;            /* user name of procedure */
98
 
        TransactionId fn_xmin;
 
106
        TransactionId fn_xmin;          /* xmin/TID of procedure's pg_proc tuple */
99
107
        ItemPointerData fn_tid;
 
108
        int                     refcount;               /* reference count of this struct */
 
109
        SV                 *reference;          /* CODE reference for Perl sub */
100
110
        plperl_interp_desc *interp; /* interpreter it's created in */
101
 
        bool            fn_readonly;
102
 
        bool            lanpltrusted;
 
111
        bool            fn_readonly;    /* is function readonly (not volatile)? */
 
112
        bool            lanpltrusted;   /* is it plperl, rather than plperlu? */
103
113
        bool            fn_retistuple;  /* true, if function returns tuple */
104
114
        bool            fn_retisset;    /* true, if function returns set */
105
115
        bool            fn_retisarray;  /* true if function returns array */
 
116
        /* Conversion info for function's result type: */
106
117
        Oid                     result_oid;             /* Oid of result type */
107
118
        FmgrInfo        result_in_func; /* I/O function and arg for result type */
108
119
        Oid                     result_typioparam;
 
120
        /* Conversion info for function's argument types: */
109
121
        int                     nargs;
110
122
        FmgrInfo        arg_out_func[FUNC_MAX_ARGS];
111
123
        bool            arg_is_rowtype[FUNC_MAX_ARGS];
112
124
        Oid                     arg_arraytype[FUNC_MAX_ARGS];   /* InvalidOid if not an array */
113
 
        SV                 *reference;
114
125
} plperl_proc_desc;
115
126
 
 
127
#define increment_prodesc_refcount(prodesc)  \
 
128
        ((prodesc)->refcount++)
 
129
#define decrement_prodesc_refcount(prodesc)  \
 
130
        do { \
 
131
                if (--((prodesc)->refcount) <= 0) \
 
132
                        free_plperl_function(prodesc); \
 
133
        } while(0)
 
134
 
116
135
/**********************************************************************
117
136
 * For speedy lookup, we maintain a hash table mapping from
118
137
 * function OID + trigger flag + user OID to plperl_proc_desc pointers.
234
253
static Datum plperl_func_handler(PG_FUNCTION_ARGS);
235
254
static Datum plperl_trigger_handler(PG_FUNCTION_ARGS);
236
255
 
 
256
static void free_plperl_function(plperl_proc_desc *prodesc);
 
257
 
237
258
static plperl_proc_desc *compile_plperl_function(Oid fn_oid, bool is_trigger);
238
259
 
239
260
static SV  *plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc);
740
761
                        char       *dummy_env[1] = {NULL};
741
762
 
742
763
                        PERL_SYS_INIT3(&nargs, (char ***) &embedding, (char ***) &dummy_env);
 
764
 
 
765
                        /*
 
766
                         * For unclear reasons, PERL_SYS_INIT3 sets the SIGFPE handler to
 
767
                         * SIG_IGN.  Aside from being extremely unfriendly behavior for a
 
768
                         * library, this is dumb on the grounds that the results of a
 
769
                         * SIGFPE in this state are undefined according to POSIX, and in
 
770
                         * fact you get a forced process kill at least on Linux.  Hence,
 
771
                         * restore the SIGFPE handler to the backend's standard setting.
 
772
                         * (See Perl bug 114574 for more information.)
 
773
                         */
 
774
                        pqsignal(SIGFPE, FloatExceptionHandler);
 
775
 
743
776
                        perl_sys_init_done = 1;
744
777
                        /* quiet warning if PERL_SYS_INIT3 doesn't use the third argument */
745
778
                        dummy_env[0] = NULL;
1662
1695
        Datum           retval;
1663
1696
        plperl_call_data *save_call_data = current_call_data;
1664
1697
        plperl_interp_desc *oldinterp = plperl_active_interp;
 
1698
        plperl_call_data this_call_data;
 
1699
 
 
1700
        /* Initialize current-call status record */
 
1701
        MemSet(&this_call_data, 0, sizeof(this_call_data));
 
1702
        this_call_data.fcinfo = fcinfo;
1665
1703
 
1666
1704
        PG_TRY();
1667
1705
        {
 
1706
                current_call_data = &this_call_data;
1668
1707
                if (CALLED_AS_TRIGGER(fcinfo))
1669
1708
                        retval = PointerGetDatum(plperl_trigger_handler(fcinfo));
1670
1709
                else
1672
1711
        }
1673
1712
        PG_CATCH();
1674
1713
        {
 
1714
                if (this_call_data.prodesc)
 
1715
                        decrement_prodesc_refcount(this_call_data.prodesc);
1675
1716
                current_call_data = save_call_data;
1676
1717
                activate_interpreter(oldinterp);
1677
1718
                PG_RE_THROW();
1678
1719
        }
1679
1720
        PG_END_TRY();
1680
1721
 
 
1722
        if (this_call_data.prodesc)
 
1723
                decrement_prodesc_refcount(this_call_data.prodesc);
1681
1724
        current_call_data = save_call_data;
1682
1725
        activate_interpreter(oldinterp);
1683
1726
        return retval;
1697
1740
        plperl_proc_desc desc;
1698
1741
        plperl_call_data *save_call_data = current_call_data;
1699
1742
        plperl_interp_desc *oldinterp = plperl_active_interp;
 
1743
        plperl_call_data this_call_data;
1700
1744
        ErrorContextCallback pl_error_context;
1701
1745
 
 
1746
        /* Initialize current-call status record */
 
1747
        MemSet(&this_call_data, 0, sizeof(this_call_data));
 
1748
 
1702
1749
        /* Set up a callback for error reporting */
1703
1750
        pl_error_context.callback = plperl_inline_callback;
1704
1751
        pl_error_context.previous = error_context_stack;
1729
1776
        desc.nargs = 0;
1730
1777
        desc.reference = NULL;
1731
1778
 
1732
 
        current_call_data = (plperl_call_data *) palloc0(sizeof(plperl_call_data));
1733
 
        current_call_data->fcinfo = &fake_fcinfo;
1734
 
        current_call_data->prodesc = &desc;
 
1779
        this_call_data.fcinfo = &fake_fcinfo;
 
1780
        this_call_data.prodesc = &desc;
 
1781
        /* we do not bother with refcounting the fake prodesc */
1735
1782
 
1736
1783
        PG_TRY();
1737
1784
        {
1738
1785
                SV                 *perlret;
1739
1786
 
 
1787
                current_call_data = &this_call_data;
 
1788
 
1740
1789
                if (SPI_connect() != SPI_OK_CONNECT)
1741
1790
                        elog(ERROR, "could not connect to SPI manager");
1742
1791
 
2118
2167
        ReturnSetInfo *rsi;
2119
2168
        ErrorContextCallback pl_error_context;
2120
2169
 
2121
 
        /*
2122
 
         * Create the call_data before connecting to SPI, so that it is not
2123
 
         * allocated in the SPI memory context
2124
 
         */
2125
 
        current_call_data = (plperl_call_data *) palloc0(sizeof(plperl_call_data));
2126
 
        current_call_data->fcinfo = fcinfo;
2127
 
 
2128
2170
        if (SPI_connect() != SPI_OK_CONNECT)
2129
2171
                elog(ERROR, "could not connect to SPI manager");
2130
2172
 
2131
2173
        prodesc = compile_plperl_function(fcinfo->flinfo->fn_oid, false);
2132
2174
        current_call_data->prodesc = prodesc;
 
2175
        increment_prodesc_refcount(prodesc);
2133
2176
 
2134
2177
        /* Set a callback for error reporting */
2135
2178
        pl_error_context.callback = plperl_exec_callback;
2236
2279
        HV                 *hvTD;
2237
2280
        ErrorContextCallback pl_error_context;
2238
2281
 
2239
 
        /*
2240
 
         * Create the call_data before connecting to SPI, so that it is not
2241
 
         * allocated in the SPI memory context
2242
 
         */
2243
 
        current_call_data = (plperl_call_data *) palloc0(sizeof(plperl_call_data));
2244
 
        current_call_data->fcinfo = fcinfo;
2245
 
 
2246
2282
        /* Connect to SPI manager */
2247
2283
        if (SPI_connect() != SPI_OK_CONNECT)
2248
2284
                elog(ERROR, "could not connect to SPI manager");
2250
2286
        /* Find or compile the function */
2251
2287
        prodesc = compile_plperl_function(fcinfo->flinfo->fn_oid, true);
2252
2288
        current_call_data->prodesc = prodesc;
 
2289
        increment_prodesc_refcount(prodesc);
2253
2290
 
2254
2291
        /* Set a callback for error reporting */
2255
2292
        pl_error_context.callback = plperl_exec_callback;
2359
2396
 
2360
2397
                /* Otherwise, unlink the obsoleted entry from the hashtable ... */
2361
2398
                proc_ptr->proc_ptr = NULL;
2362
 
                /* ... and throw it away */
2363
 
                if (prodesc->reference)
2364
 
                {
2365
 
                        plperl_interp_desc *oldinterp = plperl_active_interp;
2366
 
 
2367
 
                        activate_interpreter(prodesc->interp);
2368
 
                        SvREFCNT_dec(prodesc->reference);
2369
 
                        activate_interpreter(oldinterp);
2370
 
                }
 
2399
                /* ... and release the corresponding refcount, probably deleting it */
 
2400
                decrement_prodesc_refcount(prodesc);
 
2401
        }
 
2402
 
 
2403
        return false;
 
2404
}
 
2405
 
 
2406
 
 
2407
static void
 
2408
free_plperl_function(plperl_proc_desc *prodesc)
 
2409
{
 
2410
        Assert(prodesc->refcount <= 0);
 
2411
        /* Release CODE reference, if we have one, from the appropriate interp */
 
2412
        if (prodesc->reference)
 
2413
        {
 
2414
                plperl_interp_desc *oldinterp = plperl_active_interp;
 
2415
 
 
2416
                activate_interpreter(prodesc->interp);
 
2417
                SvREFCNT_dec(prodesc->reference);
 
2418
                activate_interpreter(oldinterp);
 
2419
        }
 
2420
        /* Get rid of what we conveniently can of our own structs */
 
2421
        /* (FmgrInfo subsidiary info will get leaked ...) */
 
2422
        if (prodesc->proname)
2371
2423
                free(prodesc->proname);
2372
 
                free(prodesc);
2373
 
        }
2374
 
 
2375
 
        return false;
 
2424
        free(prodesc);
2376
2425
}
2377
2426
 
2378
2427
 
2446
2495
                        ereport(ERROR,
2447
2496
                                        (errcode(ERRCODE_OUT_OF_MEMORY),
2448
2497
                                         errmsg("out of memory")));
 
2498
                /* Initialize all fields to 0 so free_plperl_function is safe */
2449
2499
                MemSet(prodesc, 0, sizeof(plperl_proc_desc));
 
2500
 
2450
2501
                prodesc->proname = strdup(NameStr(procStruct->proname));
2451
2502
                if (prodesc->proname == NULL)
 
2503
                {
 
2504
                        free_plperl_function(prodesc);
2452
2505
                        ereport(ERROR,
2453
2506
                                        (errcode(ERRCODE_OUT_OF_MEMORY),
2454
2507
                                         errmsg("out of memory")));
 
2508
                }
2455
2509
                prodesc->fn_xmin = HeapTupleHeaderGetXmin(procTup->t_data);
2456
2510
                prodesc->fn_tid = procTup->t_self;
2457
2511
 
2466
2520
                                                                  ObjectIdGetDatum(procStruct->prolang));
2467
2521
                if (!HeapTupleIsValid(langTup))
2468
2522
                {
2469
 
                        free(prodesc->proname);
2470
 
                        free(prodesc);
 
2523
                        free_plperl_function(prodesc);
2471
2524
                        elog(ERROR, "cache lookup failed for language %u",
2472
2525
                                 procStruct->prolang);
2473
2526
                }
2486
2539
                                                                ObjectIdGetDatum(procStruct->prorettype));
2487
2540
                        if (!HeapTupleIsValid(typeTup))
2488
2541
                        {
2489
 
                                free(prodesc->proname);
2490
 
                                free(prodesc);
 
2542
                                free_plperl_function(prodesc);
2491
2543
                                elog(ERROR, "cache lookup failed for type %u",
2492
2544
                                         procStruct->prorettype);
2493
2545
                        }
2501
2553
                                         /* okay */ ;
2502
2554
                                else if (procStruct->prorettype == TRIGGEROID)
2503
2555
                                {
2504
 
                                        free(prodesc->proname);
2505
 
                                        free(prodesc);
 
2556
                                        free_plperl_function(prodesc);
2506
2557
                                        ereport(ERROR,
2507
2558
                                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2508
2559
                                                         errmsg("trigger functions can only be called "
2510
2561
                                }
2511
2562
                                else
2512
2563
                                {
2513
 
                                        free(prodesc->proname);
2514
 
                                        free(prodesc);
 
2564
                                        free_plperl_function(prodesc);
2515
2565
                                        ereport(ERROR,
2516
2566
                                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2517
2567
                                                         errmsg("PL/Perl functions cannot return type %s",
2546
2596
                                                ObjectIdGetDatum(procStruct->proargtypes.values[i]));
2547
2597
                                if (!HeapTupleIsValid(typeTup))
2548
2598
                                {
2549
 
                                        free(prodesc->proname);
2550
 
                                        free(prodesc);
 
2599
                                        free_plperl_function(prodesc);
2551
2600
                                        elog(ERROR, "cache lookup failed for type %u",
2552
2601
                                                 procStruct->proargtypes.values[i]);
2553
2602
                                }
2557
2606
                                if (typeStruct->typtype == TYPTYPE_PSEUDO &&
2558
2607
                                        procStruct->proargtypes.values[i] != RECORDOID)
2559
2608
                                {
2560
 
                                        free(prodesc->proname);
2561
 
                                        free(prodesc);
 
2609
                                        free_plperl_function(prodesc);
2562
2610
                                        ereport(ERROR,
2563
2611
                                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2564
2612
                                                         errmsg("PL/Perl functions cannot accept type %s",
2611
2659
                pfree(proc_source);
2612
2660
                if (!prodesc->reference)        /* can this happen? */
2613
2661
                {
2614
 
                        free(prodesc->proname);
2615
 
                        free(prodesc);
 
2662
                        free_plperl_function(prodesc);
2616
2663
                        elog(ERROR, "could not create PL/Perl internal procedure");
2617
2664
                }
2618
2665
 
2624
2671
                proc_ptr = hash_search(plperl_proc_hash, &proc_key,
2625
2672
                                                           HASH_ENTER, NULL);
2626
2673
                proc_ptr->proc_ptr = prodesc;
 
2674
                increment_prodesc_refcount(prodesc);
2627
2675
        }
2628
2676
 
2629
2677
        /* restore previous error callback */