From 160ea4fe2beb1d433c96fc432772fd0122421c95 Mon Sep 17 00:00:00 2001 From: Robert Buchholz Date: Mon, 8 Jun 2009 12:04:41 +0200 Subject: [PATCH] backport CVE-2009-1760 fix from r3621 --- src/torrent_info.cpp | 47 ++++++++++++++++++++++++++++------------------- 1 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index 57c8a97..fc6d284 100755 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -39,6 +39,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #ifdef _MSC_VER #pragma warning(push, 1) @@ -74,6 +75,29 @@ namespace str += 0x80 | (chr & 0x3f); } + bool valid_path_element(std::string const& element) + { + if (element.empty() + || element == "." || element == ".." + || element[0] == '/' || element[0] == '\\' + || element[element.size()-1] == ':') + return false; + return true; + } + + fs::path sanitize_path(fs::path const& p) + { + fs::path new_path; + for (fs::path::const_iterator i = p.begin(); i != p.end(); ++i) + { + if (!valid_path_element(*i)) continue; + std::string pe = *i; + new_path /= pe; + } + TORRENT_ASSERT(!new_path.is_complete()); + return new_path; + } + void verify_encoding(file_entry& target) { std::string tmp_path; @@ -184,9 +208,9 @@ namespace for (entry::list_type::const_iterator i = list->begin(); i != list->end(); ++i) { - if (i->string() != "..") - target.path /= i->string(); + target.path /= i->string(); } + target.path = sanitize_path(target.path); verify_encoding(target); if (target.path.is_complete()) throw std::runtime_error("torrent contains " "a file with an absolute path: '" @@ -349,23 +373,8 @@ namespace libtorrent else { m_name = info["name"].string(); } - fs::path tmp = m_name; - if (tmp.is_complete()) - { - m_name = tmp.leaf(); - } - else if (tmp.has_branch_path()) - { - fs::path p; - for (fs::path::iterator i = tmp.begin() - , end(tmp.end()); i != end; ++i) - { - if (*i == "." || *i == "..") continue; - p /= *i; - } - m_name = p.string(); - } - if (m_name == ".." || m_name == ".") + m_name = sanitize_path(m_name).string(); + if (!valid_path_element(m_name)) throw std::runtime_error("invalid 'name' of torrent (possible exploit attempt)"); // extract file list -- 1.6.3.1