Commit cf147898 authored by Tom Lane's avatar Tom Lane

Modify backend switch parsing to prevent 'insecure' switches

from being accepted when they are passed from client connection request.
Get rid of a couple that no longer do anything (like -P).
parent e9edb3ef
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.103 1999/02/21 01:41:43 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.104 1999/05/22 17:47:50 tgl Exp $
* *
* NOTES * NOTES
* *
...@@ -191,7 +191,7 @@ static int ServerSock_UNIX = INVALID_SOCK; /* stream socket server */ ...@@ -191,7 +191,7 @@ static int ServerSock_UNIX = INVALID_SOCK; /* stream socket server */
/* /*
* Set by the -o option * Set by the -o option
*/ */
static char ExtraOptions[ARGV_SIZE] = ""; static char ExtraOptions[MAXPATHLEN] = "";
/* /*
* These globals control the behavior of the postmaster in case some * These globals control the behavior of the postmaster in case some
...@@ -1398,7 +1398,9 @@ BackendStartup(Port *port) ...@@ -1398,7 +1398,9 @@ BackendStartup(Port *port)
} }
/* /*
* split_opts -- destructively load a string into an argv array * split_opts -- split a string of options and append it to an argv array
*
* NB: the string is destructively modified!
* *
* Since no current POSTGRES arguments require any quoting characters, * Since no current POSTGRES arguments require any quoting characters,
* we can use the simple-minded tactic of assuming each set of space- * we can use the simple-minded tactic of assuming each set of space-
...@@ -1416,41 +1418,39 @@ split_opts(char **argv, int *argcp, char *s) ...@@ -1416,41 +1418,39 @@ split_opts(char **argv, int *argcp, char *s)
{ {
while (isspace(*s)) while (isspace(*s))
++s; ++s;
if (*s) if (*s == '\0')
argv[i++] = s; break;
argv[i++] = s;
while (*s && !isspace(*s)) while (*s && !isspace(*s))
++s; ++s;
if (isspace(*s)) if (*s)
*s++ = '\0'; *s++ = '\0';
} }
*argcp = i; *argcp = i;
} }
/* /*
* DoBackend -- set up the argument list and perform an execv system call * DoBackend -- set up the backend's argument list and invoke backend main().
*
* This used to perform an execv() but we no longer exec the backend;
* it's the same executable as the postmaster.
* *
* returns: * returns:
* Shouldn't return at all. * Shouldn't return at all.
* If execv() fails, return status. * If PostgresMain() fails, return status.
*/ */
static int static int
DoBackend(Port *port) DoBackend(Port *port)
{ {
char *av[ARGV_SIZE * 2];
int ac = 0;
char execbuf[MAXPATHLEN]; char execbuf[MAXPATHLEN];
char portbuf[ARGV_SIZE];
char debugbuf[ARGV_SIZE]; char debugbuf[ARGV_SIZE];
char ttybuf[ARGV_SIZE + 1]; char protobuf[ARGV_SIZE];
char protobuf[ARGV_SIZE + 1]; char dbbuf[ARGV_SIZE];
char argbuf[(2 * ARGV_SIZE) + 1]; char optbuf[ARGV_SIZE];
char ttybuf[ARGV_SIZE];
/*
* each argument takes at least three chars, so we can't have more
* than ARGV_SIZE arguments in (2 * ARGV_SIZE) chars (i.e.,
* port->options plus ExtraOptions)...
*/
char *av[ARGV_SIZE];
char dbbuf[ARGV_SIZE + 1];
int ac = 0;
int i; int i;
struct timeval now; struct timeval now;
struct timezone tz; struct timezone tz;
...@@ -1491,9 +1491,11 @@ DoBackend(Port *port) ...@@ -1491,9 +1491,11 @@ DoBackend(Port *port)
StreamClose(ServerSock_UNIX); StreamClose(ServerSock_UNIX);
#endif #endif
/* Save port for ps status */ /* Save port etc. for ps status */
MyProcPort = port; MyProcPort = port;
MyProcPid = getpid();
/* /*
* Don't want backend to be able to see the postmaster random number * Don't want backend to be able to see the postmaster random number
* generator state. We have to clobber the static random_seed *and* * generator state. We have to clobber the static random_seed *and*
...@@ -1503,11 +1505,16 @@ DoBackend(Port *port) ...@@ -1503,11 +1505,16 @@ DoBackend(Port *port)
gettimeofday(&now, &tz); gettimeofday(&now, &tz);
srandom(now.tv_usec); srandom(now.tv_usec);
/* Now, on to standard postgres stuff */ /* ----------------
* Now, build the argv vector that will be given to PostgresMain.
MyProcPid = getpid(); *
* The layout of the command line is
* postgres [secure switches] -p databasename [insecure switches]
* where the switches after -p come from the client request.
* ----------------
*/
strncpy(execbuf, Execfile, MAXPATHLEN - 1); StrNCpy(execbuf, Execfile, MAXPATHLEN);
av[ac++] = execbuf; av[ac++] = execbuf;
/* /*
...@@ -1528,9 +1535,6 @@ DoBackend(Port *port) ...@@ -1528,9 +1535,6 @@ DoBackend(Port *port)
real_argv[0] = Execfile; real_argv[0] = Execfile;
#endif #endif
/* Tell the backend it is being called from the postmaster */
av[ac++] = "-p";
/* /*
* Pass the requested debugging level along to the backend. We * Pass the requested debugging level along to the backend. We
* decrement by one; level one debugging in the postmaster traces * decrement by one; level one debugging in the postmaster traces
...@@ -1538,38 +1542,54 @@ DoBackend(Port *port) ...@@ -1538,38 +1542,54 @@ DoBackend(Port *port)
* passed along to the backend. This allows us to watch only the * passed along to the backend. This allows us to watch only the
* postmaster or the postmaster and the backend. * postmaster or the postmaster and the backend.
*/ */
if (DebugLvl > 1) if (DebugLvl > 1)
{ {
sprintf(debugbuf, "-d%d", DebugLvl); sprintf(debugbuf, "-d%d", DebugLvl);
av[ac++] = debugbuf; av[ac++] = debugbuf;
} }
/* Pass the requested debugging output file */ /*
if (port->tty[0]) * Pass any backend switches specified with -o in the postmaster's
{ * own command line. We assume these are secure.
strncpy(ttybuf, port->tty, ARGV_SIZE); * (It's OK to mangle ExtraOptions since we are now in the child process;
av[ac++] = "-o"; * this won't change the postmaster's copy.)
av[ac++] = ttybuf; */
} split_opts(av, &ac, ExtraOptions);
/* Tell the backend the descriptor of the fe/be socket */
sprintf(portbuf, "-P%d", port->sock);
av[ac++] = portbuf;
StrNCpy(argbuf, port->options, ARGV_SIZE);
strncat(argbuf, ExtraOptions, ARGV_SIZE);
argbuf[(2 * ARGV_SIZE)] = '\0';
split_opts(av, &ac, argbuf);
/* Tell the backend what protocol the frontend is using. */ /* Tell the backend what protocol the frontend is using. */
sprintf(protobuf, "-v%u", port->proto); sprintf(protobuf, "-v%u", port->proto);
av[ac++] = protobuf; av[ac++] = protobuf;
/*
* Tell the backend it is being called from the postmaster,
* and which database to use. -p marks the end of secure switches.
*/
av[ac++] = "-p";
StrNCpy(dbbuf, port->database, ARGV_SIZE); StrNCpy(dbbuf, port->database, ARGV_SIZE);
av[ac++] = dbbuf; av[ac++] = dbbuf;
/*
* Pass the (insecure) option switches from the connection request.
*/
StrNCpy(optbuf, port->options, ARGV_SIZE);
split_opts(av, &ac, optbuf);
/*
* Pass the (insecure) debug output file request.
*
* NOTE: currently, this is useless code, since the backend will not
* honor an insecure -o switch. I left it here since the backend
* could be modified to allow insecure -o, given adequate checking
* that the specified filename is something safe to write on.
*/
if (port->tty[0])
{
StrNCpy(ttybuf, port->tty, ARGV_SIZE);
av[ac++] = "-o";
av[ac++] = ttybuf;
}
av[ac] = (char *) NULL; av[ac] = (char *) NULL;
if (DebugLvl > 1) if (DebugLvl > 1)
...@@ -1577,7 +1597,7 @@ DoBackend(Port *port) ...@@ -1577,7 +1597,7 @@ DoBackend(Port *port)
fprintf(stderr, "%s child[%d]: starting with (", fprintf(stderr, "%s child[%d]: starting with (",
progname, MyProcPid); progname, MyProcPid);
for (i = 0; i < ac; ++i) for (i = 0; i < ac; ++i)
fprintf(stderr, "%s, ", av[i]); fprintf(stderr, "%s ", av[i]);
fprintf(stderr, ")\n"); fprintf(stderr, ")\n");
} }
......
This diff is collapsed.
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.28 1999/03/17 22:53:19 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.29 1999/05/22 17:47:46 tgl Exp $
* *
* NOTES * NOTES
* Globals used all over the place should be declared here and not * Globals used all over the place should be declared here and not
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
#include "catalog/catname.h" #include "catalog/catname.h"
ProtocolVersion FrontendProtocol = PG_PROTOCOL_LATEST; ProtocolVersion FrontendProtocol = PG_PROTOCOL_LATEST;
int Portfd = -1;
bool Noversion = false; bool Noversion = false;
bool Quiet = false; bool Quiet = false;
...@@ -47,11 +46,11 @@ struct Port *MyProcPort; ...@@ -47,11 +46,11 @@ struct Port *MyProcPort;
long MyCancelKey; long MyCancelKey;
char *DataDir = NULL; char *DataDir = NULL;
/* /*
* The PGDATA directory user says to use, or defaults to via environment * The PGDATA directory user says to use, or defaults to via environment
* variable. NULL if no option given and no environment variable set * variable. NULL if no option given and no environment variable set
*/ */
Relation reldesc; /* current relation descriptor */ Relation reldesc; /* current relation descriptor */
char OutputFileName[MAXPGPATH] = ""; char OutputFileName[MAXPGPATH] = "";
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.27 1999/05/09 00:54:30 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.28 1999/05/22 17:47:46 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "utils/syscache.h" #include "utils/syscache.h"
#include "storage/fd.h" /* for O_ */ #include "storage/fd.h" /* for O_ */
#include "storage/ipc.h" /* for proc_exit */
/* /*
* EnableAbortEnvVarName * EnableAbortEnvVarName
......
...@@ -257,9 +257,13 @@ set_option_flag(int flag, int value) ...@@ -257,9 +257,13 @@ set_option_flag(int flag, int value)
/* /*
* Parse an option string like "name,name+,name-,name=value". * Parse an option string like "name,name+,name-,name=value".
* Single options are delimited by ',',space,tab,newline or cr. * Single options are delimited by ',',space,tab,newline or cr.
*
* If 'secure' is false, the option string came from a remote client via
* connection "debug options" field --- do not obey any requests that
* might potentially be security loopholes.
*/ */
void void
parse_options(char *str) parse_options(char *str, bool secure)
{ {
char *s, char *s,
*name; *name;
...@@ -384,7 +388,7 @@ read_pg_options(SIGNAL_ARGS) ...@@ -384,7 +388,7 @@ read_pg_options(SIGNAL_ARGS)
p--; p--;
*p = '\0'; *p = '\0';
verbose = pg_options[TRACE_VERBOSE]; verbose = pg_options[TRACE_VERBOSE];
parse_options(buffer); parse_options(buffer, true);
verbose |= pg_options[TRACE_VERBOSE]; verbose |= pg_options[TRACE_VERBOSE];
if (verbose || postgres_signal_arg == SIGHUP) if (verbose || postgres_signal_arg == SIGHUP)
tprintf(TRACE_ALL, "read_pg_options: %s", buffer); tprintf(TRACE_ALL, "read_pg_options: %s", buffer);
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: miscadmin.h,v 1.37 1999/05/03 19:10:09 momjian Exp $ * $Id: miscadmin.h,v 1.38 1999/05/22 17:47:47 tgl Exp $
* *
* NOTES * NOTES
* some of the information in this file will be moved to * some of the information in this file will be moved to
...@@ -34,7 +34,6 @@ extern int PostmasterMain(int argc, char *argv[]); ...@@ -34,7 +34,6 @@ extern int PostmasterMain(int argc, char *argv[]);
/* /*
* from utils/init/globals.c * from utils/init/globals.c
*/ */
extern int Portfd;
extern bool Noversion; extern bool Noversion;
extern bool Quiet; extern bool Quiet;
extern bool QueryCancel; extern bool QueryCancel;
......
...@@ -33,7 +33,7 @@ extern int eprintf(const char *fmt,...); ...@@ -33,7 +33,7 @@ extern int eprintf(const char *fmt,...);
extern int option_flag(int flag); extern int option_flag(int flag);
extern int set_option_flag(int flag, int value); extern int set_option_flag(int flag, int value);
extern void write_syslog(int level, char *line); extern void write_syslog(int level, char *line);
extern void parse_options(char *str); extern void parse_options(char *str, bool secure);
extern void read_pg_options(SIGNAL_ARGS); extern void read_pg_options(SIGNAL_ARGS);
/* /*
......
.\" This is -*-nroff-*- .\" This is -*-nroff-*-
.\" XXX standard disclaimer belongs here.... .\" XXX standard disclaimer belongs here....
.\" $Header: /cvsroot/pgsql/src/man/Attic/postgres.1,v 1.15 1999/05/19 23:30:43 tgl Exp $ .\" $Header: /cvsroot/pgsql/src/man/Attic/postgres.1,v 1.16 1999/05/22 17:47:47 tgl Exp $
.TH POSTGRESQL UNIX 05/19/99 PostgreSQL PostgreSQL .TH POSTGRESQL UNIX 05/19/99 PostgreSQL PostgreSQL
.SH NAME .SH NAME
postgres - the Postgres backend server postgres - the Postgres backend server
...@@ -25,13 +25,10 @@ data_directory] ...@@ -25,13 +25,10 @@ data_directory]
.BR "-O" .BR "-O"
] ]
[\c [\c
.BR "-P"
filedes]
[\c
.BR "-Q" .BR "-Q"
] ]
[\c [\c
.BR "-S n_buffers" .BR "-S kbytes"
] ]
[\c [\c
.BR "-d" .BR "-d"
...@@ -111,17 +108,10 @@ while a transaction is in progress will probably cause data loss. ...@@ -111,17 +108,10 @@ while a transaction is in progress will probably cause data loss.
.BR "-O" .BR "-O"
Override restrictions, so system table structures can be modified(pg_*). Override restrictions, so system table structures can be modified(pg_*).
.TP .TP
.BR "-P" " filedes"
.IR "filedes"
specifies the file descriptor that corresponds to the socket (port) on
which to communicate to the frontend process. This option is
.BR not
useful for interactive use.
.TP
.BR "-Q" .BR "-Q"
Specifies \*(lqquiet\*(rq mode. Specifies \*(lqquiet\*(rq mode.
.TP .TP
.BR "-S" .BR "-S" " kbytes"
Specifies the amount of memory to be used by internal sorts and hashes Specifies the amount of memory to be used by internal sorts and hashes
before resorting to temporary disk files. The value is specified in before resorting to temporary disk files. The value is specified in
kilobytes, and defaults to 512 kilobytes. Note that for a complex query, kilobytes, and defaults to 512 kilobytes. Note that for a complex query,
...@@ -201,11 +191,12 @@ plan types if it has any other alternative.) ...@@ -201,11 +191,12 @@ plan types if it has any other alternative.)
.BR "-i" .BR "-i"
Prevents query execution, but shows the plan tree. Prevents query execution, but shows the plan tree.
.TP .TP
.BR "-p" .BR "-p" " databasename"
Indicates to the backend server that it has been started by a Indicates to the backend server that it has been started by a
.IR postmaster .IR postmaster
and make different assumptions about buffer pool management, file and make different assumptions about buffer pool management, file
descriptors, etc. descriptors, etc. Switches following -p are restricted to those
considered "secure".
.TP .TP
.BR "-t" "pa[rser]|pl[anner]|e[xecutor]" .BR "-t" "pa[rser]|pl[anner]|e[xecutor]"
Print timing statistics for each query relating to each of the major Print timing statistics for each query relating to each of the major
......
.\" This is -*-nroff-*- .\" This is -*-nroff-*-
.\" XXX standard disclaimer belongs here.... .\" XXX standard disclaimer belongs here....
.\" $Header: /cvsroot/pgsql/src/man/Attic/postmaster.1,v 1.16 1999/05/19 23:30:43 tgl Exp $ .\" $Header: /cvsroot/pgsql/src/man/Attic/postmaster.1,v 1.17 1999/05/22 17:47:48 tgl Exp $
.TH POSTMASTER UNIX 05/19/99 PostgreSQL PostgreSQL .TH POSTMASTER UNIX 05/19/99 PostgreSQL PostgreSQL
.SH "NAME" .SH "NAME"
postmaster - run the Postgres postmaster postmaster - run the Postgres postmaster
...@@ -90,7 +90,7 @@ set at compile-time is used. ...@@ -90,7 +90,7 @@ set at compile-time is used.
.IR "n_backends" .IR "n_backends"
is the maximum number of backend server processes that this postmaster is the maximum number of backend server processes that this postmaster
is allowed to start. In the stock configuration, this value defaults is allowed to start. In the stock configuration, this value defaults
to 64, and can be set as high as 1024 if your system will support that to 32, and can be set as high as 1024 if your system will support that
many processes. Both the default and upper limit values can be altered many processes. Both the default and upper limit values can be altered
when building Postgres (see src/include/config.h). when building Postgres (see src/include/config.h).
.TP .TP
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment