标签 Rust 下的文章

“Linux 随机数生成器”(LRNG) 已经开发了五年

作为 /dev/random 的新替代品,“Linux 随机数生成器”(LRNG)已经进行了第 41 次修订,对它的开发了已经超过了 5 年。LRNG 是对现有随机数生成器的 API/ABI 兼容的替代品。LRNG 的目标是提高速度,以及其他各种性能优化,各种加密处理的改进,测试能力的提高,选项的更大可配置性,并且是一个更现代的设计。LRNG 是否以及何时可以进入 Linux 主线还有待观察。

看似简单的随机数,其实是计算安全上最重要的基石之一,也可能是这个宇宙最重要的基础之一。

新研究确认 Rust 的安全性

Rust 有两种模式:其默认的安全模式和不安全模式。在其默认的安全模式下,Rust 可以防止内存错误和数据竞争。而在它的不安全模式下允许使用潜在的不安全的 C 风格的函数。验证 Rust 的安全声明的关键挑战是说明其安全和不安全代码之间的互动。

一篇发表在 4 月份的《ACM 通讯》的文章对 Rust 的安全性进行了研究。其共同作者,“我们能够验证 Rust 类型系统的安全性,从而表明 Rust 是如何自动和可靠地防止这一类编程错误的。”他们开发了一个理论框架,能够证明尽管有可能写出“不安全”的代码,但 Rust 的安全主张仍然成立。他们使用一个叫做 Miri 的工具来自动测试“不安全”的 Rust 代码是否符合 Rust 规范。

“不安全”的代码仍然能保证安全才是 Rust 最有趣的地方。

大量比特币矿工前往美国

美国已经迅速成为比特币挖矿世界的新宠。截至 2021 年 4 月,美国已经占世界所有比特币矿工的近 17%。这比 2020 年 9 月增加了 151%。此外,在中国禁止挖矿后,50 万台以前的中国矿工的矿机正在美国寻找家园。如果他们被部署,这将意味着到 2022 年底,北美将拥有接近 40% 的全球哈希率。多年来,美国一直在悄悄地建立其托管能力。美国也是地球上一些最便宜的能源的所在地,其中许多是可再生能源。大多数搬迁到北美的新矿工将使用可再生能源,或用可再生能源信贷抵消的天然气。

让这些能源消耗和风险去祸害他们去吧,对吧。

从 Rust 标准库学习一些有用的关键字。

 title=

我使用 Rust 已经有几个月了,写的东西比我预期的要多——尽管随着我的学习,我改进了所写的代码,并完成了一些超出我最初意图的更复杂的任务,相当多的东西已经被扔掉了。

我仍然喜欢它,并认为谈论一些在 Rust 中反复出现的重要关键字可能会有好处。我会提供我个人对它们的作用的总结:为什么你需要考虑如何使用它们,以及任何其他有用的东西,特别是对于刚接触 Rust 的新手或来自另一种语言的人(如 Java;请阅读我的文章 为什么作为一个 Java 程序员的我喜欢学习 Rust)。

事不宜迟,让我们开始吧。获取更多信息的好地方总是 Rust 官方文档 —— 你可能想从 std 标准库开始。

  1. const – 你可以用 const 来声明常量,而且你应该这样做。虽然这不是造火箭,但请一定要用 const ,如果你要在不同的模块中使用常量,那请创建一个 lib.rs 文件(Rust 默认的),你可以把所有的常量放在一个命名良好的模块中。我曾经在不同模块的不同文件中发生过 const 变量名(和值)的冲突,仅仅是因为我太懒了,除了在不同文件中剪切和粘贴之外,我本可以通过创建一个共享模块来节省大量的工作。
  2. let – 你并不 总是 需要用 let 语句声明一个变量,但当你这样做时你的代码会更加清晰。此外,如果可以,请一定要添加变量类型。Rust 会尽最大努力猜测它应该是什么类型的变量,但它不一定总能在运行时做到这一点(在这种情况下,编译器 Cargo 会提示你),它甚至可能做不到你期望的那样。在后一种情况下,对于 Cargo 来说,抱怨你所赋值的函数(例如)与声明不一致,总比 Rust 试图帮助你做错事,而你却不得不在其他地方花费大量时间来进行调试要简单。
  3. matchmatch 对我来说是新鲜事物,我喜欢使用它。它与其他编程语言中的 switch 没有什么不同,但在 Rust 中被广泛使用。它使代码更清晰易读,如果你做了一些愚蠢的事情(例如错过一些可能的情况),Cargo 会很好地提示你。我一般的经验法则是,在管理不同的选项或进行分支时,如果可以使用 match,那就请一定要使用它。
  4. mut – 在声明一个变量时,如果它的值在声明后会发生变化,那么你需要声明它是可变的(LCTT 译注:Rust 中变量默认是不可变的)。常见的错误是在某个变量 没有 变化的情况下声明它是可变的,这时编译器会警告你。如果你收到了 Cargo 的警告,说一个可变的变量没有被改变,而你认为它被 改变 了,那么你可能要检查该变量的范围,并确保你使用的是正确的那个。
  5. return – 实际上我很少使用 return,它用于从函数中返回一个值,但是如果你只是在函数的最后一行提供值(或提供返回值的函数),通常会变得更简单,能更清晰地阅读。警告:在很多情况下,你 忘记省略这一行末尾的分号(;),如果你这样做,编译器会不高兴的。
  6. unsafe – 如其意:如果你想做一些不能保证 Rust 内存安全的事情,那么你就需要使用这个关键字。我绝对无意在现在或将来的任何时候宣布我的任何 Rust 代码不安全;Rust 如此友好的原因之一是它阻止了这种黑客行为。如果你真的需要这样做,再想想,再想想,然后重新设计代码。除非你是一个非常低级的系统程序员,否则要 避免 使用 unsafe
  7. use – 当你想使用另一个 crate 中的东西时,例如结构体、变量、函数等,那么你需要在你要使用它的代码的代码块的开头声明它。另一个常见的错误是,你这样做了,但没有在 Cargo.toml 文件中添加该 crate (最好有一个最小版本号)。

我知道,这不是我写过的最复杂的文章,但这是我在开始学习 Rust 时会欣赏的那种文章。我计划在关键函数和其他 Rust 必知知识方面编写类似的文章:如果你有任何要求,请告诉我!


本文最初发表于 Alice, Eve, and Bob 经作者许可转载。


via: https://opensource.com/article/20/10/keywords-rust

作者:Mike Bursell 选题:lujun9972 译者:mcfd 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

SolarWinds 和 Kaseya 攻击动摇了对 SaaS 模式的信心

先是 SolarWinds,现在是 Kaseya。管理服务提供商(MSP)大量使用的 SaaS 软件现在已经成为两次成功的网络攻击的目标。大约 1500 家“下游”企业在他们自己的“上游”供应商被入侵后,现在 MSP 正在重新评估他们管理 IT 的方法。

许多 MSP 特别纠结的决定是,他们应该在多大程度上继续依赖可能被恶意软件破坏的 IT 服务管理平台,而不是建立和保护自己的定制平台。后一种方法对恶意软件没有免疫力,但由于网络犯罪分子越来越多地把精力集中在能够对下游造成更大破坏的平台上,因此可能不太容易成为目标。

这就和大规模云计算的副作用一样,这种成规模的云服务一旦出问题就是大问题。

针对 Kaseya 的巨大勒索软件攻击可能是完全可以避免的

据报道,Kaseya 公司的软件在 2018 年至 2019 年期间至少有两次被用来启动勒索软件,而它并没有对其安全策略进行重大反思。

前 Kaseya 员工在接受采访时称,他们在 2017 年至 2020 年期间多次警告高管 Kaseya 产品的严重安全缺陷,但该公司并没有真正解决这些问题。该公司使用的是旧代码,实施的是差劲的加密,甚至没有对软件进行常规修补。甚至一名员工声称,他在向高管发送了一份长达 40 页的安全问题简报两周后被解雇。

如果因此发生的勒索可以向软件供应商索赔,那我想他们可能就会重视了。

Tor 项目希望用 Rust 取代 C 代码

ZOMG 周二宣布,它将向注重隐私的 Tor 项目提供 67 万美元的资助,以继续开发 Arti,这是一个 Tor 客户端的 Rust 语言实现,它将更可靠、更安全,并且更容易被其他软件使用。Tor 项目联合创始人,“根据我们的非正式审计,自 2016 年以来,Tor 大约有一半的安全问题在 Rust 中是不可能出现的,其他许多问题的可能性也会小很多。”

我们已经看到很多传统的 C 语言开发的项目和软件正在或已经迁移到 Rust 了。

Tealder 是 Rust 版本的 tldr,对常用的命令提供了易于理解的说明信息。

 title=

手册页是我开始探索 Linux 时最常用的资源。当然,对于初学者熟悉命令行指令而言,man 是最频繁使用的指令。但是手册页中有大量的选项和参数列表,很难被解读,这使得你很难理解你想知道的东西。如果你想要一个更简单的解决方案,有基于例子的输出,我认为 tldr 太长不读 too long dnot's read )是最好的选择。

Tealdeer 是什么?

Tealdeer 是 tldr 的一个基于 Rust 的实现。它是一个社区驱动的手册页,给出了非常简单的命令工作原理的例子。Tealdeer 最棒的地方在于它几乎包含了所有你通常会用到的命令。

安装 Tealdeer

在 Linux 系统,你可以从软件仓库安装 Tealdeer,比如在 Fedora 上:

$ sudo dnf install tealdeer

在 macOS 可以使用 MacPorts 或者 Homebrew。 同样,你可以使用 Rust 的 Cargo 包管理器来编译和安装此工具:

$ cargo install tealdeer

使用 Tealdeer

输入 tldr-list 返回 tldr 所支持的手册页,比如 touchtardnfdockerzcatzgrep 等:

$ tldr --list
2to3
7z
7za
7zr
[
a2disconf
a2dismod
a2dissite
a2enconf
a2enmod
a2ensite
a2query
[...]

使用 tldr 跟上具体的命令(比如 tar )能够显示基于示例的手册页,描述了你可以用该命令做的所有选项。

$ tldr tar

  Archiving utility.
  Often combined with a compression method, such as gzip or bzip2.
  More information: <https://www.gnu.org/software/tar>.

  [c]reate an archive and write it to a [f]ile:

      tar cf target.tar file1 file2 file3

  [c]reate a g[z]ipped archive and write it to a [f]ile:

      tar czf target.tar.gz file1 file2 file3

  [c]reate a g[z]ipped archive from a directory using relative paths:

      tar czf target.tar.gz --directory=path/to/directory .

  E[x]tract a (compressed) archive [f]ile into the current directory [v]erbosely:

      tar xvf source.tar[.gz|.bz2|.xz]

  E[x]tract a (compressed) archive [f]ile into the target directory:

      tar xf source.tar[.gz|.bz2|.xz] --directory=directory

  [c]reate a compressed archive and write it to a [f]ile, using [a]rchive suffix to determine the compression program:

      tar caf target.tar.xz file1 file2 file3

如需控制缓存:

$ tldr --update
$ tldr --clear-cache

你能够控制 Tealdeer 输出的颜色选项,有三种模式选择:一直、自动、从不。默认选项是自动,但我喜欢颜色提供的额外信息,所以我在我的 ~/.bashrc文件中增加了这个别名:

alias tldr='tldr --color always'

结论

Tealdeer 的美妙之处在于不需要网络连接就可以使用,只有更新缓存的时候才需要联网。因此,即使你处于离线状态,依然能够查找和学习你新学到的命令。更多信息,请查看该工具的 说明文档

你会使用 Tealdeer 么?或者你已经在使用了?欢迎留言让我们知道。


via: https://opensource.com/article/21/6/tealdeer-linux

作者:Sudeshna Sur 选题:lujun9972 译者:ddl-hust 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

编者按:近些年来 Rust 语言由于其内存安全性和性能等优势得到了很多关注,尤其是 Linux 内核也在准备将其集成到其中,因此,我们特邀阿里云工程师苏子彬为我们介绍一下如何在 Linux 内核中集成 Rust 支持。

2021 年 4 月 14 号,一封主题名为《Rust support》的邮件出现在 LKML 邮件组中。这封邮件主要介绍了向内核引入 Rust 语言支持的一些看法以及所做的工作。邮件的发送者是 Miguel Ojeda,为内核中 Compiler attributes、.clang-format 等多个模块的维护者,也是目前 Rust for Linux 项目的维护者。

Rust for Linux 项目目前得到了 Google 的大力支持Miguel Ojeda 当前的全职工作就是负责 Rust for Linux 项目。

长期以来,内核使用 C 语言和汇编语言作为主要的开发语言,部分辅助语言包括 Python、Perl、shell 被用来进行代码生成、打补丁、检查等工作。2016 年 Linux 25 岁生日时,在对 Linus Torvalds 的一篇 采访中,他就曾表示过:

这根本不是一个新现象。我们有过使用 Modula-2 或 Ada 的系统人员,我不得不说 Rust 看起来比这两个灾难要好得多。

我对 Rust 用于操作系统内核并不信服(虽然系统编程不仅限于内核),但同时,毫无疑问,C 有很多局限性。

在最新的对 Rust support 的 RFC 邮件的回复中,他更是说:

所以我对几个个别补丁做了回应,但总体上我不讨厌它。

没有用他特有的回复方式来反击,应该就是暗自喜欢了吧。

目前 Rust for Linux 依然是一个独立于上游的项目,并且主要工作还集中的驱动接口相关的开发上,并非一个完善的项目。

项目地址: https://github.com/Rust-for-Linux/linux

为什么是 Rust

Miguel Ojeda 的第一个 RFC 邮件中,他已经提到了 “Why Rust”,简单总结下:

  • 安全子集 safe subset 中不存在未定义行为,包括内存安全和数据竞争;
  • 更加严格的类型检测系统能够进一步减少逻辑错误;
  • 明确区分 safeunsafe 代码;
  • 更加面向未来的语言:sum 类型、模式匹配、泛型、RAII、生命周期、共享及专属引用、模块与可见性等等;
  • 可扩展的独立标准库;
  • 集成的开箱可用工具:文档生成、代码格式化、linter 等,这些都基于编译器本身。

编译支持 Rust 的内核

根据 Rust for Linux 文档,编译一个包含 Rust 支持的内核需要如下步骤:

  1. 安装 rustc 编译器。Rust for Linux 不依赖 cargo,但需要最新的 beta 版本的 rustc。使用 rustup命令安装:
rustup default beta-2021-06-23
  1. 安装 Rust 标准库的源码。Rust for Linux 会交叉编译 Rust 的 core 库,并将这两个库链接进内核镜像。
rustup component add rust-src
  1. 安装 libclang 库。libclangbindgen 用做前端,用来处理 C 代码。libclang 可以从 llvm 官方主页 下载预编译好的版本。
  2. 安装 bindgen 工具,bindgen 是一个自动将 C 接口转为 RustFFI 接口的库:
cargo install --locked --version 0.56.0 bindgen
  1. 克隆最新的 Rust for Linux 代码:
git clone https://github.com/Rust-for-Linux/linux.git
  1. 配置内核启用 Rust 支持:
Kernel hacking
  -> Sample kernel code
    -> Rust samples
  1. 构建:
LIBCLANG_PATH=/path/to/libclang make -j LLVM=1 bzImage

这里我们使用 clang 作为默认的内核编译器,使用 gcc 理论上是可以的,但还处于 早期实验 阶段。

Rust 是如何集成进内核的

目录结构

为了将 Rust 集成进内核中,开发者首先对 Kbuild 系统进行修改,加入了相关配置项来开启/关闭 Rust 的支持。

此外,为了编译 rs 文件,添加了一些 Makefile 的规则。这些修改分散在内核目录中的不同文件里。

Rust 生成的目标代码中的符号会因为 Mangling 导致其长度超过同样的 C 程序所生成符号的长度,因此,需要对内核的符号长度相关的逻辑进行补丁。开发者引入了 “大内核符号”的概念,用来在保证向前兼容的情况下,支持 Rust 生成的目标文件符号长度。

其他 Rust 相关的代码都被放置在了 rust 目录下。

在 Rust 中使用 C 函数

Rust 提供 FFI( 外部函数接口 Foreign Function Interface )用来支持对 C 代码的调用。Bindgen 是一个 Rust 官方的工具,用来自动化地从 C 函数中生成 Rust 的 FFI 绑定。内核中的 Rust 也使用该工具从原生的内核 C 接口中生成 Rust 的 FFI 绑定。

quiet_cmd_bindgen = BINDGEN $@
      cmd_bindgen = \
    $(BINDGEN) $< $(shell grep -v '^\#\|^$$' $(srctree)/rust/bindgen_parameters) \
        --use-core --with-derive-default --ctypes-prefix c_types \
        --no-debug '.*' \
        --size_t-is-usize -o $@ -- $(bindgen_c_flags_final) -DMODULE

$(objtree)/rust/bindings_generated.rs: $(srctree)/rust/kernel/bindings_helper.h \
    $(srctree)/rust/bindgen_parameters FORCE
    $(call if_changed_dep,bindgen)

ABI

Rust 相关的代码会单独从 rs 编译为 .o,生成的目标文件是标准的 ELF 文件。在链接阶段,内核的链接器将 Rust 生成的目标文件与其他 C 程序生成的目标文件一起链接为内核镜像文件。因此,只要 Rust 生成的目标文件 ABI 与 C 程序的一致,就可以无差别的被链接(当然,被引用的符号还是要存在的)。

Rust 的 alloccore

目前 Rust for Linux 依赖于 core 库。在 core 中定义了基本的 Rust 数据结构与语言特性,例如熟悉的 Option<>Result<> 就是 core 库所提供。

这个库被交叉编译后被直接链接进内核镜像文件,这也是导致启用 Rust 的内核镜像文件尺寸较大的原因。在未来的工作中,这两个库会被进一步被优化,去除掉某些无用的部分,例如浮点操作,Unicode 相关的内容,Futures 相关的功能等。

之前的 Rust for Linux 项目还依赖于 Rust 的 alloc 库。Rust for Linux 定义了自己的 GlobalAlloc 用来管理基本的堆内存分配。主要被用来进行堆内存分配,并且使用 GFP_KERNEL 标识作为默认的内存分配模式。

不过在在最新的 拉取请求 中,社区已经将移植并修改了 Rust的 alloc 库,使其能够在尽量保证与 Rust 上游统一的情况下,允许开发者定制自己的内存分配器。不过目前使用自定义的 GFP_ 标识来分配内存依然是不支持的,但好消息是这个功能正在开发中。

“Hello World” 内核模块

用一个简单的 Hello World 来展示如何使用 Rust 语言编写驱动代码,hello_world.rs:

#![no_std]
#![feature(allocator_api, global_asm)]

use kernel::prelude::*;

module! {
    type: HelloWorld,
    name: b"hello_world",
    author: b"d0u9",
    description: b"A simple hello world example",
    license: b"GPL v2",
}

struct HelloWorld;

impl KernelModule for HelloWorld {
    fn init() -> Result<Self> {
        pr_info!("Hello world from rust!\n");

        Ok(HelloWorld)
    }
}

impl Drop for HelloWorld {
    fn drop(&mut self) {
        pr_info!("Bye world from rust!\n");
    }
}

与之对应的 Makefile

obj-m := hello_world.o

构建:

make -C /path/to/linux_src M=$(pwd) LLVM=1 modules

之后就和使用普通的内核模块一样,使用 insmod 工具或者 modprobe 工具加载就可以了。在使用体验上是没有区别的。

module! { }

这个宏可以被认为是 Rust 内核模块的入口,因为在其中定义了一个内核模块所需的所有信息,包括:AuthorLicenseDescription 等。其中最重要的是 type 字段,在其中需要指定内核模块结构的名字。在这个例子中:

module! {
    ...
    type: HelloWorld,
    ...
}

struct HelloWorld;

module_init()module_exit()

在使用 C 编写的内核模块中,这两个宏定义了模块的入口函数与退出函数。在 Rust 编写的内核模块中,对应的功能由 trait KernelModuletrait Drop 来实现。trait KernelModule 中定义 init() 函数,会在模块驱动初始化时被调用;trait Drop 是 Rust 的内置 trait,其中定义的 drop() 函数会在变量生命周期结束时被调用。

编译与链接

所有的内核模块文件会首先被编译成 .o 目标文件,之后由内核链接器将这些 .o 文件和自动生成的模块目标文件 .mod.o 一起链接成为 .ko 文件。这个 .ko 文件符合动态库 ELF 文件格式,能够被内核识别并加载。

其他

完整的介绍 Rust 是如何被集成进内核的文章可以在 我的 Github 上找到,由于写的仓促,可能存在一些不足,还请见谅。


作者:苏子彬,阿里云 PAI 平台开发工程师,主要从事 Linux 系统及驱动的相关开发,曾为 PAI 平台编写 FPGA 加速卡驱动。

安全专家告知数据被泄露后,却接到了对方的律师函

报道,安全专家 Rob Dyke 在 2 月底发现了一个公开的 GitHub 仓库,其中包含一个网站的源代码,以及包含用户名、散列密码、电子邮件地址和 API 密钥的数据库。然而在他 3 月 1 日书面告知数据泄露的 Apperta 基金会后却收到了律师函。

Apperta 的第一反应对他表示了感谢。然而 Dyke 告诉 Apperta,他将加密保留他发现的文件的副本三个月,然后销毁它们。Dyke 说他保留这些信息是为了防止再次需要这些信息,“以防出现我所不知道的更广泛的网络事件”。Apperta 将此解释为非法复制其数据。一周后,该公司的律师写信给他,要求他销毁文件的副本。在律师交锋几周后,Apperta 明确表示要向高等法院申请针对这位安全专家的禁令。

Dyke 最终在上法庭前删除了这些数据,并提交了证明。Apperta 表示他们没有提出诉讼,Dyke 已经承诺删除数据,但同时认为 Dyke “超越了善意研究的界限,而且他这样做是不道德的”。

此事引起了网络安全界的同情,人们为 Dyke 捐赠了 15000 英镑以解决法庭诉讼。然而,我们需要思考的是,白帽子的法律边界在哪里?什么是可以做的,什么是不可以做的?

研究人员制造出仅在显微镜下可见的无线、可注射的芯片

哥伦比亚大学研究人员报告说,他们已经建立了据说是世界上最小的单芯片系统,总体积小于 0.1 立方毫米,像一只尘螨一样小,只有在显微镜下才能看到。这是一个“芯片即系统”的新想法:一个单独的芯片就是一个完整的功能电子系统。该芯片是一个整体可植入/可注射的微粒,没有额外的封装。它是在台积电制造的,并进行了纳米级的工艺修改。该团队的目标是开发可以用于皮下注射的芯片,然后用超声波将其传回体外,提供它们在本地测量的信息。目前该芯片的功能是测量体温,但该团队正在研究的可能性还有很多。

这就是几十年前科幻小说里面的场景啊,这种芯片可以在医疗方面发挥很大的作用。

Rust 编程语言庆祝六岁生日

周六,Rust 编程语言的开发者庆祝了自 1.0 版本推出以来的六周年。作为 C 语言的替代品获得了很多关注,这要归功于默认开启的代码安全功能,它带来的是更少的可被利用的内存相关错误。这种内存安全特性让不少程序员注意到了它,由此它的采用率开始了编程语言当中不可思议的火箭式上升,Stack Overflow 甚至发现它是 2020 年调查中最受欢迎的编程语言

目前采用 Rust 的最引人注目的项目之一是 Firefox 浏览器,到 2020 年 7 月,macOS 上的Firefox Nightly 有 12.31% 的代码是用 Rust 代码编写的。

虽然 Rust 语言学习起来有些难,但是在某些原本是 C/C++ 独占领域里,Rust 已经显示出了明显的优势。