libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 9a5dece83e262732280730c7aa3a56cc4a62fe85
parent 1421e4394f01e8167b5b7be67b6f98159895ae4b
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon, 18 Jan 2016 20:45:12 +0000

eliminate stat/fopen race in example

Diffstat:
Msrc/examples/fileserver_example_external_select.c | 29++++++++++++++++++++++-------
1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/src/examples/fileserver_example_external_select.c b/src/examples/fileserver_example_external_select.c @@ -38,6 +38,7 @@ file_reader (void *cls, uint64_t pos, char *buf, size_t max) return fread (buf, 1, max, file); } + static void free_callback (void *cls) { @@ -45,6 +46,7 @@ free_callback (void *cls) fclose (file); } + static int ahc_echo (void *cls, struct MHD_Connection *connection, @@ -58,6 +60,7 @@ ahc_echo (void *cls, struct MHD_Response *response; int ret; FILE *file; + int fd; struct stat buf; if (0 != strcmp (method, MHD_HTTP_METHOD_GET)) @@ -69,12 +72,23 @@ ahc_echo (void *cls, return MHD_YES; } *ptr = NULL; /* reset when done */ - if ( (0 == stat (&url[1], &buf)) && - (S_ISREG (buf.st_mode)) ) - file = fopen (&url[1], "rb"); - else - file = NULL; - if (file == NULL) + + file = fopen (&url[1], "rb"); + if (NULL != file) + { + fd = fileno (file); + if (-1 == fd) + return MHD_NO; /* internal error */ + if ( (0 != fstat (fd, &buf)) || + (! S_ISREG (buf.st_mode)) ) + { + /* not a regular file, refuse to serve */ + fclose (file); + file = NULL; + } + } + + if (NULL == file) { response = MHD_create_response_from_buffer (strlen (PAGE), (void *) PAGE, @@ -88,7 +102,7 @@ ahc_echo (void *cls, &file_reader, file, &free_callback); - if (response == NULL) + if (NULL == response) { fclose (file); return MHD_NO; @@ -99,6 +113,7 @@ ahc_echo (void *cls, return ret; } + int main (int argc, char *const *argv) {