This is an automated email from the ASF dual-hosted git repository. reshke pushed a commit to branch REL_2_STABLE in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit 1f659fd9758fecd28c301aa666e4e941e2b3e261 Author: Heikki Linnakangas <[email protected]> AuthorDate: Mon Aug 10 06:38:35 2026 -0700 Use palloc_array() in pltcl and plperl to avoid overflow Some of these could overflow on 32-bit systems with the right input. Convert all cases where we called palloc() with multiplication to fix them. Not all of them were bugs, but it's better to be safe than sorry. Reported-by: Tulya Project, Team Dhiutsa, Bitecope Technologies Private Ltd Backpatch-through: 14 Security: CVE-2026-14677 --- src/pl/plperl/SPI.xs | 6 +++--- src/pl/plperl/plperl.c | 38 +++++++++++++++++++------------------- src/pl/tcl/pltcl.c | 20 ++++++++++---------- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/pl/plperl/SPI.xs b/src/pl/plperl/SPI.xs index b98c547e8be..39db3bb37a0 100644 --- a/src/pl/plperl/SPI.xs +++ b/src/pl/plperl/SPI.xs @@ -79,7 +79,7 @@ spi_spi_prepare(sv, ...) char* query = sv2cstr(sv); if (items < 1) Perl_croak(aTHX_ "Usage: spi_prepare(query, ...)"); - argv = ( SV**) palloc(( items - 1) * sizeof(SV*)); + argv = palloc_array(SV*, items - 1); for ( i = 1; i < items; i++) argv[i - 1] = ST(i); RETVAL = plperl_spi_prepare(query, items - 1, argv); @@ -107,7 +107,7 @@ spi_spi_exec_prepared(sv, ...) offset++; } argc = items - offset; - argv = ( SV**) palloc( argc * sizeof(SV*)); + argv = palloc_array(SV*, argc); for ( i = 0; offset < items; offset++, i++) argv[i] = ST(offset); ret_hash = plperl_spi_exec_prepared(query, attr, argc, argv); @@ -127,7 +127,7 @@ spi_spi_query_prepared(sv, ...) if ( items < 1) Perl_croak(aTHX_ "Usage: spi_query_prepared(query, " "[\\@bind_values])"); - argv = ( SV**) palloc(( items - 1) * sizeof(SV*)); + argv = palloc_array(SV*, items - 1); for ( i = 1; i < items; i++) argv[i - 1] = ST(i); RETVAL = plperl_spi_query_prepared(query, items - 1, argv); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index c214a1daa91..24a878d9455 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -1084,8 +1084,8 @@ plperl_build_tuple_result(HV *perlhash, TupleDesc td) HE *he; HeapTuple tup; - values = palloc0(sizeof(Datum) * td->natts); - nulls = palloc(sizeof(bool) * td->natts); + values = palloc0_array(Datum, td->natts); + nulls = palloc_array(bool, td->natts); memset(nulls, true, sizeof(bool) * td->natts); hv_iterinit(perlhash); @@ -1504,7 +1504,7 @@ plperl_ref_from_pg_array(Datum arg, Oid typid) * Currently we make no effort to cache any of the stuff we look up here, * which is bad. */ - info = palloc0(sizeof(plperl_array_info)); + info = palloc0_object(plperl_array_info); /* get element type information, including output conversion function */ get_type_io_data(elementtype, IOFunc_output, @@ -1540,7 +1540,7 @@ plperl_ref_from_pg_array(Datum arg, Oid typid) &nitems); /* Get total number of elements in each dimension */ - info->nelems = palloc(sizeof(int) * info->ndims); + info->nelems = palloc_array(int, info->ndims); info->nelems[0] = nitems; for (i = 1; i < info->ndims; i++) info->nelems[i] = info->nelems[i - 1] / dims[i - 1]; @@ -1790,9 +1790,9 @@ plperl_modify_tuple(HV *hvTD, TriggerData *tdata, HeapTuple otup) tupdesc = tdata->tg_relation->rd_att; natts = tupdesc->natts; - modvalues = (Datum *) palloc0(natts * sizeof(Datum)); - modnulls = (bool *) palloc0(natts * sizeof(bool)); - modrepls = (bool *) palloc0(natts * sizeof(bool)); + modvalues = palloc0_array(Datum, natts); + modnulls = palloc0_array(bool, natts); + modrepls = palloc0_array(bool, natts); hv_iterinit(hvNew); while ((he = hv_iternext(hvNew))) @@ -2800,7 +2800,7 @@ compile_plperl_function(Oid fn_oid, bool is_trigger, bool is_event_trigger) * struct prodesc and subsidiary data must all live in proc_cxt. ************************************************************/ oldcontext = MemoryContextSwitchTo(proc_cxt); - prodesc = (plperl_proc_desc *) palloc0(sizeof(plperl_proc_desc)); + prodesc = palloc0_object(plperl_proc_desc); prodesc->proname = pstrdup(NameStr(procStruct->proname)); MemoryContextSetIdentifier(proc_cxt, prodesc->proname); prodesc->fn_cxt = proc_cxt; @@ -2808,9 +2808,9 @@ compile_plperl_function(Oid fn_oid, bool is_trigger, bool is_event_trigger) prodesc->fn_xmin = HeapTupleHeaderGetRawXmin(procTup->t_data); prodesc->fn_tid = procTup->t_self; prodesc->nargs = procStruct->pronargs; - prodesc->arg_out_func = (FmgrInfo *) palloc0(prodesc->nargs * sizeof(FmgrInfo)); - prodesc->arg_is_rowtype = (bool *) palloc0(prodesc->nargs * sizeof(bool)); - prodesc->arg_arraytype = (Oid *) palloc0(prodesc->nargs * sizeof(Oid)); + prodesc->arg_out_func = palloc0_array(FmgrInfo, prodesc->nargs); + prodesc->arg_is_rowtype = palloc0_array(bool, prodesc->nargs); + prodesc->arg_arraytype = palloc0_array(Oid, prodesc->nargs); MemoryContextSwitchTo(oldcontext); /* Remember if function is STABLE/IMMUTABLE */ @@ -3598,13 +3598,13 @@ plperl_spi_prepare(char *query, int argc, SV **argv) "PL/Perl spi_prepare query", ALLOCSET_SMALL_SIZES); MemoryContextSwitchTo(plan_cxt); - qdesc = (plperl_query_desc *) palloc0(sizeof(plperl_query_desc)); + qdesc = palloc0_object(plperl_query_desc); snprintf(qdesc->qname, sizeof(qdesc->qname), "%p", qdesc); qdesc->plan_cxt = plan_cxt; qdesc->nargs = argc; - qdesc->argtypes = (Oid *) palloc(argc * sizeof(Oid)); - qdesc->arginfuncs = (FmgrInfo *) palloc(argc * sizeof(FmgrInfo)); - qdesc->argtypioparams = (Oid *) palloc(argc * sizeof(Oid)); + qdesc->argtypes = palloc_array(Oid, argc); + qdesc->arginfuncs = palloc_array(FmgrInfo, argc); + qdesc->argtypioparams = palloc_array(Oid, argc); MemoryContextSwitchTo(oldcontext); /************************************************************ @@ -3775,8 +3775,8 @@ plperl_spi_exec_prepared(char *query, HV *attr, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); - argvalues = (Datum *) palloc(argc * sizeof(Datum)); + nulls = palloc_array(char, argc); + argvalues = palloc_array(Datum, argc); } else { @@ -3888,8 +3888,8 @@ plperl_spi_query_prepared(char *query, int argc, SV **argv) ************************************************************/ if (argc > 0) { - nulls = (char *) palloc(argc); - argvalues = (Datum *) palloc(argc * sizeof(Datum)); + nulls = palloc_array(char, argc); + argvalues = palloc_array(Datum, argc); } else { diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c index ac8e39f8d4b..1f61c62335f 100644 --- a/src/pl/tcl/pltcl.c +++ b/src/pl/tcl/pltcl.c @@ -1485,7 +1485,7 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid, * struct prodesc and subsidiary data must all live in proc_cxt. ************************************************************/ oldcontext = MemoryContextSwitchTo(proc_cxt); - prodesc = (pltcl_proc_desc *) palloc0(sizeof(pltcl_proc_desc)); + prodesc = palloc0_object(pltcl_proc_desc); prodesc->user_proname = pstrdup(NameStr(procStruct->proname)); MemoryContextSetIdentifier(proc_cxt, prodesc->user_proname); prodesc->internal_proname = pstrdup(internal_proname); @@ -1494,8 +1494,8 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid, prodesc->fn_xmin = HeapTupleHeaderGetRawXmin(procTup->t_data); prodesc->fn_tid = procTup->t_self; prodesc->nargs = procStruct->pronargs; - prodesc->arg_out_func = (FmgrInfo *) palloc0(prodesc->nargs * sizeof(FmgrInfo)); - prodesc->arg_is_rowtype = (bool *) palloc0(prodesc->nargs * sizeof(bool)); + prodesc->arg_out_func = palloc0_array(FmgrInfo, prodesc->nargs); + prodesc->arg_is_rowtype = palloc0_array(bool, prodesc->nargs); MemoryContextSwitchTo(oldcontext); /* Remember if function is STABLE/IMMUTABLE */ @@ -2019,7 +2019,7 @@ pltcl_quote(ClientData cdata, Tcl_Interp *interp, * grow to and initialize pointers ************************************************************/ cp1 = Tcl_GetStringFromObj(objv[1], &length); - tmp = palloc(length * 2 + 1); + tmp = palloc(add_size(mul_size(length, 2), 1)); cp2 = tmp; /************************************************************ @@ -2573,12 +2573,12 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, "PL/Tcl spi_prepare query", ALLOCSET_SMALL_SIZES); MemoryContextSwitchTo(plan_cxt); - qdesc = (pltcl_query_desc *) palloc0(sizeof(pltcl_query_desc)); + qdesc = palloc0_object(pltcl_query_desc); snprintf(qdesc->qname, sizeof(qdesc->qname), "%p", qdesc); qdesc->nargs = nargs; - qdesc->argtypes = (Oid *) palloc(nargs * sizeof(Oid)); - qdesc->arginfuncs = (FmgrInfo *) palloc(nargs * sizeof(FmgrInfo)); - qdesc->argtypioparams = (Oid *) palloc(nargs * sizeof(Oid)); + qdesc->argtypes = palloc_array(Oid, nargs); + qdesc->arginfuncs = palloc_array(FmgrInfo, nargs); + qdesc->argtypioparams = palloc_array(Oid, nargs); MemoryContextSwitchTo(oldcontext); /************************************************************ @@ -2820,7 +2820,7 @@ pltcl_SPI_execute_plan(ClientData cdata, Tcl_Interp *interp, * Setup the value array for SPI_execute_plan() using * the type specific input functions ************************************************************/ - argvalues = (Datum *) palloc(callObjc * sizeof(Datum)); + argvalues = palloc_array(Datum, callObjc); for (j = 0; j < callObjc; j++) { @@ -3191,7 +3191,7 @@ pltcl_build_tuple_result(Tcl_Interp *interp, Tcl_Obj **kvObjv, int kvObjc, attinmeta = NULL; } - values = (char **) palloc0(tupdesc->natts * sizeof(char *)); + values = palloc0_array(char *, tupdesc->natts); if (kvObjc % 2 != 0) ereport(ERROR, --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
