CN112416360B - 热补丁的生成方法、装置和服务器 - Google Patents
热补丁的生成方法、装置和服务器 Download PDFInfo
- Publication number
- CN112416360B CN112416360B CN202011351540.6A CN202011351540A CN112416360B CN 112416360 B CN112416360 B CN 112416360B CN 202011351540 A CN202011351540 A CN 202011351540A CN 112416360 B CN112416360 B CN 112416360B
- Authority
- CN
- China
- Prior art keywords
- file
- jump
- variable
- static
- comparison
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/70—Software maintenance or management
- G06F8/73—Program documentation
Landscapes
- Engineering & Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Software Systems (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Library & Information Science (AREA)
- Stored Programmes (AREA)
- Debugging And Monitoring (AREA)
Abstract
本发明提供了一种热补丁的生成方法、装置和服务器,基于预先获取到的比较结果生成的比较文件包括:第二目标文件的__jump_table节区中,与发生变化的__jump_table节区相关联的目标结构体变量,以及目标结构体变量中指定地址的重定位信息;基于比较文件,生成包含有指定地址的重定位信息的热补丁文件。该方法中,由于比较文件中包含了与发生变化的__jump_table节区相关联的目标结构体变量,以及相关的指定地址的重定位信息;使基于该比较文件所生成的热补丁文件中也包含了指定地址的正确的重定位信息,通过该重定位信息,可以保持热补丁文件与原模块之间的关联关系,保证了热补丁文件中代码逻辑的正确性。
Description
技术领域
本发明涉及软件开发技术领域,尤其是涉及一种热补丁的生成方法、装置和服务器。
背景技术
热补丁,可以在不重启设备和服务的情况下,对设备当前软件版本的缺陷进行修复;在Linux内核中,存在很多的条件跳转指令,根据条件判断结果分别执行相应的两条分支中的其中一个分支,Linux内核中将这种判断关系与static_key绑定,在生成的目标文件中生成对应的jump_entry,将jump_entry中跳转指令相关的代码地址与static_key关联,根据static_key的值修改jump_entry中对应的指令码,相关技术中,__jump_table中包括多个元素,每个元素对应一个jump_entry,由于static_key符号在热补丁安装过程中无法修正,使热补丁在生成__jump_table节区时,通常会缺失与被修复代码有关的jump_entry,导致jump_entry与原static_key的值关联关系也丢失,从而无法保证热补丁中代码逻辑的正确性。
发明内容
本发明的目的在于提供一种热补丁的生成方法、装置和服务器,以保证热补丁中代码逻辑的正确性。
本发明提供的一种热补丁的生成方法,所述方法包括:基于预先获取到的比较结果,生成比较文件;其中,所述比较结果用于指示:相对于第一目标文件,第二目标文件中发生变化的__jump_table节区;所述第一目标文件通过对包含漏洞的源代码进行编译得到;所述第二目标文件通过对修复所述漏洞后的源代码进行编译得到;所述比较文件包括:所述第二目标文件的__jump_table节区中,与所述发生变化的__jump_table节区相关联的目标结构体变量,以及所述目标结构体变量中指定地址的重定位信息;基于所述比较文件,生成包含有所述指定地址的重定位信息的热补丁文件。
进一步的,所述第二目标文件的__jump_table节区中包括至少一个结构体变量;所述基于预先获取到的比较结果,生成比较文件的步骤包括:针对所述第二目标文件的__jump_table节区中的每个结构体变量,如果所述结构体变量与标记为新增的指定节区相关联,或者,所述结构体变量与标记为变更的指定节区相关联,将所述结构体变量保存至所述比较文件中的比较__jump_table节区;生成所述结构体变量中,第一存储地址、第二存储地址的重定位信息,并保存至所述比较文件的.rela__jump_table节区中;其中,所述第一存储地址指向条件跳转分支中的第一分支;所述第二存储地址指向所述条件跳转分支中的第二分支。
进一步的,所述结构体变量中包括static_key变量的存储地址;所述方法还包括:如果所述static_key变量包含在所述第二目标文件中,且不包含在所述第一目标文件中,生成所述结构体变量中,所述static_key变量的存储地址的重定位信息,并保存至所述比较文件的.rela__jump_table节区中。
进一步的,所述第二目标文件的__jump_table节区中包括至少一个结构体变量;所述结构体变量中包括static_key变量的存储地址;所述基于所述比较文件,生成包含有所述指定地址的重定位信息的热补丁文件的步骤之后,所述方法还包括:针对所述第二目标文件的__jump_table节区中的每个结构体变量,如果所述static_key变量不属于全局可访问符号,输出所述static_key变量的日志信息;其中,所述日志信息包括:所述static_key变量的名称和所述static_key变量所在的第一目标文件;基于所述日志信息,生成配置文件;其中,所述配置文件中包括:所述static_key变量的名称、所述static_key变量所在的第一目标文件所在的指定文件的名称、所述热补丁文件的名称、以及所述static_key变量在所述比较文件的比较__jump_table节区中的节区内偏移;其中,所述指定文件包括内核模块文件或vmlinux;基于所述配置文件,确定所述热补丁文件中,所述static_key变量的存储地址的重定位信息。
进一步的,所述static_key变量包括多个;所述基于所述配置文件,确定所述热补丁文件中,所述static_key变量的存储地址的重定位信息的步骤包括:针对每个所述static_key变量,解析所述配置文件中的热补丁文件,确定所述比较__jump_table节区在所述热补丁文件中的文件内偏移;将所述比较__jump_table节区在所述热补丁文件中的文件内偏移与所述static_key变量在所述比较文件的所述比较__jump_table节区中的节区内偏移求和,确定所述static_key变量在所述热补丁文件中的文件内偏移;获取所述static_key变量的实际运行地址;将所述实际运行地址写入所述static_key变量在所述热补丁文件中的文件内偏移对应的地址处,确定所述static_key变量的存储地址的重定位信息。
进一步的,所述确定所述static_key变量的存储地址的重定位信息的步骤之后,所述方法还包括:如果重新加载所述热补丁文件,重复执行针对每个所述static_key变量,解析所述配置文件中的热补丁文件的步骤,以确定重新加载的所述热补丁文件中,所述static_key变量的存储地址的重定位信息。
本发明提供的一种热补丁的生成装置,所述装置包括:第一生成模块,用于基于预先获取到的比较结果,生成比较文件;其中,所述比较结果用于指示:相对于第一目标文件,第二目标文件中发生变化的__jump_table节区;所述第一目标文件通过对包含漏洞的源代码进行编译得到;所述第二目标文件通过对修复所述漏洞后的源代码进行编译得到;所述比较文件包括:所述第二目标文件的__jump_table节区中,与所述发生变化的__jump_table节区相关联的目标结构体变量,以及所述目标结构体变量中指定地址的重定位信息;第二生成模块,用于基于所述比较文件,生成包含有所述指定地址的重定位信息的热补丁文件。
进一步的,所述第二目标文件的__jump_table节区中包括至少一个结构体变量;所述第一生成模块还用于:针对所述第二目标文件的__jump_table节区中的每个结构体变量,如果所述结构体变量与标记为新增的指定节区相关联,或者,所述结构体变量与标记为变更的指定节区相关联,将所述结构体变量保存至所述比较文件中的比较__jump_table节区;生成所述结构体变量中,第一存储地址、第二存储地址的重定位信息,并保存至所述比较文件的.rela__jump_table节区中;其中,所述第一存储地址指向条件跳转分支中的第一分支;所述第二存储地址指向所述条件跳转分支中的第二分支。
本发明提供的一种服务器,包括处理器和存储器,所述存储器存储有能够被所述处理器执行的机器可执行指令,所述处理器执行所述机器可执行指令以实现上述任一项所述的热补丁的生成方法。
本发明提供的一种机器可读存储介质,该机器可读存储介质存储有机器可执行指令,该机器可执行指令在被处理器调用和执行时,机器可执行指令促使处理器实现上述任一项所述的热补丁的生成方法。
本发明提供的一种热补丁的生成方法、装置和服务器,首先基于预先获取到的比较结果,生成比较文件;其中,比较结果用于指示:相对于第一目标文件,第二目标文件中发生变化的__jump_table节区;第一目标文件通过对包含漏洞的源代码进行编译得到;第二目标文件通过对修复漏洞后的源代码进行编译得到;比较文件包括:第二目标文件的__jump_table节区中,与发生变化的__jump_table节区相关联的目标结构体变量,以及目标结构体变量中指定地址的重定位信息;基于比较文件,生成包含有指定地址的重定位信息的热补丁文件。该方法中,由于比较文件中包含了与发生变化的__jump_table节区相关联的目标结构体变量,以及相关的指定地址的重定位信息;使基于该比较文件所生成的热补丁文件中也包含了指定地址的正确的重定位信息,通过该重定位信息,可以保持热补丁文件与原模块之间的关联关系,保证了热补丁文件中代码逻辑的正确性。
附图说明
为了更清楚地说明本发明具体实施方式或现有技术中的技术方案,下面将对具体实施方式或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图是本发明的一些实施方式,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
图1为本发明实施例提供的一种条件判断指令序列示意图;
图2为本发明实施例提供的另一种条件判断指令序列示意图;
图3为本发明实施例提供的一种热补丁的生成方法的流程图;
图4为本发明实施例提供的另一种热补丁的生成方法的流程图;
图5为本发明实施例提供的另一种热补丁的生成方法的流程图;
图6为本发明实施例提供的一种热补丁注册的流程图;
图7为本发明实施例提供的一种条件跳转指令修改示意图;
图8为本发明实施例提供的一种热补丁的生成装置的结构示意图;
图9为本发明实施例提供的一种服务器的结构示意图。
具体实施方式
下面将结合实施例对本发明的技术方案进行清楚、完整地描述,显然,所描述的实施例是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
补丁可以理解为用于修复某个缺陷的程序包,是能够修复软件或硬件漏洞的一些代码,是一种快速、低成本修复产品软件版本缺陷的方式。热补丁(hotfix)和升级软件版本相比,热补丁的主要优势是不会使设备当前正在运行的业务中断,即在不重启设备、服务的情况下,可以对设备当前软件版本的缺陷进行修复。
现有技术中,通常采用热补丁技术对Linux(一种开源电脑操作系统内核)内核中存在的漏洞(bug)进行热修复。当前制作热补丁的工具主要包括ksplice(一种可以在运行时对内核应用补丁的工具)和kpatch,其中,kpatch是开源社区发布的可免费获取工具源码的开源软件。
在Linux内核中,通常存在较多的条件跳转指令,根据条件判断结果分别执行相应的两条条件跳转分支中的其中一个分支,不同的分支被执行的频率通常并不相同,有些条件跳转指令,其中一条分支被执行的频率非常高,另一条分支则很少被执行到,并且执行哪一条分支通常是可控的。参见图1所示的一种条件判断指令序列示意图;该指令序列未使用static_key变量,该条件判断指令序列中,code对应的是条件跳转分支中的分支1中的指令,target对应的是条件跳转分支中的分支2中的指令。
在Linux内核中,可以将这种可控的关系与static_key变量进行绑定,可以使用“asmgoto”来实现,在编译阶段将条件跳转指令替换为无条件跳转指令,跳转到紧挨着当前指令的下一条指令,同时在生成的目标文件中生成对应的jump_entry结构体变量,将跳转指令相关的代码地址与static_key变量关联起来,参见图2所示的另一种条件判断指令序列示意图;该条件判断指令序列中,code对应的是当前判断条件的指令的位置;target对应的是如果判断条件发生改变,要跳转到的指令的位置;key是一个结构体,指向的是static_key变量的存储地址的起始位置,是一个8字节的连续的地址空间。
在__jump_table节区中的jump_entry结构体变量中,code和target两个存储空间中存储的地址指向热补丁内部的函数,key中存储的地址,指向热补丁所修复的存在bug的vmlinux或原module模块中的原static_key变量,即key所指向的对象不在当前的热补丁中,需要与原static_key变量进行关联,确认原static_key变量对应的判断条件,根据该判断条件修改code处的指令,在将热补丁加载到内核时,需要重定位到原static_key变量。
当原static_key变量的状态值被置为0时,对应条件判断的结果使处理器始终执行条件跳转分支中的分支1中的指令,当原static_key变量的状态值被置为大于0时,对应条件判断的结果使处理器始终执行条件跳转分支中的分支2中的指令,即条件判断的结果完全取决于原static_key变量的状态值,且static_key变量的状态值通常会长期保持不变,具体的,static_key变量的状态值对应的即为上述代码中enabled的值,即,如果enabled的值为0,则static_key变量的状态值被置为0,如果enabled的值大于0,则static_key的状态值被置为大于0,每使能一次,enable的值就会加1,每去使能一次,enable的值就会减1。
在实际实现时,可以根据应用场景判断需要执行的是分支1还是分支2,在Linux内核有个特定函数,该特定函数可以根据应用场景自动判断enable的值应该加1还是减1,然后根据判断结果,自动调整enable的值;比如,可能有多个需求方可以使能或去使能enable,进而调整static_key变量的状态值,默认情况下,条件跳转指令通常会执行其中的一个分支,只要有任何一个需求方需要改变条件,该需求方就会使能enable,enable的值加1,static_key变量的状态值被置为大于0,就可以切换到另一个分支;只有当所有需求方都不需要执行另一个分支时,才能再切换回原来的分支。
当前热补丁制作工具在制作热补丁时,在生成__jump_table节区时,受到原static_key变量在热补丁安装过程中无法修正的问题的限制,导致大部分与被修复的代码有关的jump_entry结构体变量,无法生成到热补丁的__jump_table节区中。另外,当前的热补丁制作工具在处理__jump_table节区时,对大部分jump_entry结构体变量通常会采取忽略的处理方式,导致生成的热补丁中没有__jump_table节区,或者__jump_table节区中缺少与被改代码相关的jump_entry结构体变量,因此,大部分jump_entry结构体变量与原static_key变量的关联关系也会丢失;具体的,如果热补丁中生成的__jump_table节区中,只要有一个jump_entry结构体变量存在缺失,就可以认为该__jump_table节区存在缺失或不完整,或者,热补丁中可能缺失了整个__jump_table节区,也可以认为该__jump_table节区存在缺失或不完整。
在实际实现时,原static_key变量主要有以下三种存在形式:第一种存在形式为:原static_key变量为全局可访问符号,使用EXPORT_SYMBOL导出,不仅在vmlinux中,在其它模块中均可对此static_key变量进行访问;第二种存在形式为:原static_key变量为局部静态符号,即,原static_key变量是static符号,作用域局限在原static_key变量所在的源码文件中;比如,用户编写了一个新函数,该新函数需要访问原static_key变量,如果这个新函数与原来存在漏洞的函数不在同一个源码文件中,即不在原static_key变量所在的源码文件,则该新函数就无法访问原static_key变量,该方式的限定范围最小;第三种存在形式为:原static_key变量为模块内全局符号,没有经过static限制作用域,但是也没有使用EXPORT_SYMBOL机制导出为外部符号,若原static_key变量在vmlinux中,则仅可在vmlinux中访问;若原static_key变量在模块中,仅可在原模块中访问,在其它模块中不可见,若在其它模块中使用到此static_key变量,当此模块将要安装到内核中时,会因无法解析原static_key变量的存储地址而报错,因此,无法通过动态重定位的方式,对被限制作用域的static_key变量的存储地址进行重定位;比如,有多个模块,每个模块中可能包括多个源码文件,同一模块中的多个源码文件之间可以相互访问该模块内的原static_key变量,但其他模块不能访问该模块内的原static_key变量。
当前热补丁制作工具在制作热补丁时,会对含bug的目标文件与修复bug后的目标文件进行比对;若两个目标文件中均不包含__jump_table节区,则可以正常生成热补丁。若原含bug的目标文件与修复bug后的目标文件中的__jump_table节区中的jump_entry结构体变量与被修复的代码有关,且这些jump_entry结构体变量无法在热补丁加载阶段完成符号地址的自动修正,当前热补丁的处理策略是忽略相关的jump_entry结构体变量,这种处理策略会导致热补丁中与static_key变量相关的代码,失去与原static_key变量的关联关系。
如果缺失了jump_entry结构体变量,则code与static_key变量的关系也会丢失,相关code所指向的代码默认只执行条件跳转分支中的一个固定的分支程序,不仅无条件跳转指令没有在模块加载时被替换为空操作指令,而且,当原static_key变量的值发生改变时,由于没有code与static_key变量的关联关系,导致热补丁中的code处的指令并没有随着static_key变量的状态值的改变而调整为跳转到target的跳转指令,因此,也无法执行另一个分支的程序,造成逻辑错误。
所以,当前热补丁工具中对原含bug的代码涉及的jump_entry结构体变量采取直接忽略的处理策略,无法将jump_entry结构体变量与原static_key变量关联起来,且相关的代码,固定只执行其中一个分支中的代码,当static_key变量的状态值发生改变,比如,从0变为大于0的值时,存在逻辑错误。综合上述可知,现有技术中的热补丁技术,在热补丁中生成的__jump_table节区存在缺失或不完整的问题,并且,无法将热补丁中所有的static_key变量与原static_key相关联。
基于此,本发明实施例提供了一种热补丁的生成方法、装置和服务器,该技术可以应用于移动终端、计算机等设备,尤其可以应用于需要生成热补丁的应用中。为便于对本实施例进行理解,首先对本发明实施例所公开的一种热补丁的生成方法进行详细介绍;如图3所示,该方法包括如下步骤:
步骤S302,基于预先获取到的比较结果,生成比较文件;其中,比较结果用于指示:相对于第一目标文件,第二目标文件中发生变化的__jump_table节区;第一目标文件通过对包含漏洞的源代码进行编译得到;第二目标文件通过对修复漏洞后的源代码进行编译得到;比较文件包括:第二目标文件的__jump_table节区中,与发生变化的__jump_table节区相关联的目标结构体变量,以及目标结构体变量中指定地址的重定位信息。
上述目标结构体变量可以是jump_entry结构体变量等;该目标结构体变量的数量可能是一个,也可能是多个;上述指定地址通常包括目标结构体变量中所包含的static_key变量的存储地址,以及指向条件跳转分支的相关存储地址,如,指向条件跳转分支中的第一分支的第一存储地址和第二分支的第二存储地址;上述重定位信息可以理解为对目标结构体变量中的指定地址进行重定位时的相关信息;在实际实现时,当需要在Linux内核热补丁中修复__jump_table节区时,热补丁制作工具通常会通过比较两个目标文件,如第一目标文件origin/obj.o和第二目标文件patched/obj.o,根据比较差异结果生成新的目标文件,如output/tmp.o,即为上述比较文件;该比较文件中通常包括第二目标文件的__jump_table节区中,与发生变化的__jump_table节区相关联的目标结构体变量,还可以包括该目标结构体变量中指定地址的重定位信息。
为方便说明,以第一目标文件的文件名是origin/obj.o,第二目标文件的文件名是patched/obj.o,比较文件的文件名是output/tmp.o为例,origin/obj.o可以理解为,在打热补丁之前,包含有漏洞(bug)的源代码经过编译后所生成的目标文件,该origin/obj.o文件可以是ELF(Executable and Linkable Format,可执行和可链接的格式)文件格式;patched/obj.o可以理解为,在打热补丁之后,修复了漏洞(bug)的源代码经过编译后所生成的目标文件,该patched/obj.o文件也可以是ELF文件格式;根据origin/obj.o和patched/obj.o的比较结果所生成的比较文件output/tmp.o也可以是ELF文件格式。
比较过程调整前,一般首先需要对orig/obj.o文件和patched/obj.o文件,使用ELF格式进行解析,解析后的orig/obj.o文件和解析后的patched/obj.o文件中通常包括多个节区section,可以根据不同的功能来确定多个节区section,每个节区section可以对应一类功能,可能有多个节区section对应同一类功能,比如,多个节区section都是文字等;对解析后的两个文件内的节区section进行比较,相同的节区section会被标记为SAME,即相同,新节区section会被标记为NEW,即新增,存在差异变化的节区section被标记为CHANGED,即变更;其中,相同的节区section可以理解为,在解析后的orig/obj.o文件和解析后的patched/obj.o文件中存在同名的两个节区,且此同名节区内容相同;新节区section可以理解为,在解析后的orig/obj.o文件中不存在解析后的patched/obj.o文件中的同名节区,即在解析后的patched/obj.o文件中的新增内容,如新增函数、符号等;存在差异变化的节区section可以理解为,在解析后的orig/obj.o文件和解析后的patched/obj.o文件中存在同名的两个节区,且此同名节区内容不同。
上述目标结构体变量通常与上述节区section的比较结果有关,比如,在第二目标文件的__jump_table节区所包含的多个结构体变量中,如果某个结构体变量与标记为CHANGED的节区section有关联,或者与标记为NEW的节区section有关联,则可以将该结构体变量确定为目标结构体变量,该__jump_table节区即为发生变化的__jump_table节区。相关技术中,在生成热补丁时,也可以对第一目标文件和第二目标文件进行比较,可以对__jump_table节区进行比较,也可以比较出SAME、CHANGED和NEW,但只是会反馈一个报错信息,并不会进行相关处理,在生成热补丁时会忽略__jump_table节区中的结构体变量,使热补丁中缺失了__jump_table节区。
步骤S304,基于比较文件,生成包含有指定地址的重定位信息的热补丁文件。
当生成上述比较文件后,基于该比较文件,最终生成热补丁文件,比如,通过上述步骤和热补丁工具也可以生成其他比较文件,将该比较文件,与其他比较文件链接后生成最终的热补丁文件,该热补丁文件的文件名可以是kpatch-module.ko等,该热补丁文件也可以是ELF格式文件;由于比较文件中包含了第二目标文件的__jump_table节区中,与发生变化的__jump_table节区相关联的目标结构体变量,以及该目标结构体变量中指定地址的重定位信息;因此,所生成的热补丁文件中也包含了指定地址的重定位信息。
本发明实施例提供的一种热补丁的生成方法,首先基于预先获取到的比较结果,生成比较文件;其中,该比较结果用于指示:相对于第一目标文件,第二目标文件中发生变化的__jump_table节区;该第一目标文件通过对包含漏洞的源代码进行编译得到;该第二目标文件通过对修复漏洞后的源代码进行编译得到;该比较文件包括:第二目标文件的__jump_table节区中,与发生变化的__jump_table节区相关联的目标结构体变量,以及该目标结构体变量中指定地址的重定位信息;然后基于该比较文件,生成包含有指定地址的重定位信息的热补丁文件。该方法中,由于比较文件中包含了与发生变化的__jump_table节区相关联的目标结构体变量,以及相关的指定地址的重定位信息;使基于该比较文件所生成的热补丁文件中也包含了指定地址的正确的重定位信息,通过该重定位信息,可以保持热补丁文件与原模块之间的关联关系,保证了热补丁文件中代码逻辑的正确性。
本发明实施例还提供了另一种热补丁的生成方法,该方法在上述实施例方法的基础上实现;该方法重点描述基于预先获取到的比较结果,生成比较文件的具体过程,具体对应下述步骤S402至步骤S406,该方法中,第二目标文件的__jump_table节区中包括至少一个结构体变量;结构体变量中包括static_key变量的存储地址;以结构体变量为jump_entry结构体变量为例,在第二目标文件的__jump_table节区中可以包括多个jump_entry结构体变量;该jump_entry结构体变量中包括static_key变量的存储地址,比如该存储地址可以以符号名key来表示等;如图4所示,该方法包括如下步骤:
步骤S402,针对第二目标文件的__jump_table节区中的每个结构体变量,如果结构体变量与标记为新增的指定节区相关联,或者,结构体变量与标记为变更的指定节区相关联,将结构体变量保存至比较文件中的比较__jump_table节区。
上述新增的指定节区可以理解为,解析后的第一目标文件和解析后的第二目标文件在按节区section进行比较时,被标记为新增的节区section;上述变更的指定节区可以理解为,解析后的第一目标文件和解析后的第二目标文件在按节区section进行比较时,被标记为变更的节区section。
在基于预先获取到的比较结果生成比较文件的过程中,当对__jump_table节区进行处理时,可以采用特殊节区处理方式进行处理,具体的,以结构体变量为jump_entry结构体变量为例,由于第二目标文件的__jump_table节区中包括可能包括多个jump_entry结构体变量,可以对该_jump_table节区中的每个jump_entry结构体变量逐个分析,在分析过程中,如果当前jump_entry结构体变量与标记为新增的指定节区或标记为变更的指定节区之间有调用关系,即有关联关系,则通常可以认为当前jump_entry结构体变量也存在变化,这时可以将该当前jump_entry结构体变量生成到比较文件的比较__jump_table节区中,比如,如果比较文件的文件名为output/tmp.o,则将该当前jump_entry结构体变量保存到比较文件output/tmp.o的比较__jump_table节区中;再比如,第二目标文件的__jump_table中有5个jump_entry结构体变量,经过比对,发现有两个jump_entry结构体变量是与标记为新增的指定节区有关联的,就可以把这两个jump_entry结构体变量复制到比较文件output/tmp.o的比较__jump_table节区中。
如果当前jump_entry结构体变量与标记为相同的指定节区之间有调用关系,即有关联关系,则不会将其生成到比较文件的比较__jump_table节区中,比如,仍以比较文件的文件名为output/tmp.o为例,则不会将该当前jump_entry结构体变量保存到比较文件output/tmp.o的比较__jump_table节区中。
步骤S404,生成结构体变量中,第一存储地址、第二存储地址的重定位信息,并保存至比较文件的.rela__jump_table节区中;其中,第一存储地址指向条件跳转分支中的第一分支;第二存储地址指向条件跳转分支中的第二分支。
假设第一存储地址的符号名以code来表示,第二存储地址的符号名以target来表示,结构体变量为jump_entry结构体变量,如果jump_entry结构体变量与标记为新增的指定节区相关联,或者,与标记为变更的指定节区相关联,则将该jump_entry结构体变量的code和target的重定位信息生成到比较文件的.rela__jump_table中,如比较文件output/tmp.o的.rela__jump_table中;其中,.rela__jump_table节区与__jump_table节区通常是一一对应的,在热补丁加载之前,jump_entry结构体变量中的code和target一般是不确定的,在编译生成热补丁阶段是无法生成的,只有加载到内核之后,才能确定唯一的值,如果需要对code和target的关联关系进行操作,需要在热补丁中保留一个重定位相关的信息,这个信息就可以存在.rela__jump_table中,当需要对code和target这两个地址进行重定位时,只需要把这个重定位信息保留到内核,内核就会自动从.rela__jump_table节区中查找相关的重定位信息,并把查找到的地址填进相应的位置。
而现有技术中,原热补丁生成工具的早期版本中,在生成比较文件output/tmp.o过程中,对__jump_table节区的.rela__jump_table通常会采取直接忽略的处理方式。虽然随着热补丁工具的不断改进,对__jump_table节区的有效性进行了识别,但是也仅保留了对static_key变量在vmlinux和热补丁模块本身的重定位信息,仍然缺失对上述第一存储地址code和第二存储地址target的重定位信息,从而无法解决static_key变量存在vmlinux中,在热补丁安装到内核的过程中符号地址无法修正的问题,留下了隐患。
步骤S406,如果static_key变量包含在第二目标文件中,且不包含在第一目标文件中,生成结构体变量中,static_key变量的存储地址的重定位信息,并保存至比较文件的.rela__jump_table节区中。
如果在第二目标文件中出现了新的static_key变量,即该static_key变量仅包含在第二目标文件中,而并没有包含在第一目标文件中,则生成该static_key变量的存储地址的重定位信息,并将该重定位信息保存至比较文件的.rela__jump_table节区中;比如,该static_key变量的存储地址以符号key来表示,比较文件的文件名为output/tmp.o,则将该key的重定位信息生成至比较文件output/tmp.o的.rela__jump_table节区中。
步骤S408,基于比较文件,生成包含有指定地址的重定位信息的热补丁文件。
本发明实施例提供的一种热补丁的生成方法,首先针对第二目标文件的__jump_table节区中的每个结构体变量,如果结构体变量与标记为新增的指定节区相关联,或者,结构体变量与标记为变更的指定节区相关联,将结构体变量保存至比较文件中的比较__jump_table节区;然后生成结构体变量中,第一存储地址、第二存储地址的重定位信息,并保存至比较文件的.rela__jump_table节区中;如果static_key变量包含在第二目标文件中,且不包含在第一目标文件中,生成结构体变量中,static_key变量的存储地址的重定位信息,并保存至比较文件的.rela__jump_table节区中;最后基于比较文件,生成包含有指定地址的重定位信息的热补丁文件。该方法基于第一目标文件和第二目标文件的比较结果所生成的比较文件中,包含了发生变化的__jump_table节区相关联的目标结构体变量,以及所述目标结构体变量中指定地址的重定位信息;进而使基于该比较文件所生成的热补丁文件中也包含了指定地址的正确的重定位信息,通过该重定位信息,可以保持热补丁文件与原模块之间的关联关系,进而保证了热补丁文件中代码逻辑的正确性。
本发明实施例还提供了另一种热补丁的生成方法,该方法在上述实施例方法的基础上实现;该方法中,第二目标文件的__jump_table节区中包括至少一个结构体变量;结构体变量中包括static_key变量的存储地址;static_key变量包括多个;如图5所示,该方法包括如下步骤:
步骤S502,基于预先获取到的比较结果,生成比较文件;其中,比较结果用于指示:相对于第一目标文件,第二目标文件中发生变化的__jump_table节区;第一目标文件通过对包含漏洞的源代码进行编译得到;第二目标文件通过对修复漏洞后的源代码进行编译得到;比较文件包括:第二目标文件的__jump_table节区中,与发生变化的__jump_table节区相关联的目标结构体变量,以及目标结构体变量中指定地址的重定位信息。
步骤S504,基于比较文件,生成包含有指定地址的重定位信息的热补丁文件。
步骤S506,针对第二目标文件的__jump_table节区中的每个结构体变量,如果static_key变量不属于全局可访问符号,输出static_key变量的日志信息;其中,日志信息包括:static_key变量的名称和static_key变量所在的第一目标文件。
由于第二目标文件的__jump_table节区中可能包括多个结构体变量,对于每个结构体变量,如果该结构体变量中所包含的static_key变量的存储地址所指向的static_key变量属于上述全局可访问符号,可以理解为在内核中的任何模块都可以访问该static_key变量,即不仅在vmlinux中,在内核中的其他模块均可以使用该static_key变量,且该static_key变量通常使用EXPORT_SYMBOL导出,此被EXPORT_SYMBOL导出的static_key变量,在vmlinux、内核模块和热补丁中,均可访问;在实际实现时,如果static_key变量在原vmlinux或内核模块中,则通常会检查该static_key变量是否为EXPORT_SYMBOL,即,检查该static_key变量是否属于全局可访问符号,如果是,则将该static_key变量的存储地址的重定位信息,生成至比较文件的.rela__jump_table节区中。
如果static_key变量不属于全局可访问符号,则不会将该static_key变量的存储地址的重定位信息生成至比较文件的.rela__jump_table节区中,这时通常会打印输出static_key变量的日志信息,打印输出的日志信息中通常包括static_key变量的名称和static_key变量所在的第一目标文件,如static_key变量的符号名为key,符号名为key的static_key变量所在的第一目标文件orig/obj.o等,在日志信息中,static_key变量所在的第一目标文件的信息可以以objname来表示;另外,该日志信息中通常还包括符号名为key的static_key变量在第一目标文件orig/obj.o的__jump_table节区中的节区内偏移,该偏移可以用orig-offset来表示,具体的,该偏移是基于第一目标文件中orig/obj.o的__jump_table节区的起始位置得到的偏移,比如,以结构体变量为jump_entry结构体变量,该jump_entry结构体变量中的第一存储地址的符号名以code来表示,第二存储地址的符号名以target来表示为例,假如比较文件output/tmp.o的__jump_table节区中的第1个符号名为key的static_key变量,在第一目标文件orig/obj.o的__jump_table节区中属于第4个jump_entry结构体变量,即,该第4个jump_entry结构体变量的前面有3个jump_entry结构体变量,用3乘以每个jump_entry结构体变量的长度,再加上第4个jump_entry结构体变量中code和target的长度,即为上述orig-offset偏移。
另外,日志信息中通常还包括符号名为key的static_key变量在比较文件output/tmp.o的__jump_table节区中的节区内偏移,该偏移可以用now-offset来表示,具体的,该偏移是基于比较文件output/tmp.o的__jump_table节区的起始位置得到的偏移,具体可参考上述偏移计算方式,在此不再赘述。
步骤S508,基于日志信息,生成配置文件;其中,配置文件中包括:static_key变量的名称、static_key变量所在的第一目标文件所在的指定文件的名称、热补丁文件的名称、以及static_key变量在比较文件的比较__jump_table节区中的节区内偏移;其中,指定文件包括内核模块文件或vmlinux。
上述vmlinux可以理解为未压缩的内核,该vmlinux通常是ELF文件,即编译出来的最原始的文件;在实际实现时,对于没有在比较文件中生成重定位信息的static_key变量符号名key,需要分析上述所输出的日志信息,以生成配置文件;具体的,通过分析上述日志信息,可以获取到需要重定位的key,即static_key变量的符号名,可以根据objname获取到第一目标文件orig/obj.o所在的原内核模块名orig-module或者vmlinux,可以获取到最终生成的热补丁文件名称,如kpatch-module.ko;以及符号名为key的static_key变量在比较文件output/tmp.o的__jump_table节区中的节区内偏移,即上述now-offset;基于从日志信息中所分析出的上述信息,所生成的配置文件中就可以包括以下四项配置信息,即key,orig-module或vmlinux,kpatch-module.ko和now-offset。
需要说明的是,在所生成的配置文件中,每一条重定位信息对应一个配置项,该配置项中包含上述四项配置信息,也可以理解为配置文件中的每一行可以对应一个包含上述四项配置信息的配置项,每个配置项对应一个static_key变量的存储地址的重定位信息。同一个static_key变量可以对应多个配置项,对应多条static_key变量的存储地址的重定位信息。
步骤S510,基于配置文件,确定热补丁文件中,static_key变量的存储地址的重定位信息。
具体的,该步骤S510可以通过下述步骤一至步骤五实现:
步骤一,针对每个static_key变量,解析配置文件中的热补丁文件,确定比较__jump_table节区在热补丁文件中的文件内偏移。
在实际实现时,由于static_key变量可能包括多个,需要针对每个static_key变量,读取其对应的配置文件中的热补丁文件,如kpatch-module.ko,并使用操作系统自带的binutils(一种二进制工具集)工具解析该热补丁文件,获取到比较__jump_table节区在该热补丁文件中的文件内偏移。
步骤二,将比较__jump_table节区在热补丁文件中的文件内偏移与static_key变量在比较文件的比较__jump_table节区中的节区内偏移求和,确定static_key变量在热补丁文件中的文件内偏移。
将上述确定的比较__jump_table节区在热补丁文件中的文件内偏移,加上配置文件中的now-offset节区内偏移,即加上static_key变量在比较文件的比较__jump_table节区中的节区内偏移,即可确定static_key变量在热补丁文件kpatch-module.ko中的文件内偏移,该偏移可以以file-offset来表示。
步骤三,获取static_key变量的实际运行地址。
在实际实现时,获取static_key变量的实际运行地址的方式可以包括两种:即静态获取方式和动态获取方式;其中,静态获取方式针对的是在编译阶段就能确定的符号地址,可以通过分析vmlinux文件解析出其运行时地址,因为此类地址在内核运行阶段不会发生改变,所以静态获取的地址即动态运行时地址;动态获取方式是指内核在运行时,部分符号地址可能会发生变化,所以每次安装热补丁前,都要动态获取运行时的符号地址,可以通过读取/proc/kallsyms文件中的符号地址,获取动态符号地址,并通过orig-module或vmlinux区分不同模块中的同名符号;其中,/proc/kallsyms包含了内核中的函数符号(包括没有EXPORT_SYMBOL)、全局变量(用EXPORT_SYMBOL导出的全局可访问符号)。
步骤四,将实际运行地址写入static_key变量在热补丁文件中的文件内偏移对应的地址处,确定static_key变量的存储地址的重定位信息。
在实际实现时,可以使用二进制文件编辑工具,将获取到的运行时static_key变量的实际运行地址,写入到热补丁文件中的文件内偏移对应的地址处,如,文件内偏移file-offset处,完成static_key变量的存储地址的静态重定位;另外,用户也可以参与该写入步骤,当接收到用户输入的写入指令后,将实际运行地址写入static_key变量在热补丁文件中的文件内偏移对应的地址处。针对每个static_key变量,重复执行上述步骤一至步骤四,直到配置文件中的所有static_key变量的存储地址都被静态重定位。
步骤五,如果重新加载热补丁文件,重复执行针对每个static_key变量,解析配置文件中的热补丁文件的步骤,以确定重新加载的热补丁文件中,static_key变量的存储地址的重定位信息。
当热补丁被卸载之后,再次安装前,需要重复执行上述步骤一至步骤四的过程,以重新对配置文件中所有的static_key变量的存储地址进行静态重定位。
由本实施例可知,上述重定位过程主要分为两个阶段,即制作热补丁阶段和安装热补丁阶段,其中,制作热补丁阶段主要用于生成需要重定位的static_key变量的配置文件,安装热补丁阶段主要用于根据配置文件进行static_key变量的存储地址的静态重定位。
本发明实施例提供的一种热补丁的生成方法,修改了现有技术中热补丁制作工具的部分功能,通过比较第一目标文件和第二目标文件的差异,生成热补丁所需的比较结果,在生成过程中对__jump_table和.rela__jump_table两个特殊节区进行特殊处理,使热补丁中具有__jump_table节区和其对应的重定位节区.rela__jump_table;其中__jump_table节区中不包含与被修改代码无关的jump_entry结构体变量;另外,在.rela__jump_table节区的生成过程中,有选择的生成static_key变量存储地址的重定位信息,根据static_key变量是否为EXPORT_SYMBOL判断是否生成其重定位信息,若存在无法动态重定位的static_key变量,通过打印日志的方式将相关信息打印出来,并根据日志信息生成这些static_key变量的配置文件,根据配置文件中的配置,获取static_key变量的实际运行地址,并将该实际运行地址静态写入热补丁文件,完成对这些static_key变量的存储地址的静态重定位。
下面对现有技术中存在的对模块加载与static_key变量的存储地址的重定位之间的冲突问题进行说明,参见图6所示的一种热补丁注册的流程图,该热补丁注册流程主要包括以下S1-S6共六个阶段:S1:加载module.ko,即加载内核模块;S2:加载__jump_table节区;S3:修正符号表中static_key变量的存储地址key符号地址;其中,符号表可以理解为一种内核符号及其对应地址的列表;S4:根据.rela__jump_table节区中的重定位符号信息,重定位并回填__jump_table节区中的code、target和key的地址;S5:根据__jump_table节区中key的地址大小,重新排列jump_entry结构体变量,并将jump_entry结构体变量通过key与static_key变量进行关联,根据static_key变量的值,修改code处的指令码;S6:热补丁模块自我初始化,完成热补丁的注册。
当热补丁中包含__jump_table节区,内核在加载热补丁时,对static_key变量的存储地址的重定位,也会受到局限,在S3阶段中,内核不会修正未使用EXPORT_SYMBOL导出的static_key变量的存储地址,并将此种使用方式视作非法操作,加以拦截,导致热补丁安装失败,且无法修改已经运行的内核对此种变量的处理方式。如果S3阶段中未对static_key变量的存储地址,即key符号地址进行修正,则在S5阶段中,就无法将jump_entry结构体变量与static_key变量进行关联,也无法根据static_key变量的值修改code处的指令码。如果在S5阶段不对static_key变量的存储地址进行修正,而是在S6阶段进行修正,则会错过内核对特殊节区__jump_table节区进行关联处理的时机,也就是说,此时修正的static_key变量的存储地址,已经没有意义,不会被内核再次关联。
综合上述实施例可知,本申请中的热补丁生成方法主要包括以下四个过程:过程一,比较含bug的目标文件与修复bug后的目标文件时,将相关的jump_entry结构体变量生成到热补丁中,使热补丁含有__jump_table节区;过程二,生成的热补丁中包含对__jump_table节区中jump_entry结构体变量所含元素进行重定位的.rela__jump_table节区;过程三,.rela__jump_table节区中含所有code、target的重定位信息;对于原static_key变量被EXPORT_SYMBOL的key符号,在.rela__jump_table节区中包含此key符号的重定位信息;对于原static_key变量未被EXPORT_SYMBOL的key符号,不包含此key符号的重定位信息;过程四,每次热补丁安装前,若热补丁中使用到了未被EXPORT_SYMBOL的static_key变量,修改热补丁文件,对__jump_table节区中的jump_entry结构体变量中的key符号进行静态重定位。
通过上述热补丁的生成方法,解决了现有技术中存在的以下三个主要问题:
A.修复了热补丁中缺失__jump_table节区的问题。
通过修改热补丁制作工具,在比较含bug的目标文件与修复bug后的目标文件时,当遇到有jump_entry结构体变量与差异代码相关时,修改现有技术中忽略jump_entry结构体变量的处理策略,将相关的jump_entry结构体变量生成到热补丁中,使热补丁包含__jump_table节区;与被修改代码无关的jump_entry结构体变量不会生成到热补丁中。
B.解决了jump_entry结构体变量与原static_key变量关联的问题。
通过修改热补丁制作工具,为与被修改代码有关的jump_entry结构体变量中的code和target,生成重定位信息,重定位信息存储在.rela__jump_table节区中,对原static_key变量被EXPORT_SYMBOL的key符号,也为其生成重定位符号信息。当热补丁模块加载到内核时,内核可以自动修正jump_entry结构体变量中key符号的地址,并且在内核处理__jump_table节区时,自动将jump_entry结构体变量与原static_key变量的key关联起来,修改code处的指令码。
C.解决了static_key变量作用域受限时符号重定位的问题。
通过修改热补丁制作工具,在为jump_entry结构体变量生成重定位符号信息时,对原static_key变量未使用EXPORT_SYMBOL的key符号,不在.rela__jump_table节区中为其生成重定位信息,而是在热补丁安装到内核之前,通过查询static_key变量的实际运行地址,使用静态重定位的方式,修改热补丁文件,直接将static_key变量的实际运行地址填入__jump_table节区中jump_entry结构体变量的key的存储位置。因此,当热补丁安装到内核时,内核处理__jump_table节区,static_key变量的存储地址,即key符号的符号地址已经被修正,因此,可以正确处理jump_entry结构体变量与原static_key变量的关联关系,使其正确关联,保证热补丁中__jump_table节区的功能正确。
上述热补丁的生成方法中,对__jump_table节区的修复方式,是在热补丁工具kpatch的基础上,将对__jump_table节区的支持进一步优化,以完成对热补丁功能的修复和完善,将和热补丁相关的jump_entry结构体变量生成到热补丁中,可以在热补丁中支持与被修改代码相关的__jump_table节区,并使其在热补丁中生效,恢复热补丁中jumpentry结构体变量与原static_key变量的关联关系,当原来的static_key变量的状态值发生改变时,热补丁中的对应的指令码会被修改为匹配的指令码,保证热补丁中代码逻辑的正确性,从而消除热补丁中的逻辑错误。
参见图7所示的一种条件跳转指令修改示意图,图7中,使用static_key变量时,Linux内核可以根据static_key变量的当前状态值修改条件跳转指令为非条件跳转指令,即,将跳转指令相关的代码地址与static_key变量的状态值进行了关联;在静态编译生成的条件跳转指令序列中,code处的条件跳转指令为jmp分支1,判断是否存在__jump_table节区,如果存在__jump_table节区,该__jump_table节区中通常包括至少一个jump_entry结构体变量,这时,当static_key变量的状态值为0时,code处的条件跳转指令被修改为nop(空操作指令),不需要判断,直接执行条件跳转分支中的分支1中的指令;当static_key变量的状态值为大于0时,如状态值为1时,code处的条件跳转指令被修改为jmp target无条件跳转指令,直接跳转到分支2,以执行分支2中的指令。即当需要执行分支1时,通过将static_key变量的状态值减为0即可,当需要执行分支2时,通过累加static_key变量的状态值,使其大于0即可。需要说明的是,在static_key变量的状态值发生改变的同时,通常就把条件跳转的指令进行了替换。
在实际实现时,CPU(central processing unit,中央处理器)在运行过程中,在顺序执行程序时,可以缓存相应的指令,当需要执行该指令时,可以直接从CPU的缓存中获取该指令,以提高执行效率;通过该处理方式可以提高处理器分支预测的指令在指令缓存中的命中率,提高执行效率;而对于有条件判断的条件跳转指令,在根据条件判断的结果执行相应的指令时,需要等到实际判断结果出来以后,才能继续缓存对应分支的指令,相对来说执行效率较低。
需要说明的是,当内核加载或模块加载时,会检查__jump_table节区中的jump_entry结构体变量,如果static_key变量的状态值为0,则将code处的条件跳转指令修改为“空操作”指令,顺序执行分支1中的指令,当static_key变量的状态值为1时,则将code处的条件跳转指令修改为无条件跳转指令,跳转的目标地址为target,执行分支2中的指令。
上述热补丁的生成方法已经过验证,验证结果显示,该方法可以解决现有热补丁中缺失__jump_table节区缺失的问题,可以解决因__jump_table节区无法处理而导致热补丁制作失败的问题,使热补丁能修复更多的线上问题;另外,本方法适用于x86_64指令架构的所有使用了__jump_table节区的内核版本,可以在线上环境使用,可修复线上宕机、内存泄露等问题。
本发明实施例还提供了一种热补丁的生成装置,如图8所示,该装置包括:第一生成模块80,用于基于预先获取到的比较结果,生成比较文件;其中,比较结果用于指示:相对于第一目标文件,第二目标文件中发生变化的__jump_table节区;第一目标文件通过对包含漏洞的源代码进行编译得到;第二目标文件通过对修复漏洞后的源代码进行编译得到;比较文件包括:第二目标文件的__jump_table节区中,与发生变化的__jump_table节区相关联的目标结构体变量,以及目标结构体变量中指定地址的重定位信息;第二生成模块81,用于基于比较文件,生成包含有指定地址的重定位信息的热补丁文件。
本发明提供的一种热补丁的生成装置,首先基于预先获取到的比较结果,生成比较文件;其中,该比较结果用于指示:相对于第一目标文件,第二目标文件中发生变化的__jump_table节区;该第一目标文件通过对包含漏洞的源代码进行编译得到;该第二目标文件通过对修复漏洞后的源代码进行编译得到;该比较文件包括:第二目标文件的__jump_table节区中,与发生变化的__jump_table节区相关联的目标结构体变量,以及该目标结构体变量中指定地址的重定位信息;然后基于该比较文件,生成包含有指定地址的重定位信息的热补丁文件。该装置中,由于比较文件中包含了与发生变化的__jump_table节区相关联的目标结构体变量,以及相关的指定地址的重定位信息;使基于该比较文件所生成的热补丁文件中也包含了指定地址的正确的重定位信息,通过该重定位信息,可以保持热补丁文件与原模块之间的关联关系,保证了热补丁文件中代码逻辑的正确性。
进一步的,第二目标文件的__jump_table节区中包括至少一个结构体变量;第一生成模块80还用于:针对第二目标文件的__jump_table节区中的每个结构体变量,如果结构体变量与标记为新增的指定节区相关联,或者,结构体变量与标记为变更的指定节区相关联,将结构体变量保存至比较文件中的比较__jump_table节区;生成结构体变量中,第一存储地址、第二存储地址的重定位信息,并保存至比较文件的.rela__jump_table节区中;其中,第一存储地址指向条件跳转分支中的第一分支;第二存储地址指向条件跳转分支中的第二分支。
进一步的,结构体变量中包括static_key变量的存储地址;该装置还用于:如果static_key变量包含在第二目标文件中,且不包含在第一目标文件中,生成结构体变量中,static_key变量的存储地址的重定位信息,并保存至比较文件的.rela__jump_table节区中。
进一步的,第二目标文件的__jump_table节区中包括至少一个结构体变量;结构体变量中包括static_key变量的存储地址;该装置还用于:针对第二目标文件的__jump_table节区中的每个结构体变量,如果static_key变量不属于全局可访问符号,输出static_key变量的日志信息;其中,日志信息包括:static_key变量的名称和static_key变量所在的第一目标文件;基于日志信息,生成配置文件;其中,配置文件中包括:static_key变量的名称、static_key变量所在的第一目标文件所在的指定文件的名称、热补丁文件的名称、以及static_key变量在比较文件的比较__jump_table节区中的节区内偏移;其中,指定文件包括内核模块文件或vmlinux;基于配置文件,确定热补丁文件中,static_key变量的存储地址的重定位信息。
进一步的,static_key变量包括多个;该装置还用于:针对每个static_key变量,解析配置文件中的热补丁文件,确定比较__jump_table节区在热补丁文件中的文件内偏移;将比较__jump_table节区在热补丁文件中的文件内偏移与static_key变量在比较文件的比较__jump_table节区中的节区内偏移求和,确定static_key变量在热补丁文件中的文件内偏移;获取static_key变量的实际运行地址;将实际运行地址写入static_key变量在热补丁文件中的文件内偏移对应的地址处,确定static_key变量的存储地址的重定位信息。
进一步的,该装置还用于:如果重新加载热补丁文件,重复执行针对每个static_key变量,解析配置文件中的热补丁文件的步骤,以确定重新加载的热补丁文件中,static_key变量的存储地址的重定位信息。
本发明实施例所提供的热补丁的生成装置,其实现原理及产生的技术效果和前述热补丁的生成方法实施例相同,为简要描述,热补丁的生成装置实施例部分未提及之处,可参考前述热补丁的生成方法实施例中相应内容。
本发明实施例还提供了一种服务器,参见图9所示,该服务器包括处理器130和存储器131,该存储器131存储有能够被处理器130执行的机器可执行指令,该处理器130执行机器可执行指令以实现上述XX方法。
进一步地,图9所示的服务器还包括总线132和通信接口133,处理器130、通信接口133和存储器131通过总线132连接。
其中,存储器131可能包含高速随机存取存储器(RAM,Random Access Memory),也可能还包括非不稳定的存储器(non-volatile memory),例如至少一个磁盘存储器。通过至少一个通信接口133(可以是有线或者无线)实现该系统网元与至少一个其他网元之间的通信连接,可以使用互联网,广域网,本地网,城域网等。总线132可以是ISA总线、PCI总线或EISA总线等。所述总线可以分为地址总线、数据总线、控制总线等。为便于表示,图9中仅用一个双向箭头表示,但并不表示仅有一根总线或一种类型的总线。
处理器130可能是一种集成电路芯片,具有信号的处理能力。在实现过程中,上述方法的各步骤可以通过处理器130中的硬件的集成逻辑电路或者软件形式的指令完成。上述的处理器130可以是通用处理器,包括中央处理器(Central Processing Unit,简称CPU)、网络处理器(Network Processor,简称NP)等;还可以是数字信号处理器(DigitalSignal Processor,简称DSP)、专用集成电路(Application Specific IntegratedCircuit,简称ASIC)、现场可编程门阵列(Field-Programmable Gate Array,简称FPGA)或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件。可以实现或者执行本发明实施例中的公开的各方法、步骤及逻辑框图。通用处理器可以是微处理器或者该处理器也可以是任何常规的处理器等。结合本发明实施例所公开的方法的步骤可以直接体现为硬件译码处理器执行完成,或者用译码处理器中的硬件及软件模块组合执行完成。软件模块可以位于随机存储器,闪存、只读存储器,可编程只读存储器或者电可擦写可编程存储器、寄存器等本领域成熟的存储介质中。该存储介质位于存储器131,处理器130读取存储器131中的信息,结合其硬件完成前述实施例的方法的步骤。
本发明实施例还提供了一种机器可读存储介质,该机器可读存储介质存储有机器可执行指令,该机器可执行指令在被处理器调用和执行时,该机器可执行指令促使处理器实现上述热补丁的生成方法,具体实现可参见方法实施例,在此不再赘述。
本发明实施例所提供的热补丁的生成方法、装置和服务器的计算机程序产品,包括存储了程序代码的计算机可读存储介质,所述程序代码包括的指令可用于执行前面方法实施例中所述的方法,具体实现可参见方法实施例,在此不再赘述。
所述功能如果以软件功能单元的形式实现并作为独立的产品销售或使用时,可以存储在一个计算机可读取存储介质中。基于这样的理解,本发明的技术方案本质上或者说对现有技术做出贡献的部分或者该技术方案的部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质中,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)执行本发明各个实施例所述方法的全部或部分步骤。而前述的存储介质包括:U盘、移动硬盘、只读存储器(ROM,Read-Only Memory)、随机存取存储器(RAM,Random Access Memory)、磁碟或者光盘等各种可以存储程序代码的介质。
最后应说明的是:以上各实施例仅用以说明本发明的技术方案,而非对其限制;尽管参照前述各实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分或者全部技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本发明各实施例技术方案的范围。
Claims (8)
1.一种热补丁的生成方法,其特征在于,所述方法包括:
基于预先获取到的比较结果,生成比较文件;其中,所述比较结果用于指示:相对于第一目标文件,第二目标文件中发生变化的__jump_table节区;所述第一目标文件通过对包含漏洞的源代码进行编译得到;所述第二目标文件通过对修复所述漏洞后的源代码进行编译得到;所述比较文件包括:所述第二目标文件的__jump_table节区中,与所述发生变化的__jump_table节区相关联的目标结构体变量,以及所述目标结构体变量中指定地址的重定位信息;
基于所述比较文件,生成包含有所述指定地址的重定位信息的热补丁文件;
所述第二目标文件的__jump_table节区中包括至少一个结构体变量;所述基于预先获取到的比较结果,生成比较文件的步骤包括:
针对所述第二目标文件的__jump_table节区中的每个结构体变量,如果所述结构体变量与标记为新增的指定节区相关联,或者,所述结构体变量与标记为变更的指定节区相关联,将所述结构体变量保存至所述比较文件中的比较__jump_table节区;
生成所述结构体变量中,第一存储地址、第二存储地址的重定位信息,并保存至所述比较文件的.rela__jump_table节区中;其中,所述第一存储地址指向条件跳转分支中的第一分支;所述第二存储地址指向所述条件跳转分支中的第二分支。
2.根据权利要求1所述的方法,其特征在于,所述结构体变量中包括static_key变量的存储地址;所述方法还包括:
如果所述static_key变量包含在所述第二目标文件中,且不包含在所述第一目标文件中,生成所述结构体变量中,所述static_key变量的存储地址的重定位信息,并保存至所述比较文件的.rela__jump_table节区中。
3.根据权利要求1所述的方法,其特征在于,所述第二目标文件的__jump_table节区中包括至少一个结构体变量;所述结构体变量中包括static_key变量的存储地址;所述基于所述比较文件,生成包含有所述指定地址的重定位信息的热补丁文件的步骤之后,所述方法还包括:
针对所述第二目标文件的__jump_table节区中的每个结构体变量,如果所述static_key变量不属于全局可访问符号,输出所述static_key变量的日志信息;其中,所述日志信息包括:所述static_key变量的名称和所述static_key变量所在的第一目标文件;
基于所述日志信息,生成配置文件;其中,所述配置文件中包括:所述static_key变量的名称、所述static_key变量所在的第一目标文件所在的指定文件的名称、所述热补丁文件的名称、以及所述static_key变量在所述比较文件的比较__jump_table节区中的节区内偏移;其中,所述指定文件包括内核模块文件或vmlinux;
基于所述配置文件,确定所述热补丁文件中,所述static_key变量的存储地址的重定位信息。
4.根据权利要求3所述的方法,其特征在于,所述static_key变量包括多个;所述基于所述配置文件,确定所述热补丁文件中,所述static_key变量的存储地址的重定位信息的步骤包括:
针对每个所述static_key变量,解析所述配置文件中的热补丁文件,确定所述比较__jump_table节区在所述热补丁文件中的文件内偏移;
将所述比较__jump_table节区在所述热补丁文件中的文件内偏移与所述static_key变量在所述比较文件的所述比较__jump_table节区中的节区内偏移求和,确定所述static_key变量在所述热补丁文件中的文件内偏移;
获取所述static_key变量的实际运行地址;
将所述实际运行地址写入所述static_key变量在所述热补丁文件中的文件内偏移对应的地址处,确定所述static_key变量的存储地址的重定位信息。
5.根据权利要求4所述的方法,其特征在于,所述确定所述static_key变量的存储地址的重定位信息的步骤之后,所述方法还包括:
如果重新加载所述热补丁文件,重复执行针对每个所述static_key变量,解析所述配置文件中的热补丁文件的步骤,以确定重新加载的所述热补丁文件中,所述static_key变量的存储地址的重定位信息。
6.一种热补丁的生成装置,其特征在于,所述装置包括:
第一生成模块,用于基于预先获取到的比较结果,生成比较文件;其中,所述比较结果用于指示:相对于第一目标文件,第二目标文件中发生变化的__jump_table节区;所述第一目标文件通过对包含漏洞的源代码进行编译得到;所述第二目标文件通过对修复所述漏洞后的源代码进行编译得到;所述比较文件包括:所述第二目标文件的__jump_table节区中,与所述发生变化的__jump_table节区相关联的目标结构体变量,以及所述目标结构体变量中指定地址的重定位信息;
第二生成模块,用于基于所述比较文件,生成包含有所述指定地址的重定位信息的热补丁文件;
所述第二目标文件的__jump_table节区中包括至少一个结构体变量;所述第一生成模块还用于:
针对所述第二目标文件的__jump_table节区中的每个结构体变量,如果所述结构体变量与标记为新增的指定节区相关联,或者,所述结构体变量与标记为变更的指定节区相关联,将所述结构体变量保存至所述比较文件中的比较__jump_table节区;
生成所述结构体变量中,第一存储地址、第二存储地址的重定位信息,并保存至所述比较文件的.rela__jump_table节区中;其中,所述第一存储地址指向条件跳转分支中的第一分支;所述第二存储地址指向所述条件跳转分支中的第二分支。
7.一种服务器,其特征在于,包括处理器和存储器,所述存储器存储有能够被所述处理器执行的机器可执行指令,所述处理器执行所述机器可执行指令以实现权利要求1-5任一项所述的热补丁的生成方法。
8.一种机器可读存储介质,其特征在于,该机器可读存储介质存储有机器可执行指令,该机器可执行指令在被处理器调用和执行时,机器可执行指令促使处理器实现权利要求1-5任一项所述的热补丁的生成方法。
Priority Applications (2)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202011351540.6A CN112416360B (zh) | 2020-11-25 | 2020-11-25 | 热补丁的生成方法、装置和服务器 |
PCT/CN2021/129249 WO2022111262A1 (zh) | 2020-11-25 | 2021-11-08 | 热补丁的生成方法、装置、服务器和机器可读存储介质 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202011351540.6A CN112416360B (zh) | 2020-11-25 | 2020-11-25 | 热补丁的生成方法、装置和服务器 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN112416360A CN112416360A (zh) | 2021-02-26 |
CN112416360B true CN112416360B (zh) | 2023-08-08 |
Family
ID=74843398
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202011351540.6A Active CN112416360B (zh) | 2020-11-25 | 2020-11-25 | 热补丁的生成方法、装置和服务器 |
Country Status (2)
Country | Link |
---|---|
CN (1) | CN112416360B (zh) |
WO (1) | WO2022111262A1 (zh) |
Families Citing this family (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN112416360B (zh) * | 2020-11-25 | 2023-08-08 | 北京金山云网络技术有限公司 | 热补丁的生成方法、装置和服务器 |
CN116225770B (zh) * | 2023-04-26 | 2023-10-20 | 阿里云计算有限公司 | 补丁匹配方法、装置、设备及存储介质 |
Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN103077062A (zh) * | 2012-11-30 | 2013-05-01 | 华为技术有限公司 | 一种代码改动的检测方法和装置 |
CN103744709A (zh) * | 2014-01-23 | 2014-04-23 | 华为技术有限公司 | 补丁加载方法及装置 |
CN106598667A (zh) * | 2016-12-12 | 2017-04-26 | 百度在线网络技术(北京)有限公司 | 用于修复内核漏洞的方法和装置 |
Family Cites Families (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US7784044B2 (en) * | 2002-12-02 | 2010-08-24 | Microsoft Corporation | Patching of in-use functions on a running computer system |
US9342285B2 (en) * | 2012-11-30 | 2016-05-17 | Huawei Technologies Co., Ltd. | Method and apparatus for detecting code change |
CN107656753A (zh) * | 2016-07-25 | 2018-02-02 | 中兴通讯股份有限公司 | 一种补丁实现方法及装置 |
CN109492406A (zh) * | 2018-11-15 | 2019-03-19 | 百度在线网络技术(北京)有限公司 | 监测内核漏洞攻击的方法、装置和系统 |
CN112416360B (zh) * | 2020-11-25 | 2023-08-08 | 北京金山云网络技术有限公司 | 热补丁的生成方法、装置和服务器 |
-
2020
- 2020-11-25 CN CN202011351540.6A patent/CN112416360B/zh active Active
-
2021
- 2021-11-08 WO PCT/CN2021/129249 patent/WO2022111262A1/zh active Application Filing
Patent Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN103077062A (zh) * | 2012-11-30 | 2013-05-01 | 华为技术有限公司 | 一种代码改动的检测方法和装置 |
CN103744709A (zh) * | 2014-01-23 | 2014-04-23 | 华为技术有限公司 | 补丁加载方法及装置 |
CN106598667A (zh) * | 2016-12-12 | 2017-04-26 | 百度在线网络技术(北京)有限公司 | 用于修复内核漏洞的方法和装置 |
CN109117169A (zh) * | 2016-12-12 | 2019-01-01 | 百度在线网络技术(北京)有限公司 | 用于修复内核漏洞的方法和装置 |
Also Published As
Publication number | Publication date |
---|---|
CN112416360A (zh) | 2021-02-26 |
WO2022111262A1 (zh) | 2022-06-02 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US10867028B2 (en) | Program-instruction-controlled instruction flow supervision | |
CN101154187B (zh) | 用于为程序打补丁的方法、装置、服务处理器和系统 | |
US10713024B2 (en) | Load module compiler | |
US8694977B2 (en) | Distributed compiling process with instruction signature support | |
US9027014B2 (en) | Updating firmware compatibility data | |
CN112416360B (zh) | 热补丁的生成方法、装置和服务器 | |
CN110088736B (zh) | 自调试方法和系统 | |
CN105446712B (zh) | 一种应用程序缺陷修补方法及装置 | |
US9134977B2 (en) | Compiler operation for handling conditional statements | |
CN112882718B (zh) | 编译处理方法、装置、设备及存储介质 | |
CN115617687B (zh) | 程序插桩方法、装置、设备和存储介质 | |
CN102364433B (zh) | 在ARM处理器上实现Wine构建工具移植的方法 | |
US20050039196A1 (en) | Method and system for using a library | |
CN111142922B (zh) | 应用程序更新方法、装置、终端及服务器 | |
CN115167862A (zh) | 补丁方法及相关设备 | |
CN113254941A (zh) | 一种Linux内核源码处理方法、装置和设备 | |
US20080133838A1 (en) | Data processing device | |
CN112084112B (zh) | 热补丁的测试方法、装置和服务器 | |
US8655638B2 (en) | Methods for converting instructions with base register-relative addressing in an emulation | |
JP2016029547A (ja) | 実行モジュール生成装置、及び電子制御装置 | |
CN106897588B (zh) | 一种标签函数的处理方法及装置 | |
CN110543322A (zh) | 一种针对龙芯平台的热补丁方法及装置 | |
CN111984329A (zh) | 一种boot引导软件标准化生成、执行方法及系统 | |
KR102626841B1 (ko) | 동적 라이브러리의 자가 무결성 검증 방법 및 이를 위한 장치 | |
CN117251165B (zh) | Buildroot编译方法、装置、终端及介质 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |