Linuxが消えた:わたしのGithubのリポジトリには赤の他人の知らないコミットが含まれている

Posted on

さよならLinux

今日はびっくりしました。

毎日お世話になっているLinux。その作者がついに嫌気がさしてカーネルのリポジトリからファイルをすべて消去するという痛ましい事件があったからです。

まぁ30年書いてりゃ飽きるよね(?)

ドッキリでした

…というのはもちろん嘘で、これはLinuxの作者、Linus 本人によるものではありません。

では何なのか?といいますと、これは別人のforkされたリポジトリに書かれているものです。

でも、最初の画像はLinusのリポジトリのページだったはずです。おかしいですよね。

Githubはすべてのfork間でデータを共有している?

どうも、Githubでは

  • forkしたリポジトリすべてでデータを共有しており、かつ、
  • githubにはあるコミットIDが自分のリポジトリにあるかそうでないかの区別が付かない

ようなのです。

ブラウザだけでなく、gitを使っても、同じようにLinusのリポジトリからこのコミットを取り出すことができます。

# 初期化
% git init
Initialized empty Git repository in C:/Users/kaede/src/t/.git/

# Linusのリポジトリをoriginとして追加
% git remote add origin git@github.com:torvalds/linux.git

# 問題のコミットだけfetch
% git fetch --depth=1 origin 4fbc49920463c394fc2615f00ecc907a2ce943da
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 638 bytes | 70.00 KiB/s, done.
From github.com:torvalds/linux
 * branch            4fbc49920463c394fc2615f00ecc907a2ce943da -> FETCH_HEAD

# mainブランチにmerge
% git merge 4fbc49920463c394fc2615f00ecc907a2ce943da

# ファイルを確認すると…
% cat README
Hyy there. It's me, Linus Torvalds: See the URL, Where is says /torvals/linux/.

I have deleted my kernel because it is garbage. You should instead check out
this OS called Microsoft Windows Vista. It is much smaller and faster then linux
ever was.

...

いや…これ…シンプルに頭おかしい仕様だろ…

ジョークならいいけどさ

今回はジョークだから、いいですよ。でも、悪い大人が悪用したらどうなるんでしょうね?

Linusに限らず、自分のリポジトリのURLで自分の名前を騙って意見などを書くことができるわけです。フェイクニュースの情報源にぴったりです。今回の例なら、「Linux開発者がLinuxを削除!Linuxを利用しているIT企業への影響は…」みたいな「ニュース」を書いたら市場が動いたりすらするかもしれません。

フィッシングに使うこともできますね。「このコミットでセキュリティ問題を修正したらしい。詳しくはここのソースのn行目に書いてあるURLを見てくれ」と書いておけば、Linusのリポジトリなら信用できると思った人がリンクをクリックしてくれるかもしれません。

任意のソースコードを実行させることだってできるかもしれません。上記に書いた通り、gitのコマンドを通してコミットIDの時点のスナップショットが取得できます。「このリビジョンで問題が修正されてるらしいから、使ってみて。cloneは重いからこの方法でshallow fetchするといいよ」と言いながら複数行のコマンドを渡されたら、あなたは「Linusやその他有名な人・公式アカウントなどのURLなら大丈夫」と思ってターミナルにコピペしませんか?でもそのコミットは実はマルウェアが仕込まれてるバージョンかもしれません

最後に。オリジナルのリポジトリと同じSHA-1ハッシュのコミットが生成できれば、オリジナルのリポジトリを汚染することができるかもしれません。これはgithub側の実装次第なので、なんとも言えません。

ストレージが高いのは分かるけど…

なんでこんな事になってしまったのでしょう。

これは推測ですが、たぶんストレージを節約したかったからだと思います。Linuxのリポジトリは数GBありますが、それを4万回もForkされたときに実直にコピーしてたら数10TBになってしまいます。

悪意を抜きにすれば、forkしたリポジトリ間でデータを共有しても、とくに問題ありません。別人の書いたforkのコミットには、それぞれオリジナルの作者のものとは違うコミットIDが振られます。同じ根本から違う枝が生えるだけです。

しかし、セキュリティの面では悪手です。

今まで見た通りのことに加えて、最近信用性の下がってきたSHA-1が問題になってきます。SHA-1はGitでそれぞれのコミットを識別するために使われます。セキュリティ担保のためには使われれてません(本人談)。しかし、データを共有したとなると、これはセキュリティ問題になりえます。githubのgitの実装次第ですが、もし同じコミットIDをpushしたときに上書きされるような挙動になっていた場合、fork先がfork元のリポジトリを汚染できてしまうかもしれませんgithub社は内製のgitサーバを用いており、それを知るすべはありません。

どうすれば…

SHA-1はまだそこまで破られてはいないので気にする必要は今のところないかもしれません。ただ、コミットをgpgで署名してなりすましを防ぐのは有効かもしれません。まぁ、Gitの最初の開発者でもあるLinusは普段からしてないようですが…。

一応、githubには署名されていないコミットにフラグを立てる機能があるので、これを有効にするのもいいかもしれません。ただ、そのフラグを忙しい現代人(スマホを覗くとだいたい暇つぶししてますけど)が見てくれるかどうかは別問題です。

gitにもgithubにも飽きた

正直なところ、飽きた。もう14年?くらい使ってるよ。飽きたよ。githubも10年以上使ってるよ。飽きたよ。なんかない?


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください