Zsh shell在5.9.1版本中存在一个导致历史文件数据丢失的bug,已在5.9.2版本中得到修复[1]。这一问题的根源在于shell退出时的信号处理机制。
当readhistfile函数在读取历史文件过程中被信号中断,并设置了errflag & ERRFLAG_INT标志后会中止循环[1]。此时如果shell继续执行savehistfile函数,后者会直接将不完整的历史内容写入文件,从而覆盖原有的完整历史记录[1]。用户重复按压Ctrl+D、Ctrl+C等快捷键的退出习惯可能在savehistfile执行时发送SIGINT信号,触发这一bug[1]。
问题的修复补丁由Bart Schaefer在2025年4月提供,但在5.9.1发布时遗漏了该补丁的集成[1]。该bug的定位过程运用了inotify、fatrace、bpftrace等系统追踪工具来监控文件操作,同时利用coredumpctl收集崩溃core dump进行假设验证[1]。5.9.2版本已于2026年7月12日正式发布[1]。
A critical data loss vulnerability affecting Zsh 5.9.1 has been identified and resolved, with the fix deployed in version 5.9.2 released on July 12th, 2026 [1]. The bug caused shell history files to be mysteriously truncated, a problem that persisted undetected for years before being systematically diagnosed using advanced system tracing tools [1].
The root cause stems from an interruption handling flaw in the shell's history management functions [1]. When the readhistfile function was interrupted by a signal during file reading and the errflag & ERRFLAG_INT flag was set, it would exit its loop prematurely, leaving the history buffer incomplete [1]. Subsequently, when the shell exited, the savehistfile function would write this truncated history back to disk, overwriting the original file contents [1]. User behavior patterns—specifically repeated rapid presses of Ctrl+D and Ctrl+C during shell exit—could trigger an SIGINT signal during the savehistfile execution, creating the conditions for data loss [1].
The investigation employed multiple diagnostic techniques to isolate the issue, including inotify monitoring, fatrace for file operation tracing, and bpftrace for deeper system-level inspection [1]. The underlying code defect was that savehistfile failed to verify the interrupt status before writing to disk [1]. A patch addressing this vulnerability was provided by Bart Schaefer in April 2025, though it was inadvertently omitted from the 5.9.1 release [1].