动态决定运行态的可加载系统模块实现方法及系统技术方案

技术编号:34773065 阅读:42 留言:0更新日期:2022-08-31 19:39
本发明专利技术提供了一种动态决定运行态的可加载系统模块实现方法及系统,包括:通过基于capability的访问控制实现内核向运行在内核态和用户态的系统模块提供统一的API;通过符号重定位技术,实现加载系统模块时动态决定其所调用的内核API采用内核态实现还是用户态实现;在内核中基于capability机制提供跨模块调用机制,采用共享内存页传递参数和返回值;通过提供预设接口,允许在跨模块调用的内核API中一次在多个连接上等待。本发明专利技术利用符号重定位技术、capability机制,提出了新的跨模块调用机制,最终实现了可加载系统模块在操作系统运行期可选地加载到内核态或用户态并进行相互通信的方法。互通信的方法。互通信的方法。

【技术实现步骤摘要】
动态决定运行态的可加载系统模块实现方法及系统


[0001]本专利技术涉及内核安全
,具体地,涉及一种动态决定运行态的可加载系统模块实现方法及系统。

技术介绍

[0002]在操作系统内核的研究和工程实践领域,一直存在着内核的可扩展性、功能模块的隔离性与性能之间的权衡问题。
[0003]为了使操作系统内核的功能可扩展,许多常见内核往往提供在运行期根据需要动态加载可选内核模块的功能,例如Linux的可加载内核模块(Loadable Kernel Module,LKM)和macOS的内核扩展(Kernel Extension,Kext)等。以Linux的可加载内核模块为例,该机制允许用户通过配置或手动通过insmod命令将官方或第三方提供的内核模块安装到内核中,提供系统功能。内核模块加载到内存后,运行在内核态,在内核模块中,代码可以任意访问Linux内核的符号,包括全局变量和函数等。因此内核在加载模块时,需要首先将内核模块的ELF可加载段加载到内核地址空间,然后根据ELF的符号表(Symbol Table)对模块所访问的内核符号进行符号重定位,从而使模块知道这些内核符号在运行期的内存地址。除了访问内核符号,内核模块也可以通过指针访问内核地址空间的任意位置,这种对内核任意数据的访问能力,使得内核模块的安全性尤为重要,加载一个未知安全性的内核模块可能导致内核数据被恶意访问或篡改。研究界最近有许多工作利用CPU硬件特性如Intel VT

x硬件虚拟化技术来对运行在内核态的内核模块与内核进行隔离,以保证内核不受入侵。
[0004]微内核从另一个思路上提高操作系统各功能模块的隔离性,它将操作系统内核的大部分功能从内核态剥离出来,作为用户态系统服务进程运行,同理,宏内核中为内核提供扩展功能的第三方内核模块,在微内核中也可以以用户态进程的形式提供服务。进程级别的地址空间隔离保证了系统服务之间无法互相任意访问对方的数据,而只能通过进程间通信(Inter

Process Communication,IPC)机制经由内核的辅助完成相互沟通。同时,系统服务运行在用户态保证了系统服务无法任意访问内核的数据,也无法直接调用CPU特权指令,而只能通过系统调用(System Call)机制请求内核提供的功能。由此可见,在微内核中,IPC的性能是整个系统性能的关键指标,因为在宏内核中一次系统调用之后的所有服务过程都是函数调用,而在微内核中相同的服务可能需要在多个系统服务之间多次IPC调用,而一次IPC调用涉及四次CPU特权级的切换,相比系统调用的两次多了一倍,开销相比函数调用更是高很多。
[0005]最近几年,随着Rust这门系统编程语言的兴起,一些研究工作如RedLeaf开始探索利用Rust语言的编译期内存安全检查和模块、函数、字段的可见性检查的特性来对内核中的功能模块进行隔离。Rust的内存安全特性通过所有权(ownership)机制实现,该机制在编译期为每个变量确定一个所有者(owner),并追踪所有权的转移,从而使得程序在默认情况下,即不使用unsafe语句的情况下,不能随意访问不属于自己的内存空间;模块、函数、字段的可见性设置通过pub、pub(crate)等关键字实现,该特性使得程序不能随意调用其它模块
中设置为外部不可见的函数、访问其它模块中设置为外部不可见的全局变量或结构体字段。同时,由于这些内存安全和可见性检查发生在编译期,使得编译出的程序在运行期几乎没有额外开销。利用这些特性,一些工作将操作系统内核的功能拆分为逻辑上的模块,和Linux可加载内核模块类似,这些模块被运行在内核态,但又和微内核类似,这些模块不能直接访问内核数据和函数,而必须经过一层良好设计的跨模块调用机制,来传递数据和请求服务,这使得内核模块之间的通信具有接近函数调用的性能,同时保证模块之间和模块与内核之间的隔离。
[0006]综上所述,现有的机制要么将内核模块加载到内核态运行,暴露内核地址空间,要么将内核功能分离到用户态运行,提高隔离性的同时降低跨模块调用性能,要么依赖新编程语言的特性,无法支持其它语言编写的模块。这些方法都有它们各自适应的场景和局限性。而本专利技术希望提供一种能够在操作系统运行期根据系统模块性质和实际需求,综合决定其运行在内核态还是用户态的动态可定制方案。
[0007]专利文献CN104112098A(申请号:CN201410340870.3)公开了一种操作系统中的内核模块加载控制方法,步骤为:1)执行操作系统引导过程中,通过内核态下的内核密封模块关闭所有用户的内核模块处理能力,并启用内核密封模块用户验证功能,使得操作系统内核进入密封状态;2)在操作系统运行过程中,通过内核密封模块截获内核模块操作请求,并对发起内核模块操作请求的用户或应用进行用户验证,若验证通过,则开启用户或者应用的内核模块处理能力,并通过操作系统内核加载或卸载用户或者应用所请求的目标内核模块。但该专利技术不能实现可加载系统模块在操作系统运行期可选地加载到内核态或用户态并进行相互通信。

技术实现思路

[0008]针对现有技术中的缺陷,本专利技术的目的是提供一种动态决定运行态的可加载系统模块实现方法及系统。
[0009]根据本专利技术提供的一种动态决定运行态的可加载系统模块实现方法,包括:
[0010]步骤S1:通过基于capability的访问控制实现内核向运行在内核态和用户态的系统模块提供统一的API;
[0011]步骤S2:通过符号重定位技术,实现加载系统模块时动态决定其所调用的内核API采用内核态实现还是用户态实现;
[0012]步骤S3:在内核中基于capability机制提供跨模块调用机制,采用共享内存页传递参数和返回值;
[0013]步骤S4:通过提供预设接口,允许在跨模块调用的内核API中一次在多个连接上等待。
[0014]优选地,在所述步骤S1中:
[0015]将系统模块加载到内存运行时,采用capability机制来提供对内核对象的访问控制,系统模块代码不直接访问内核对象的内存数据,而是通过方法调用进行读写;
[0016]为了能使直接调用内核中实现系统调用的函数和通过syscall指令进行系统调用产生相同的效果,系统模块能观测到相同的行为,引入capability机制向系统模块提供统一的内核对象抽象,运行在内核态的系统模块和运行在用户态的系统模块一样,通过
capability间接地访问内核对象,capability机制使不同系统模块之间对内核对象的访问权限相互隔离,系统模块无法通过伪造capability值来访问它没有权限访问的内核对象,当使用内存安全语言编写系统模块时,通过capability和系统内核提供的封装库,将系统模块运行在内核态而不必担心模块通过猜测内存地址、构造指针的方式任意访问内核数据;当使用不内存安全的语言编写系统模块时,将其运行在用户态以通过进程级别的地址空间隔离保证内核的安全。
[0017]优选地,在所述步骤本文档来自技高网
...

【技术保护点】

【技术特征摘要】
1.一种动态决定运行态的可加载系统模块实现方法,其特征在于,包括:步骤S1:通过基于capability的访问控制实现内核向运行在内核态和用户态的系统模块提供统一的API;步骤S2:通过符号重定位技术,实现加载系统模块时动态决定其所调用的内核API采用内核态实现还是用户态实现;步骤S3:在内核中基于capability机制提供跨模块调用机制,采用共享内存页传递参数和返回值;步骤S4:通过提供预设接口,允许在跨模块调用的内核API中一次在多个连接上等待。2.根据权利要求1所述的动态决定运行态的可加载系统模块实现方法,其特征在于,在所述步骤S1中:将系统模块加载到内存运行时,采用capability机制来提供对内核对象的访问控制,系统模块代码不直接访问内核对象的内存数据,而是通过方法调用进行读写;为了能使直接调用内核中实现系统调用的函数和通过syscall指令进行系统调用产生相同的效果,系统模块能观测到相同的行为,引入capability机制向系统模块提供统一的内核对象抽象,运行在内核态的系统模块和运行在用户态的系统模块一样,通过capability间接地访问内核对象,capability机制使不同系统模块之间对内核对象的访问权限相互隔离,系统模块无法通过伪造capability值来访问它没有权限访问的内核对象,当使用内存安全语言编写系统模块时,通过capability和系统内核提供的封装库,将系统模块运行在内核态而不必担心模块通过猜测内存地址、构造指针的方式任意访问内核数据;当使用非内存安全的语言编写系统模块时,将其运行在用户态以通过进程级别的地址空间隔离保证内核的安全。3.根据权利要求1所述的动态决定运行态的可加载系统模块实现方法,其特征在于,在所述步骤S2中:通过符号重定位技术,通过特制动态加载器的不同参数来控制将ELF格式的系统模块的未定义符号重定向到内核态实现或用户态实现,未定义符号是操作系统内核对系统模块提供的API,内核态实现表现为对内核函数的直接调用,用户态实现表现为对内核的系统调用;特制的动态加载器根据用户指定的参数决定将系统模块加载到内核态还是用户态执行,动态加载器首先将ELF的各可加载段加载到内存中,然后对其中未定义的符号根据其重定位类型做重定位,将符号在运行期的实际内存地址,根据重定位类型的不同进行不同运算,填充到重定位地址,根据用户给出的参数不同,特制的动态加载器为ELF所需的符号重定位到不同的实现,当用户将系统模块加载到内核态运行时,加载器为其重定位的实现是直接调用内核中实现系统调用的函数,使其运行时无需真的向用户态程序一样通过系统调用请求内核服务;当用户将系统模块加载到用户态运行时,通过syscall指令陷入内核处理,该过程会发生CPU特权级切换。4.根据权利要求1所述的动态决定运行态的可加载系统模块实现方法,其特征在于,在所述步骤S3中:基于capability机制,内核向系统模块提供跨模块调用机制,使系统模块之间能够通过统一的机制对外提供服务和调用外部服务,该机制的运行需要服务端和客户端两端的参
与,服务端首先向内核注册服务,随后在该服务的capability上等待客户端连接,客户端通过向内核查询服务,得到capability,向服务端建立连接,连接成功后,服务端在该连接的capability上等待客户端的调用请求,收到请求后为期提供服务并返回;在跨模块调用机制中,内核为系统模块提供接口,跨模块调用双方分为客户端和服务端,基本的工作方式如下:在服务端:步骤A1:通过cmc_register_server接口向内核注册一个Server内核对象,该接口以一个字符串作为键,Server对象作为值,在内核中维护一个映射表,以便之后客户端查询,并返回用于访问此内核对象的capability;步骤A2:在该Server对象上调用cmc_accept接口,使当前线程进入等待状态,等待客户端发起连接请求,连接成功后返回Connection内核对象的capability;步骤A3:服务端不断在Connection对象上调用cmc_wait接口以等待客户端的跨模块调用,使当前线程进入等待状态,当接口返回时表明收到了客户端的调用请求,应对其进行处理;在客户端:步骤B1:通过cmc_find_server接口向内核查询具有特定名字的Server内核对象,并获得能够用于访问它的capability;步骤B2:在此Server对象上调用cmc_connect接口,以向服务端发起连接,该接口检查服务端是否已经调用cmc_accept接口等待连接,若是,则在内核中创建Connection内核对象,以表示两者建立的连接,并返回用于访问Connection内核对象的capability,同时服务端的cmc_accept接口调用也返回;步骤B3:客户端多次在该Connection对象上调用cmc_call接口来发起跨模块调用。5.根据权利要求1所述的动态决定运行态的可加载系统模块实现方法,其特征在于,在所述步骤S4中:跨模块调用机制的API允许系统模块的一个线程在多个连接上等待调用请求,从而使服务端能够自由决定为客户端服务的线程数量;内核为系统模块提供了cmc_select接口,允许跨模块调用服务端同时在多个Connection对象上等待,其中任何一个收到跨模块调用都会返回,通过cmc_select接口,系统模块能够根据实际情况决定需要用多少线程处理跨模块调用;当跨模块参数需要传递参数和返回值时,客户端和服务端双方通过cmc_get_shared_pmo接口获取Connection对象对应的共享PMO,同样是以capability的形式,并各自映射到自己的地址空间来访问,共享PMO在调用cmc_get_shared_pmo时创建,内核保证客户端和服务端能够获得对同一个PMO的访问权限,在调用cmc_call发起跨模块调用之前,客户端根据服务端约定的ABI在共享PMO中特定位置填写要请求的具体服务和所需参数,然后服务端在cmc_wait返回后从该共享PMO中取得参数,并进行相应处理,根据约定的ABI,在共享PMO中特定位置填写返回值,并在下一次cmc_wait调用时将执行流返回到客户端;在cmc_wait和cmc_select接口中,加入一个当前要返回的Connection对象的capability,从而在将当前服务端线程转为等待状态之后,立即将执行流迁移到刚刚处理的调用请求的发起侧。...

【专利技术属性】
技术研发人员:钱宇超古金宇臧斌宇陈海波
申请(专利权)人:上海交通大学
类型:发明
国别省市:

网友询问留言 已有0条评论
  • 还没有人留言评论。发表了对其他浏览者有用的留言会获得科技券。

1