From 14a5f8f266c16c87ab6c086fc52b770b27701e01 Mon Sep 17 00:00:00 2001
From: Matt Wilson <msw@amazon.com>
Date: Wed, 17 Jan 2024 14:46:18 -0800
Subject: [PATCH] Neutralize zip file traversal attacks in miniunz.

Archive formats such as .zip files are generally susceptible to
so-called "traversal attacks". This allows an attacker to craft
an archive that writes to unexpected locations of the file system
(e.g., /etc/shadow) if an unspecting root user were to unpack a
malicious archive.

This patch neutralizes absolute paths such as /tmp/moo and deeply
relative paths such as dummy/../../../../../../../../../../tmp/moo

The Debian project requested CVE-2014-9485 be allocated for the
first identified weakness. The fix was incomplete, resulting in a
revised patch applied here. Since there wasn't an updated version
released by Debian with the incomplete fix, I suggest we use this
CVE to identify both issues.

Link: https://security.snyk.io/research/zip-slip-vulnerability
Link: https://bugs.debian.org/774321
Link: https://bugs.debian.org/776831
Link: https://nvd.nist.gov/vuln/detail/CVE-2014-9485
Reported-by: Jakub Wilk <jwilk@debian.org>
Fixed-by: Michael Gilbert <mgilbert@debian.org>

CVE: CVE-2014-9485

Upstream-Status: Backport [https://github.com/madler/zlib/commit/14a5f8f266c16c87ab6c086fc52b770b27701e01]

Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
---
 contrib/minizip/miniunz.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/contrib/minizip/miniunz.c b/contrib/minizip/miniunz.c
index 3d65401..479e475 100644
--- a/contrib/minizip/miniunz.c
+++ b/contrib/minizip/miniunz.c
@@ -367,6 +367,20 @@ int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
         else
             write_filename = filename_withoutpath;
 
+        if (write_filename[0]!='\0')
+        {
+            const char* relative_check = write_filename;
+            while (relative_check[1]!='\0')
+            {
+                if (relative_check[0]=='.' && relative_check[1]=='.')
+                    write_filename = relative_check;
+                relative_check++;
+            }
+        }
+
+        while (write_filename[0]=='/' || write_filename[0]=='.')
+            write_filename++;
+
         err = unzOpenCurrentFilePassword(uf,password);
         if (err!=UNZ_OK)
         {
-- 
2.40.0

