Linux 内核升级 C 语言标准


根据 Linux 内核邮件列表的消息,社区近日讨论了是否要为内核采用现代 C 语言标准

虽然 Linux 内核在快速发展,但它同时依赖着一些非常古老的工具,其中之一就是内核代码仍在使用 1989 年版本的 C 语言标准——此标准在 30 多年前内核项目启动之前就已经编写完成。从讨论结果来看,这一情况有望在 5.18 版本内核中改变。

Jakob Koschel 在向 Linus Torvalds 递交的补丁 (Proposal for speculative safe list iterator) 中修复了内核链表相关的预测执行漏洞

起因是 Jakob 发现了一个问题,Linux 内核广泛使用由 struct list_head 定义的双向链表:

struct list_head {
	struct list_head *next, *prev;
};

这种结构体通常被嵌入到其他结构体中,通过这种方式,开发者可以使用任何感兴趣的结构类型制作链表。除此之外,内核还提供了大量可用于遍历和操作链表的函数和宏。其中之一是 list_for_each_entry(),这是一个伪装成控制结构的宏。要了解如何使用此宏,请假设内核包含如下结构:

struct foo {
int fooness;
struct list_head list;
};

list 成员可用于创建 foo 结构体的双向链表,假设我们有一个叫做 foo_list 的结构声明作为此类链表的头,使用以下代码可以遍历此列表:

struct foo *iterator;

list_for_each_entry(iterator, &foo_list, list) {
do_something_with(iterator);
}
/* Should not use iterator here */

list 参数告诉宏在 foo 结构中 list_head 结构体的名称。此循环将为列表中的每个元素执行一次,迭代器指向该元素。由此导致了 USB 子系统中的一个 bug:传递给该宏的迭代器在退出宏后还能被使用。

Koschel 通过重新编写有问题的代码,以在循环后停止使用迭代器来解决问题。

不过 Linus 却对补丁修复的问题表示不解,也没有看到它与预测执行漏洞的关系。Koschel 对此进行了进一步解释,对此 Linus 认为这只是一个普通的 bug。但不久之后 Linus 发现了问题的根源所在:传递给列表遍历宏的迭代器,必须在循环本身之外的范围内声明。

随后,Linus 认为也许可以采用更直接的修复如块级变量声明。但 C89 不支持,而 1999 年发布的 C99 标准支持。所以 Linux 内核也许是时候转向使用 C99 标准了。

Linus 说到,内核代码一直停留在 C89 的原因之一是编译器 gcc 的旧版本会出现奇怪的问题,导致初始化程序被破坏。不过现在内核要求的 GCC 最低版本已经提高到了 v5.1,那些 bug 可能不再相关了。

另一位密切关注架构编译器问题的内核开发者 Arnd Bergmann 提议直接升级到 C11 甚至 C2x,尽管他不确定 C11 是否会带来任何对内核有用的新内容。不过如果升级到 C17 或 C2x,会破坏对 gcc-5/6/7 的支持,因此升级到 C11 更容易实现,而且跨越太大内核社区未必接受。

Linus 赞成了这个想法,在 Bergmann 确认应该可以这样做之后,Linus 宣布将在下一个内核版本 v5.18 中尝试使用 C11 标准。如果一切顺利,下一个内核版本使用的 C 语言标准有望升级到 C11。


相關推薦

2022-11-20

不考虑使用任何其他语言重写 curl。 延伸阅读 Linux 内核升级 C 语言标准 Linux 5.18 内核 C 标准从 C89 升级到 C11/GNU11

2024-02-02

口之一,广泛应用于 GNU/Linux 系统以及其他使用 Linux 内核的系统。 此版本带来了多项新功能、安全修复和其他增强功能,包括与 x86 shadow-stack 机制的集成、用于控制 groups 的几个新 posix_spawn() 变体、pidfd_spawn() 和 pidfd_spawnp()

2022-04-02

RISC-V 的本质是一组规范,从软件的角度定义了兼容的 CPU 内核应该如何运行:指令类型、在内存中的格式以及其他核心功能。它有时被称为芯片中的 Linux,因为全世界的工程师都在合作设计和改进其架构。 RISC-V 采用模块化方法

2023-03-18

本首发 在经过近4个月的开发后,搭载全新内核的洛书1.6系列终于与大家见面了 基本信息 项目 信息 版本号 1.6.x 内核 EasyLosu 1.x 版本代号 Rex Lapis 更新方式 长期支持 + 修订更新

2022-09-21

露,没有意外的话 Rust 将在 6.1 版本进入 Linux 内核 Cloudflare 放弃 Nginx,使用内部 Rust 编写的 Pingora GStreamer 准备将 Rust 编写的插件作为其官方二进制版本的一部分发布 Rust 成立专门的安全团队 Asahi Linux 计划使用 R

2023-05-24

能,可以使用不同的编程语言编写。 操作系统的核心是内核 (Kernel),它负责与硬件交互——几乎都是采用 C 或汇编语言编写。至于面向用户的组件(例如 GUI 应用程序),可以采用任何语言编写。 例如,Android 采用 Java 编写用

2022-09-30

先回顾关于 Linux 内核支持 Rust 的消息。 2019 年,内核维护者 Greg 表示愿意接受用 Rust 开发 Linux 内核的驱动程序。 2020 年,Linus Torvalds 回应了针对 Linux 内核支持 Rust 的个人看法。他没有否定该提议,而是提倡在默认

2022-04-12

C++20/C++23 的支持 改进了 GCC JIT 增加了对较新的 Arm CPU 内核的支持 增加了对 Intel AVX512-FP16 的支持 引入了 x86 SLS 缓解 还有其他许多编译器的增加和改进 除了 openSUSE Tumbleweed,即将发布的 Fedora 36 已经在使用接近最后的 GCC

2022-05-24

之一是将英特尔软件定义芯片(SDSi) 驱动程序包含到主线内核中,该功能引起了不小的争议,但英特尔尚未明确表示该驱动的具体用途。 硬件方面,  Raspberry Pi Zero 2 W 在此版本中获得了完整的主线 Linux 内核支持;Tesla

2023-06-15

我们修复了Windows系统下 GBK/UTF8 编码转换问题,统一了内核 UTF8 编码支持 我们修复了 Windows/Linux 功能割裂的问题,统一多平台使用体验 全新功能,集中上线 全新模块管理器(LPT) 全平台可用,功能与使用方法一致

2022-12-09

打开之前的早期拉取请求中,有一项更改是默认为 Linux 内核构建启用“-funsigned-char”,这意味着如果没有指定,“-funsigned-char”编译器标志会将所有“char”字符类型设为无符号。 C 的 char 字符数据类型分为 signed char 和 unsigned

2022-04-02

目中可以:... 深度操作系统 20.5 现已发布,升级Stable内核至5.15.24,修复底层漏洞,进一步提升系统兼容性和安全性,功能层面上积极响应社区用户反馈的需求,开发并集成了大量实用功能。 人脸识别 新增人脸识别功能模块

2022-05-08

。 GCC 12 编译器提供 x86 直线推测 (SLS) 缓解支持。Linux 内核已准备好使用这个新的安全选项。 GCC 的 Fortran "gfortran" 前端现在完全支持 TS 29113 以实现与 C 编程语言的互操作性。TS 29113 是提高 Fortran 与 C 的互操作性的技术规范。

2022-04-02

的 LoongArch 对 GNU 编译器集的初步支持,这也为 Linux 内核主线的 LoongArch CPU 架构支持扫清了障碍,因为它一直需要合适的上游编译器支持。 Chris McKillop 是 Google Fuchsia OS 的负责人兼工程总监,近日他在个人社交媒体上宣布已