fix: cve-fix.sh hardening - idempotency, error checks, read -r, kernel detection

- module blacklist: idempotent dedup + write error checks + caller return gating
- module restore: rm error check before success log
- GRUB update-grub/grub-mkconfig: fail closed on all 3 call sites
- menu reads: read -p -> read -rp (SC2162)
- kernel detection: build date is heuristic only, handle unknown state (rc=2)
This commit is contained in:
Maple
2026-07-08 14:17:20 +08:00
parent 74cc60176c
commit 94ca8d142d

View File

@@ -38,19 +38,20 @@ security_cve_detect_nested_virt() {
return 1
}
# 检测当前内核是否存在 Januscape 漏洞
security_cve_detect_kernel_vulnerable() {
# 检测内核构建日期是否早于修复日期仅供参考backport 内核可能误判)
security_cve_detect_kernel_build_date_before() {
local cutoff_date="${1:-2026-06-19}"
local kernel_build_date
kernel_build_date="$(cat /proc/version 2>/dev/null | sed -n 's/.*SMP PREEMPT[^ ]* //p' | cut -d' ' -f2- 2>/dev/null)"
if [[ -z "$kernel_build_date" ]]; then
kernel_build_date="$(uname -v 2>/dev/null)"
fi
local build_epoch now_epoch patch_epoch
build_epoch="$(date -d "$kernel_build_date" +%s 2>/dev/null)" || return 0
patch_epoch="$(date -d "2026-06-19" +%s 2>/dev/null)" || return 0
local build_epoch cutoff_epoch
build_epoch="$(date -d "$kernel_build_date" +%s 2>/dev/null)" || return 2
cutoff_epoch="$(date -d "$cutoff_date" +%s 2>/dev/null)" || return 2
[[ "$build_epoch" -lt "$patch_epoch" ]] && return 0
[[ "$build_epoch" -lt "$cutoff_epoch" ]] && return 0
return 1
}
@@ -100,11 +101,12 @@ security_cve_januscape_detect() {
current_kernel="$(uname -r)"
echo " 当前内核: $current_kernel"
if security_cve_detect_kernel_vulnerable; then
echo -e " 内核编译日期早于 2026-06-19: ${RED}可能受影响${NC}"
else
echo -e " 内核编译日期晚于 2026-06-19: ${GREEN}可能已包含修复${NC}"
fi
security_cve_detect_kernel_build_date_before "2026-06-19"
case $? in
0) echo -e " 内核编译日期早于 2026-06-19: ${RED}可能受影响${NC} (仅供参考)" ;;
1) echo -e " 内核编译日期晚于 2026-06-19: ${GREEN}可能已包含修复${NC} (仅供参考)" ;;
*) echo -e " 内核编译日期: ${YELLOW}无法确定${NC} (若有疑问请检查 changelog)" ;;
esac
echo "$UI_DIVIDER"
echo -e "${RED}[警告] 检测到潜在风险!建议立即采取修补措施。${NC}"
@@ -160,9 +162,18 @@ security_cve_januscape_mitigate() {
log_info "正在更新 GRUB 配置..."
if command -v update-grub &>/dev/null; then
update-grub
if ! update-grub; then
log_error "update-grub 执行失败,请手动检查 GRUB 配置"
return 1
fi
elif command -v grub-mkconfig &>/dev/null; then
grub-mkconfig -o /boot/grub/grub.cfg
if ! grub-mkconfig -o /boot/grub/grub.cfg; then
log_error "grub-mkconfig 执行失败,请手动检查 GRUB 配置"
return 1
fi
else
log_error "找不到 GRUB 更新工具 (update-grub / grub-mkconfig)"
return 1
fi
log_success "临时修补完成!嵌套虚拟化将在重启后关闭"
@@ -187,11 +198,12 @@ security_cve_januscape_kernel_fix() {
current_kernel="$(uname -r)"
echo -e " 当前内核版本: ${CYAN}$current_kernel${NC}"
if security_cve_detect_kernel_vulnerable; then
echo -e " 状态: ${RED}内核编译日期早于修复日期,可能受影响${NC}"
else
echo -e " 状态: ${GREEN}内核编译日期晚于修复日期,可能已包含修复${NC}"
fi
security_cve_detect_kernel_build_date_before "2026-06-19"
case $? in
0) echo -e " 状态: ${RED}内核编译日期早于修复日期,可能受影响${NC} (仅供参考)" ;;
1) echo -e " 状态: ${GREEN}内核编译日期晚于修复日期,可能已包含修复${NC} (仅供参考)" ;;
*) echo -e " 状态: ${YELLOW}无法通过编译日期确定${NC}" ;;
esac
echo "$UI_DIVIDER"
echo " 修补方式:"
@@ -254,9 +266,18 @@ security_cve_januscape_restore() {
log_info "正在更新 GRUB 配置..."
if command -v update-grub &>/dev/null; then
update-grub
if ! update-grub; then
log_error "update-grub 执行失败,请手动检查 GRUB 配置"
return 1
fi
elif command -v grub-mkconfig &>/dev/null; then
grub-mkconfig -o /boot/grub/grub.cfg
if ! grub-mkconfig -o /boot/grub/grub.cfg; then
log_error "grub-mkconfig 执行失败,请手动检查 GRUB 配置"
return 1
fi
else
log_error "找不到 GRUB 更新工具 (update-grub / grub-mkconfig)"
return 1
fi
log_success "嵌套虚拟化将在重启后恢复正常"
@@ -275,9 +296,17 @@ security_cve_module_blacklist() {
backup_file "$conf_path" 2>/dev/null || true
for mod in "${modules[@]}"; do
echo "install $mod /bin/false" >> "$conf_path"
if [[ -f "$conf_path" ]] && grep -q "^install $mod " "$conf_path" 2>/dev/null; then
log_info "模块 $mod 已在黑名单中,跳过"
continue
fi
if ! echo "install $mod /bin/false" >> "$conf_path"; then
log_error "无法写入黑名单: $conf_path"
return 1
fi
done
log_success "已写入模块黑名单: $conf_path"
return 0
}
# 通用:移除内核模块黑名单配置文件
@@ -290,7 +319,10 @@ security_cve_module_restore() {
return 0
fi
backup_file "$conf_path" 2>/dev/null || true
rm -f "$conf_path"
if ! rm -f "$conf_path"; then
log_error "无法移除黑名单配置: $conf_path"
return 1
fi
log_success "已移除模块黑名单: $conf_path"
}
@@ -376,7 +408,10 @@ security_cve_copyfail_mitigate() {
return 0
fi
security_cve_module_blacklist "pve-tools-copyfail" "algif_aead"
if ! security_cve_module_blacklist "pve-tools-copyfail" "algif_aead"; then
log_error "Copy Fail 黑名单写入失败"
return 1
fi
security_cve_rmmod_and_drop_caches "algif_aead"
log_success "Copy Fail 缓解措施已应用"
log_tips "建议立即前往 Dirty Frag 页面应用完整修补"
@@ -459,7 +494,10 @@ security_cve_dirtyfrag_mitigate() {
return 0
fi
security_cve_module_blacklist "pve-tools-dirtyfrag" "esp4" "esp6" "rxrpc"
if ! security_cve_module_blacklist "pve-tools-dirtyfrag" "esp4" "esp6" "rxrpc"; then
log_error "Dirty Frag 黑名单写入失败"
return 1
fi
security_cve_rmmod_and_drop_caches "esp4" "esp6" "rxrpc"
log_success "Dirty Frag 缓解措施已应用"
log_tips "建议升级内核以获得永久修复"
@@ -573,11 +611,15 @@ security_cve_batch_mitigate() {
fi
# 2. Dirty Frag
security_cve_module_blacklist "pve-tools-dirtyfrag" "esp4" "esp6" "rxrpc"
if ! security_cve_module_blacklist "pve-tools-dirtyfrag" "esp4" "esp6" "rxrpc"; then
log_warn "Dirty Frag 黑名单写入失败,继续执行后续步骤"
fi
security_cve_rmmod_and_drop_caches "esp4" "esp6" "rxrpc"
# 3. Copy Fail
security_cve_module_blacklist "pve-tools-copyfail" "algif_aead"
if ! security_cve_module_blacklist "pve-tools-copyfail" "algif_aead"; then
log_warn "Copy Fail 黑名单写入失败,继续执行后续步骤"
fi
security_cve_rmmod_and_drop_caches "algif_aead"
# 4. Update GRUB
@@ -621,7 +663,7 @@ security_cve_menu() {
show_menu_footer
local choice
read -p "请选择操作 [0-9]: " choice
read -rp "请选择操作 [0-9]: " choice
case "$choice" in
1) security_cve_januscape_menu ;;
2) security_cve_dirtyfrag_menu ;;
@@ -651,7 +693,7 @@ security_cve_januscape_menu() {
show_menu_footer
local choice
read -p "请选择操作 [0-4]: " choice
read -rp "请选择操作 [0-4]: " choice
case "$choice" in
1) security_cve_januscape_detect ;;
2) security_cve_januscape_mitigate ;;
@@ -680,7 +722,7 @@ security_cve_dirtyfrag_menu() {
show_menu_footer
local choice
read -p "请选择操作 [0-4]: " choice
read -rp "请选择操作 [0-4]: " choice
case "$choice" in
1) security_cve_dirtyfrag_detect ;;
2) security_cve_dirtyfrag_mitigate ;;
@@ -711,7 +753,7 @@ security_cve_copyfail_menu() {
show_menu_footer
local choice
read -p "请选择操作 [0-4]: " choice
read -rp "请选择操作 [0-4]: " choice
case "$choice" in
1) security_cve_copyfail_detect ;;
2) security_cve_copyfail_mitigate ;;