-
-
Save ice799/abc2522397b1605a5d7f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Proof of concept instructions: | |
NOTE: I've gotten segfaults and tested the fixed package on the following systems: | |
Debian 7 | |
Ubuntu 12.04 | |
CentOS 7 | |
The patch (which is the same on all OSes) fixed the issue in the above systems. | |
1.) install nginx, spawn-fcgi, libfcgi, libfcgi-dev, and ab. Package names might | |
drift from this depending on Linux version. In particular: ab (apachebench) | |
might be named: http-utils, or apache2-utils, or something else. | |
2.) increase your max files to some large amount, say 1048576. To do this, you | |
can add these lines to your /etc/security/limits.conf: | |
* soft nofile 1048576 | |
* hard nofile 1048576 | |
You may need to reboot after modifying /etc/security/limits.conf for changes to | |
take effect. | |
3.) Start nginx giving full path to the nginx.conf from this gist: sudo nginx -c `pwd`/nginx_cgi.conf | |
4.) Build the threaded.c example in this gist: gcc threaded.c -o threaded -lfcgi -lpthread | |
5.) Start the fcgi process: spawn-fcgi -p 8000 -n threaded | |
6.) Run apache bench to generate a lot of connections: ab -n 8192 -c 2048 http://127.0.0.1:8081/ | |
On my tests, I get a segfault and you probably will too. It is possible that instead | |
you just get data corruption and don't see a segfault. If so, increase the number of -n | |
to ab and sooner or later the corruption will catch up to you and you will segfault. | |
Once you install an fcgi with the patch, the segfault stops. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
events { | |
worker_connections 8192; | |
} | |
http { | |
server { | |
listen 8081; | |
server_name localhost; | |
location / { | |
fastcgi_pass 127.0.0.1:8000; | |
fastcgi_param GATEWAY_INTERFACE CGI/1.1; | |
fastcgi_param SERVER_SOFTWARE nginx; | |
fastcgi_param QUERY_STRING $query_string; | |
fastcgi_param REQUEST_METHOD $request_method; | |
fastcgi_param CONTENT_TYPE $content_type; | |
fastcgi_param CONTENT_LENGTH $content_length; | |
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | |
fastcgi_param SCRIPT_NAME $fastcgi_script_name; | |
fastcgi_param REQUEST_URI $request_uri; | |
fastcgi_param DOCUMENT_URI $document_uri; | |
fastcgi_param DOCUMENT_ROOT $document_root; | |
fastcgi_param SERVER_PROTOCOL $server_protocol; | |
fastcgi_param REMOTE_ADDR $remote_addr; | |
fastcgi_param REMOTE_PORT $remote_port; | |
fastcgi_param SERVER_ADDR $server_addr; | |
fastcgi_param SERVER_PORT $server_port; | |
fastcgi_param SERVER_NAME $server_name; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* threaded.c -- A simple multi-threaded FastCGI application. | |
*/ | |
#ifndef lint | |
static const char rcsid[] = "$Id: threaded.c,v 1.9 2001/11/20 03:23:21 robs Exp $"; | |
#endif /* not lint */ | |
#include "fcgi_config.h" | |
#include <stdio.h> | |
#include <pthread.h> | |
#include <sys/types.h> | |
#ifdef HAVE_UNISTD_H | |
#include <unistd.h> | |
#endif | |
#include "fcgiapp.h" | |
#define THREAD_COUNT 2048 | |
static int counts[THREAD_COUNT]; | |
static void *doit(void *a) | |
{ | |
int rc, i, thread_id = (int)a; | |
pid_t pid = getpid(); | |
FCGX_Request request; | |
char *server_name; | |
FCGX_InitRequest(&request, 0, 0); | |
for (;;) | |
{ | |
static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER; | |
static pthread_mutex_t counts_mutex = PTHREAD_MUTEX_INITIALIZER; | |
/* Some platforms require accept() serialization, some don't.. */ | |
pthread_mutex_lock(&accept_mutex); | |
rc = FCGX_Accept_r(&request); | |
pthread_mutex_unlock(&accept_mutex); | |
if (rc < 0) { | |
printf("bye!\n"); | |
break; | |
} | |
server_name = FCGX_GetParam("SERVER_NAME", request.envp); | |
FCGX_FPrintF(request.out, | |
"Content-type: text/html\r\n" | |
"\r\n" | |
"<title>FastCGI Hello! (multi-threaded C, fcgiapp library)</title>" | |
"<h1>FastCGI Hello! (multi-threaded C, fcgiapp library)</h1>" | |
"Thread %d, Process %ld<p>" | |
"Request counts for %d threads running on host <i>%s</i><p><code>", | |
thread_id, pid, THREAD_COUNT, server_name ? server_name : "?"); | |
sleep(2); | |
pthread_mutex_lock(&counts_mutex); | |
++counts[thread_id]; | |
for (i = 0; i < THREAD_COUNT; i++) | |
FCGX_FPrintF(request.out, "%5d " , counts[i]); | |
pthread_mutex_unlock(&counts_mutex); | |
FCGX_Finish_r(&request); | |
} | |
return NULL; | |
} | |
int main(void) | |
{ | |
int i; | |
pthread_t id[THREAD_COUNT]; | |
FCGX_Init(); | |
for (i = 1; i < THREAD_COUNT; i++) | |
pthread_create(&id[i], NULL, doit, (void*)i); | |
doit(0); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment