From 1e13a08865bf66dd1c5740030da9d453a431586d Mon Sep 17 00:00:00 2001 From: prx Date: Tue, 20 Sep 2022 12:57:45 +0200 Subject: [PATCH] improve check of cgi_dir request --- vger.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/vger.c b/vger.c index a253501..aeda353 100644 --- a/vger.c +++ b/vger.c @@ -214,18 +214,22 @@ int do_cgi(const char *rel_cgi_dir, const char *path, const char *hostname, const char *query) { - /* WARNING : this function is fragile since it - * compares path using the string to access them. - * It would be preferable to use stat() to check - * if two path refer to the same inode - */ + struct stat sbcgi = {0}; + struct stat sbpath = {0}; + char cgifp[PATH_MAX] = {'\0'}; /* cgi file to execute */ + char path_dir[PATH_MAX] = {'\0'}; + char *path_info = NULL; - char cgifp[PATH_MAX] = {'\0'}; /* cgi file to execute */ - char *path_info = NULL; + /* get beginning of path */ + /* path_dir is initialized so there is an \0 at the end */ + memcpy(path_dir, path, strlen(rel_cgi_dir)); - /* check if path starts with rel_cgi_dir */ - if (strncmp(rel_cgi_dir, path, strlen(rel_cgi_dir)) != 0) - return 1; /* not in cgi_dir, go to display_file */ + if (stat(rel_cgi_dir, &sbcgi) + stat(path_dir, &sbpath) != 0) + goto nocgi; + + /* compare inodes */ + if (sbcgi.st_ino != sbpath.st_ino) + goto nocgi; /* not in cgi_dir, go to display_file */ /* set env variables for CGI * see @@ -251,7 +255,7 @@ do_cgi(const char *rel_cgi_dir, const char *path, const char *hostname, const ch /* cgi file to execute */ esnprintf(cgifp, sizeof(cgifp), "%s", path + strlen(rel_cgi_dir) + 1); if (!(*cgifp)) /* problem with cgi file, abort */ - return 1; + goto nocgi; /* check if there is something after cgi file for PATH_INFO */ path_info = strchr(cgifp, '/'); @@ -268,6 +272,9 @@ do_cgi(const char *rel_cgi_dir, const char *path, const char *hostname, const ch cgi(cgifp); return 0; + +nocgi: + return 1; } ssize_t