Lines 8-10
Link Here
|
8 |
#include <sys/socket.h> |
8 |
#include <sys/socket.h> |
9 |
#include <sys/un.h> |
9 |
#include <sys/un.h> |
10 |
|
10 |
|
|
|
11 |
--- ./fcgiwrap.c.orig 2013-02-03 22:25:17.000000000 +0900 |
12 |
+++ ./fcgiwrap.c 2014-01-09 20:10:43.000000000 +0900 |
13 |
@@ -58,6 +58,8 @@ |
14 |
|
15 |
extern char **environ; |
16 |
static char * const * inherited_environ; |
17 |
+static const char **allowed_programs; |
18 |
+static size_t allowed_programs_count; |
19 |
|
20 |
static const char * blacklisted_env_vars[] = { |
21 |
"AUTH_TYPE", |
22 |
@@ -485,6 +487,19 @@ |
23 |
} |
24 |
} |
25 |
|
26 |
+static bool is_allowed_program(const char *program) { |
27 |
+ size_t i; |
28 |
+ if (!allowed_programs_count) |
29 |
+ return true; |
30 |
+ |
31 |
+ for (i = 0; i < allowed_programs_count; i++) { |
32 |
+ if (!strcmp(allowed_programs[i], program)) |
33 |
+ return true; |
34 |
+ } |
35 |
+ |
36 |
+ return false; |
37 |
+} |
38 |
+ |
39 |
static void cgi_error(const char *message, const char *reason, const char *filename) |
40 |
{ |
41 |
printf("Status: %s\r\nContent-Type: text/plain\r\n\r\n%s\r\n", |
42 |
@@ -541,6 +556,9 @@ |
43 |
if (!filename) |
44 |
cgi_error("403 Forbidden", "Cannot get script name, are DOCUMENT_ROOT and SCRIPT_NAME (or SCRIPT_FILENAME) set and is the script executable?", NULL); |
45 |
|
46 |
+ if (!is_allowed_program(filename)) |
47 |
+ cgi_error("403 Forbidden", "The given script is not allowed to execute", filename); |
48 |
+ |
49 |
last_slash = strrchr(filename, '/'); |
50 |
if (!last_slash) |
51 |
cgi_error("403 Forbidden", "Script name must be a fully qualified path", filename); |
52 |
@@ -605,7 +623,7 @@ |
53 |
{ |
54 |
int status; |
55 |
|
56 |
- while ((dummy = waitpid(-1, &status, WNOHANG)) != -1) { |
57 |
+ while ((dummy = waitpid(-1, &status, WNOHANG)) > 0) { |
58 |
/* sanity check */ |
59 |
if (nrunning > 0) |
60 |
nrunning--; |
61 |
@@ -760,7 +778,7 @@ |
62 |
char *socket_url = NULL; |
63 |
int c; |
64 |
|
65 |
- while ((c = getopt(argc, argv, "c:hfs:")) != -1) { |
66 |
+ while ((c = getopt(argc, argv, "c:hfs:p:")) != -1) { |
67 |
switch (c) { |
68 |
case 'f': |
69 |
stderr_to_fastcgi++; |
70 |
@@ -773,6 +791,7 @@ |
71 |
" -c <number>\t\tNumber of processes to prefork\n" |
72 |
" -s <socket_url>\tSocket to bind to (say -s help for help)\n" |
73 |
" -h\t\t\tShow this help message and exit\n" |
74 |
+ " -p <path>\t\tRestrict execution to this script. (repeated options will be merged)\n" |
75 |
"\nReport bugs to Grzegorz Nosek <"PACKAGE_BUGREPORT">.\n" |
76 |
PACKAGE_NAME" home page: <http://nginx.localdomain.pl/wiki/FcgiWrap>\n", |
77 |
argv[0] |
78 |
@@ -784,8 +803,14 @@ |
79 |
case 's': |
80 |
socket_url = strdup(optarg); |
81 |
break; |
82 |
+ case 'p': |
83 |
+ allowed_programs = realloc(allowed_programs, (allowed_programs_count + 1) * sizeof (char *)); |
84 |
+ if (!allowed_programs) |
85 |
+ abort(); |
86 |
+ allowed_programs[allowed_programs_count++] = strdup(optarg); |
87 |
+ break; |
88 |
case '?': |
89 |
- if (optopt == 'c' || optopt == 's') |
90 |
+ if (optopt == 'c' || optopt == 's' || optopt == 'p') |
91 |
fprintf(stderr, "Option -%c requires an argument.\n", optopt); |
92 |
else if (isprint(optopt)) |
93 |
fprintf(stderr, "Unknown option `-%c'.\n", optopt); |