---
title: "zlib 1.4 發布　修補逾十個記憶體安全問題並帶來破壞性變更"
url: https://sammy.hk/zlib-1-4-release/
author: Ethan
published: 2026-11-06T18:41:00+08:00
modified: 2026-11-06T09:03:45+08:00
description: "zlib 專案於 2026 年 11 月 4 日發布 zlib 1.4，是自 2026 年 2 月 1.3.2 以來首個版本更新。這個幾乎所有作業系統與應用程式都直接或間接依賴的壓縮庫，在新版本中修補了多個緩衝區溢出、越界讀寫與未初始化記憶體問題，同時亦包含若干會影響建置與行為的破壞性變更[1][2]。 安全修補涵蓋多…"
categories: ["開放源碼"]
tags: [CVE, zlib, "壓縮庫", "安全漏洞"]
source: https://sammy.hk
---
zlib 專案於 2026 年 11 月 4 日發布 zlib 1.4，是自 2026 年 2 月 1.3.2 以來首個版本更新。這個幾乎所有作業系統與應用程式都直接或間接依賴的壓縮庫，在新版本中修補了多個緩衝區溢出、越界讀寫與未初始化記憶體問題，同時亦包含若干會影響建置與行為的破壞性變更\[1\]\[2\]。

## 安全修補涵蓋多個核心函式

新版本處理的安全問題橫跨 gzip 檔案操作、inflate 解壓與 minizip 三個層面，當中最受注目的是非阻塞模式 `gzwrite()` 的緩衝區溢出，獲分配編號 CVE-2026-85091\[1\]。

在解壓路徑方面，`inflateGetDictionary()` 在特定 zlib 標頭（window size 不合法）配合 `inflateReset()` 或 `inflateSync()` 的情況下，最多可以寫入超出呼叫者 32K 緩衝區達 8MB，影響 1.3.1 與 1.3.2。`inflateSync()` 在 window size 尚未確定之前會配置一個只有 1 位元組的 window，之後可被越界覆寫；`inflatePrime()` 可能令 `inflate()` 讀取輸入緩衝區起始位置之前的資料；`inflateBack()` 未能偵測過遠的回溯距離，會把未初始化記憶體複製到輸出\[1\]。

壓縮路徑亦有同類問題：重複呼叫 `deflatePrime()` 可寫出 pending buffer 之外；`gzseek()` 在尚未寫入任何資料前向前 seek，會把未初始化記憶體寫入 gzip 輸出；`deflateResetKeep()` 在串流中途使用時會讀取 window 以外的記憶體。另外 `gzdopen()` 現時以正確的旗標設定 close-on-exec，避免檔案描述符意外外洩至子程序\[1\]。

minizip 的修正同樣值得注意。`block_central_name()` 有 double free；`zipAlreadyThere()` 在中央目錄損壞後重複呼叫會出現 NULL 解引用；解壓時不再從 extra-field 記錄以外讀取 Zip64 數值，亦只採用緊貼中央目錄結束記錄之前的那個 Zip64 locator，避免特製壓縮檔令 minizip 回報與其他工具不同的檔案清單。更嚴重的是 miniunz 以往可以建立解壓目錄以外的資料夾，在 Windows 上更可寫入任意位置，現已改為逐段處理路徑名稱\[1\]。

contrib/infback9 的越界指標運算獲分配 CVE-2026-4738。官方在公告中補充，該些指標在使用前已回到合法範圍，亦沒有已知編譯器會處理錯誤，因此認為 critical 評級有所誇大，但在 CHERI 這類 capability 硬體上仍可能觸發 trap\[1\]。

## 行為與 ABI 層面的破壞性變更

升級時最需要留意的是 `z_off_t` 在未另行決定的情況下回復為 `long`（與 1.3.1 相同），而非 1.3.2 的 `long long`。以 1.3.2 標頭建置的 Windows 應用程式需要重新編譯，否則 64 位元偏移的處理會出錯\[1\]。

`deflateReset()` 現在會重設由 `deflateSetHeader()` 設定的 gzip 標頭，與 zlib.h 長久以來的描述一致；依賴標頭持續存在的程式碼必須重新設定。若 raw deflate 剛好在輸出緩衝區末端完成，現時會回傳 `Z_STREAM_END` 而非 `Z_OK`。`gzopen()` 使用 `"x"` 模式時，在沒有 `O_EXCL` 的平台上會直接失敗，不再改為截斷既有檔案\[1\]。

另外，gzip 讀取遇到錯誤時，會先交付已解壓的資料，然後才回報錯誤；以往的做法是直接放棄。這項改動對依賴「一出錯就沒有輸出」的流程可能造成差異\[1\]。

## 建置系統與平台支援

CMake 最低版本要求由 3.12 提升至 3.15。MSVC 下的函式庫檔名由 `z` 改為 `libz`，即 `libz.dll`、`libz.lib` 與靜態版 `libzs.lib`，minizip 亦同步改名；Cygwin 上則統一加上 `lib` 前綴。contrib 目標與測試的名稱改為 `zlib_` 前綴，`ENABLE_BZIP2` 選項更名為 `ZLIB1_DLL_ENABLE_BZIP2`。這些改動會令既有建置腳本與打包規則失效，發行版維護者需要同步更新\[1\]。

功能方面，Windows 上的 MSVC 或 MinGW 建置現可透過 `_FILE_OFFSET_BITS=64` 或 `_LARGEFILE64_SOURCE` 取得 64 位元偏移，函式庫本身毋須改動；Android 加入大檔案支援，AIX 有匯出清單，Win32 Makefile.msc 支援 ARM64。minizip 的傳統加密標頭亦由 `rand()` 改用 PCG 產生器\[1\]。

## 升級前要注意的遺留問題

官方在已知問題一節明確指出，contrib/iostream2 對不可信輸入並不安全：讀取字串時直接採用壓縮資料內儲存的長度而沒有檢查，特製檔案可以寫出目的緩衝區之外，建議改用 contrib/iostream3\[1\]。

對於發行版與下游專案，較穩妥的做法是先確認自身有否使用上述被改動的介面，特別是自行處理 gzip 標頭、依賴 `z_off_t` 大小，或直接呼叫 minizip 解壓不受信任壓縮檔的程式，再安排建置測試。由於 zlib 被大量元件靜態連結，應用程式層面亦應留意是否已重新連結至 1.4\[2\]。

## 參考資料

\[1\] [zlib 1.4 Release Notes（2026-11-04）](https://github.com/madler/zlib/releases/tag/v1.4)

\[2\] [zlib Home Site](https://zlib.net/)

### 相關文章：

1. [PHP 修補兩個嚴重漏洞：未認證即可遙距執行代碼，官方籲即時更新](https://sammy.hk/php2shell/ "PHP 修補兩個嚴重漏洞：未認證即可遙距執行代碼，官方籲即時更新")
2. [Ubuntu 為核心漏洞 CVE-2026-98432 提供測試渠道修補 22.04 起四個版本可先行套用](https://sammy.hk/ubuntu-cve-2026-98432-fix/ "Ubuntu 為核心漏洞 CVE-2026-98432 提供測試渠道修補 22.04 起四個版本可先行套用")
3. [Cloudflare Containers 跨租戶資料外洩漏洞：dm-thin 未清零的殘留磁碟區塊](https://sammy.hk/cloudflare-containers-%e8%b7%a8%e7%a7%9f%e6%88%b6%e8%b3%87%e6%96%99%e5%a4%96%e6%b4%a9%e6%bc%8f%e6%b4%9e%ef%bc%9adm-thin-%e6%9c%aa%e6%b8%85%e9%9b%b6%e7%9a%84%e6%ae%98%e7%95%99%e7%a3%81%e7%a2%9f/ "Cloudflare Containers 跨租戶資料外洩漏洞：dm-thin 未清零的殘留磁碟區塊")
4. [Ruby 三條版本線同步發布：修正 Regexp 編譯問題、對應 GitLab 多個 CVE](https://sammy.hk/ruby-version-sync-regexp-gitlab-cve/ "Ruby 三條版本線同步發布：修正 Regexp 編譯問題、對應 GitLab 多個 CVE")
