TS-2323: defend against .including directories

Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/b984db31
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/b984db31
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/b984db31

Branch: refs/heads/master
Commit: b984db31f54257f621b33c9f9e2968392f273f25
Parents: 39cc54c
Author: James Peach <[email protected]>
Authored: Fri Nov 1 19:53:55 2013 -0700
Committer: James Peach <[email protected]>
Committed: Tue Nov 5 16:48:05 2013 -0800

----------------------------------------------------------------------
 lib/ts/ink_file.cc              | 15 +++++++++++++++
 lib/ts/ink_file.h               |  4 ++++
 proxy/http/remap/RemapConfig.cc | 23 ++++++++++++++++-------
 3 files changed, 35 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b984db31/lib/ts/ink_file.cc
----------------------------------------------------------------------
diff --git a/lib/ts/ink_file.cc b/lib/ts/ink_file.cc
index f5a1eba..53d064f 100644
--- a/lib/ts/ink_file.cc
+++ b/lib/ts/ink_file.cc
@@ -23,6 +23,9 @@
 
 #include "libts.h"
 
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
 
 int
 ink_fputln(FILE * stream, const char *s)
@@ -350,3 +353,15 @@ ink_file_fd_zerofill(int fd, off_t size)
   return 0;
 #endif
 }
+
+bool
+ink_file_is_directory(const char * path)
+{
+  struct stat sbuf;
+
+  if (stat(path, &sbuf) == -1) {
+    return false;
+  }
+
+  return S_ISDIR(sbuf.st_mode);
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b984db31/lib/ts/ink_file.h
----------------------------------------------------------------------
diff --git a/lib/ts/ink_file.h b/lib/ts/ink_file.h
index a22e33d..c6429d7 100644
--- a/lib/ts/ink_file.h
+++ b/lib/ts/ink_file.h
@@ -99,4 +99,8 @@ int ink_filepath_make(char *path, int pathsz, const char 
*rootpath,
  */
 int ink_file_fd_zerofill(int fd, off_t size);
 
+/**
+ Return true if the path is a directory.
+ */
+bool ink_file_is_directory(const char * path);
 #endif // _ink_file_h_

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b984db31/proxy/http/remap/RemapConfig.cc
----------------------------------------------------------------------
diff --git a/proxy/http/remap/RemapConfig.cc b/proxy/http/remap/RemapConfig.cc
index f454269..1257f05 100644
--- a/proxy/http/remap/RemapConfig.cc
+++ b/proxy/http/remap/RemapConfig.cc
@@ -247,22 +247,31 @@ parse_include_directive(const char * directive, 
BUILD_TABLE_INFO * bti, char * e
     // We need to create a new bti so that we don't clobber any state in the 
parent parse, but we want
     // to keep the ACL rules from the parent because ACLs must be global 
across the full set of config
     // files.
-    BUILD_TABLE_INFO nbti;
-    char * path;
-    bool success;
+    BUILD_TABLE_INFO  nbti;
+    xptr<char>        path;
+    bool              success;
+
+    // The included path is relative to SYSCONFDIR, just like remap.config is.
+    path = Layout::relative_to(Layout::get()->sysconfdir, bti->paramv[i]);
+
+    // XXX including directories is not supported (yet!).
+    if (ink_file_is_directory(path)) {
+      snprintf(errbuf, errbufsize, "included path %s is a directory", 
bti->paramv[i]);
+      return (const char *)errbuf;
+    }
 
     nbti.rules_list = bti->rules_list;
     nbti.rewrite = bti->rewrite;
 
-    // The included path is relative to SYSCONFDIR, just like remap.config is.
-    path = Layout::relative_to(Layout::get()->sysconfdir, bti->paramv[i]);
+    // XXX at this point, we need to register the included file(s) with the 
management subsystem
+    // so that we can correctly reload them when they change. Otherwise, the 
operator will have to
+    // touch remap.config before reloading the configuration.
 
-    Debug("url_rewrite", "[%s] including remap configuration from %s", 
__func__, path);
+    Debug("url_rewrite", "[%s] including remap configuration from %s", 
__func__, (const char *)path);
     success = remap_parse_config_bti(path, &nbti);
 
     // The sub-parse might have updated the rules list, so push it up to the 
parent parse.
     bti->rules_list = nbti.rules_list;
-    ats_free(path);
 
     if (!success) {
       snprintf(errbuf, errbufsize, "failed to parse included file %s", 
bti->paramv[i]);

Reply via email to