——从显卡黑屏到 3 个未修补的内核 LPE,再到一块快没电的 CMOS 电池:作为一个安全 PM,我为什么不放过任何"小问题"
一、流亡的硬盘
那天下班前,公司那台陪了我两年的台式机——一块 H61 主板的低配机——突然不开机了。POST 没过,电源一闪就熄。
主板修不划算,我做了个决定:把硬盘和显卡拎回家,插到家里那台同样老的 X79 主板上接着用。
为什么这么折腾?因为那块硬盘是双系统:Windows 10 + Ubuntu 24.04。**重装一次系统少说半天,把所有开发环境、配置、密钥重新搬一遍,得两天。**只要硬盘没坏,主板坏了就只是换一台机器的事。
晚上 9 点,我把 GTX 660 从原机扒下来,连同硬盘一起塞进 X79 那台。开机,Windows 引导正常进了桌面,Ubuntu 也能起来——但屏幕越看越不对劲:分辨率怪、字体糊。
那一刻我下意识做了一个事后想起来错得离谱的判断:会不会是 GTX 660 也跟着主板一起坏了?
家里抽屉还有一块从老笔记本拆下来的 GTX 950M(虽然是笔记本卡,但配上转接卡能在台式机上用)。换上吧,先不让显卡耽误事。
然后……灾难开始了。
二、错怪了一块好卡
GTX 950M 装上去,Ubuntu 桌面终于"看起来正常"——分辨率对了、字也清楚了。我心想问题搞定,做我的事去。
直到我习惯性地 sudo reboot。
显示器黑屏。
主机风扇狂转。
硬盘灯不亮。
键盘 NumLock 灯按了没反应。
像一台被某个无形的手按住的机器——电是通的,但什么也没在跑。
等了 30 秒、1 分钟、3 分钟……还是这样。我只能长按电源键强制关机。开机,进系统,一切正常。再 sudo reboot,又卡死。
当时的我,盯着那块嗡嗡作响的机箱,脑子里只有一个念头:这块 950M 是不是又坏了?
折腾了快 1 个小时之后,我意识到这事不对劲。我把 GTX 660 重新装回去。这次我决定不再凭直觉做判断,而是好好把问题查清楚。
三、真相:是我自己装错了一整代驱动
把 660 装回去之后开机,跑 nvidia-smi,得到的回应是:
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver.我顺手查了下当前装的是哪个驱动:
$ dpkg -l | grep nvidia-driver
ii nvidia-driver-535 535.288.01-0ubuntu0.24.04.2535 系列。
然后我搜了一下:NVIDIA 在 495 版本之后,就完全放弃了 Kepler 架构(GTX 6 系/7 系)的支持。也就是说——
535 这个驱动,在 GTX 660 上根本不会工作。
更荒诞的是:那块"被我冤枉"的 GTX 950M 是 Maxwell 架构,本来 535 是支持它的,但我有一种强烈的怀疑——之前公司那台机器上配的是 H61 + GTX 660,那套 Ubuntu 是当年配着 660 装的,整套显示驱动是按 660 当年版本配的老驱动。后来某次 apt 自动升级把驱动拉到了 535,但那时候机器还是 660,所以显示其实早就半残了,只是表现得不那么明显。
塞进 X79 之后我看到的"分辨率怪、字体糊",根本不是硬件问题,是 nouveau 接管的回退显示。我换上 950M 之后能正常显示,是因为 950M 的 Maxwell 架构是 535 驱动还支持的——但 sudo reboot 卡死那个现象,是另一个独立问题:老 950M + 新内核 + 不完整驱动栈,关机阶段在卸载 nvidia 模块时死锁了,于是机器进了一个"半关机"状态。
这是给所有技术人的第一个钩子:
当一个症状出现的时候,最危险的不是没思路,而是凭直觉得出第一个结论,然后从此只为这个结论找证据。
我看到屏幕黑了,立刻就锁定"显卡坏了"——但其实显卡好得很,是我自己装了一个根本不该装的驱动。
打个比方:这就像你给一台 iPhone 4 装了 iOS 18。系统看起来"装上去了",但开机之后要么黑屏要么没反应。你以为是手机坏了,其实是你逼一台 2010 年的硬件去跑 2024 年的代码。
修复方案很简单——但简单不代表轻松。
四、给显卡找回它该穿的"码"
GTX 660 是 Kepler 架构(2012 年的卡),NVIDIA 官方最后支持它的驱动分支是 470 系列。这就是它该穿的"码"。
我做了这件事:
第一步:把当前的 535 系列彻底清干净,然后装 470。
sudo apt-get purge -y 'nvidia-*' 'libnvidia-*'
sudo apt-get autoremove -y
sudo apt-get install -y nvidia-driver-470
sudo reboot重启完——nvidia-smi 依然失败。这是第二个坑。
排查发现:DKMS 包确实安装了,但编译模块这一步静默地失败了,根本没有 nvidia.ko 文件被生成到当前内核目录下。
DKMS 是什么?
一句话:它是显卡驱动和内核之间的翻译官。Linux 内核每升一次小版本(哪怕是个修 bug 的版本),它的"内部接口"都可能微调。显卡驱动要继续工作,就得针对当前内核重新编译一遍——这件事就是 DKMS 自动做的。
如果哪天 DKMS 编译失败了(比如内核升得太新、驱动太老),它不会大喊大叫——它只会把状态从
installed变成added,然后等着你某天发现。
我手动触发了一次编译:
sudo dkms install nvidia/470.256.02 -k $(uname -r) --force这次它跑了出来,5 个 .ko 模块全部就位。nvidia-smi 终于亮起来:
NVIDIA GeForce GTX 660, Driver 470.256.02, 1991 MiB第三步:保证下次开机能自动加载。
这一步必须做,否则关机后这套配置就丢了。我做了两件事:
# 把 nouveau 拉黑(防止它和 nvidia 抢 GPU)
echo -e "blacklist nouveau\noptions nouveau modeset=0" \
| sudo tee /etc/modprobe.d/blacklist-nouveau.conf
# 声明开机自动加载 nvidia 模块
echo -e "nvidia\nnvidia_modeset\nnvidia_uvm\nnvidia_drm" \
| sudo tee /etc/modules-load.d/nvidia.conf
sudo update-initramfs -u
sudo reboot重启之后再跑 nvidia-smi——一次成功。
整个过程花了大约 2 个小时。这 2 个小时里我至少强制关机了 5 次,怀疑过显卡、内存、主板、电源。但真正的问题,从头到尾就是一个:我让一个 2022 年的驱动去管一块 2012 年的显卡。
五、那就别再升级内核了
显卡的事搞定后,我又意识到一个隐患:Ubuntu 默认每个月都会推送新的内核 ABI 版本。每次升级内核,DKMS 就要重新编译一次 nvidia 模块——而 470 驱动已经停止官方维护,新内核出来又会越来越多和它不兼容的地方。
我突然不想再玩这个滚石上山的游戏了。我又不做内核开发,硬件也老了,何必每个月被 apt 推着走?
锁定内核版本,Linux 上用一行命令就能搞定:
sudo apt-mark hold linux-generic linux-image-generic linux-headers-generic
apt-mark hold是什么?
想象 apt 是一个负责"管家"的角色,它每个月例行去仓库里给所有东西换新版本。hold就相当于你贴了张便条在某几个箱子上写:"这些不要动"。其它箱子(浏览器、SSH 服务、桌面环境)该升还是升,只是内核不动。想"撕便条"也只要一行:
sudo apt-mark unhold。
到这一步如果停下,我也就是把一件"前期问题"做完了。但下一个钩子出现了——而且是真正属于我职业本能的。
六、安全 PM 的职业病发作了
我是做网络安全行业的产品经理。"锁住内核"这个动作刚做完,脑子里立刻条件反射地冒出一句话:
最近几个月那几个挺火的 Linux LPE 漏洞,我这版内核打补丁了吗?
LPE = Local Privilege Escalation = 本地提权。白话翻译:你以普通用户登录到系统里,能找到办法变成 root。
这种漏洞看起来"我自己用的电脑无所谓"——但在很多场景下它是致命的最后一公里。比如:
- • 一个 Web 漏洞让攻击者获得了 nginx 用户的 shell ——单独看是低危
- • 但如果他在系统里能找到 LPE ——他能立刻拿到 root
- • 1 + 1 = 拿下整台服务器
这就是为什么搞安全的人对未打补丁的 LPE 漏洞如此敏感。
我查了下 2026 年 5 月公开的几个:
| 漏洞 | 别名 | 影响模块 | 披露日期 |
|---|---|---|---|
| CVE-2026-31431 | Copy Fail | algif_aead(用户态加密接口) | 2026-04-30 |
| CVE-2026-43284 | Dirty Frag (ESP) | IPsec ESP | 2026-05-08 |
| CVE-2026-43500 | Dirty Frag (RxRPC) | AFS 文件系统协议 | 2026-05-08 |
然后我对照了 Ubuntu 安全公告。结论让我手心微微一凉:
直到今天(2026-05-14),Ubuntu 24.04 还没有发布修复内核。
哪怕我现在解锁内核去升级到最新的6.8.0-111,它也是 4 月 11 日打包的——比所有这三个漏洞披露日期都早。升级也没用。
换句话说:全世界用 Ubuntu 24.04 的人,此刻都在裸奔。
打个比方:这就像整个小区刚发现自己的门锁可以用回形针拧开,但是锁匠还没赶来。等锁匠没有意义——你能做的事是用别的方法堵住那扇门。
幸好这三个漏洞都不是无解的——Ubuntu 安全团队给出了应用层缓解:
- • Copy Fail:通过升级
kmod包(不在我锁定的范围内)→ 自动 blacklistalgif_aead模块 - • Dirty Frag (ESP):手动 blacklist
esp4、esp6模块(我又不用 IPsec VPN,无影响) - • Dirty Frag (RxRPC):手动 blacklist
rxrpc模块(AFS 文件系统,更没人用)
我写了个脚本一次搞定:
#!/usr/bin/env bash
# 缓解 2026-05 的三个 Linux 内核 LPE
set -e
sudo apt-get update
sudo apt-get install -y --only-upgrade kmod # Copy Fail
cat <<EOF | sudo tee /etc/modprobe.d/blacklist-lpe-2026-05.conf
install esp4 /bin/true
install esp6 /bin/true
install rxrpc /bin/true
blacklist esp4
blacklist esp6
blacklist rxrpc
EOF
for m in esp4 esp6 rxrpc algif_aead; do
lsmod | grep -q "^$m " && sudo rmmod "$m" || true
done
sudo update-initramfs -u跑完之后我做了一件很关键的验证——主动模拟攻击者去加载这些模块,看会不会被拦下:
$ sudo modprobe -n -v algif_aead
install /bin/false # ← 拦截成功
$ sudo modprobe -n -v esp4
install /bin/true # ← 拦截成功
$ sudo modprobe -n -v rxrpc
install /bin/true # ← 拦截成功这一步比写脚本更重要:永远不要相信"我配置完了"这句话,要相信"我验证过了"。
到这一步,那三扇被回形针能撬开的门,都已经被木条钉死了。等 Ubuntu 出补丁的那天,再把木条拆掉就行。
七、最后是那块快没电的电池
时间已经过去三个多小时了。一切都按部就班地修好了,我本该去睡觉。但脑子里又冒出来一个执念:
这块主板 BIOS 是 2019 年的,主板上的 CMOS 电池估计也是 7 年前装上去的。
如果哪天它真没电了,每次断电后 BIOS 设置都会重置——启动顺序、CPU 频率、SATA 模式全部回到出厂。
到那个时候再处理,才是真正的烦。
软件层面,没法直接测 CMOS 电池电压——消费级主板不通过 SMBus 暴露这个数据。但有几个间接信号可以推断它的状态:
# 1. RTC 时钟漂移:开机时硬件时间 vs 真实时间
timedatectl status
# 2. 历次开机时间是否合理(如果偶尔跳回 1970/2010,就是电池坏了)
last reboot -n 10
# 3. 内核启动期 RTC 相关错误
sudo journalctl -b -k | grep -iE "rtc|cmos"我跑下来:RTC 漂移 = 1 秒(极优秀);过去 10 次开机时间都正常连续;没有 CMOS 错误。电池目前是健康的。
但——电池都 7 年了,CR2032 设计寿命是 5–10 年,已经进入**"还能用,但已开始衰减"** 的区间。这种情况怎么办?
比方一下:CMOS 电池就像电脑的心脏起搏器。
主板关机休眠的时候,机箱里唯一还活着的东西就是它——靠它续着 BIOS 设置、维持时钟、记着启动顺序。
它失效之前不会"提示"你,只会某天断电后开机让你发现日期回到 2010 年、SATA 模式被重置、Windows 因找不到启动盘而蓝屏。
我顺手下单了一块松下 CR2032——5 块钱不到。
预防性更换比等出问题再修,省的不是钱,是当时那种"屎到临头才发现"的崩溃感。
八、为什么我要折腾这一晚?
凌晨 1 点多,所有事都做完了。我合上电脑前回想了一下整晚做的事:
- 1. 第一遍:搬硬盘,原以为是搬完就完事
- 2. 第二遍:换 GTX 950M,以为修了显卡
- 3. 第三遍:换回 GTX 660,发现是驱动错了
- 4. 第四遍:装 470 驱动,遇到 DKMS 静默失败
- 5. 第五遍:锁内核 + 应用 CVE 缓解
- 6. 第六遍:检查 CMOS 电池
6 件事,每一件都本来可以"算了,先用着再说"。 但我都没放过。
我并不是要在公众号面前装个"完美主义"的人设。让我说为什么——
作为技术人,最伤人的不是 bug,是"先放着"留下的心理债。
那块"先放着不查的显卡问题"会变成:以后每次重启心里都不踏实,怕它再卡死。
那行"先不动的 535 驱动"会变成:某天你换了别的硬件,突然发现根本起不来。
那条"等等再装的 CVE 缓解"会变成:某天看到一篇新闻里有公司因为这个被入侵了,你心里咯噔一下。
那块"过几年再换的 CMOS 电池"会变成:某次断电之后开机蓝屏,你才想起来一年前就该换。
每一个"先放着"的问题,都会在某个最不该出问题的时刻冒出来咬你。
反过来——每一个被刨根究底解决掉的问题,都是一笔复利:
- • 弄清楚了 Kepler 架构和 470 驱动的关系 → 以后再装老显卡不会再绕弯
- • 学会了 DKMS 的"静默失败"机制 → 以后任何内核相关问题都会想到去
dkms status看一眼 - • 理解了
apt-mark hold的边界 → 知道它能锁什么、不能锁什么 - • 见识了"漏洞已公开但 Ubuntu 还没修"的真实窗口期 → 以后会主动跟 USN 公告,而不是等 apt 推
- • 知道了 RTC 漂移可以反推 CMOS 电池状态 → 这事将来对任何老机器都适用
每个被刨根究底的问题,都从"以后会回来咬你的隐患"变成了"以后帮你省事的资产"。
每个被"先放着"的问题,反过来——它会在你脑子里安一个小钩子,时不时提醒你"那个事还没解决"。 它会变成你内心的一块阴影。
技术人成长这件事,没有别的捷径。它就是由无数个"我本可以放过它,但我没有"组成的。
写在最后
这篇文章很长,但其实只想说一件事——
遇到问题,就一次性把它修好;想清楚问题,就一次性把根挖到底。
可能你说"我没那么多时间"——但其实你算过吗?我今晚花的 3 个多小时,省下来的是未来 N 次"莫名其妙问题"的折腾时间、是未来某个安全事件发生时"我以为我没事"的窗口期、是未来某次断电后开机蓝屏的崩溃感。
这不是完美主义,这是工程师的"复利账户"。
愿你今晚不要错过一个本可以查清楚的问题。
本文从一次硬件搬迁讲到 LPE 漏洞缓解再到 CMOS 电池——背后所有的脚本都是真实跑过的、所有的命令都是可以复用的。如果对其中某个细节感兴趣,欢迎评论区或加微信群一起讨论。

夜雨聆风