CatCoding

第 11 期,隐藏的后门;Worse is Better;Wolfram 和 Jobs

2022-05-01

我每周会分享一下这周看到的好内容,加上自己的一些个人理解和评注。前面三期为:

#8 Valve,另一种公司

#9 理想中的开发者

#10 下一个 Google;最高形式的财富;冒名顶替综合症

这期分享的都是一些经典的老文章,有的老到比我的年纪都大,比如第一篇:

隐藏的后门

Reflections on Trusting Trust by Ken Thompson

A Discussion of Ken Thompson’s “Reflections on Trusting Trust”

Unix 的缔造者之一 Ken Thompson 在 1983 和 Dennis Ritchie 共同获得了图灵奖,他的的获奖演讲以《Reflections on Trusting Trust》(反思对信任的信任)为题,就是上面那篇短短三页的论文。

在这篇文章中 Ken Thompson 阐述了一种在编译器里面加上后门的巧妙办法,让他可以登录任何早期的 Unix 系统。

有的人会说编译器里加恶意代码,我们看看编译器的源代码不就知道了么,所以大家通常认为开源软件更安全,毕竟源码面前,毫无秘密。

Ken Thompson 的办法巧妙在于,他先修改了一个编译器的源码,编译出来的编译器为 P0, P0 可以在另外一份没有后门的编译器源码中插入代码,这样出来的编译器就还是有后门的 P1,但是你看源码又发现不了任何踪迹。

compile (code)
{
  /* If the code we're compiling is code for the Unix login command */
  if (match (code, login_code_pattern))
  {
    compile (backdoor);
    return;
  }

  /* If the code we're compiling is similar to the compiler source code */
  if (match (code, compiler_code_pattern))
  {
    compile (compiler_code_with_both_if_statements_inserted);
    return;
  }

  else
  {
    /* Do regular compilation things */
    ...
  }
}

编译器开发中有个常用的概念是自举 (bootstrapping),就是用这门语言实现的编译器编译新版本的编译器源码,一门新的编译型编程语言,实现自举是第一个里程碑。

这里就牵涉到鸡生蛋还是蛋生鸡的问题,那第一个编译器肯定不是自身语言实现的,比如 C 第一个编译器是 B 语言写的,Rust 编译器的第一份源码是 OCaml 的。

Ken Thompson 的做法可以理解为在自举过程中加入了特定的后门逻辑,导致编译出来的编译器都会有问题。

这里有位作者在 Go 编译器上做了 PoC,为编译器植入隐藏后门——亲手实践 Thompson hack

这类安全问题可以统称为信任链攻击,使用这种攻击手法,越底层的软件被动了手脚危害越大。一个 npm install 下去可能几百个第三方包就安装了,之前也出现过在 npm 包里加入挖矿代码这样的事。

现在软件开发的依赖如此错综复杂,我们只能相信写代码的人了。

Worse is Better

Rise of Worse Is Better

这篇文章是 1991 年写的,可以说影响了好几代程序员。我在学校的时候也读到过,这次重读一遍。

一个好的、理论上正确的设计包含这几点:

  1. 简单性
  2. 正确性
  3. 一致性
  4. 完整性

实践中采用这种设计哲学的方式称作 MIT 方式,在这种方式下设计的是 Lisp 和 Lisp Machine(一种专门跑 Lisp 的硬件)。

worse is better 的哲学认为简单性是最重要的,但为了保持简单可以一定程度上牺牲其他三个特性,这称之为 New Jersey 方式。这种方式下实现的产物是 C 和 Unix。

为什么称为 New Jersey 方式 ?

因为 C/Unix 的创造者 Dennis Ritchie 和 Thompson 所在的学校 UC Berkeley 在 New Jersey,另外美国人喜欢调侃新泽西,觉得相比起附近高贵的纽约,这地方真是又土又穷。新泽西乡巴佬,赤裸裸的地域歧视和小讽刺啊!

这篇文章中的主要例子是一个操作系统中的 PC loser-ing 问题,我看的时候没太看懂,然后搜到了这篇文章 EINTR and PC loser-ing , The “Worse Is Better” case study。这篇文章的推测我认为是对的,早期的 Unix 系统调用有一个 EINTR 返回状态 (被中断的系统调用),表示系统调用过程中发生了中断,需要重试,所以调用的时候经常写这种代码:

again:
  if ((n = read(fd, buf, BUFFSIZE)) < 0) {
    if (errno == EINTR)
      goto again;  /* just an interrupted system call */
    /* handle other errors */
  }

这看起来确实够丑陋的,不过因为几乎所有的开发者默认都想重试,所以 4.2BSD 开始就已经支持自动重试,而 POSIX API 通过修改 struct sigactionSA_RESTART 参数来决定是否重试。

所以,Unix 系统调用接口虽然当时看起来丑陋,但是逐渐已经通过缝缝补补把这个问题解决了!

In other words, Berkeley UNIX was already doing “the right thing” five years before “Worse is Better” was written!

而 Lisp Machine 对比 Unix,虽然设计精美、统一,但是却迅速陨落了。在软件开发中,这种新泽西方法似乎更有生命力,简单而言就是小步快跑,实现简单,快速出活。Unix 就是这样,虽然理论上看起来不够优雅,但是足够简单,可以很快地移植到不同的硬件上去,所以越来越流行:

The worse-is-better philosophy means that implementation simplicity has highest priority, which means Unix and C are easy to port on such machines. Therefore, one expects that if the 50% functionality Unix and C support is satisfactory, they will start to appear everywhere. And they have, haven’t they? Unix and C are the ultimate computer viruses.

The lesson to be learned from this is that it is often undesirable to go for the right thing first. It is better to get half of the right thing available so that it spreads like a virus. Once people are hooked on it, take the time to improve it to 90% of the right thing.

这和另外一个软件开发箴言是一个意思:

Make it work, make it right, make it fast
– Kent Beck.

而 Lisp 本身虽然已经没落,但一些核心的东西却深刻地改变了编程语言和软件开发,比如递归、函数式编程、GC、Eval、Code as Data 等等,参考 为什么 Lisp 语言如此先进

Wolfram 和 Jobs

Stephen Wolfram on Twitter

Wolfram 是著名软件 Mathematica 的作者,在这封 1987 年的信件里面他回复了 Jobs 的咨询。这个文件里面倒是没有列出 Jobs 的原问题,不过从标题和回复内容看,大概是 Jobs 想在 NeXT 里面做一个叫作 jobsbooks 的东西,里面包含一些词典、手册、等常用的书籍和参考,所以向 Wolfram 咨询数据来源有哪些?

当然这是我的猜测,Wolfram 是很适合问这个问题的人,他几乎是一个百科全书式的天才。他年轻的时候开始做物理方面的研究,后来开始写软件:

“我一直认为,做研究一定要用最好的工具。即使我用的是当时最先进的计算机,还是不断遇到故障。我明白,唯一的方法就是自己把它们造出来。所以,我就动手了。”

于是 Mathematica 诞生了,这个软件被称作是“有史以来最重要的科学软件”。

我搜索后发现 Wolfram 和 Jobs 也就是在 1985 年左右结识的,这篇文章是 Wolfram 2011 年 Jobs 去世时写的 Steve Jobs: A Few Memories—Stephen Wolfram Writings

里面写到了多年前的往事,甚至 Mathematica 这个软件的名字是 Jobs 给取的。其中有段还写到,一次交谈时 Jobs 心烦意乱、小鹿乱撞,原来他晚上有个约会:

The Steve Jobs—so confident as a businessman and technologist—had melted away, and he was asking me—hardly a noted known authority on such things—about his date.

但 Wolfram 肯定比 Jobs 更“书呆”,怎么可能给出约会的建议,哈哈。


这些老文看起来也挺有趣!

各位劳动节快乐!

公号同步更新,欢迎关注👻