2003-05-15 18:35:30 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* port.h
|
2004-11-06 02:16:22 +01:00
|
|
|
* Header for src/port/ compatibility functions.
|
2003-05-15 18:35:30 +02:00
|
|
|
*
|
2023-01-02 21:00:37 +01:00
|
|
|
* Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
|
2003-05-15 18:35:30 +02:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/include/port.h
|
2003-05-15 18:35:30 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
2006-10-04 00:18:23 +02:00
|
|
|
#ifndef PG_PORT_H
|
|
|
|
#define PG_PORT_H
|
2003-05-15 18:35:30 +02:00
|
|
|
|
2004-05-20 03:47:01 +02:00
|
|
|
#include <ctype.h>
|
2003-06-14 16:35:42 +02:00
|
|
|
|
2017-11-16 16:36:18 +01:00
|
|
|
/*
|
|
|
|
* Windows has enough specialized port stuff that we push most of it off
|
|
|
|
* into another file.
|
|
|
|
* Note: Some CYGWIN includes might #define WIN32.
|
|
|
|
*/
|
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
|
|
|
#include "port/win32_port.h"
|
|
|
|
#endif
|
|
|
|
|
2010-01-10 15:16:08 +01:00
|
|
|
/* socket has a different definition on WIN32 */
|
|
|
|
#ifndef WIN32
|
|
|
|
typedef int pgsocket;
|
2010-02-26 03:01:40 +01:00
|
|
|
|
2010-01-31 18:35:46 +01:00
|
|
|
#define PGINVALID_SOCKET (-1)
|
2010-01-10 15:16:08 +01:00
|
|
|
#else
|
|
|
|
typedef SOCKET pgsocket;
|
2010-02-26 03:01:40 +01:00
|
|
|
|
2010-01-10 15:16:08 +01:00
|
|
|
#define PGINVALID_SOCKET INVALID_SOCKET
|
|
|
|
#endif
|
|
|
|
|
2021-11-11 16:36:39 +01:00
|
|
|
/* if platform lacks socklen_t, we assume this will work */
|
2021-11-09 15:20:47 +01:00
|
|
|
#ifndef HAVE_SOCKLEN_T
|
2021-11-11 16:36:39 +01:00
|
|
|
typedef unsigned int socklen_t;
|
2021-11-09 15:20:47 +01:00
|
|
|
#endif
|
|
|
|
|
2004-03-10 22:12:49 +01:00
|
|
|
/* non-blocking */
|
2010-01-10 15:16:08 +01:00
|
|
|
extern bool pg_set_noblock(pgsocket sock);
|
|
|
|
extern bool pg_set_block(pgsocket sock);
|
2004-03-10 22:12:49 +01:00
|
|
|
|
2006-09-11 22:10:30 +02:00
|
|
|
/* Portable path handling for Unix/Win32 (in path.c) */
|
2004-06-11 00:26:24 +02:00
|
|
|
|
2022-09-20 22:09:30 +02:00
|
|
|
extern bool has_drive_prefix(const char *path);
|
2004-06-11 00:26:24 +02:00
|
|
|
extern char *first_dir_separator(const char *filename);
|
|
|
|
extern char *last_dir_separator(const char *filename);
|
2011-02-03 04:49:54 +01:00
|
|
|
extern char *first_path_var_separator(const char *pathlist);
|
2004-11-06 02:16:22 +01:00
|
|
|
extern void join_path_components(char *ret_path,
|
|
|
|
const char *head, const char *tail);
|
2004-03-09 05:49:02 +01:00
|
|
|
extern void canonicalize_path(char *path);
|
2022-09-20 22:09:30 +02:00
|
|
|
extern void make_native_path(char *filename);
|
2016-02-17 18:12:06 +01:00
|
|
|
extern void cleanup_path(char *path);
|
2005-08-12 23:07:53 +02:00
|
|
|
extern bool path_contains_parent_reference(const char *path);
|
2011-02-12 15:47:51 +01:00
|
|
|
extern bool path_is_relative_and_below_cwd(const char *path);
|
2005-08-29 21:39:39 +02:00
|
|
|
extern bool path_is_prefix_of_path(const char *path1, const char *path2);
|
2014-04-05 00:42:13 +02:00
|
|
|
extern char *make_absolute_path(const char *path);
|
2004-05-12 15:38:49 +02:00
|
|
|
extern const char *get_progname(const char *argv0);
|
2004-05-17 16:35:34 +02:00
|
|
|
extern void get_share_path(const char *my_exec_path, char *ret_path);
|
|
|
|
extern void get_etc_path(const char *my_exec_path, char *ret_path);
|
|
|
|
extern void get_include_path(const char *my_exec_path, char *ret_path);
|
|
|
|
extern void get_pkginclude_path(const char *my_exec_path, char *ret_path);
|
2004-08-01 08:56:39 +02:00
|
|
|
extern void get_includeserver_path(const char *my_exec_path, char *ret_path);
|
|
|
|
extern void get_lib_path(const char *my_exec_path, char *ret_path);
|
2004-05-17 16:35:34 +02:00
|
|
|
extern void get_pkglib_path(const char *my_exec_path, char *ret_path);
|
2004-05-25 03:00:30 +02:00
|
|
|
extern void get_locale_path(const char *my_exec_path, char *ret_path);
|
2005-09-27 19:39:35 +02:00
|
|
|
extern void get_doc_path(const char *my_exec_path, char *ret_path);
|
2008-02-18 15:51:48 +01:00
|
|
|
extern void get_html_path(const char *my_exec_path, char *ret_path);
|
2005-09-27 19:39:35 +02:00
|
|
|
extern void get_man_path(const char *my_exec_path, char *ret_path);
|
2004-08-18 04:59:12 +02:00
|
|
|
extern bool get_home_path(char *ret_path);
|
2004-08-29 23:08:48 +02:00
|
|
|
extern void get_parent_directory(char *path);
|
2004-05-17 16:35:34 +02:00
|
|
|
|
2015-03-14 19:08:45 +01:00
|
|
|
/* common/pgfnames.c */
|
2008-04-18 19:05:45 +02:00
|
|
|
extern char **pgfnames(const char *path);
|
2007-01-19 17:42:24 +01:00
|
|
|
extern void pgfnames_cleanup(char **filenames);
|
|
|
|
|
2022-10-21 14:21:55 +02:00
|
|
|
#define IS_NONWINDOWS_DIR_SEP(ch) ((ch) == '/')
|
|
|
|
#define is_nonwindows_absolute_path(filename) \
|
2004-05-19 06:21:49 +02:00
|
|
|
( \
|
2022-10-21 14:21:55 +02:00
|
|
|
IS_NONWINDOWS_DIR_SEP((filename)[0]) \
|
2004-05-19 06:21:49 +02:00
|
|
|
)
|
2011-02-03 16:46:31 +01:00
|
|
|
|
2022-10-21 14:21:55 +02:00
|
|
|
#define IS_WINDOWS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\')
|
2011-02-12 15:47:51 +01:00
|
|
|
/* See path_is_relative_and_below_cwd() for how we handle 'E:abc'. */
|
2022-10-21 14:21:55 +02:00
|
|
|
#define is_windows_absolute_path(filename) \
|
2004-05-19 06:21:49 +02:00
|
|
|
( \
|
2022-10-21 14:21:55 +02:00
|
|
|
IS_WINDOWS_DIR_SEP((filename)[0]) || \
|
2006-09-22 23:39:58 +02:00
|
|
|
(isalpha((unsigned char) ((filename)[0])) && (filename)[1] == ':' && \
|
2022-10-21 14:21:55 +02:00
|
|
|
IS_WINDOWS_DIR_SEP((filename)[2])) \
|
2004-05-19 06:21:49 +02:00
|
|
|
)
|
2022-10-21 14:21:55 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* is_absolute_path and IS_DIR_SEP
|
|
|
|
*
|
|
|
|
* By using macros here we avoid needing to include path.c in libpq.
|
|
|
|
*/
|
|
|
|
#ifndef WIN32
|
|
|
|
#define IS_DIR_SEP(ch) IS_NONWINDOWS_DIR_SEP(ch)
|
|
|
|
#define is_absolute_path(filename) is_nonwindows_absolute_path(filename)
|
|
|
|
#else
|
|
|
|
#define IS_DIR_SEP(ch) IS_WINDOWS_DIR_SEP(ch)
|
|
|
|
#define is_absolute_path(filename) is_windows_absolute_path(filename)
|
2004-05-19 06:21:49 +02:00
|
|
|
#endif
|
|
|
|
|
Recognize network-failure errnos as indicating hard connection loss.
Up to now, only ECONNRESET (and EPIPE, in most but not quite all places)
received special treatment in our error handling logic. This patch
changes things so that related error codes such as ECONNABORTED are
also recognized as indicating that the connection's dead and unlikely
to come back.
We continue to think, however, that only ECONNRESET and EPIPE should be
reported as probable server crashes; the other cases indicate network
connectivity problems but prove little about the server's state. Thus,
there's no change in the error message texts that are output for such
cases. The key practical effect is that errcode_for_socket_access()
will report ERRCODE_CONNECTION_FAILURE rather than
ERRCODE_INTERNAL_ERROR for a network failure. It's expected that this
will fix buildfarm member lorikeet's failures since commit 32a9c0bdf,
as that seems to be due to not treating ECONNABORTED equivalently to
ECONNRESET.
The set of errnos treated this way now includes ECONNABORTED, EHOSTDOWN,
EHOSTUNREACH, ENETDOWN, ENETRESET, and ENETUNREACH. Several of these
were second-class citizens in terms of their handling in places like
get_errno_symbol(), so upgrade the infrastructure where necessary.
As committed, this patch assumes that all these symbols are defined
everywhere. POSIX specifies all of them except EHOSTDOWN, but that
seems to exist on all platforms of interest; we'll see what the
buildfarm says about that.
Probably this should be back-patched, but let's see what the buildfarm
thinks of it first.
Fujii Masao and Tom Lane
Discussion: https://postgr.es/m/2621622.1602184554@sss.pgh.pa.us
2020-10-10 19:28:12 +02:00
|
|
|
/*
|
|
|
|
* This macro provides a centralized list of all errnos that identify
|
|
|
|
* hard failure of a previously-established network connection.
|
|
|
|
* The macro is intended to be used in a switch statement, in the form
|
|
|
|
* "case ALL_CONNECTION_FAILURE_ERRNOS:".
|
|
|
|
*
|
|
|
|
* Note: this groups EPIPE and ECONNRESET, which we take to indicate a
|
|
|
|
* probable server crash, with other errors that indicate loss of network
|
|
|
|
* connectivity without proving much about the server's state. Places that
|
|
|
|
* are actually reporting errors typically single out EPIPE and ECONNRESET,
|
|
|
|
* while allowing the network failures to be reported generically.
|
|
|
|
*/
|
|
|
|
#define ALL_CONNECTION_FAILURE_ERRNOS \
|
|
|
|
EPIPE: \
|
|
|
|
case ECONNRESET: \
|
|
|
|
case ECONNABORTED: \
|
|
|
|
case EHOSTDOWN: \
|
|
|
|
case EHOSTUNREACH: \
|
|
|
|
case ENETDOWN: \
|
|
|
|
case ENETRESET: \
|
2021-09-30 20:16:08 +02:00
|
|
|
case ENETUNREACH: \
|
|
|
|
case ETIMEDOUT
|
Recognize network-failure errnos as indicating hard connection loss.
Up to now, only ECONNRESET (and EPIPE, in most but not quite all places)
received special treatment in our error handling logic. This patch
changes things so that related error codes such as ECONNABORTED are
also recognized as indicating that the connection's dead and unlikely
to come back.
We continue to think, however, that only ECONNRESET and EPIPE should be
reported as probable server crashes; the other cases indicate network
connectivity problems but prove little about the server's state. Thus,
there's no change in the error message texts that are output for such
cases. The key practical effect is that errcode_for_socket_access()
will report ERRCODE_CONNECTION_FAILURE rather than
ERRCODE_INTERNAL_ERROR for a network failure. It's expected that this
will fix buildfarm member lorikeet's failures since commit 32a9c0bdf,
as that seems to be due to not treating ECONNABORTED equivalently to
ECONNRESET.
The set of errnos treated this way now includes ECONNABORTED, EHOSTDOWN,
EHOSTUNREACH, ENETDOWN, ENETRESET, and ENETUNREACH. Several of these
were second-class citizens in terms of their handling in places like
get_errno_symbol(), so upgrade the infrastructure where necessary.
As committed, this patch assumes that all these symbols are defined
everywhere. POSIX specifies all of them except EHOSTDOWN, but that
seems to exist on all platforms of interest; we'll see what the
buildfarm says about that.
Probably this should be back-patched, but let's see what the buildfarm
thinks of it first.
Fujii Masao and Tom Lane
Discussion: https://postgr.es/m/2621622.1602184554@sss.pgh.pa.us
2020-10-10 19:28:12 +02:00
|
|
|
|
2006-09-11 22:10:30 +02:00
|
|
|
/* Portable locale initialization (in exec.c) */
|
|
|
|
extern void set_pglocale_pgservice(const char *argv0, const char *app);
|
2004-05-19 06:21:49 +02:00
|
|
|
|
2020-04-01 03:57:03 +02:00
|
|
|
/* Portable way to find and execute binaries (in exec.c) */
|
2021-03-03 09:44:46 +01:00
|
|
|
extern int validate_exec(const char *path);
|
2004-05-20 17:38:11 +02:00
|
|
|
extern int find_my_exec(const char *argv0, char *retpath);
|
2004-05-21 18:06:23 +02:00
|
|
|
extern int find_other_exec(const char *argv0, const char *target,
|
2004-05-14 19:04:48 +02:00
|
|
|
const char *versionstr, char *retpath);
|
2020-04-01 03:57:03 +02:00
|
|
|
extern char *pipe_read_line(char *cmd, char *line, int maxsize);
|
2004-08-29 07:07:03 +02:00
|
|
|
|
Change pg_ctl to detect server-ready by watching status in postmaster.pid.
Traditionally, "pg_ctl start -w" has waited for the server to become
ready to accept connections by attempting a connection once per second.
That has the major problem that connection issues (for instance, a
kernel packet filter blocking traffic) can't be reliably told apart
from server startup issues, and the minor problem that if server startup
isn't quick, we accumulate "the database system is starting up" spam
in the server log. We've hacked around many of the possible connection
issues, but it resulted in ugly and complicated code in pg_ctl.c.
In commit c61559ec3, I changed the probe rate to every tenth of a second.
That prompted Jeff Janes to complain that the log-spam problem had become
much worse. In the ensuing discussion, Andres Freund pointed out that
we could dispense with connection attempts altogether if the postmaster
were changed to report its status in postmaster.pid, which "pg_ctl start"
already relies on being able to read. This patch implements that, teaching
postmaster.c to report a status string into the pidfile at the same
state-change points already identified as being of interest for systemd
status reporting (cf commit 7d17e683f). pg_ctl no longer needs to link
with libpq at all; all its functions now depend on reading server files.
In support of this, teach AddToDataDirLockFile() to allow addition of
postmaster.pid lines in not-necessarily-sequential order. This is needed
on Windows where the SHMEM_KEY line will never be written at all. We still
have the restriction that we don't want to truncate the pidfile; document
the reasons for that a bit better.
Also, fix the pg_ctl TAP tests so they'll notice if "start -w" mode
is broken --- before, they'd just wait out the sixty seconds until
the loop gives up, and then report success anyway. (Yes, I found that
out the hard way.)
While at it, arrange for pg_ctl to not need to #include miscadmin.h;
as a rather low-level backend header, requiring that to be compilable
client-side is pretty dubious. This requires moving the #define's
associated with the pidfile into a new header file, and moving
PG_BACKEND_VERSIONSTR someplace else. For lack of a clearly better
"someplace else", I put it into port.h, beside the declaration of
find_other_exec(), since most users of that macro are passing the value to
find_other_exec(). (initdb still depends on miscadmin.h, but at least
pg_ctl and pg_upgrade no longer do.)
In passing, fix main.c so that PG_BACKEND_VERSIONSTR actually defines the
output of "postgres -V", which remarkably it had never done before.
Discussion: https://postgr.es/m/CAMkU=1xJW8e+CTotojOMBd-yzUvD0e_JZu2xHo=MnuZ4__m7Pg@mail.gmail.com
2017-06-28 23:31:24 +02:00
|
|
|
/* Doesn't belong here, but this is used with find_other_exec(), so... */
|
|
|
|
#define PG_BACKEND_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n"
|
|
|
|
|
2022-01-10 11:54:11 +01:00
|
|
|
#ifdef EXEC_BACKEND
|
|
|
|
/* Disable ASLR before exec, for developer builds only (in exec.c) */
|
|
|
|
extern int pg_disable_aslr(void);
|
|
|
|
#endif
|
|
|
|
|
2008-02-29 16:31:33 +01:00
|
|
|
|
2004-08-07 23:48:09 +02:00
|
|
|
#if defined(WIN32) || defined(__CYGWIN__)
|
2004-05-11 23:57:15 +02:00
|
|
|
#define EXE ".exe"
|
|
|
|
#else
|
|
|
|
#define EXE ""
|
2004-11-17 18:46:24 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
|
|
|
#define DEVNULL "nul"
|
|
|
|
#else
|
2004-05-11 23:57:15 +02:00
|
|
|
#define DEVNULL "/dev/null"
|
|
|
|
#endif
|
|
|
|
|
2004-02-10 04:42:45 +01:00
|
|
|
/* Portable delay handling */
|
|
|
|
extern void pg_usleep(long microsec);
|
|
|
|
|
2004-05-07 02:24:59 +02:00
|
|
|
/* Portable SQL-like case-independent comparisons and conversions */
|
|
|
|
extern int pg_strcasecmp(const char *s1, const char *s2);
|
|
|
|
extern int pg_strncasecmp(const char *s1, const char *s2, size_t n);
|
|
|
|
extern unsigned char pg_toupper(unsigned char ch);
|
|
|
|
extern unsigned char pg_tolower(unsigned char ch);
|
2011-03-20 17:43:39 +01:00
|
|
|
extern unsigned char pg_ascii_toupper(unsigned char ch);
|
|
|
|
extern unsigned char pg_ascii_tolower(unsigned char ch);
|
2004-05-07 02:24:59 +02:00
|
|
|
|
2018-09-26 19:13:57 +02:00
|
|
|
/*
|
|
|
|
* Beginning in v12, we always replace snprintf() and friends with our own
|
|
|
|
* implementation. This symbol is no longer consulted by the core code,
|
|
|
|
* but keep it defined anyway in case any extensions are looking at it.
|
|
|
|
*/
|
|
|
|
#define USE_REPL_SNPRINTF 1
|
Revert error-throwing wrappers for the printf family of functions.
This reverts commit 16304a013432931e61e623c8d85e9fe24709d9ba, except
for its changes in src/port/snprintf.c; as well as commit
cac18a76bb6b08f1ecc2a85e46c9d2ab82dd9d23 which is no longer needed.
Fujii Masao reported that the previous commit caused failures in psql on
OS X, since if one exits the pager program early while viewing a query
result, psql sees an EPIPE error from fprintf --- and the wrapper function
thought that was reason to panic. (It's a bit surprising that the same
does not happen on Linux.) Further discussion among the security list
concluded that the risk of other such failures was far too great, and
that the one-size-fits-all approach to error handling embodied in the
previous patch is unlikely to be workable.
This leaves us again exposed to the possibility of the type of failure
envisioned in CVE-2015-3166. However, that failure mode is strictly
hypothetical at this point: there is no concrete reason to believe that
an attacker could trigger information disclosure through the supposed
mechanism. In the first place, the attack surface is fairly limited,
since so much of what the backend does with format strings goes through
stringinfo.c or psprintf(), and those already had adequate defenses.
In the second place, even granting that an unprivileged attacker could
control the occurrence of ENOMEM with some precision, it's a stretch to
believe that he could induce it just where the target buffer contains some
valuable information. So we concluded that the risk of non-hypothetical
problems induced by the patch greatly outweighs the security risks.
We will therefore revert, and instead undertake closer analysis to
identify specific calls that may need hardening, rather than attempt a
universal solution.
We have kept the portion of the previous patch that improved snprintf.c's
handling of errors when it calls the platform's sprintf(). That seems to
be an unalloyed improvement.
Security: CVE-2015-3166
2015-05-20 00:14:52 +02:00
|
|
|
|
2005-12-06 03:29:04 +01:00
|
|
|
/*
|
Revert error-throwing wrappers for the printf family of functions.
This reverts commit 16304a013432931e61e623c8d85e9fe24709d9ba, except
for its changes in src/port/snprintf.c; as well as commit
cac18a76bb6b08f1ecc2a85e46c9d2ab82dd9d23 which is no longer needed.
Fujii Masao reported that the previous commit caused failures in psql on
OS X, since if one exits the pager program early while viewing a query
result, psql sees an EPIPE error from fprintf --- and the wrapper function
thought that was reason to panic. (It's a bit surprising that the same
does not happen on Linux.) Further discussion among the security list
concluded that the risk of other such failures was far too great, and
that the one-size-fits-all approach to error handling embodied in the
previous patch is unlikely to be workable.
This leaves us again exposed to the possibility of the type of failure
envisioned in CVE-2015-3166. However, that failure mode is strictly
hypothetical at this point: there is no concrete reason to believe that
an attacker could trigger information disclosure through the supposed
mechanism. In the first place, the attack surface is fairly limited,
since so much of what the backend does with format strings goes through
stringinfo.c or psprintf(), and those already had adequate defenses.
In the second place, even granting that an unprivileged attacker could
control the occurrence of ENOMEM with some precision, it's a stretch to
believe that he could induce it just where the target buffer contains some
valuable information. So we concluded that the risk of non-hypothetical
problems induced by the patch greatly outweighs the security risks.
We will therefore revert, and instead undertake closer analysis to
identify specific calls that may need hardening, rather than attempt a
universal solution.
We have kept the portion of the previous patch that improved snprintf.c's
handling of errors when it calls the platform's sprintf(). That seems to
be an unalloyed improvement.
Security: CVE-2015-3166
2015-05-20 00:14:52 +02:00
|
|
|
* Versions of libintl >= 0.13 try to replace printf() and friends with
|
|
|
|
* macros to their own versions that understand the %$ format. We do the
|
|
|
|
* same, so disable their macros, if they exist.
|
2005-12-06 03:29:04 +01:00
|
|
|
*/
|
|
|
|
#ifdef vsnprintf
|
|
|
|
#undef vsnprintf
|
|
|
|
#endif
|
|
|
|
#ifdef snprintf
|
|
|
|
#undef snprintf
|
|
|
|
#endif
|
2018-10-09 01:15:55 +02:00
|
|
|
#ifdef vsprintf
|
|
|
|
#undef vsprintf
|
|
|
|
#endif
|
2005-12-06 03:29:04 +01:00
|
|
|
#ifdef sprintf
|
|
|
|
#undef sprintf
|
|
|
|
#endif
|
2006-11-28 02:12:34 +01:00
|
|
|
#ifdef vfprintf
|
|
|
|
#undef vfprintf
|
|
|
|
#endif
|
2005-12-06 03:29:04 +01:00
|
|
|
#ifdef fprintf
|
|
|
|
#undef fprintf
|
|
|
|
#endif
|
2018-10-09 01:15:55 +02:00
|
|
|
#ifdef vprintf
|
|
|
|
#undef vprintf
|
|
|
|
#endif
|
2005-12-06 03:29:04 +01:00
|
|
|
#ifdef printf
|
|
|
|
#undef printf
|
|
|
|
#endif
|
|
|
|
|
2022-09-16 17:10:48 +02:00
|
|
|
extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args) pg_attribute_printf(3, 0);
|
Revert error-throwing wrappers for the printf family of functions.
This reverts commit 16304a013432931e61e623c8d85e9fe24709d9ba, except
for its changes in src/port/snprintf.c; as well as commit
cac18a76bb6b08f1ecc2a85e46c9d2ab82dd9d23 which is no longer needed.
Fujii Masao reported that the previous commit caused failures in psql on
OS X, since if one exits the pager program early while viewing a query
result, psql sees an EPIPE error from fprintf --- and the wrapper function
thought that was reason to panic. (It's a bit surprising that the same
does not happen on Linux.) Further discussion among the security list
concluded that the risk of other such failures was far too great, and
that the one-size-fits-all approach to error handling embodied in the
previous patch is unlikely to be workable.
This leaves us again exposed to the possibility of the type of failure
envisioned in CVE-2015-3166. However, that failure mode is strictly
hypothetical at this point: there is no concrete reason to believe that
an attacker could trigger information disclosure through the supposed
mechanism. In the first place, the attack surface is fairly limited,
since so much of what the backend does with format strings goes through
stringinfo.c or psprintf(), and those already had adequate defenses.
In the second place, even granting that an unprivileged attacker could
control the occurrence of ENOMEM with some precision, it's a stretch to
believe that he could induce it just where the target buffer contains some
valuable information. So we concluded that the risk of non-hypothetical
problems induced by the patch greatly outweighs the security risks.
We will therefore revert, and instead undertake closer analysis to
identify specific calls that may need hardening, rather than attempt a
universal solution.
We have kept the portion of the previous patch that improved snprintf.c's
handling of errors when it calls the platform's sprintf(). That seems to
be an unalloyed improvement.
Security: CVE-2015-3166
2015-05-20 00:14:52 +02:00
|
|
|
extern int pg_snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3, 4);
|
2022-09-16 17:10:48 +02:00
|
|
|
extern int pg_vsprintf(char *str, const char *fmt, va_list args) pg_attribute_printf(2, 0);
|
Revert error-throwing wrappers for the printf family of functions.
This reverts commit 16304a013432931e61e623c8d85e9fe24709d9ba, except
for its changes in src/port/snprintf.c; as well as commit
cac18a76bb6b08f1ecc2a85e46c9d2ab82dd9d23 which is no longer needed.
Fujii Masao reported that the previous commit caused failures in psql on
OS X, since if one exits the pager program early while viewing a query
result, psql sees an EPIPE error from fprintf --- and the wrapper function
thought that was reason to panic. (It's a bit surprising that the same
does not happen on Linux.) Further discussion among the security list
concluded that the risk of other such failures was far too great, and
that the one-size-fits-all approach to error handling embodied in the
previous patch is unlikely to be workable.
This leaves us again exposed to the possibility of the type of failure
envisioned in CVE-2015-3166. However, that failure mode is strictly
hypothetical at this point: there is no concrete reason to believe that
an attacker could trigger information disclosure through the supposed
mechanism. In the first place, the attack surface is fairly limited,
since so much of what the backend does with format strings goes through
stringinfo.c or psprintf(), and those already had adequate defenses.
In the second place, even granting that an unprivileged attacker could
control the occurrence of ENOMEM with some precision, it's a stretch to
believe that he could induce it just where the target buffer contains some
valuable information. So we concluded that the risk of non-hypothetical
problems induced by the patch greatly outweighs the security risks.
We will therefore revert, and instead undertake closer analysis to
identify specific calls that may need hardening, rather than attempt a
universal solution.
We have kept the portion of the previous patch that improved snprintf.c's
handling of errors when it calls the platform's sprintf(). That seems to
be an unalloyed improvement.
Security: CVE-2015-3166
2015-05-20 00:14:52 +02:00
|
|
|
extern int pg_sprintf(char *str, const char *fmt,...) pg_attribute_printf(2, 3);
|
2022-09-16 17:10:48 +02:00
|
|
|
extern int pg_vfprintf(FILE *stream, const char *fmt, va_list args) pg_attribute_printf(2, 0);
|
Revert error-throwing wrappers for the printf family of functions.
This reverts commit 16304a013432931e61e623c8d85e9fe24709d9ba, except
for its changes in src/port/snprintf.c; as well as commit
cac18a76bb6b08f1ecc2a85e46c9d2ab82dd9d23 which is no longer needed.
Fujii Masao reported that the previous commit caused failures in psql on
OS X, since if one exits the pager program early while viewing a query
result, psql sees an EPIPE error from fprintf --- and the wrapper function
thought that was reason to panic. (It's a bit surprising that the same
does not happen on Linux.) Further discussion among the security list
concluded that the risk of other such failures was far too great, and
that the one-size-fits-all approach to error handling embodied in the
previous patch is unlikely to be workable.
This leaves us again exposed to the possibility of the type of failure
envisioned in CVE-2015-3166. However, that failure mode is strictly
hypothetical at this point: there is no concrete reason to believe that
an attacker could trigger information disclosure through the supposed
mechanism. In the first place, the attack surface is fairly limited,
since so much of what the backend does with format strings goes through
stringinfo.c or psprintf(), and those already had adequate defenses.
In the second place, even granting that an unprivileged attacker could
control the occurrence of ENOMEM with some precision, it's a stretch to
believe that he could induce it just where the target buffer contains some
valuable information. So we concluded that the risk of non-hypothetical
problems induced by the patch greatly outweighs the security risks.
We will therefore revert, and instead undertake closer analysis to
identify specific calls that may need hardening, rather than attempt a
universal solution.
We have kept the portion of the previous patch that improved snprintf.c's
handling of errors when it calls the platform's sprintf(). That seems to
be an unalloyed improvement.
Security: CVE-2015-3166
2015-05-20 00:14:52 +02:00
|
|
|
extern int pg_fprintf(FILE *stream, const char *fmt,...) pg_attribute_printf(2, 3);
|
2022-09-16 17:10:48 +02:00
|
|
|
extern int pg_vprintf(const char *fmt, va_list args) pg_attribute_printf(1, 0);
|
Revert error-throwing wrappers for the printf family of functions.
This reverts commit 16304a013432931e61e623c8d85e9fe24709d9ba, except
for its changes in src/port/snprintf.c; as well as commit
cac18a76bb6b08f1ecc2a85e46c9d2ab82dd9d23 which is no longer needed.
Fujii Masao reported that the previous commit caused failures in psql on
OS X, since if one exits the pager program early while viewing a query
result, psql sees an EPIPE error from fprintf --- and the wrapper function
thought that was reason to panic. (It's a bit surprising that the same
does not happen on Linux.) Further discussion among the security list
concluded that the risk of other such failures was far too great, and
that the one-size-fits-all approach to error handling embodied in the
previous patch is unlikely to be workable.
This leaves us again exposed to the possibility of the type of failure
envisioned in CVE-2015-3166. However, that failure mode is strictly
hypothetical at this point: there is no concrete reason to believe that
an attacker could trigger information disclosure through the supposed
mechanism. In the first place, the attack surface is fairly limited,
since so much of what the backend does with format strings goes through
stringinfo.c or psprintf(), and those already had adequate defenses.
In the second place, even granting that an unprivileged attacker could
control the occurrence of ENOMEM with some precision, it's a stretch to
believe that he could induce it just where the target buffer contains some
valuable information. So we concluded that the risk of non-hypothetical
problems induced by the patch greatly outweighs the security risks.
We will therefore revert, and instead undertake closer analysis to
identify specific calls that may need hardening, rather than attempt a
universal solution.
We have kept the portion of the previous patch that improved snprintf.c's
handling of errors when it calls the platform's sprintf(). That seems to
be an unalloyed improvement.
Security: CVE-2015-3166
2015-05-20 00:14:52 +02:00
|
|
|
extern int pg_printf(const char *fmt,...) pg_attribute_printf(1, 2);
|
2005-12-06 06:13:46 +01:00
|
|
|
|
2022-09-29 02:12:11 +02:00
|
|
|
#ifndef WIN32
|
|
|
|
/*
|
|
|
|
* We add a pg_ prefix as a warning that the Windows implementations have the
|
|
|
|
* non-standard side-effect of changing the current file position.
|
|
|
|
*/
|
|
|
|
#define pg_pread pread
|
|
|
|
#define pg_pwrite pwrite
|
|
|
|
#endif
|
|
|
|
|
2005-03-11 20:13:43 +01:00
|
|
|
/*
|
2018-09-26 23:35:01 +02:00
|
|
|
* We use __VA_ARGS__ for printf to prevent replacing references to
|
|
|
|
* the "printf" format archetype in format() attribute declarations.
|
|
|
|
* That unfortunately means that taking a function pointer to printf
|
|
|
|
* will not do what we'd wish. (If you need to do that, you must name
|
|
|
|
* pg_printf explicitly.) For printf's sibling functions, use
|
|
|
|
* parameterless macros so that function pointers will work unsurprisingly.
|
2005-03-11 20:13:43 +01:00
|
|
|
*/
|
Revert error-throwing wrappers for the printf family of functions.
This reverts commit 16304a013432931e61e623c8d85e9fe24709d9ba, except
for its changes in src/port/snprintf.c; as well as commit
cac18a76bb6b08f1ecc2a85e46c9d2ab82dd9d23 which is no longer needed.
Fujii Masao reported that the previous commit caused failures in psql on
OS X, since if one exits the pager program early while viewing a query
result, psql sees an EPIPE error from fprintf --- and the wrapper function
thought that was reason to panic. (It's a bit surprising that the same
does not happen on Linux.) Further discussion among the security list
concluded that the risk of other such failures was far too great, and
that the one-size-fits-all approach to error handling embodied in the
previous patch is unlikely to be workable.
This leaves us again exposed to the possibility of the type of failure
envisioned in CVE-2015-3166. However, that failure mode is strictly
hypothetical at this point: there is no concrete reason to believe that
an attacker could trigger information disclosure through the supposed
mechanism. In the first place, the attack surface is fairly limited,
since so much of what the backend does with format strings goes through
stringinfo.c or psprintf(), and those already had adequate defenses.
In the second place, even granting that an unprivileged attacker could
control the occurrence of ENOMEM with some precision, it's a stretch to
believe that he could induce it just where the target buffer contains some
valuable information. So we concluded that the risk of non-hypothetical
problems induced by the patch greatly outweighs the security risks.
We will therefore revert, and instead undertake closer analysis to
identify specific calls that may need hardening, rather than attempt a
universal solution.
We have kept the portion of the previous patch that improved snprintf.c's
handling of errors when it calls the platform's sprintf(). That seems to
be an unalloyed improvement.
Security: CVE-2015-3166
2015-05-20 00:14:52 +02:00
|
|
|
#define vsnprintf pg_vsnprintf
|
|
|
|
#define snprintf pg_snprintf
|
2018-10-09 01:15:55 +02:00
|
|
|
#define vsprintf pg_vsprintf
|
Revert error-throwing wrappers for the printf family of functions.
This reverts commit 16304a013432931e61e623c8d85e9fe24709d9ba, except
for its changes in src/port/snprintf.c; as well as commit
cac18a76bb6b08f1ecc2a85e46c9d2ab82dd9d23 which is no longer needed.
Fujii Masao reported that the previous commit caused failures in psql on
OS X, since if one exits the pager program early while viewing a query
result, psql sees an EPIPE error from fprintf --- and the wrapper function
thought that was reason to panic. (It's a bit surprising that the same
does not happen on Linux.) Further discussion among the security list
concluded that the risk of other such failures was far too great, and
that the one-size-fits-all approach to error handling embodied in the
previous patch is unlikely to be workable.
This leaves us again exposed to the possibility of the type of failure
envisioned in CVE-2015-3166. However, that failure mode is strictly
hypothetical at this point: there is no concrete reason to believe that
an attacker could trigger information disclosure through the supposed
mechanism. In the first place, the attack surface is fairly limited,
since so much of what the backend does with format strings goes through
stringinfo.c or psprintf(), and those already had adequate defenses.
In the second place, even granting that an unprivileged attacker could
control the occurrence of ENOMEM with some precision, it's a stretch to
believe that he could induce it just where the target buffer contains some
valuable information. So we concluded that the risk of non-hypothetical
problems induced by the patch greatly outweighs the security risks.
We will therefore revert, and instead undertake closer analysis to
identify specific calls that may need hardening, rather than attempt a
universal solution.
We have kept the portion of the previous patch that improved snprintf.c's
handling of errors when it calls the platform's sprintf(). That seems to
be an unalloyed improvement.
Security: CVE-2015-3166
2015-05-20 00:14:52 +02:00
|
|
|
#define sprintf pg_sprintf
|
|
|
|
#define vfprintf pg_vfprintf
|
|
|
|
#define fprintf pg_fprintf
|
2018-10-09 01:15:55 +02:00
|
|
|
#define vprintf pg_vprintf
|
2018-09-26 23:35:01 +02:00
|
|
|
#define printf(...) pg_printf(__VA_ARGS__)
|
2005-03-11 18:20:35 +01:00
|
|
|
|
Improve snprintf.c's handling of NaN, Infinity, and minus zero.
Up to now, float4out/float8out handled NaN and Infinity cases explicitly,
and invoked psprintf only for ordinary float values. This was done because
platform implementations of snprintf produce varying representations of
these special cases. But now that we use snprintf.c always, it's better
to give it the responsibility to produce a uniform representation of
these cases, so that we have uniformity across the board not only in
float4out/float8out. Hence, move that work into fmtfloat().
Also, teach fmtfloat() to recognize IEEE minus zero and handle it
correctly. The previous coding worked only accidentally, and would
fail for e.g. "%+f" format (it'd print "+-0.00000"). Now that we're
using snprintf.c everywhere, it's not acceptable for it to do weird
things in corner cases. (This incidentally avoids a portability
problem we've seen on some really ancient platforms, that native
sprintf does the wrong thing with minus zero.)
Also, introduce a new entry point in snprintf.c to allow float[48]out
to bypass the work of interpreting a well-known format spec, as well
as bypassing the overhead of the psprintf layer. I modeled this API
loosely on strfromd(). In my testing, this brings float[48]out back
to approximately the same speed they had when using native snprintf,
fixing one of the main performance issues caused by using snprintf.c.
(There is some talk of more aggressive work to improve the speed of
floating-point output conversion, but these changes seem to provide
a better starting point for such work anyway.)
Getting rid of the previous ad-hoc hack for Infinity/NaN in fmtfloat()
allows removing <ctype.h> from snprintf.c's #includes. I also removed
a few other #includes that I think are historical, though the buildfarm
may expose that as wrong.
Discussion: https://postgr.es/m/13178.1538794717@sss.pgh.pa.us
2018-10-08 18:19:20 +02:00
|
|
|
/* This is also provided by snprintf.c */
|
|
|
|
extern int pg_strfromd(char *str, size_t count, int precision, double value);
|
|
|
|
|
Convert elog.c's useful_strerror() into a globally-used strerror wrapper.
elog.c has long had a private strerror wrapper that handles assorted
possible failures or deficiencies of the platform's strerror. On Windows,
it also knows how to translate Winsock error codes, which the native
strerror does not. Move all this code into src/port/strerror.c and
define strerror() as a macro that invokes it, so that both our frontend
and backend code will have all of this behavior.
I believe this constitutes an actual bug fix on Windows, since AFAICS
our frontend code did not report Winsock error codes properly before this.
However, the main point is to lay the groundwork for implementing %m
in src/port/snprintf.c: the behavior we want %m to have is this one,
not the native strerror's.
Note that this throws away the prior use of src/port/strerror.c,
which was to implement strerror() on platforms lacking it. That's
been dead code for nigh twenty years now, since strerror() was
already required by C89.
We should likewise cause strerror_r to use this behavior, but
I'll tackle that separately.
Patch by me, reviewed by Michael Paquier
Discussion: https://postgr.es/m/2975.1526862605@sss.pgh.pa.us
2018-09-26 17:06:42 +02:00
|
|
|
/* Replace strerror() with our own, somewhat more robust wrapper */
|
|
|
|
extern char *pg_strerror(int errnum);
|
|
|
|
#define strerror pg_strerror
|
|
|
|
|
2018-09-26 18:35:57 +02:00
|
|
|
/* Likewise for strerror_r(); note we prefer the GNU API for that */
|
|
|
|
extern char *pg_strerror_r(int errnum, char *buf, size_t buflen);
|
|
|
|
#define strerror_r pg_strerror_r
|
|
|
|
#define PG_STRERROR_R_BUFLEN 256 /* Recommended buffer size for strerror_r */
|
|
|
|
|
Modernize our code for looking up descriptive strings for Unix signals.
At least as far back as the 2008 spec, POSIX has defined strsignal(3)
for looking up descriptive strings for signal numbers. We hadn't gotten
the word though, and were still using the crufty old sys_siglist array,
which is in no standard even though most Unixen provide it.
Aside from not being formally standards-compliant, this was just plain
ugly because it involved #ifdef's at every place using the code.
To eliminate the #ifdef's, create a portability function pg_strsignal,
which wraps strsignal(3) if available and otherwise falls back to
sys_siglist[] if available. The set of Unixen with neither API is
probably empty these days, but on any platform with neither, you'll
just get "unrecognized signal". All extant callers print the numeric
signal number too, so no need to work harder than that.
Along the way, upgrade pg_basebackup's child-error-exit reporting
to match the rest of the system.
Discussion: https://postgr.es/m/25758.1544983503@sss.pgh.pa.us
2018-12-17 01:38:57 +01:00
|
|
|
/* Wrap strsignal(), or provide our own version if necessary */
|
|
|
|
extern const char *pg_strsignal(int signum);
|
|
|
|
|
2004-05-11 23:57:15 +02:00
|
|
|
extern int pclose_check(FILE *stream);
|
2004-04-05 05:16:21 +02:00
|
|
|
|
2004-09-09 16:18:20 +02:00
|
|
|
/* Global variable holding time zone information. */
|
2016-03-29 02:59:25 +02:00
|
|
|
#if defined(WIN32) || defined(__CYGWIN__)
|
2004-09-09 16:18:20 +02:00
|
|
|
#define TIMEZONE_GLOBAL _timezone
|
|
|
|
#define TZNAME_GLOBAL _tzname
|
2016-03-29 02:59:25 +02:00
|
|
|
#else
|
|
|
|
#define TIMEZONE_GLOBAL timezone
|
|
|
|
#define TZNAME_GLOBAL tzname
|
2004-09-09 16:18:20 +02:00
|
|
|
#endif
|
|
|
|
|
2005-07-06 23:40:09 +02:00
|
|
|
#if defined(WIN32) || defined(__CYGWIN__)
|
2003-05-15 18:35:30 +02:00
|
|
|
/*
|
2007-07-13 01:28:49 +02:00
|
|
|
* Win32 doesn't have reliable rename/unlink during concurrent access.
|
2003-05-15 18:35:30 +02:00
|
|
|
*/
|
2003-08-08 06:52:22 +02:00
|
|
|
extern int pgrename(const char *from, const char *to);
|
|
|
|
extern int pgunlink(const char *path);
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2004-09-27 22:37:20 +02:00
|
|
|
/* Include this first so later includes don't see these defines */
|
2017-04-11 15:21:25 +02:00
|
|
|
#ifdef _MSC_VER
|
2004-09-27 22:37:20 +02:00
|
|
|
#include <io.h>
|
|
|
|
#endif
|
|
|
|
|
2004-08-07 23:48:09 +02:00
|
|
|
#define rename(from, to) pgrename(from, to)
|
|
|
|
#define unlink(path) pgunlink(path)
|
2007-07-13 01:28:49 +02:00
|
|
|
#endif /* defined(WIN32) || defined(__CYGWIN__) */
|
|
|
|
|
2004-10-12 00:50:48 +02:00
|
|
|
/*
|
2007-07-13 01:28:49 +02:00
|
|
|
* Win32 also doesn't have symlinks, but we can emulate them with
|
|
|
|
* junction points on newer Win32 versions.
|
|
|
|
*
|
2004-10-12 00:50:48 +02:00
|
|
|
* Cygwin has its own symlinks which work on Win95/98/ME where
|
2007-07-13 01:28:49 +02:00
|
|
|
* junction points don't, so use those instead. We have no way of
|
2004-10-12 00:50:48 +02:00
|
|
|
* knowing what type of system Cygwin binaries will be run on.
|
2004-11-17 18:46:24 +01:00
|
|
|
* Note: Some CYGWIN includes might #define WIN32.
|
2004-10-12 00:50:48 +02:00
|
|
|
*/
|
2004-11-17 18:46:24 +01:00
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
2004-10-12 00:50:48 +02:00
|
|
|
extern int pgsymlink(const char *oldpath, const char *newpath);
|
2011-01-09 15:06:55 +01:00
|
|
|
extern int pgreadlink(const char *path, char *buf, size_t size);
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2004-08-07 23:48:09 +02:00
|
|
|
#define symlink(oldpath, newpath) pgsymlink(oldpath, newpath)
|
2011-01-09 15:06:55 +01:00
|
|
|
#define readlink(path, buf, size) pgreadlink(path, buf, size)
|
2003-05-15 18:35:30 +02:00
|
|
|
#endif
|
2004-10-12 00:50:48 +02:00
|
|
|
|
2008-04-18 19:05:45 +02:00
|
|
|
extern bool rmtree(const char *path, bool rmtopdir);
|
2004-08-01 08:19:26 +02:00
|
|
|
|
2005-07-06 23:40:09 +02:00
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
2004-03-24 04:54:16 +01:00
|
|
|
|
2008-04-12 01:53:00 +02:00
|
|
|
/*
|
|
|
|
* open() and fopen() replacements to allow deletion of open files and
|
2006-08-30 20:06:27 +02:00
|
|
|
* passing of other special options.
|
|
|
|
*/
|
2007-04-13 12:30:30 +02:00
|
|
|
#define O_DIRECT 0x80000000
|
2021-12-10 04:13:14 +01:00
|
|
|
extern HANDLE pgwin32_open_handle(const char *, int, bool);
|
2006-06-25 02:18:24 +02:00
|
|
|
extern int pgwin32_open(const char *, int,...);
|
2006-08-30 20:06:27 +02:00
|
|
|
extern FILE *pgwin32_fopen(const char *, const char *);
|
2006-06-25 02:18:24 +02:00
|
|
|
#define open(a,b,c) pgwin32_open(a,b,c)
|
2006-08-30 20:06:27 +02:00
|
|
|
#define fopen(a,b) pgwin32_fopen(a,b)
|
2004-03-24 04:54:16 +01:00
|
|
|
|
2014-05-15 11:18:49 +02:00
|
|
|
/*
|
|
|
|
* Mingw-w64 headers #define popen and pclose to _popen and _pclose. We want
|
|
|
|
* to use our popen wrapper, rather than plain _popen, so override that. For
|
|
|
|
* consistency, use our version of pclose, too.
|
|
|
|
*/
|
|
|
|
#ifdef popen
|
|
|
|
#undef popen
|
|
|
|
#endif
|
|
|
|
#ifdef pclose
|
|
|
|
#undef pclose
|
|
|
|
#endif
|
|
|
|
|
Replace SYSTEMQUOTEs with Windows-specific wrapper functions.
It's easy to forget using SYSTEMQUOTEs when constructing command strings
for system() or popen(). Even if we fix all the places missing it now, it is
bound to be forgotten again in the future. Introduce wrapper functions that
do the the extra quoting for you, and get rid of SYSTEMQUOTEs in all the
callers.
We previosly used SYSTEMQUOTEs in all the hard-coded command strings, and
this doesn't change the behavior of those. But user-supplied commands, like
archive_command, restore_command, COPY TO/FROM PROGRAM calls, as well as
pgbench's \shell, will now gain an extra pair of quotes. That is desirable,
but if you have existing scripts or config files that include an extra
pair of quotes, those might need to be adjusted.
Reviewed by Amit Kapila and Tom Lane
2014-05-05 15:07:40 +02:00
|
|
|
/*
|
|
|
|
* system() and popen() replacements to enclose the command in an extra
|
|
|
|
* pair of quotes.
|
|
|
|
*/
|
|
|
|
extern int pgwin32_system(const char *command);
|
|
|
|
extern FILE *pgwin32_popen(const char *command, const char *type);
|
|
|
|
|
|
|
|
#define system(a) pgwin32_system(a)
|
|
|
|
#define popen(a,b) pgwin32_popen(a,b)
|
2004-04-19 19:42:59 +02:00
|
|
|
#define pclose(a) _pclose(a)
|
|
|
|
|
2004-11-06 02:16:22 +01:00
|
|
|
#else /* !WIN32 */
|
2003-05-16 03:57:52 +02:00
|
|
|
|
2003-05-15 18:35:30 +02:00
|
|
|
/*
|
|
|
|
* Win32 requires a special close for sockets and pipes, while on Unix
|
|
|
|
* close() does them all.
|
|
|
|
*/
|
|
|
|
#define closesocket close
|
2004-11-06 02:16:22 +01:00
|
|
|
#endif /* WIN32 */
|
2003-08-04 02:43:34 +02:00
|
|
|
|
2014-05-15 21:57:54 +02:00
|
|
|
/*
|
|
|
|
* On Windows, setvbuf() does not support _IOLBF mode, and interprets that
|
|
|
|
* as _IOFBF. To add insult to injury, setvbuf(file, NULL, _IOFBF, 0)
|
|
|
|
* crashes outright if "parameter validation" is enabled. Therefore, in
|
|
|
|
* places where we'd like to select line-buffered mode, we fall back to
|
|
|
|
* unbuffered mode instead on Windows. Always use PG_IOLBF not _IOLBF
|
|
|
|
* directly in order to implement this behavior.
|
|
|
|
*/
|
|
|
|
#ifndef WIN32
|
|
|
|
#define PG_IOLBF _IOLBF
|
|
|
|
#else
|
|
|
|
#define PG_IOLBF _IONBF
|
|
|
|
#endif
|
|
|
|
|
2003-05-15 18:35:30 +02:00
|
|
|
/*
|
|
|
|
* Default "extern" declarations or macro substitutes for library routines.
|
|
|
|
* When necessary, these routines are provided by files in src/port/.
|
|
|
|
*/
|
|
|
|
|
2020-02-21 18:49:42 +01:00
|
|
|
/* Type to use with fseeko/ftello */
|
|
|
|
#ifndef WIN32 /* WIN32 is handled in port/win32_port.h */
|
2009-01-07 04:39:33 +01:00
|
|
|
#define pgoff_t off_t
|
|
|
|
#endif
|
2004-11-06 02:16:22 +01:00
|
|
|
|
2019-10-30 12:58:32 +01:00
|
|
|
#ifndef HAVE_GETPEEREID
|
2019-12-16 11:48:01 +01:00
|
|
|
/* On Windows, Perl might have incompatible definitions of uid_t and gid_t. */
|
|
|
|
#ifndef PLPERL_HAVE_UID_GID
|
2011-06-02 19:05:01 +02:00
|
|
|
extern int getpeereid(int sock, uid_t *uid, gid_t *gid);
|
|
|
|
#endif
|
2019-12-16 11:48:01 +01:00
|
|
|
#endif
|
2011-06-02 19:05:01 +02:00
|
|
|
|
2018-03-28 21:45:32 +02:00
|
|
|
/*
|
|
|
|
* Glibc doesn't use the builtin for clang due to a *gcc* bug in a version
|
|
|
|
* newer than the gcc compatibility clang claims to have. This would cause a
|
2018-09-01 01:56:11 +02:00
|
|
|
* *lot* of superfluous function calls, therefore revert when using clang. In
|
|
|
|
* C++ there's issues with libc++ (not libstdc++), so disable as well.
|
2018-03-28 21:45:32 +02:00
|
|
|
*/
|
2018-09-01 01:56:11 +02:00
|
|
|
#if defined(__clang__) && !defined(__cplusplus)
|
2018-03-28 21:45:32 +02:00
|
|
|
/* needs to be separate to not confuse other compilers */
|
|
|
|
#if __has_builtin(__builtin_isinf)
|
2018-09-01 01:56:11 +02:00
|
|
|
/* need to include before, to avoid getting overwritten */
|
|
|
|
#include <math.h>
|
2018-03-28 21:45:32 +02:00
|
|
|
#undef isinf
|
|
|
|
#define isinf __builtin_isinf
|
|
|
|
#endif /* __has_builtin(isinf) */
|
Convert elog.c's useful_strerror() into a globally-used strerror wrapper.
elog.c has long had a private strerror wrapper that handles assorted
possible failures or deficiencies of the platform's strerror. On Windows,
it also knows how to translate Winsock error codes, which the native
strerror does not. Move all this code into src/port/strerror.c and
define strerror() as a macro that invokes it, so that both our frontend
and backend code will have all of this behavior.
I believe this constitutes an actual bug fix on Windows, since AFAICS
our frontend code did not report Winsock error codes properly before this.
However, the main point is to lay the groundwork for implementing %m
in src/port/snprintf.c: the behavior we want %m to have is this one,
not the native strerror's.
Note that this throws away the prior use of src/port/strerror.c,
which was to implement strerror() on platforms lacking it. That's
been dead code for nigh twenty years now, since strerror() was
already required by C89.
We should likewise cause strerror_r to use this behavior, but
I'll tackle that separately.
Patch by me, reviewed by Michael Paquier
Discussion: https://postgr.es/m/2975.1526862605@sss.pgh.pa.us
2018-09-26 17:06:42 +02:00
|
|
|
#endif /* __clang__ && !__cplusplus */
|
2003-05-15 18:35:30 +02:00
|
|
|
|
2019-09-05 08:15:58 +02:00
|
|
|
#ifndef HAVE_EXPLICIT_BZERO
|
|
|
|
extern void explicit_bzero(void *buf, size_t len);
|
|
|
|
#endif
|
|
|
|
|
2019-02-16 02:50:16 +01:00
|
|
|
#ifdef HAVE_BUGGY_STRTOF
|
|
|
|
extern float pg_strtof(const char *nptr, char **endptr);
|
|
|
|
#define strtof(a,b) (pg_strtof((a),(b)))
|
|
|
|
#endif
|
|
|
|
|
2022-08-04 23:36:50 +02:00
|
|
|
#ifdef WIN32
|
|
|
|
/* src/port/win32link.c */
|
2020-03-04 08:05:33 +01:00
|
|
|
extern int link(const char *src, const char *dst);
|
|
|
|
#endif
|
|
|
|
|
2014-10-18 04:55:20 +02:00
|
|
|
#ifndef HAVE_MKDTEMP
|
|
|
|
extern char *mkdtemp(char *path);
|
|
|
|
#endif
|
|
|
|
|
2003-05-15 18:35:30 +02:00
|
|
|
#ifndef HAVE_INET_ATON
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
extern int inet_aton(const char *cp, struct in_addr *addr);
|
|
|
|
#endif
|
|
|
|
|
2007-02-07 01:28:55 +01:00
|
|
|
#if !HAVE_DECL_STRLCAT
|
|
|
|
extern size_t strlcat(char *dst, const char *src, size_t siz);
|
|
|
|
#endif
|
|
|
|
|
2006-10-02 02:06:18 +02:00
|
|
|
#if !HAVE_DECL_STRLCPY
|
2006-09-27 18:29:46 +02:00
|
|
|
extern size_t strlcpy(char *dst, const char *src, size_t siz);
|
2003-05-15 18:35:30 +02:00
|
|
|
#endif
|
|
|
|
|
2017-10-10 23:42:16 +02:00
|
|
|
#if !HAVE_DECL_STRNLEN
|
|
|
|
extern size_t strnlen(const char *str, size_t maxlen);
|
|
|
|
#endif
|
|
|
|
|
2023-07-09 08:12:28 +02:00
|
|
|
/* port/user.c */
|
Fix libpq's behavior when /etc/passwd isn't readable.
Some users run their applications in chroot environments that lack an
/etc/passwd file. This means that the current UID's user name and home
directory are not obtainable. libpq used to be all right with that,
so long as the database role name to use was specified explicitly.
But commit a4c8f14364c27508233f8a31ac4b10a4c90235a9 broke such cases by
causing any failure of pg_fe_getauthname() to be treated as a hard error.
In any case it did little to advance its nominal goal of causing errors
in pg_fe_getauthname() to be reported better. So revert that and instead
put some real error-reporting code in place. This requires changes to the
APIs of pg_fe_getauthname() and pqGetpwuid(), since the latter had
departed from the POSIX-specified API of getpwuid_r() in a way that made
it impossible to distinguish actual lookup errors from "no such user".
To allow such failures to be reported, while not failing if the caller
supplies a role name, add a second call of pg_fe_getauthname() in
connectOptions2(). This is a tad ugly, and could perhaps be avoided with
some refactoring of PQsetdbLogin(), but I'll leave that idea for later.
(Note that the complained-of misbehavior only occurs in PQsetdbLogin,
not when using the PQconnect functions, because in the latter we will
never bother to call pg_fe_getauthname() if the user gives a role name.)
In passing also clean up the Windows-side usage of GetUserName(): the
recommended buffer size is 257 bytes, the passed buffer length should
be the buffer size not buffer size less 1, and any error is reported
by GetLastError() not errno.
Per report from Christoph Berg. Back-patch to 9.4 where the chroot
failure case was introduced. The generally poor reporting of errors
here is of very long standing, of course, but given the lack of field
complaints about it we won't risk changing these APIs further back
(even though they're theoretically internal to libpq).
2015-01-11 18:35:44 +01:00
|
|
|
#ifndef WIN32
|
2022-01-11 19:46:12 +01:00
|
|
|
extern bool pg_get_user_name(uid_t user_id, char *buffer, size_t buflen);
|
|
|
|
extern bool pg_get_user_home_dir(uid_t user_id, char *buffer, size_t buflen);
|
2003-09-05 19:43:40 +02:00
|
|
|
#endif
|
2003-06-14 16:35:42 +02:00
|
|
|
|
2006-10-19 22:56:22 +02:00
|
|
|
extern void pg_qsort(void *base, size_t nel, size_t elsize,
|
|
|
|
int (*cmp) (const void *, const void *));
|
2012-07-20 17:38:47 +02:00
|
|
|
extern int pg_qsort_strcmp(const void *a, const void *b);
|
2006-10-19 22:56:22 +02:00
|
|
|
|
|
|
|
#define qsort(a,b,c,d) pg_qsort(a,b,c,d)
|
|
|
|
|
2006-10-04 00:18:23 +02:00
|
|
|
typedef int (*qsort_arg_comparator) (const void *a, const void *b, void *arg);
|
|
|
|
|
|
|
|
extern void qsort_arg(void *base, size_t nel, size_t elsize,
|
|
|
|
qsort_arg_comparator cmp, void *arg);
|
|
|
|
|
2022-07-12 22:30:36 +02:00
|
|
|
extern void qsort_interruptible(void *base, size_t nel, size_t elsize,
|
|
|
|
qsort_arg_comparator cmp, void *arg);
|
|
|
|
|
2022-09-20 22:09:30 +02:00
|
|
|
extern void *bsearch_arg(const void *key, const void *base0,
|
2021-03-23 00:11:20 +01:00
|
|
|
size_t nmemb, size_t size,
|
|
|
|
int (*compar) (const void *, const void *, void *),
|
|
|
|
void *arg);
|
|
|
|
|
2007-09-29 00:25:49 +02:00
|
|
|
/* port/chklocale.c */
|
2011-02-08 22:04:18 +01:00
|
|
|
extern int pg_get_encoding_from_locale(const char *ctype, bool write_message);
|
2007-09-29 00:25:49 +02:00
|
|
|
|
Renovate display of non-ASCII messages on Windows.
GNU gettext selects a default encoding for the messages it emits in a
platform-specific manner; it uses the Windows ANSI code page on Windows
and follows LC_CTYPE on other platforms. This is inconvenient for
PostgreSQL server processes, so realize consistent cross-platform
behavior by calling bind_textdomain_codeset() on Windows each time we
permanently change LC_CTYPE. This primarily affects SQL_ASCII databases
and processes like the postmaster that do not attach to a database,
making their behavior consistent with PostgreSQL on non-Windows
platforms. Messages from SQL_ASCII databases use the encoding implied
by the database LC_CTYPE, and messages from non-database processes use
LC_CTYPE from the postmaster system environment. PlatformEncoding
becomes unused, so remove it.
Make write_console() prefer WriteConsoleW() to write() regardless of the
encodings in use. In this situation, write() will invariably mishandle
non-ASCII characters.
elog.c has assumed that messages conform to the database encoding.
While usually true, this does not hold for SQL_ASCII and MULE_INTERNAL.
Introduce MessageEncoding to track the actual encoding of message text.
The present consumers are Windows-specific code for converting messages
to UTF16 for use in system interfaces. This fixes the appearance in
Windows event logs and consoles of translated messages from SQL_ASCII
processes like the postmaster. Note that SQL_ASCII inherently disclaims
a strong notion of encoding, so non-ASCII byte sequences interpolated
into messages by %s may yet yield a nonsensical message. MULE_INTERNAL
has similar problems at present, albeit for a different reason: its lack
of libiconv support or a conversion to UTF8.
Consequently, one need no longer restart Windows with a different
Windows ANSI code page to broadly test backend logging under a given
language. Changing the user's locale ("Format") is enough. Several
accounts can simultaneously run postmasters under different locales, all
correctly logging localized messages to Windows event logs and consoles.
Alexander Law and Noah Misch
2013-06-26 17:17:33 +02:00
|
|
|
#if defined(WIN32) && !defined(FRONTEND)
|
|
|
|
extern int pg_codepage_to_encoding(UINT cp);
|
|
|
|
#endif
|
|
|
|
|
2010-11-24 23:04:19 +01:00
|
|
|
/* port/inet_net_ntop.c */
|
2019-08-19 01:27:23 +02:00
|
|
|
extern char *pg_inet_net_ntop(int af, const void *src, int bits,
|
|
|
|
char *dst, size_t size);
|
2010-11-24 23:04:19 +01:00
|
|
|
|
Replace PostmasterRandom() with a stronger source, second attempt.
This adds a new routine, pg_strong_random() for generating random bytes,
for use in both frontend and backend. At the moment, it's only used in
the backend, but the upcoming SCRAM authentication patches need strong
random numbers in libpq as well.
pg_strong_random() is based on, and replaces, the existing implementation
in pgcrypto. It can acquire strong random numbers from a number of sources,
depending on what's available:
- OpenSSL RAND_bytes(), if built with OpenSSL
- On Windows, the native cryptographic functions are used
- /dev/urandom
Unlike the current pgcrypto function, the source is chosen by configure.
That makes it easier to test different implementations, and ensures that
we don't accidentally fall back to a less secure implementation, if the
primary source fails. All of those methods are quite reliable, it would be
pretty surprising for them to fail, so we'd rather find out by failing
hard.
If no strong random source is available, we fall back to using erand48(),
seeded from current timestamp, like PostmasterRandom() was. That isn't
cryptographically secure, but allows us to still work on platforms that
don't have any of the above stronger sources. Because it's not very secure,
the built-in implementation is only used if explicitly requested with
--disable-strong-random.
This replaces the more complicated Fortuna algorithm we used to have in
pgcrypto, which is unfortunate, but all modern platforms have /dev/urandom,
so it doesn't seem worth the maintenance effort to keep that. pgcrypto
functions that require strong random numbers will be disabled with
--disable-strong-random.
Original patch by Magnus Hagander, tons of further work by Michael Paquier
and me.
Discussion: https://www.postgresql.org/message-id/CAB7nPqRy3krN8quR9XujMVVHYtXJ0_60nqgVc6oUk8ygyVkZsA@mail.gmail.com
Discussion: https://www.postgresql.org/message-id/CAB7nPqRWkNYRRPJA7-cF+LfroYV10pvjdz6GNvxk-Eee9FypKA@mail.gmail.com
2016-12-05 12:42:59 +01:00
|
|
|
/* port/pg_strong_random.c */
|
2020-11-06 13:21:28 +01:00
|
|
|
extern void pg_strong_random_init(void);
|
Replace PostmasterRandom() with a stronger source, second attempt.
This adds a new routine, pg_strong_random() for generating random bytes,
for use in both frontend and backend. At the moment, it's only used in
the backend, but the upcoming SCRAM authentication patches need strong
random numbers in libpq as well.
pg_strong_random() is based on, and replaces, the existing implementation
in pgcrypto. It can acquire strong random numbers from a number of sources,
depending on what's available:
- OpenSSL RAND_bytes(), if built with OpenSSL
- On Windows, the native cryptographic functions are used
- /dev/urandom
Unlike the current pgcrypto function, the source is chosen by configure.
That makes it easier to test different implementations, and ensures that
we don't accidentally fall back to a less secure implementation, if the
primary source fails. All of those methods are quite reliable, it would be
pretty surprising for them to fail, so we'd rather find out by failing
hard.
If no strong random source is available, we fall back to using erand48(),
seeded from current timestamp, like PostmasterRandom() was. That isn't
cryptographically secure, but allows us to still work on platforms that
don't have any of the above stronger sources. Because it's not very secure,
the built-in implementation is only used if explicitly requested with
--disable-strong-random.
This replaces the more complicated Fortuna algorithm we used to have in
pgcrypto, which is unfortunate, but all modern platforms have /dev/urandom,
so it doesn't seem worth the maintenance effort to keep that. pgcrypto
functions that require strong random numbers will be disabled with
--disable-strong-random.
Original patch by Magnus Hagander, tons of further work by Michael Paquier
and me.
Discussion: https://www.postgresql.org/message-id/CAB7nPqRy3krN8quR9XujMVVHYtXJ0_60nqgVc6oUk8ygyVkZsA@mail.gmail.com
Discussion: https://www.postgresql.org/message-id/CAB7nPqRWkNYRRPJA7-cF+LfroYV10pvjdz6GNvxk-Eee9FypKA@mail.gmail.com
2016-12-05 12:42:59 +01:00
|
|
|
extern bool pg_strong_random(void *buf, size_t len);
|
2019-05-22 18:55:34 +02:00
|
|
|
|
2019-01-01 12:05:51 +01:00
|
|
|
/*
|
|
|
|
* pg_backend_random used to be a wrapper for pg_strong_random before
|
|
|
|
* Postgres 12 for the backend code.
|
|
|
|
*/
|
|
|
|
#define pg_backend_random pg_strong_random
|
Replace PostmasterRandom() with a stronger source, second attempt.
This adds a new routine, pg_strong_random() for generating random bytes,
for use in both frontend and backend. At the moment, it's only used in
the backend, but the upcoming SCRAM authentication patches need strong
random numbers in libpq as well.
pg_strong_random() is based on, and replaces, the existing implementation
in pgcrypto. It can acquire strong random numbers from a number of sources,
depending on what's available:
- OpenSSL RAND_bytes(), if built with OpenSSL
- On Windows, the native cryptographic functions are used
- /dev/urandom
Unlike the current pgcrypto function, the source is chosen by configure.
That makes it easier to test different implementations, and ensures that
we don't accidentally fall back to a less secure implementation, if the
primary source fails. All of those methods are quite reliable, it would be
pretty surprising for them to fail, so we'd rather find out by failing
hard.
If no strong random source is available, we fall back to using erand48(),
seeded from current timestamp, like PostmasterRandom() was. That isn't
cryptographically secure, but allows us to still work on platforms that
don't have any of the above stronger sources. Because it's not very secure,
the built-in implementation is only used if explicitly requested with
--disable-strong-random.
This replaces the more complicated Fortuna algorithm we used to have in
pgcrypto, which is unfortunate, but all modern platforms have /dev/urandom,
so it doesn't seem worth the maintenance effort to keep that. pgcrypto
functions that require strong random numbers will be disabled with
--disable-strong-random.
Original patch by Magnus Hagander, tons of further work by Michael Paquier
and me.
Discussion: https://www.postgresql.org/message-id/CAB7nPqRy3krN8quR9XujMVVHYtXJ0_60nqgVc6oUk8ygyVkZsA@mail.gmail.com
Discussion: https://www.postgresql.org/message-id/CAB7nPqRWkNYRRPJA7-cF+LfroYV10pvjdz6GNvxk-Eee9FypKA@mail.gmail.com
2016-12-05 12:42:59 +01:00
|
|
|
|
2010-12-11 01:42:44 +01:00
|
|
|
/* port/pgcheckdir.c */
|
|
|
|
extern int pg_check_dir(const char *dir);
|
|
|
|
|
|
|
|
/* port/pgmkdirp.c */
|
|
|
|
extern int pg_mkdir_p(char *path, int omode);
|
|
|
|
|
2013-03-17 17:06:42 +01:00
|
|
|
/* port/pqsignal.c */
|
2022-09-14 20:44:45 +02:00
|
|
|
typedef void (*pqsigfunc) (SIGNAL_ARGS);
|
2013-03-17 17:06:42 +01:00
|
|
|
extern pqsigfunc pqsignal(int signo, pqsigfunc func);
|
|
|
|
|
2013-01-05 15:40:19 +01:00
|
|
|
/* port/quotes.c */
|
|
|
|
extern char *escape_single_quotes_ascii(const char *src);
|
|
|
|
|
2019-01-23 12:39:00 +01:00
|
|
|
/* common/wait_error.c */
|
2022-09-20 22:09:30 +02:00
|
|
|
extern char *wait_result_to_str(int exitstatus);
|
Improve detection of child-process SIGPIPE failures.
Commit ffa4cbd62 added logic to detect SIGPIPE failure of a COPY child
process, but it only worked correctly if the SIGPIPE occurred in the
immediate child process. Depending on the shell in use and the
complexity of the shell command string, we might instead get back
an exit code of 128 + SIGPIPE, representing a shell error exit
reporting SIGPIPE in the child process.
We could just hack up ClosePipeToProgram() to add the extra case,
but it seems like this is a fairly general issue deserving a more
general and better-documented solution. I chose to add a couple
of functions in src/common/wait_error.c, which is a natural place
to know about wait-result encodings, that will test for either a
specific child-process signal type or any child-process signal failure.
Then, adjust other places that were doing ad-hoc tests of this type
to use the common functions.
In RestoreArchivedFile, this fixes a race condition affecting whether
the process will report an error or just silently proc_exit(1): before,
that depended on whether the intermediate shell got SIGTERM'd itself
or reported a child process failing on SIGTERM.
Like the previous patch, back-patch to v10; we could go further
but there seems no real need to.
Per report from Erik Rijkers.
Discussion: https://postgr.es/m/f3683f87ab1701bea5d86a7742b22432@xs4all.nl
2018-12-16 20:32:14 +01:00
|
|
|
extern bool wait_result_is_signal(int exit_status, int signum);
|
|
|
|
extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_found);
|
2023-03-21 18:03:42 +01:00
|
|
|
extern int wait_result_to_exit_code(int exit_status);
|
Add support for piping COPY to/from an external program.
This includes backend "COPY TO/FROM PROGRAM '...'" syntax, and corresponding
psql \copy syntax. Like with reading/writing files, the backend version is
superuser-only, and in the psql version, the program is run in the client.
In the passing, the psql \copy STDIN/STDOUT syntax is subtly changed: if you
the stdin/stdout is quoted, it's now interpreted as a filename. For example,
"\copy foo from 'stdin'" now reads from a file called 'stdin', not from
standard input. Before this, there was no way to specify a filename called
stdin, stdout, pstdin or pstdout.
This creates a new function in pgport, wait_result_to_str(), which can
be used to convert the exit status of a process, as returned by wait(3),
to a human-readable string.
Etsuro Fujita, reviewed by Amit Kapila.
2013-02-27 17:17:21 +01:00
|
|
|
|
2022-08-04 23:18:34 +02:00
|
|
|
/*
|
|
|
|
* Interfaces that we assume all Unix system have. We retain individual macros
|
|
|
|
* for better documentation.
|
2022-08-04 23:22:56 +02:00
|
|
|
*
|
|
|
|
* For symlink-related functions, there is often no need to test these macros,
|
|
|
|
* because we provided basic support on Windows that can work with absolute
|
|
|
|
* paths to directories. Code that wants to test for complete symlink support
|
|
|
|
* (including relative paths and non-directories) should be conditional on
|
|
|
|
* HAVE_READLINK or HAVE_SYMLINK.
|
2022-08-04 23:18:34 +02:00
|
|
|
*/
|
|
|
|
#ifndef WIN32
|
|
|
|
#define HAVE_GETRLIMIT 1
|
2022-08-04 23:37:53 +02:00
|
|
|
#define HAVE_POLL 1
|
|
|
|
#define HAVE_POLL_H 1
|
2022-08-04 23:22:56 +02:00
|
|
|
#define HAVE_READLINK 1
|
2022-08-04 23:21:51 +02:00
|
|
|
#define HAVE_SETSID 1
|
2022-08-04 23:19:36 +02:00
|
|
|
#define HAVE_SHM_OPEN 1
|
2022-08-04 23:22:56 +02:00
|
|
|
#define HAVE_SYMLINK 1
|
2022-08-04 23:18:34 +02:00
|
|
|
#endif
|
|
|
|
|
2006-10-04 00:18:23 +02:00
|
|
|
#endif /* PG_PORT_H */
|