openEuler 的操作系统热补丁探究实验

举报
pluto1447 发表于 2025/12/26 17:39:44 2025/12/26
【摘要】 本实验深入探讨了 openEuler 系统的热补丁技术 SysCare。通过理论分析,掌握了热补丁基于“函数重定向”实现零停机修复漏洞的核心原理。实验流程涵盖了 SysCare 环境搭建、基于 zlib 源码与调试信息包的热补丁制作、安装及动态激活全过程。

openEuler 的操作系统热补丁探究实验

一、 实验目的

  1. 了解操作系统热补丁:掌握什么是操作系统热补丁。
  2. 学会使用openEuler 的操作系统热补丁:学会安装并使用 SysCare,即 openEuler 的操作系统热补丁服务。

二、 实验环境

  • 宿主机:Windows 10/11 或 macOS
  • 虚拟机软件:VMware Workstation
  • 目标系统:openEuler 22.03 LTS 或 24.03 LTS (x86_64 架构)
  • 开发工具:VS Code

三、 实验内容与步骤

1 操作系统热补丁

1.1 什么是操作系统热补丁

操作系统热补丁(Operating System Hot Patching),在 Linux 领域常被称为 Kernel Live Patching (KLP),是一种在不重启系统的情况下,动态修复操作系统内核或关键服务漏洞的技术。

1.2 为什么要用热补丁?

通常,操作系统内核(Kernel)出现严重安全漏洞(比如提权漏洞、缓冲区溢出)时,标准的修复流程是:

  1. 下载新内核。
  2. 安装新内核。
  3. 重启服务器 (Reboot)

痛点在于“重启”:

  • 业务中断:数据库、Web 服务、AI 训练任务会被强制中断。
  • 维护窗口难协调:对于 7x24 小时运行的系统(如双十一期间的淘宝服务器、证券交易系统),很难找到时间重启。
  • 状态丢失:内存中的缓存数据(Cache)会丢失,重启后系统需要预热,性能会抖动。

热补丁的价值零停机(Zero Downtime)。你可以在用户毫无感知的情况下,修复高危漏洞。

1.3 操作系统热补丁是如何实现的?

热补丁的核心技术原理通常涉及 “函数重定向(Function Redirection)”“跳板(Trampoline)” 机制。

以 Linux 内核为例,过程大致如下:

1. 准备阶段

开发者发现内核函数 vulnerable_func() 有 Bug,于是写了一个修复后的新函数 patched_func()。编译器将这个新函数编译成二进制机器码。

2. 加载阶段

通过内核模块(Kernel Module, .ko)将包含 patched_func() 的代码加载到内核内存中。

3. 替换阶段

热补丁工具会找到内存中旧函数 vulnerable_func()入口地址
它会利用 CPU 的指令,将旧函数的第一条指令(Prolog)修改为一条 跳转指令(JMP / ftrace call)

  • 修改前

    vulnerable_func:
        push rbp          <-- 这是第一条指令
        mov rbp, rsp
        ... (有 Bug 的代码) ...
    
  • 修改后(热补丁生效瞬间):

    vulnerable_func:
        jmp patched_func  <-- 被强行改为跳转到新函数
        mov rbp, rsp      <-- 后面的代码永远不会被执行到了
        ...
    

4. 执行阶段

当操作系统或其他进程再次调用 vulnerable_func() 时,CPU 刚读到第一行,就被“踢”到了 patched_func() 里去执行。执行完新函数后,直接返回调用者。

结果:旧代码虽然还在内存里,但实际上已经被“架空”了。


三、 操作系统热补丁的局限性

虽然听起来很完美,但热补丁不能修复所有问题。它的技术限制非常大:

  1. 不能修改数据结构(Data Structure)
    如果你想修复的 Bug 需要给某个 struct task_struct 增加一个字段(比如加个 int id),热补丁通常做不到。因为内存里已经存在的成千上万个旧结构体是没有这个字段的,代码一旦访问就会内存越界(Crash)。

    • 结论:热补丁通常只能改逻辑(代码),不能改结构(数据)。
  2. 函数签名限制
    如果新函数的参数个数、类型发生了剧烈变化,或者涉及复杂的栈操作,热补丁极其难以实现。

  3. 性能损耗
    虽然很小,但多了一次跳转指令(JMP/Trampoline),在极度高频调用的函数上可能会有纳秒级的性能损耗。


四、 主流实现方案

在业界,不同的厂商有不同的实现:

  1. kpatch (Red Hat)
    基于 ftrace 机制。它通过生成二进制差异(binary diff),暂停内核执行(stop_machine),替换函数,然后恢复。这是 RHEL/CentOS 的标准方案。

  2. kGraft (SUSE)
    主打“懒加载”。它不强制暂停所有 CPU,而是等待进程自己“慢慢切换”到新代码。

  3. Livepatch (Canonical/Ubuntu)
    基于上游 Linux 内核的通用 Live Patching 框架,结合了 kpatch 和 kGraft 的优点。

  4. Windows Hotpatching
    微软在 Azure 和 Windows Server 2022 引入的功能。它要求代码在编译时就预留好“空位”(Padding),方便后续填入跳转指令。

2 openEuler 的操作系统热补丁(SysCare)

2.1 认识 SysCare

一、简介

SysCare是一个操作系统热补丁服务,统一了操作系统内核态、用户态热补丁服务。为操作系统提供在线的热补丁修复能力,可以自动化、无感知地在线修复内核、用户态服务、动态库等系统基础组件bug和漏洞。

二、SysCare 系统功能

SysCare提供补丁制作、补丁激活和补丁卸载等功能,支持内核热补丁、用户态热补丁制作和管理:

  1. 一键式补丁制作能力:

    • 目前SysCare统一内核热补丁和用户态热补丁的制作流程,提供一键制作补丁能力,对用户屏蔽制作补丁细节及用户态、内核态补丁制作差异。
  2. 补丁安装、激活、卸载:

    • SysCare提供统一补丁管理接口,方便用户在补丁安装、激活、卸载查询使用。

三、SysCare 系统技术

  1. SysCare归一化补丁制作,对用户屏蔽补丁制作的细节及差异,提供统一的补丁管理工具,提升运维效率。
  2. SysCare提供的用户态热补丁支持用户态多进程/多线程业务热修复,修复简单、提升运维效率;对进程/线程新拉起、重启均生效。
  3. 热补丁lazy机制,克服ptrace缺陷(需全部退出内核调用),提升修复成功率。

2.2 安装 SysCare

  1. 挂载镜像

    mount /dev/sr0 /mnt
    
  2. SysCare在编译前需要安装依赖包,相关命令如下:

    sudo dnf install cmake make rust cargo kernel-devel elfutils-libelf-devel llvm clang bpftool libbpf libbpf-devel libbpf-static
    
  3. 下载 git

    sudo dnf install -y git
    
  4. 源码编译安装SysCare

    git clone https://gitee.com/openeuler/syscare.git
    cd syscare
    mkdir build
    cd build
    cmake -DCMAKE_INSTALL_PREFIX=/usr -DKERNEL_VERSION=$(uname -r) ..
    make
    make install
    

2.3 热补丁制作

用户可以使用sycare build命令制作热补丁,该命令为纯CLI工具,提供从RPM包生成热补丁包的功能,热补丁包以RPM包的形式封装维护,支持制作内核热补丁及用户态热补丁。

  1. 准备热补丁目标软件 zlib 的源码包(source rpm)及软件调试信息包(debuginfo rpm)

    # 下载 zlib 的源码包和调试包
    dnf download --source zlib
    dnf download zlib-debuginfo
    
  2. 编写用户态补丁 zlib_lab.patch

    补丁的作用是把 zlib 的版本名加上 " -Syscare-Lab-Success"

     # 查看 zlib 版本
     dnf list installed zlib
    
     # 把 1.2.13 替换成你自己的版本
     cat << EOF > zlib_lab.patch
     --- a/zutil.c
     +++ b/zutil.c
     @@ -28,7 +28,7 @@
     
     const char * ZEXPORT zlibVersion()
     {
     -    return ZLIB_VERSION;
     +    return "1.2.13-Syscare-Lab-Success";
     }
     #endif
    
  3. 编写测试程序 test_zlib.c

    cat << EOF > test_zlib.c
     #include <stdio.h>
     #include <zlib.h>
     #include <unistd.h>
    
     int main() {
         while(1) {
             printf("当前 zlib 版本: %s\n", zlibVersion());
             sleep(2); // 每2秒打印一次,方便观察动态替换
         }
         return 0;
     }
     EOF
    
     # 编译并运行测试程序(后台运行)
     gcc test_zlib.c -o test_zlib -lz
     ./test_zlib
    

    可以看到当前版本为 1.2.13

  4. 执行 syscare build 命令构建热补丁

    syscare build \
    --patch-name HP_ZLIB \
    --source zlib-*.src.rpm \
    --debuginfo zlib-debuginfo-*.rpm \
    --patch zlib_lab.patch \
    --output output
    

2.4 热补丁的管理

  1. 热补丁包安装

    dnf install output/patch-zlib-*.rpm -y
    
  2. 查询所有补丁状态

    syscare list
    

  3. 加载热补丁

    # name 替换成之前查询到的补丁名字
    syscare apply zlib-1.2.13-4.oe2403sp2/HP_ZLIB-1-1/libz.so.1.2.13
    

    可以看到程序没有重新运行,但是 zlib 的版本变了,代表热补丁加载成功。

  4. 卸载热补丁

    # name 替换成之前查询到的补丁名字
    syscare remove zlib-1.2.13-4.oe2403sp2/HP_ZLIB-1-1/libz.so.1.2.13
    

    卸载热补丁后 zlib 版本又变回 1.2.13

  5. 热补丁包卸载

    dnf remove output/patch-zlib-*
    
  6. 关闭程序

    # 查找进程
    ps -ef | grep test_zlib
    
    #删除进程
    pkill test_zlib
    

*思考题

1. 原理理解:函数重定向

在实验的理论部分提到,热补丁通过将旧函数的入口地址修改为一条“跳转指令(JMP)”来实现修复。请思考:

  • 在执行 syscare apply 后,原有的旧代码是否从内存中消失了?
  • 如果旧函数正在被某个线程执行(即处于运行栈中),此时打入热补丁是否会立刻引发崩溃?(提示:了解 SysCare 的 lazy 机制)。

2. 关键素材:Debuginfo 的作用

在实验 2.3 节中,我们除了下载源码包,还专门下载了 zlib-debuginfo

  • 为什么在“制作”热补丁时必须使用调试信息包?
  • 如果我们在一个内核版本为 6.6.0-1 的系统上,使用 6.6.0-2 版本的 Debuginfo 制作补丁,可能会发生什么后果?

3. 运维场景:热补丁 vs. 冷补丁

对比传统的 dnf update 修复漏洞(冷补丁/冷更新)与使用 syscare(热补丁),请从以下三个维度总结热补丁的优势与挑战:

  • 业务连续性(系统是否需要重启)
  • 素材准备(操作复杂程度)
  • 生效范围(是仅对当前运行进程有效,还是对重启后的进程也有效)

4. 实验现象观察

在 2.4 节激活补丁时,观察 test_zlib 程序的输出:

  • 程序在版本号从 1.2.13 变为 1.2.13-Syscare-Lab-Success 的瞬间,进程 ID (PID) 是否发生了变化?
  • 这一现象说明了热补丁与普通重启服务的本质区别是什么?
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。