Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit cf14789

Browse files
committed
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).
1 parent e9edb3e commit cf14789

File tree

9 files changed

+210
-180
lines changed

9 files changed

+210
-180
lines changed

src/backend/postmaster/postmaster.c

Lines changed: 68 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.103 1999/02/21 01:41:43 tgl Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.104 1999/05/22 17:47:50 tgl Exp $
1414
*
1515
* NOTES
1616
*
@@ -191,7 +191,7 @@ static int ServerSock_UNIX = INVALID_SOCK; /* stream socket server */
191191
/*
192192
* Set by the -o option
193193
*/
194-
static char ExtraOptions[ARGV_SIZE] = "";
194+
static char ExtraOptions[MAXPATHLEN] = "";
195195

196196
/*
197197
* These globals control the behavior of the postmaster in case some
@@ -1398,7 +1398,9 @@ BackendStartup(Port *port)
13981398
}
13991399

14001400
/*
1401-
* split_opts -- destructively load a string into an argv array
1401+
* split_opts -- split a string of options and append it to an argv array
1402+
*
1403+
* NB: the string is destructively modified!
14021404
*
14031405
* Since no current POSTGRES arguments require any quoting characters,
14041406
* 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)
14161418
{
14171419
while (isspace(*s))
14181420
++s;
1419-
if (*s)
1420-
argv[i++] = s;
1421+
if (*s == '\0')
1422+
break;
1423+
argv[i++] = s;
14211424
while (*s && !isspace(*s))
14221425
++s;
1423-
if (isspace(*s))
1426+
if (*s)
14241427
*s++ = '\0';
14251428
}
1429+
14261430
*argcp = i;
14271431
}
14281432

14291433
/*
1430-
* DoBackend -- set up the argument list and perform an execv system call
1434+
* DoBackend -- set up the backend's argument list and invoke backend main().
1435+
*
1436+
* This used to perform an execv() but we no longer exec the backend;
1437+
* it's the same executable as the postmaster.
14311438
*
14321439
* returns:
14331440
* Shouldn't return at all.
1434-
* If execv() fails, return status.
1441+
* If PostgresMain() fails, return status.
14351442
*/
14361443
static int
14371444
DoBackend(Port *port)
14381445
{
1446+
char *av[ARGV_SIZE * 2];
1447+
int ac = 0;
14391448
char execbuf[MAXPATHLEN];
1440-
char portbuf[ARGV_SIZE];
14411449
char debugbuf[ARGV_SIZE];
1442-
char ttybuf[ARGV_SIZE + 1];
1443-
char protobuf[ARGV_SIZE + 1];
1444-
char argbuf[(2 * ARGV_SIZE) + 1];
1445-
1446-
/*
1447-
* each argument takes at least three chars, so we can't have more
1448-
* than ARGV_SIZE arguments in (2 * ARGV_SIZE) chars (i.e.,
1449-
* port->options plus ExtraOptions)...
1450-
*/
1451-
char *av[ARGV_SIZE];
1452-
char dbbuf[ARGV_SIZE + 1];
1453-
int ac = 0;
1450+
char protobuf[ARGV_SIZE];
1451+
char dbbuf[ARGV_SIZE];
1452+
char optbuf[ARGV_SIZE];
1453+
char ttybuf[ARGV_SIZE];
14541454
int i;
14551455
struct timeval now;
14561456
struct timezone tz;
@@ -1491,9 +1491,11 @@ DoBackend(Port *port)
14911491
StreamClose(ServerSock_UNIX);
14921492
#endif
14931493

1494-
/* Save port for ps status */
1494+
/* Save port etc. for ps status */
14951495
MyProcPort = port;
14961496

1497+
MyProcPid = getpid();
1498+
14971499
/*
14981500
* Don't want backend to be able to see the postmaster random number
14991501
* generator state. We have to clobber the static random_seed *and*
@@ -1503,11 +1505,16 @@ DoBackend(Port *port)
15031505
gettimeofday(&now, &tz);
15041506
srandom(now.tv_usec);
15051507

1506-
/* Now, on to standard postgres stuff */
1507-
1508-
MyProcPid = getpid();
1508+
/* ----------------
1509+
* Now, build the argv vector that will be given to PostgresMain.
1510+
*
1511+
* The layout of the command line is
1512+
* postgres [secure switches] -p databasename [insecure switches]
1513+
* where the switches after -p come from the client request.
1514+
* ----------------
1515+
*/
15091516

1510-
strncpy(execbuf, Execfile, MAXPATHLEN - 1);
1517+
StrNCpy(execbuf, Execfile, MAXPATHLEN);
15111518
av[ac++] = execbuf;
15121519

15131520
/*
@@ -1528,56 +1535,69 @@ DoBackend(Port *port)
15281535
real_argv[0] = Execfile;
15291536
#endif
15301537

1531-
/* Tell the backend it is being called from the postmaster */
1532-
av[ac++] = "-p";
1533-
15341538
/*
15351539
* Pass the requested debugging level along to the backend. We
15361540
* decrement by one; level one debugging in the postmaster traces
15371541
* postmaster connection activity, and levels two and higher are
15381542
* passed along to the backend. This allows us to watch only the
15391543
* postmaster or the postmaster and the backend.
15401544
*/
1541-
15421545
if (DebugLvl > 1)
15431546
{
15441547
sprintf(debugbuf, "-d%d", DebugLvl);
15451548
av[ac++] = debugbuf;
15461549
}
15471550

1548-
/* Pass the requested debugging output file */
1549-
if (port->tty[0])
1550-
{
1551-
strncpy(ttybuf, port->tty, ARGV_SIZE);
1552-
av[ac++] = "-o";
1553-
av[ac++] = ttybuf;
1554-
}
1555-
1556-
/* Tell the backend the descriptor of the fe/be socket */
1557-
sprintf(portbuf, "-P%d", port->sock);
1558-
av[ac++] = portbuf;
1559-
1560-
StrNCpy(argbuf, port->options, ARGV_SIZE);
1561-
strncat(argbuf, ExtraOptions, ARGV_SIZE);
1562-
argbuf[(2 * ARGV_SIZE)] = '\0';
1563-
split_opts(av, &ac, argbuf);
1551+
/*
1552+
* Pass any backend switches specified with -o in the postmaster's
1553+
* own command line. We assume these are secure.
1554+
* (It's OK to mangle ExtraOptions since we are now in the child process;
1555+
* this won't change the postmaster's copy.)
1556+
*/
1557+
split_opts(av, &ac, ExtraOptions);
15641558

15651559
/* Tell the backend what protocol the frontend is using. */
1566-
15671560
sprintf(protobuf, "-v%u", port->proto);
15681561
av[ac++] = protobuf;
15691562

1563+
/*
1564+
* Tell the backend it is being called from the postmaster,
1565+
* and which database to use. -p marks the end of secure switches.
1566+
*/
1567+
av[ac++] = "-p";
1568+
15701569
StrNCpy(dbbuf, port->database, ARGV_SIZE);
15711570
av[ac++] = dbbuf;
15721571

1572+
/*
1573+
* Pass the (insecure) option switches from the connection request.
1574+
*/
1575+
StrNCpy(optbuf, port->options, ARGV_SIZE);
1576+
split_opts(av, &ac, optbuf);
1577+
1578+
/*
1579+
* Pass the (insecure) debug output file request.
1580+
*
1581+
* NOTE: currently, this is useless code, since the backend will not
1582+
* honor an insecure -o switch. I left it here since the backend
1583+
* could be modified to allow insecure -o, given adequate checking
1584+
* that the specified filename is something safe to write on.
1585+
*/
1586+
if (port->tty[0])
1587+
{
1588+
StrNCpy(ttybuf, port->tty, ARGV_SIZE);
1589+
av[ac++] = "-o";
1590+
av[ac++] = ttybuf;
1591+
}
1592+
15731593
av[ac] = (char *) NULL;
15741594

15751595
if (DebugLvl > 1)
15761596
{
15771597
fprintf(stderr, "%s child[%d]: starting with (",
15781598
progname, MyProcPid);
15791599
for (i = 0; i < ac; ++i)
1580-
fprintf(stderr, "%s, ", av[i]);
1600+
fprintf(stderr, "%s ", av[i]);
15811601
fprintf(stderr, ")\n");
15821602
}
15831603

0 commit comments

Comments
 (0)