projects
/
openwrt.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
[package] uhttpd: fix a signal related race condition exposed by LuCI on fast machines
[openwrt.git]
/
package
/
uhttpd
/
src
/
uhttpd.c
diff --git
a/package/uhttpd/src/uhttpd.c
b/package/uhttpd/src/uhttpd.c
index
a7db794
..
c6a8b6c
100644
(file)
--- a/
package/uhttpd/src/uhttpd.c
+++ b/
package/uhttpd/src/uhttpd.c
@@
-42,6
+42,11
@@
static void uh_sigterm(int sig)
run = 0;
}
run = 0;
}
+static void uh_sigchld(int sig)
+{
+ while( waitpid(-1, NULL, WNOHANG) > 0 ) { }
+}
+
static void uh_config_parse(const char *path)
{
FILE *c;
static void uh_config_parse(const char *path)
{
FILE *c;
@@
-155,6
+160,7
@@
static int uh_socket_bind(
/* add socket to server fd set */
FD_SET(sock, serv_fds);
/* add socket to server fd set */
FD_SET(sock, serv_fds);
+ fd_cloexec(sock);
*max_fd = max(*max_fd, sock);
bound++;
*max_fd = max(*max_fd, sock);
bound++;
@@
-404,6
+410,9
@@
int main (int argc, char **argv)
struct sigaction sa;
struct config conf;
struct sigaction sa;
struct config conf;
+ /* signal mask */
+ sigset_t ss;
+
/* maximum file descriptor number */
int new_fd, cur_fd, max_fd = 0;
/* maximum file descriptor number */
int new_fd, cur_fd, max_fd = 0;
@@
-413,7
+422,7
@@
int main (int argc, char **argv)
int nofork = 0;
/* args */
int nofork = 0;
/* args */
-
char
opt;
+
int
opt;
char bind[128];
char *port = NULL;
char bind[128];
char *port = NULL;
@@
-426,18
+435,25
@@
int main (int argc, char **argv)
FD_ZERO(&serv_fds);
FD_ZERO(&read_fds);
FD_ZERO(&serv_fds);
FD_ZERO(&read_fds);
- /* handle SIGPIPE, SIG
CHI
LD */
+ /* handle SIGPIPE, SIG
INT, SIGTERM, SIGCH
LD */
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, NULL);
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, NULL);
+
+ sa.sa_handler = uh_sigchld;
sigaction(SIGCHLD, &sa, NULL);
sa.sa_handler = uh_sigterm;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGCHLD, &sa, NULL);
sa.sa_handler = uh_sigterm;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
+ /* defer SIGCHLD */
+ sigemptyset(&ss);
+ sigaddset(&ss, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &ss, NULL);
+
/* prepare addrinfo hints */
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
/* prepare addrinfo hints */
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
@@
-485,7
+501,7
@@
int main (int argc, char **argv)
}
#endif
}
#endif
- while( (opt = getopt(argc, argv, "fC:K:p:s:h:c:l:L:d:r:m:x:")) > 0 )
+ while( (opt = getopt(argc, argv, "fC:K:p:s:h:c:l:L:d:r:m:x:
t:
")) > 0 )
{
switch(opt)
{
{
switch(opt)
{
@@
-593,6
+609,13
@@
int main (int argc, char **argv)
break;
#endif
break;
#endif
+#if defined(HAVE_CGI) || defined(HAVE_LUA)
+ /* script timeout */
+ case 't':
+ conf.script_timeout = atoi(optarg);
+ break;
+#endif
+
/* no fork */
case 'f':
nofork = 1;
/* no fork */
case 'f':
nofork = 1;
@@
-644,6
+667,9
@@
int main (int argc, char **argv)
#endif
#ifdef HAVE_CGI
" -x string URL prefix for CGI handler, default is '/cgi-bin'\n"
#endif
#ifdef HAVE_CGI
" -x string URL prefix for CGI handler, default is '/cgi-bin'\n"
+#endif
+#if defined(HAVE_CGI) || defined(HAVE_LUA)
+ " -t seconds CGI and Lua script timeout in seconds, default is 60\n"
#endif
" -d string URL decode given string\n"
" -r string Specify basic auth realm\n"
#endif
" -d string URL decode given string\n"
" -r string Specify basic auth realm\n"
@@
-684,6
+710,12
@@
int main (int argc, char **argv)
/* config file */
uh_config_parse(conf.file);
/* config file */
uh_config_parse(conf.file);
+#if defined(HAVE_CGI) || defined(HAVE_LUA)
+ /* default script timeout */
+ if( conf.script_timeout <= 0 )
+ conf.script_timeout = 60;
+#endif
+
#ifdef HAVE_CGI
/* default cgi prefix */
if( ! conf.cgi_prefix )
#ifdef HAVE_CGI
/* default cgi prefix */
if( ! conf.cgi_prefix )
@@
-794,6
+826,7
@@
int main (int argc, char **argv)
/* add client socket to global fdset */
FD_SET(new_fd, &used_fds);
/* add client socket to global fdset */
FD_SET(new_fd, &used_fds);
+ fd_cloexec(new_fd);
max_fd = max(max_fd, new_fd);
}
max_fd = max(max_fd, new_fd);
}
This page took
0.021791 seconds
and
4
git commands to generate.