前陣子小弟的公司如火如荼地進行 ISO 相關驗證,其中的作業程序書中明定所有電腦的作業系統都需要自動或手動定期更新到最新的版本,以避免駭客利用系統弱點並執行惡意程式或取得系統權限。如同專家們建議的一樣,通常我們會將作業系統更版到最新,尤其是內含重大安全性修補時。不過,歷史上也曾經發生過更新檔有臭蟲而導致更大的漏洞,甚或系統崩潰再起不能的事件。這一次,MacOS Sonoma 14.4 也面臨到了同樣狀況。
事件摘要
3 月 15 日,Oracle 甲骨文的資深產品總監 Aurelio Garcia-Ribeyro 在網誌中提到,macOS 14 的 Java 使用者應避免更新到 14.4 版。他說:「macOS 14.4 中的某個臭蟲會導致 Java 程式非預期地中止,影響範圍從 Java 8 到 Java 22 早期存取版本為止的所有版本。目前沒有暫時解法,而且 macOS 並沒有簡易的退版方式,除非受影響的使用者保存了作業系統升級前的完整系統備份。」
本臭蟲並未存在於 macOS 14.4 之前的早期版本中,因此它是本次更新釋出之後才出現的,包括了蘋果的 M1、M2 以及 M3 晶片都會受到影響。
技術根因分析
主要的原因來自於 JVM 代碼存取記憶體的過程中發生問題時,macOS 14.4 的回應與過去版本不同。
JIT(Just in Time)編譯和執行的周期裡,程式有可能會存取位於未映射或受保護記憶體區域中的內容。在 macOS 14.4 之前的版本中,某些特定的場景下,當程式讀取到這些記憶體區域時,作業系統會回應 SIGSEGV
或 SIGBUS
信號。程式收到這些信號時,可以會忽略或處理這些信號並繼續執行。
然而,在 macOS 14.4 中有不同的行為。當執行緒在寫入模式中操作時,如果試圖存取受保護記憶體區域的話,macOS 核心會回應 SIGKILL
信號。JVM 收到 SIGKILL
信號後無法處理,反而會被非預期地終止,不會產生任何 hs_err 檔案或 stacktrace 記錄。
由於 JVM 動態生成代碼,會利用受保護記憶體存取信號的機制來確保正確性與性能。這使得從 macOS 14.4 開始,嘗試這樣做的程式將會被終止,而不是有機會處理該信號。使用 GraalVM 原生映像檔創建的 Ahead-of-Time 編譯應用程式不應受到影響,但是我們可能無法建立新的映像檔。
補救措施
蘋果已於 3 月 25 日釋出了 macOS 14.4.1 版本,並且提到新版中修正了「 Apps that include Java may quit unexpectedly」的臭蟲。同時,Oracle 也已確認新版中無法重現此問題。因此已升級到 macOS 14.4 的使用者請儘速更新,避免 Java 程式無預警地終止。
結語
雖然系統升級難免會出現新的臭蟲導致各式千奇百怪的狀況出現,老喬仍然建議大家儘可能地都升級到最新版本,不論是作業系統或是應用程式。畢竟每次更新都會修正許多安全性的漏洞,可有效避免駭客入侵導致嚴重的損失。