Create libpgcommon, and move pg_malloc et al to it
libpgcommon is a new static library to allow sharing code among the
various frontend programs and backend; this lets us eliminate duplicate
implementations of common routines. We avoid libpgport, because that's
intended as a place for porting issues; per discussion, it seems better
to keep them separate.
The first use case, and the only implemented by this patch, is pg_malloc
and friends, which many frontend programs were already using.
At the same time, we can use this to provide palloc emulation functions
for the frontend; this way, some palloc-using files in the backend can
also be used by the frontend cleanly. To do this, we change palloc() in
the backend to be a function instead of a macro on top of
MemoryContextAlloc(). This was previously believed to cause loss of
performance, but this implementation has been tweaked by Tom and Andres
so that on modern compilers it provides a slight improvement over the
previous one.
This lets us clean up some places that were already with
localized hacks.
Most of the pg_malloc/palloc changes in this patch were authored by
Andres Freund. Zoltán Böszörményi also independently provided a form of
that. libpgcommon infrastructure was authored by Álvaro.
2013-02-12 08:33:40 -05:00
|
|
|
/*
|
|
|
|
|
* fe_memutils.h
|
|
|
|
|
* memory management support for frontend code
|
|
|
|
|
*
|
2024-01-03 20:49:05 -05:00
|
|
|
* Copyright (c) 2003-2024, PostgreSQL Global Development Group
|
Create libpgcommon, and move pg_malloc et al to it
libpgcommon is a new static library to allow sharing code among the
various frontend programs and backend; this lets us eliminate duplicate
implementations of common routines. We avoid libpgport, because that's
intended as a place for porting issues; per discussion, it seems better
to keep them separate.
The first use case, and the only implemented by this patch, is pg_malloc
and friends, which many frontend programs were already using.
At the same time, we can use this to provide palloc emulation functions
for the frontend; this way, some palloc-using files in the backend can
also be used by the frontend cleanly. To do this, we change palloc() in
the backend to be a function instead of a macro on top of
MemoryContextAlloc(). This was previously believed to cause loss of
performance, but this implementation has been tweaked by Tom and Andres
so that on modern compilers it provides a slight improvement over the
previous one.
This lets us clean up some places that were already with
localized hacks.
Most of the pg_malloc/palloc changes in this patch were authored by
Andres Freund. Zoltán Böszörményi also independently provided a form of
that. libpgcommon infrastructure was authored by Álvaro.
2013-02-12 08:33:40 -05:00
|
|
|
*
|
|
|
|
|
* src/include/common/fe_memutils.h
|
|
|
|
|
*/
|
|
|
|
|
#ifndef FE_MEMUTILS_H
|
|
|
|
|
#define FE_MEMUTILS_H
|
|
|
|
|
|
2026-05-11 08:13:48 -04:00
|
|
|
/*
|
|
|
|
|
* Assumed maximum size for allocation requests.
|
|
|
|
|
*
|
|
|
|
|
* We don't enforce this, so the actual maximum is the platform's SIZE_MAX.
|
|
|
|
|
* But it's useful to have it defined in frontend builds, so that common
|
|
|
|
|
* code can check for oversized requests without having frontend-vs-backend
|
|
|
|
|
* differences. Also, some code relies on MaxAllocSize being no more than
|
|
|
|
|
* INT_MAX/2, so rather than setting this to SIZE_MAX, make it the same as
|
|
|
|
|
* the backend's value.
|
|
|
|
|
*/
|
|
|
|
|
#define MaxAllocSize ((Size) 0x3fffffff) /* 1 gigabyte - 1 */
|
|
|
|
|
|
2015-04-03 04:36:12 -04:00
|
|
|
/*
|
|
|
|
|
* Flags for pg_malloc_extended and palloc_extended, deliberately named
|
|
|
|
|
* the same as the backend flags.
|
|
|
|
|
*/
|
|
|
|
|
#define MCXT_ALLOC_HUGE 0x01 /* allow huge allocation (> 1 GB) not
|
|
|
|
|
* actually used for frontends */
|
|
|
|
|
#define MCXT_ALLOC_NO_OOM 0x02 /* no failure if out-of-memory */
|
|
|
|
|
#define MCXT_ALLOC_ZERO 0x04 /* zero allocated memory */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* "Safe" memory allocation functions --- these exit(1) on failure
|
|
|
|
|
* (except pg_malloc_extended with MCXT_ALLOC_NO_OOM)
|
|
|
|
|
*/
|
2013-02-12 10:43:09 -05:00
|
|
|
extern char *pg_strdup(const char *in);
|
Create libpgcommon, and move pg_malloc et al to it
libpgcommon is a new static library to allow sharing code among the
various frontend programs and backend; this lets us eliminate duplicate
implementations of common routines. We avoid libpgport, because that's
intended as a place for porting issues; per discussion, it seems better
to keep them separate.
The first use case, and the only implemented by this patch, is pg_malloc
and friends, which many frontend programs were already using.
At the same time, we can use this to provide palloc emulation functions
for the frontend; this way, some palloc-using files in the backend can
also be used by the frontend cleanly. To do this, we change palloc() in
the backend to be a function instead of a macro on top of
MemoryContextAlloc(). This was previously believed to cause loss of
performance, but this implementation has been tweaked by Tom and Andres
so that on modern compilers it provides a slight improvement over the
previous one.
This lets us clean up some places that were already with
localized hacks.
Most of the pg_malloc/palloc changes in this patch were authored by
Andres Freund. Zoltán Böszörményi also independently provided a form of
that. libpgcommon infrastructure was authored by Álvaro.
2013-02-12 08:33:40 -05:00
|
|
|
extern void *pg_malloc(size_t size);
|
|
|
|
|
extern void *pg_malloc0(size_t size);
|
2015-04-03 04:36:12 -04:00
|
|
|
extern void *pg_malloc_extended(size_t size, int flags);
|
2022-09-20 16:09:30 -04:00
|
|
|
extern void *pg_realloc(void *ptr, size_t size);
|
|
|
|
|
extern void pg_free(void *ptr);
|
Create libpgcommon, and move pg_malloc et al to it
libpgcommon is a new static library to allow sharing code among the
various frontend programs and backend; this lets us eliminate duplicate
implementations of common routines. We avoid libpgport, because that's
intended as a place for porting issues; per discussion, it seems better
to keep them separate.
The first use case, and the only implemented by this patch, is pg_malloc
and friends, which many frontend programs were already using.
At the same time, we can use this to provide palloc emulation functions
for the frontend; this way, some palloc-using files in the backend can
also be used by the frontend cleanly. To do this, we change palloc() in
the backend to be a function instead of a macro on top of
MemoryContextAlloc(). This was previously believed to cause loss of
performance, but this implementation has been tweaked by Tom and Andres
so that on modern compilers it provides a slight improvement over the
previous one.
This lets us clean up some places that were already with
localized hacks.
Most of the pg_malloc/palloc changes in this patch were authored by
Andres Freund. Zoltán Böszörményi also independently provided a form of
that. libpgcommon infrastructure was authored by Álvaro.
2013-02-12 08:33:40 -05:00
|
|
|
|
Make palloc_array() and friends safe against integer overflow.
Sufficiently large "count" arguments could result in undetected
overflow, causing the allocated memory chunk to be much smaller
than what the caller will subsequently write into it. This is
unlikely to be a hazard with 64-bit size_t but can sometimes
happen on 32-bit builds, primarily where a function allocates
workspace that's significantly larger than its input data.
Rather than trying to patch the at-risk callers piecemeal,
let's just redefine these macros so that they always check.
To do that, move the longstanding add_size() and mul_size() functions
into palloc.h and mcxt.c, and adjust them to not be specific to
shared-memory allocation. Then invent palloc_mul(), palloc0_mul(),
palloc_mul_extended() to use these functions. Actually, the latter
use inlined copies to save one function call. repalloc_array() gets
similar treatment. I didn't bother trying to inline the calls for
repalloc0_array() though.
In v14 and v15, this also adds repalloc_extended(), which previously
was only available in v16 and up.
We need copies of all this in fe_memutils.[hc] as well, since that
module also provides palloc_array() etc.
Reported-by: Xint Code
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>
Backpatch-through: 14
Security: CVE-2026-6473
2026-05-11 08:13:48 -04:00
|
|
|
/*
|
|
|
|
|
* Support for safe calculation of memory request sizes
|
|
|
|
|
*/
|
|
|
|
|
extern Size add_size(Size s1, Size s2);
|
|
|
|
|
extern Size mul_size(Size s1, Size s2);
|
|
|
|
|
extern void *pg_malloc_mul(Size s1, Size s2);
|
|
|
|
|
extern void *pg_malloc0_mul(Size s1, Size s2);
|
|
|
|
|
extern void *pg_malloc_mul_extended(Size s1, Size s2, int flags);
|
|
|
|
|
extern void *pg_realloc_mul(void *p, Size s1, Size s2);
|
|
|
|
|
|
2022-09-12 02:31:56 -04:00
|
|
|
/*
|
|
|
|
|
* Variants with easier notation and more type safety
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Allocate space for one object of type "type"
|
|
|
|
|
*/
|
|
|
|
|
#define pg_malloc_object(type) ((type *) pg_malloc(sizeof(type)))
|
|
|
|
|
#define pg_malloc0_object(type) ((type *) pg_malloc0(sizeof(type)))
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Allocate space for "count" objects of type "type"
|
|
|
|
|
*/
|
Make palloc_array() and friends safe against integer overflow.
Sufficiently large "count" arguments could result in undetected
overflow, causing the allocated memory chunk to be much smaller
than what the caller will subsequently write into it. This is
unlikely to be a hazard with 64-bit size_t but can sometimes
happen on 32-bit builds, primarily where a function allocates
workspace that's significantly larger than its input data.
Rather than trying to patch the at-risk callers piecemeal,
let's just redefine these macros so that they always check.
To do that, move the longstanding add_size() and mul_size() functions
into palloc.h and mcxt.c, and adjust them to not be specific to
shared-memory allocation. Then invent palloc_mul(), palloc0_mul(),
palloc_mul_extended() to use these functions. Actually, the latter
use inlined copies to save one function call. repalloc_array() gets
similar treatment. I didn't bother trying to inline the calls for
repalloc0_array() though.
In v14 and v15, this also adds repalloc_extended(), which previously
was only available in v16 and up.
We need copies of all this in fe_memutils.[hc] as well, since that
module also provides palloc_array() etc.
Reported-by: Xint Code
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>
Backpatch-through: 14
Security: CVE-2026-6473
2026-05-11 08:13:48 -04:00
|
|
|
#define pg_malloc_array(type, count) ((type *) pg_malloc_mul(sizeof(type), count))
|
|
|
|
|
#define pg_malloc0_array(type, count) ((type *) pg_malloc0_mul(sizeof(type), count))
|
|
|
|
|
#define pg_malloc_array_extended(type, count, flags) ((type *) pg_malloc_mul_extended(sizeof(type), count, flags))
|
2022-09-12 02:31:56 -04:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Change size of allocation pointed to by "pointer" to have space for "count"
|
|
|
|
|
* objects of type "type"
|
|
|
|
|
*/
|
Make palloc_array() and friends safe against integer overflow.
Sufficiently large "count" arguments could result in undetected
overflow, causing the allocated memory chunk to be much smaller
than what the caller will subsequently write into it. This is
unlikely to be a hazard with 64-bit size_t but can sometimes
happen on 32-bit builds, primarily where a function allocates
workspace that's significantly larger than its input data.
Rather than trying to patch the at-risk callers piecemeal,
let's just redefine these macros so that they always check.
To do that, move the longstanding add_size() and mul_size() functions
into palloc.h and mcxt.c, and adjust them to not be specific to
shared-memory allocation. Then invent palloc_mul(), palloc0_mul(),
palloc_mul_extended() to use these functions. Actually, the latter
use inlined copies to save one function call. repalloc_array() gets
similar treatment. I didn't bother trying to inline the calls for
repalloc0_array() though.
In v14 and v15, this also adds repalloc_extended(), which previously
was only available in v16 and up.
We need copies of all this in fe_memutils.[hc] as well, since that
module also provides palloc_array() etc.
Reported-by: Xint Code
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>
Backpatch-through: 14
Security: CVE-2026-6473
2026-05-11 08:13:48 -04:00
|
|
|
#define pg_realloc_array(pointer, type, count) ((type *) pg_realloc_mul(pointer, sizeof(type), count))
|
2022-09-12 02:31:56 -04:00
|
|
|
|
2014-04-26 14:14:28 -04:00
|
|
|
/* Equivalent functions, deliberately named the same as backend functions */
|
|
|
|
|
extern char *pstrdup(const char *in);
|
2019-12-04 17:36:06 -05:00
|
|
|
extern char *pnstrdup(const char *in, Size size);
|
2014-04-26 14:14:28 -04:00
|
|
|
extern void *palloc(Size size);
|
|
|
|
|
extern void *palloc0(Size size);
|
2015-04-03 04:36:12 -04:00
|
|
|
extern void *palloc_extended(Size size, int flags);
|
2014-04-26 14:14:28 -04:00
|
|
|
extern void *repalloc(void *pointer, Size size);
|
|
|
|
|
extern void pfree(void *pointer);
|
Make palloc_array() and friends safe against integer overflow.
Sufficiently large "count" arguments could result in undetected
overflow, causing the allocated memory chunk to be much smaller
than what the caller will subsequently write into it. This is
unlikely to be a hazard with 64-bit size_t but can sometimes
happen on 32-bit builds, primarily where a function allocates
workspace that's significantly larger than its input data.
Rather than trying to patch the at-risk callers piecemeal,
let's just redefine these macros so that they always check.
To do that, move the longstanding add_size() and mul_size() functions
into palloc.h and mcxt.c, and adjust them to not be specific to
shared-memory allocation. Then invent palloc_mul(), palloc0_mul(),
palloc_mul_extended() to use these functions. Actually, the latter
use inlined copies to save one function call. repalloc_array() gets
similar treatment. I didn't bother trying to inline the calls for
repalloc0_array() though.
In v14 and v15, this also adds repalloc_extended(), which previously
was only available in v16 and up.
We need copies of all this in fe_memutils.[hc] as well, since that
module also provides palloc_array() etc.
Reported-by: Xint Code
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>
Backpatch-through: 14
Security: CVE-2026-6473
2026-05-11 08:13:48 -04:00
|
|
|
extern void *palloc_mul(Size s1, Size s2);
|
|
|
|
|
extern void *palloc0_mul(Size s1, Size s2);
|
|
|
|
|
extern void *palloc_mul_extended(Size s1, Size s2, int flags);
|
|
|
|
|
extern void *repalloc_mul(void *p, Size s1, Size s2);
|
2014-04-26 14:14:28 -04:00
|
|
|
|
2022-09-12 02:31:56 -04:00
|
|
|
#define palloc_object(type) ((type *) palloc(sizeof(type)))
|
|
|
|
|
#define palloc0_object(type) ((type *) palloc0(sizeof(type)))
|
Make palloc_array() and friends safe against integer overflow.
Sufficiently large "count" arguments could result in undetected
overflow, causing the allocated memory chunk to be much smaller
than what the caller will subsequently write into it. This is
unlikely to be a hazard with 64-bit size_t but can sometimes
happen on 32-bit builds, primarily where a function allocates
workspace that's significantly larger than its input data.
Rather than trying to patch the at-risk callers piecemeal,
let's just redefine these macros so that they always check.
To do that, move the longstanding add_size() and mul_size() functions
into palloc.h and mcxt.c, and adjust them to not be specific to
shared-memory allocation. Then invent palloc_mul(), palloc0_mul(),
palloc_mul_extended() to use these functions. Actually, the latter
use inlined copies to save one function call. repalloc_array() gets
similar treatment. I didn't bother trying to inline the calls for
repalloc0_array() though.
In v14 and v15, this also adds repalloc_extended(), which previously
was only available in v16 and up.
We need copies of all this in fe_memutils.[hc] as well, since that
module also provides palloc_array() etc.
Reported-by: Xint Code
Author: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>
Backpatch-through: 14
Security: CVE-2026-6473
2026-05-11 08:13:48 -04:00
|
|
|
#define palloc_array(type, count) ((type *) palloc_mul(sizeof(type), count))
|
|
|
|
|
#define palloc0_array(type, count) ((type *) palloc0_mul(sizeof(type), count))
|
|
|
|
|
#define palloc_array_extended(type, count, flags) ((type *) palloc_mul_extended(sizeof(type), count, flags))
|
|
|
|
|
#define repalloc_array(pointer, type, count) ((type *) repalloc_mul(pointer, sizeof(type), count))
|
2022-09-12 02:31:56 -04:00
|
|
|
|
2014-04-26 14:14:28 -04:00
|
|
|
/* sprintf into a palloc'd buffer --- these are in psprintf.c */
|
|
|
|
|
extern char *psprintf(const char *fmt,...) pg_attribute_printf(1, 2);
|
|
|
|
|
extern size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) pg_attribute_printf(3, 0);
|
Create libpgcommon, and move pg_malloc et al to it
libpgcommon is a new static library to allow sharing code among the
various frontend programs and backend; this lets us eliminate duplicate
implementations of common routines. We avoid libpgport, because that's
intended as a place for porting issues; per discussion, it seems better
to keep them separate.
The first use case, and the only implemented by this patch, is pg_malloc
and friends, which many frontend programs were already using.
At the same time, we can use this to provide palloc emulation functions
for the frontend; this way, some palloc-using files in the backend can
also be used by the frontend cleanly. To do this, we change palloc() in
the backend to be a function instead of a macro on top of
MemoryContextAlloc(). This was previously believed to cause loss of
performance, but this implementation has been tweaked by Tom and Andres
so that on modern compilers it provides a slight improvement over the
previous one.
This lets us clean up some places that were already with
localized hacks.
Most of the pg_malloc/palloc changes in this patch were authored by
Andres Freund. Zoltán Böszörményi also independently provided a form of
that. libpgcommon infrastructure was authored by Álvaro.
2013-02-12 08:33:40 -05:00
|
|
|
|
|
|
|
|
#endif /* FE_MEMUTILS_H */
|