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]);
