开启linux kernel rust support

背景 试图用Rust做操作系统小组作业,某组员遇到环境配置问题。我尝试了一下,发现网上中文资料确实比较少,而且官方文档翻译略有过时。(可能有Rust更新比较快的原因。于是写了篇没什么用的流水账记录一下编译一个启用Rust支持的Linux kernel的过程。 环境配置 本文所述内容均在archlinux下进行。 Rust: 参照官方文档配置一下rust相关环境。 LLVM 省流版(不保证完全准确,在我这能跑): 从 https://www.kernel.org/ 下载linux-6.8.2源码 在linux-6.8.2目录下切换rustc版本 rustup override set $(scripts/min-tool-version.sh rustc) 添加rust-src rustup component add rust-src 安装bindgen-cli 注意:此处中文文档已经滞后,需要安装的是bindgen-cli而非bindgen. 详见: https://github.com/rust-lang/cargo/issues/11249 cargo install --locked --version $(scripts/min-tool-version.sh bindgen) bindgen-cli 需要将~/.cargo/bin添加到环境变量 生成rust-analyzer配置文件 make LLVM=1 rust-analyzer 查看rust工具链是否符合要求 make LLVM=1 rustavailable 在我这的输出是(我没锁bindgen版本) ❯ make LLVM=1 rustavailable *** *** Rust bindings generator 'bindgen' is too new. This may or may not work. *** Your version: 0.69.4 *** Expected version: 0.65.1 *** *** *** Please see Documentation/rust/quick-start.rst for details *** on how to set up the Rust support. *** Rust is available! 然后就可以编译内核了 ...

April 1, 2024 · 1 min · 142 words · JuicyMio

天选4Archlinux安装及使用小记

背景 Laptop:华硕天选4锐龙版 CPU:AMD Ryzen 7940H GPU:Radeon 780m Graphics + NVIDIA RTX 4060 Laptop 安装过程主要参考archlinux 简明指南 (icekylin.online) 由于要在win11的D盘切分出来一块空间(好不容易清出来的200G)安装,没办法使用archinstall脚本。(archinstall的分区方案只会分配一整块硬盘,差点把我D盘数据全清了)。 双显卡驱动 仍然按照archlinux 简明指南 (icekylin.online)进行操作。 安装nvidia闭源驱动时出现了各种问题,但是不装闭源驱动又经常卡死,尤其是我的双屏还需要独显输出,于是在timeshift数次之后终于艰难地驯服了双显卡驱动。使用了下面知乎老哥的方案:不安装optimus-manager,仅使用华硕提供的supergfxctl进行显卡切换。猜测optimus-manager使用Xorg进行切换和Wayland一起使用可能会出现卡死等问题,笔者暂且没有能力验证。 华硕天选5Pro使用Win11+ArchLinux双系统 - 知乎 (zhihu.com) sddm改为使用wayland启动(其实没什么意义,而且sddm的wayland支持尚不稳定)。 Kernel mode setting - ArchWiki (archlinux.org) 输入法 只装了个最基础的fcitx5就没管了。 WPS等软件中无法使用输入法: https://wszqkzqk.github.io/2024/03/09/WPS-Fcitx5/ 字体 不知道怎么同时配置中文字体和英文字体,装了教程里的一堆字体之后,暂时摆了。 KDE 由于刚刚更新Plasma6,很多插件,主题还没有更新。(悲) 打算搞一套仿Mac的主题玩。 upd: 使用了Apple-Sonoma-Dark (KDE6的主题更新的还是很快的,给大佬点赞 GTK主题 White-Sur,跟全局主题尽量像一点。 桌面特效 窗口(比如Konsole)的透明度,模糊等配置在这里。 终端 Shell: zsh + zim + powerlevel10k, 常用插件装上 Terminal Emulator: Konsole Konsole好丑,想换。 alt+n会new tab,跟我钟爱的zellij冲突了。看了keyboard shortcut里没有这个快捷键,然后发现是按住alt+某个字母会触发toolbar上以该字母为首字母的功能(New Tab) 。。。索性直接把toolbar关了,反正也没什么用还丑。 zellij不知道为什么不能alt+方向键了。。。好在还能alt+hjkl zellij不能粘贴:config.kdl里修改copy_command为wl-copy NeoVim 下了个LazyVim,被眼花缭乱的功能吓晕,不过感觉可能习惯一下+关一些没用的东西之后会比LunarVim好用。 upd: LunarVim已停止更新 Terminal-Multiplexer zellij 很好用,但是也有一定问题: 快捷键alt+hjkl是切换pane, nvim中shift+hl是切换buffer,ctrl+hjkl是切换split的windows,相当手忙脚乱。并且在用ctrl组合快捷键的时候需要ctrl+g把zellij的快捷键锁起来。 nvim中显示中文(以及其它多字节字符)有问题。提了个issue ...

March 26, 2024 · 1 min · 113 words · JuicyMio

为什么bss上有时会有stdin,stdout,stderr指针

研究了一下bss段上为什么会有stdin,stdout,stderr, 根据经验观察似乎在使用setvbuf时会出现这种情况, 经过控制变量测试, 发现只要setvbuf这三个变量的一个, 就会使该变量出现在bss段中. setvbuf使用了这三个stdio.h中的extern变量 /* Standard streams. */ extern FILE *stdin; /* Standard input stream. */ extern FILE *stdout; /* Standard output stream. */ extern FILE *stderr; /* Standard error output stream. */ /* C89/C99 say they're macros. Make them happy. */ #define stdin stdin #define stdout stdout #define stderr stderr 他们定义在stdio.c中, 不过右边的仍然是extern变量 #include "libioP.h" #include "stdio.h" #undef stdin #undef stdout #undef stderr FILE *stdin = (FILE *) &_IO_2_1_stdin_; FILE *stdout = (FILE *) &_IO_2_1_stdout_; FILE *stderr = (FILE *) &_IO_2_1_stderr_; 他们最初的定义在stdfile.c中 DEF_STDFILE(_IO_2_1_stdin_, 0, 0, _IO_NO_WRITES); DEF_STDFILE(_IO_2_1_stdout_, 1, &_IO_2_1_stdin_, _IO_NO_READS); DEF_STDFILE(_IO_2_1_stderr_, 2, &_IO_2_1_stdout_, _IO_NO_READS+_IO_UNBUFFERED); struct _IO_FILE_plus *_IO_list_all = &_IO_2_1_stderr_; libc_hidden_data_def (_IO_list_all) 因为stdin等三个变量是未初始化的全局变量, 所以他们被分配到bss段. 在执行setvbuf时, 经过两次重定位将libc地址填入其中. 如果不setvbuf, 这三个符号就不会被用到, 也就不会被解析. ...

December 12, 2023 · 1 min · 116 words · JuicyMio

CVE-2023-25139

0x00 背景 TPCTF里和qym师傅研究了两天safehttpd这题(虽然我一直在背英语pre,没干什么活),把整个程序可能的漏洞点翻遍了也没找到突破口的off by null如何触发(实际上是测试过程中出现了重大失误,已经找对了地方却没有测试出漏洞),赛后看wp发现有这样一个CVE: 30068 – (CVE-2023-25139) incorrect printf output for integers with thousands separator and width field (CVE-2023-25139) (sourceware.org) 0x01 分析 先看上面链接中的复现样例: #include <stdio.h> #include <locale.h> int main (void) { if (setlocale (LC_ALL, "")) { printf ("1234567890123:\n"); printf ("%0+ -'13ld:\n", 1234567L); } return 0; } 在有漏洞的Glibc2.37下的输出: 1234567890123: +1,234,567 : 输出的长度是15而不是13,因为两个千位分隔符没有被计入宽度,导致输出时多补了两个空格。 这是一个glibc 2.37里短暂出现就被迅速修复的漏洞:千位分隔符在限制长度的格式化输出时没有被正确计入宽度,导致出现了溢出。 由该commit修复: Account for grouping in printf width (bug 30068) · bminor/glibc@c980549 (github.com) 下面就通过这个修复的commit分析一下这个bug是如何产生的。 其中第266行由 width -= workend - string + prec 改成了 width -= number_length + prec_inc 这里的width变量为补足宽度限制需要添加的字符的宽度。prec和prec_inc的值是相同的,区别在于number_length和workend - string并不等同:(168-182行) int number_length; #ifndef COMPILE_WPRINTF if (use_outdigits && base == 10) number_length = __translated_number_width (_NL_CURRENT_LOCALE, string, workend); else number_length = workend - string; if (group) number_length += iter.separators * strlen (thousands_sep); #else number_length = workend - string; /* All wide separators have length 1. */ if (group && thousands_sep != L'\0') number_length += iter.separators; #endif 在上面代码的后几行可以看到number_length是原本的数字长度加上千位分隔符的长度,而workend-string没有计算千位分隔符的长度,导致了错误的长度计算。 ...

December 11, 2023 · 2 min · 311 words · JuicyMio

WSL2中C/C++开发环境配置

基础 编辑器: LunarVim 基于clangd的代码提示, compile_commands.json由bear生成, 命令是bear -- make tmux管理窗口(目前又改成了zellij, 感觉快捷键更好用一点) 美化 WSL2: 运行在Windows Terminal中, 安装oh my posh, One Half Dark主题 字体: Fira Code Nerd Font (为了显示LunarVim以及终端中各种小图标) Powerlevel10k 效果: 图炸了() 比之前那个运行在CMD里调个窗口大小就闪退, 配色还极其阴间, 显示不出来图标的状态强了不知道多少. 效率提升 lazygit LunarVim中打包的一些插件差不多够用, 懒得折腾新的了 问题 挂代理也连不上各种东西, 经一通检查之后发现 感觉是wsl和steam++一起干的好事…

July 8, 2023 · 1 min · 40 words · JuicyMio