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

Commit 0fba3be

Browse files
committed
Simplify validate_exec() by using access(2) to check file permissions,
rather than trying to implement the equivalent logic by hand. The motivation for the original coding appears to have been to check with the effective uid's permissions not the real uid's; but there is no longer any difference, because we don't run the postmaster setuid (indeed, main.c enforces that they're the same). Using access() means we will get it right in situations the original coding failed to handle, such as ACL-based permissions. Besides it's a lot shorter, cleaner, and more thread-safe. Per bug #5275 from James Bellinger.
1 parent 715120e commit 0fba3be

File tree

1 file changed

+8
-78
lines changed

1 file changed

+8
-78
lines changed

src/port/exec.c

+8-78
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/port/exec.c,v 1.66 2010/01/02 16:58:13 momjian Exp $
12+
* $PostgreSQL: pgsql/src/port/exec.c,v 1.67 2010/01/14 00:14:06 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -20,25 +20,11 @@
2020
#include "postgres_fe.h"
2121
#endif
2222

23-
#include <grp.h>
24-
#include <pwd.h>
2523
#include <signal.h>
2624
#include <sys/stat.h>
2725
#include <sys/wait.h>
2826
#include <unistd.h>
2927

30-
#ifndef S_IRUSR /* XXX [TRH] should be in a header */
31-
#define S_IRUSR S_IREAD
32-
#define S_IWUSR S_IWRITE
33-
#define S_IXUSR S_IEXEC
34-
#define S_IRGRP ((S_IRUSR)>>3)
35-
#define S_IWGRP ((S_IWUSR)>>3)
36-
#define S_IXGRP ((S_IXUSR)>>3)
37-
#define S_IROTH ((S_IRUSR)>>6)
38-
#define S_IWOTH ((S_IWUSR)>>6)
39-
#define S_IXOTH ((S_IXUSR)>>6)
40-
#endif
41-
4228
#ifndef FRONTEND
4329
/* We use only 3-parameter elog calls in this file, for simplicity */
4430
/* NOTE: caller must provide gettext call around str! */
@@ -70,20 +56,12 @@ static int
7056
validate_exec(const char *path)
7157
{
7258
struct stat buf;
73-
74-
#ifndef WIN32
75-
uid_t euid;
76-
struct group *gp;
77-
struct passwd *pwp;
78-
int i;
79-
int in_grp = 0;
80-
#else
81-
char path_exe[MAXPGPATH + sizeof(".exe") - 1];
82-
#endif
8359
int is_r;
8460
int is_x;
8561

8662
#ifdef WIN32
63+
char path_exe[MAXPGPATH + sizeof(".exe") - 1];
64+
8765
/* Win32 requires a .exe suffix for stat() */
8866
if (strlen(path) >= strlen(".exe") &&
8967
pg_strcasecmp(path + strlen(path) - strlen(".exe"), ".exe") != 0)
@@ -106,62 +84,18 @@ validate_exec(const char *path)
10684
if (!S_ISREG(buf.st_mode))
10785
return -1;
10886

109-
/*
110-
* Ensure that we are using an authorized executable.
111-
*/
112-
11387
/*
11488
* Ensure that the file is both executable and readable (required for
11589
* dynamic loading).
11690
*/
117-
#ifdef WIN32
91+
#ifndef WIN32
92+
is_r = (access(path, R_OK) == 0);
93+
is_x = (access(path, X_OK) == 0);
94+
#else
11895
is_r = buf.st_mode & S_IRUSR;
11996
is_x = buf.st_mode & S_IXUSR;
120-
return is_x ? (is_r ? 0 : -2) : -1;
121-
#else
122-
euid = geteuid();
123-
124-
/* If owned by us, just check owner bits */
125-
if (euid == buf.st_uid)
126-
{
127-
is_r = buf.st_mode & S_IRUSR;
128-
is_x = buf.st_mode & S_IXUSR;
129-
return is_x ? (is_r ? 0 : -2) : -1;
130-
}
131-
132-
/* OK, check group bits */
133-
134-
pwp = getpwuid(euid); /* not thread-safe */
135-
if (pwp)
136-
{
137-
if (pwp->pw_gid == buf.st_gid) /* my primary group? */
138-
++in_grp;
139-
else if (pwp->pw_name &&
140-
(gp = getgrgid(buf.st_gid)) != NULL && /* not thread-safe */
141-
gp->gr_mem != NULL)
142-
{ /* try list of member groups */
143-
for (i = 0; gp->gr_mem[i]; ++i)
144-
{
145-
if (!strcmp(gp->gr_mem[i], pwp->pw_name))
146-
{
147-
++in_grp;
148-
break;
149-
}
150-
}
151-
}
152-
if (in_grp)
153-
{
154-
is_r = buf.st_mode & S_IRGRP;
155-
is_x = buf.st_mode & S_IXGRP;
156-
return is_x ? (is_r ? 0 : -2) : -1;
157-
}
158-
}
159-
160-
/* Check "other" bits */
161-
is_r = buf.st_mode & S_IROTH;
162-
is_x = buf.st_mode & S_IXOTH;
163-
return is_x ? (is_r ? 0 : -2) : -1;
16497
#endif
98+
return is_x ? (is_r ? 0 : -2) : -1;
16599
}
166100

167101

@@ -178,10 +112,6 @@ validate_exec(const char *path)
178112
* path because we will later change working directory. Finally, we want
179113
* a true path not a symlink location, so that we can locate other files
180114
* that are part of our installation relative to the executable.
181-
*
182-
* This function is not thread-safe because it calls validate_exec(),
183-
* which calls getgrgid(). This function should be used only in
184-
* non-threaded binaries, not in library routines.
185115
*/
186116
int
187117
find_my_exec(const char *argv0, char *retpath)

0 commit comments

Comments
 (0)