Kernel Linux内核中的安全编码约定
在查看内核代码时,我遇到了以下情况 假设我们有两个内核组件A和B(比如,内核模块),A调用Kernel Linux内核中的安全编码约定,kernel,security,linux-kernel,conventions,Kernel,Security,Linux Kernel,Conventions,在查看内核代码时,我遇到了以下情况 假设我们有两个内核组件A和B(比如,内核模块),A调用导出符号从B导出一些函数()。假设some_func()有输入参数,应该只为其指定“合法”或“有效”值。例如,假设我们有 some_func(void * p); 其中void*p应为非NULL,可能还指向正确分配的内存块 我的问题是:某些_func()的论点确实是合法的,谁对此负责?是呼叫者A还是被呼叫者B?我找不到一个权威的消息来源来规定内核应该遵循什么约定 在考虑指针输入参数示例时,从安全角度来看,
导出符号从B导出一些函数()。假设some_func()
有输入参数,应该只为其指定“合法”或“有效”值。例如,假设我们有
some_func(void * p);
其中void*p
应为非NULL
,可能还指向正确分配的内存块
我的问题是:某些_func()
的论点确实是合法的,谁对此负责?是呼叫者A还是被呼叫者B?我找不到一个权威的消息来源来规定内核应该遵循什么约定
在考虑指针输入参数示例时,从安全角度来看,很明显我们可能会遇到NULL
-指针解引用问题,这应该避免。因此,为了专门回答我的问题,A是否负责传递给B的参数的安全性,或者B是否应该在其导出的每个符号的入口处进行验证
请注意,这个问题是关于在内核中调用约定的,与从用户空间调用约定无关。所有内核代码都在相同的权限级别上工作。因此,传递无效的排序参数是编程错误
对于kicks,假设B试图以某种方式验证。显然,空检查是微不足道的。但是,如何验证指针指向可以访问的对象呢?这里有一个额外的提示:如果B验证并得出结论,然后在另一个cpu上运行的a模块的代码释放了目标区域,该怎么办。如果B现在访问,所有的工作都将变得无用
但是如果你和B有相同的权限,为什么要这样玩呢?如果你愿意,你可以直接覆盖它的代码
正如你所看到的,这个问题毫无意义
另一方面,让我们将其与用户空间进行对比。kerneluser接口是一个安全边界,传递的数据/指针本质上是不可信的,只能通过保证安全的专用原语访问。请注意在提供保证的能力方面的基本区别:您访问时,它可能会触发页面错误,如果发生了这种情况,并且没有任何映射,您知道用户空间正在运行,您可以很好地返回错误。如果内核代码也发生同样的情况,那么您就有一个bug 所有内核代码都在相同的权限级别上工作。因此,传递无效的排序参数是编程错误
对于kicks,假设B试图以某种方式验证。显然,空检查是微不足道的。但是,如何验证指针指向可以访问的对象呢?这里有一个额外的提示:如果B验证并得出结论,然后在另一个cpu上运行的a模块的代码释放了目标区域,该怎么办。如果B现在访问,所有的工作都将变得无用
但是如果你和B有相同的权限,为什么要这样玩呢?如果你愿意,你可以直接覆盖它的代码
正如你所看到的,这个问题毫无意义
另一方面,让我们将其与用户空间进行对比。kerneluser接口是一个安全边界,传递的数据/指针本质上是不可信的,只能通过保证安全的专用原语访问。请注意在提供保证的能力方面的基本区别:您访问时,它可能会触发页面错误,如果发生了这种情况,并且没有任何映射,您知道用户空间正在运行,您可以很好地返回错误。如果内核代码也发生同样的情况,那么您就有一个bug