summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2016-03-07 14:18:39 +0100
committerMax Kellermann <max@duempel.org>2016-03-07 14:21:01 +0100
commite140a28073f75375a33b28bcbcd0ecc669c5a518 (patch)
treeebd7207c3192c42ed5a59288f65599132c043953
parentde61c3b9626d24685e58f880667001129e5b8921 (diff)
archive/iso9660: check path buffer bounds
-rw-r--r--NEWS2
-rw-r--r--src/archive/plugins/Iso9660ArchivePlugin.cxx15
2 files changed, 13 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index 1d6762a54..62ea0c08e 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,8 @@ ver 0.19.14 (not yet released)
* decoder
- dsdiff: fix off-by-one buffer overflow
- opus: limit tag size to 64 kB
+* archive
+ - iso9660: fix buffer overflow
* fix build failures on non-glibc builds due to constexpr Mutex
ver 0.19.13 (2016/02/23)
diff --git a/src/archive/plugins/Iso9660ArchivePlugin.cxx b/src/archive/plugins/Iso9660ArchivePlugin.cxx
index 24609f1ed..6b5f47e86 100644
--- a/src/archive/plugins/Iso9660ArchivePlugin.cxx
+++ b/src/archive/plugins/Iso9660ArchivePlugin.cxx
@@ -66,7 +66,10 @@ public:
return iso9660_iso_seek_read(iso, ptr, start, i_size);
}
- void Visit(char *path, size_t length,
+ /**
+ * @param capacity the path buffer size
+ */
+ void Visit(char *path, size_t length, size_t capacity,
ArchiveVisitor &visitor);
virtual void Close() override {
@@ -85,7 +88,7 @@ static constexpr Domain iso9660_domain("iso9660");
/* archive open && listing routine */
inline void
-Iso9660ArchiveFile::Visit(char *path, size_t length,
+Iso9660ArchiveFile::Visit(char *path, size_t length, size_t capacity,
ArchiveVisitor &visitor)
{
auto *entlist = iso9660_ifs_readdir(iso, path);
@@ -102,12 +105,16 @@ Iso9660ArchiveFile::Visit(char *path, size_t length,
continue;
size_t filename_length = strlen(filename);
+ if (length + filename_length + 1 >= capacity)
+ /* file name is too long */
+ continue;
+
memcpy(path + length, filename, filename_length + 1);
size_t new_length = length + filename_length;
if (iso9660_stat_s::_STAT_DIR == statbuf->type ) {
memcpy(path + new_length, "/", 2);
- Visit(path, new_length + 1, visitor);
+ Visit(path, new_length + 1, capacity, visitor);
} else {
//remove leading /
visitor.VisitArchiveEntry(path + 1);
@@ -135,7 +142,7 @@ void
Iso9660ArchiveFile::Visit(ArchiveVisitor &visitor)
{
char path[4096] = "/";
- Visit(path, 1, visitor);
+ Visit(path, 1, sizeof(path), visitor);
}
/* single archive handling */