はじめに
Linuxの安定カーネルのリリースモデルの説明(2018/02/05)の訳文です。
著者は安定版カーネルのメンテナ、Greg.K.H氏です。
個人的にLinuxのバージョン番号についてあまり良く知らず(2.6が長く続いたことを知ってるくらいです)、また安定版とLTSの違いについてもあまり良くわかっていませんでしたが、それらの点に関してよく理解することができました。歴史的経緯や裏話も含めて説明されています。
加えて、Meltdown/Spectre問題等でにわかにセキュリティ面に注目が集まるようになりましたが、セキュリティ情報を(OSSとはいえ)むやみに広めない方針やその理由、こまめなアップデートがなぜ推奨されているかについて触れられており、非常にタイムリーな情報となっています。大抵のユーザはディストリビューション提供のカーネルを使うので余り意識しないかもしれませんが、SoCベンダ等独自カーネルを使っている利用者もできるだけLTSを使用し、アップデートを促す内容となっています。
ライセンス
原文は当人のブログでby-nc-sa3.0で公開されています。
この文章のライセンスも原文に準じます。
謝辞
多忙な中情報をシェアしてくれた原著者のGreg氏に。
Linuxカーネルのリリースモデルについて(訳)
注釈
この投稿は2016年初頭に自分が書いたホワイトペーパーをベースにしている。多くの企業にLinuxカーネルのリリースモデルについて理解してもらうため、またもっと頻繁にLTSカーネルをアップデートするように励ますためだ。2017年9月に行われたLinux Recipesカンファレンスでのプレゼン資料としてもこれを用いた。ここで視聴できる。
最近のMeltdownとSpectreの狂騒のせいで、Linuxのリリース方法やセキュリティパッチの扱い方についてのひどく不正確なドキュメントを大量に目にしてきた。それでほこりをふるい落とし、数か所更新し、ここで公開することでみんなの益とするべき時が来たと考えた。
オリジナルのホワイトペーパーを推敲するのを手伝ってくれたレビュアーに感謝したい。それは多くの企業が自社のデバイスのカーネルへのランダムなパッチからの"cherry picking"をやめる必要を理解する助けとなった。レビュアーの助けなしには、この投稿は全くまとまらなかっただろう。この記事の問題点や間違いは無論すべて自分に責任がある[※この訳文は当然訳者に責任があります]。もし何か気づいたり疑問があるなら、どうか自分に知らせてほしい。
概観
この投稿では
- Linuxカーネル開発モデルがどのように機能しているか
- 長期サポートカーネル(LTS)とは何か
- カーネル開発者たちのセキュリティバグに対するアプローチ方法
- Linuxを使用しているシステムがみな安定版リリースを用い、適当に選んだパッチをあてるべきでない理由
について記述する。
Linuxカーネルの開発モデルについて
Linuxカーネルは史上最大のソフトウェア共同プロジェクトだ。2017年には530超の企業から4,300人超の開発者がこのプロジェクトに貢献した。2017年には5つの異なるリリースがあったが、それぞれのリリースには12,000から14,000もの異なる変更が含まれていた。平均では、毎日、1時間当たり8.5の変更がLinuxカーネルに受け付けられていることになる。科学的に厳密とは言えない調査(自分のEmailボックスなど)だが、それぞれの変更にはカーネルソースツリーに含まれるまで2,3回は投稿される。カーネル変更統合時の厳しいレビューとテストプロセスのためだ。だから技術的な労力は毎時8回の変更を優に上回って生じている。
2017年末の時点でLinuxカーネル(4.14)は2,500万行のコードから成る61,000超のファイル、ビルド・スクリプト、ドキュメンテーションで構成されている。Linuxカーネルは対応済みの種々チップのアーキテクチャやハードウェア全てを含んでいる。そのようなわけで、個々のシステムは全体のコードベースの一部分だけを動かしていることになる。標準的なラップトップのシステムであれば適切に機能させるために5,000のファイルの200万行のカーネルコードを使用する。Pixel Phone であれば6,000のファイルの320万行ものカーネルコードを使用する。SoCの複雑性が増大しているからだ。
カーネルのリリースモデルについて
2003年12月の2.6カーネルリリース時、カーネル開発者のコミュニティ開発版と安定版の分離されたカーネルブランチを持つモデルから「安定版のみ」ブランチモデルに切り替えた。新しいリリースは2, 3ヶ月毎に出、そのリリースは「安定版」と宣言され、全てのユーザが動かすように推奨された。この変更が開発モデルに加えられた理由は、非常に長いリリースサイクルが2.6カーネル以前にはあったからだ(ほぼ3年)。また2つの異なるブランチのコードベースを同時にメンテナンスする事に苦労していたからだ。
カーネルリリースのナンバリングは2.6.xの形式で始まり、xはリリースごとに増加していく。数字には、前の番号よりも新しいリリースであるという他はなんの意味もない。2011年7月、Linus Torvaldsは2.6.39のカーネルのリリース後、バージョンナンバーを3.xに変えた。これはユーザの間で徐々にxの番号が大きくなるにつれ混乱をきたしたのと、カーネルメンテナーのグレッグ・クラーハートマンが大きい番号を扱うことに疲れ、Linusを日本の上質なウイスキー一瓶で買収したためである。
3.x系列への切り替えはメジャーリリース番号の変更以外は何も意味していない。そして再び2015年の4月には3.19から4.0へのリリース番号の変更が行われた。この時ウィスキーの授受が行われた記憶はない。現在のリリース番号について言えば、2018年中には5.xへ変更されるだろう。
安定版カーネルリリース
Linuxカーネルの安定版リリースモデルは2005年に開始した。(2-3か月に一度ずつ)新たにリリースするという旧来の開発モデルがほとんどのユーザのニーズにそぐわないと判断された。ユーザは2-3か月のうちにバグ修正があることを望むが、Linuxディストリビューションはカーネルコミュニティのフィードバックを受けることなくカーネルをアップデートすることに疲弊していた。それぞれのディストリビューションが、各々のカーネルをセキュアに保ち、かつ最新のバグフィックスに追従するのに多大な労力と混乱をきたした。
このことのために、安定版カーネルのリリースはスタートした。それぞれのリリースは直接Linusのリリース[=rc. リリース候補版]を土台としており、外部の様々な要因(一年のうちの時期、利用可能なパッチ、メンテナの負荷等)にもよるが、ほぼ毎週リリースされることになった。
安定版リリースのナンバリングはカーネルリリース番号から始まり、それからは終了まで付加的な番号が加えられていく。
例えば、4.9カーネルはLinusによりリリースされたが、これをベースにした安定版カーネルリリース番号は4.9.1, 4.9.2, 4.9.3と続く。このシーケンスを4.9.yなどと略して記述して、安定版カーネルツリーを参照する。それぞれの安定版カーネルのリリースツリーは単独のカーネル開発者がメンテナーであり、メンテナーはそれぞれのリリースで必要なパッチの選択・レビュー・リリースプロセスについて責任を負っている。それらの変更点がどこで見られるかについては下記を参照のこと。
安定版カーネルは現在の開発サイクルが続いている間はメンテナンスされる。Linusが新たなカーネルをリリースしたなら、以前の安定版カーネルは停止されユーザは新たにリリースされたカーネルに移行する必要がある。
長期サポートカーネル(LTS)
上記の新たな安定版リリースプロセスが開始してから一年後、別の多くのLinuxユーザはカーネルが数か月よりも長くサポートされることを望んでいる、と判断された。それでLTS(長期サポート)カーネルが登場することになった。最初のLTSカーネルは2.6.16で、2006年にリリースされた。それからと言うもの、1年ごとに一つの新たなLTSカーネルが選択されるようになった。それらのLTSカーネルは最低2年はコミニュティによってメンテナンスされる。LTSリリースのカーネルの選び方については次項を見てくれ。
現在LTSカーネルは4.4.y、4.9.y、4.14.yリリースだ。新しいカーネルは平均週に一度出ている。この3つのカーネルとともに、いくつかの古いカーネルが未だ幾人かの開発者によりゆっくりとしたサイクルで未だにメンテナンスされているが、これは一部のユーザやディストリビューションのためだ。
全てのLTSカーネルの情報、メンテナは誰か、いつまでメンテナンスされるかといった情報についてはkernel.orgのリリースページから見ることができる。
LTSカーネルへ平均して毎日9から10のパッチが受け付けられる。通常の安定版のパッチの場合10-15だ。リリースごとのパッチ投稿率は開発中のカーネルリリースへの対応時間や、他の外部要因によって変動する。古いLTSカーネルが受け付けることのできるパッチはより少ない。なぜなら多くの新しいバグ修正は古いカーネルに関連していないからだ。とはいえ、古いカーネルになると、必要な修正でも、コードベースの変化により対応するのが大変になる。それでパッチ全体から見れば少ないかもしれないが、LTSカーネルをメンテナンスするのは通常の安定版カーネルよりもずっと骨が折れる。
LTSカーネルの選定
どのカーネルがLTSとしてリリースするか、誰がメンテナンスするかを選定するメソッドは何年もの間に、半ばランダムなやり方から信頼性があるものへと変化してきた、と信じたい。
もともと選定の方法は、単に安定版カーネルのメンテナーの所属企業が製品に使用しているもの (2.6.16.y と 2.6.27.y) が選ばれた。メンテナンスの労力軽減のためだ。他のディストリビューションのメンテナはこのモデルの利点に気づき、談合して自分たちの企業に気づかれる事無く同じカーネルのバージョン(2.6.32.y)をベースにすることになった。企業は開発者たちに企業間でのワークシェアを許したが、この大成功の後、それらの企業はもう二度とそうしないと決定した。それ以後LTSカーネルはそれぞれのディストリビューションのニーズにより選ばれ (3.0.y, 3.2.y, 3.12.y, 3.16.y,3.18.y)るようになった。異なる開発者がメンテナンスし、多大の労力と混乱を関係者すべてにもたらすこととなった。
このその場しのぎの、特定のLinuxディストリビューションへの出前のようなやり方は、何百万もの組込システムで使用されているLinuxには有益ではなかった。それらのシステムは定番のLinuxディストリビューションをベースにしていないからだ。このゆえに、グレッグ・クラーハートマンはLTSカーネルの選定のやり方を、[他の一般の]企業がLTSカーネルを製品に使用できるようにするやり方に切り替えることを決定した。そのルールは「一年に一つのカーネルが選ばれ、二年間保守される」というやり方となった。このルールに基づき、3.4.y, 3.10.y,3.14.y カーネルが選ばれた。
大きな番号の違ったLTSカーネルを1年のうちにリリースするというのはベンダとユーザに大きな混乱をもたらすため、もはや特定のディストリビューションのニーズによりLTSカーネルの選定は行わない、と言うルールが作られた。これは年次会議で合意を得ており、4.1.yLTSカーネルをLTSカーネルとしての選定した時からスタートした。
この作業の最中、LTSカーネルはリリース後にアナウンスが行われるようになった。企業にとっては新製品にどのカーネルを使用するか事前に計画することが困難になり、たくさんの憶測や誤った情報が広がるようになった。これは前述の目的のために行われた。企業とカーネル開発者が次のLTSカーネルが何になるか前もって知っていると、通常の厳しいレビュープロセスが緩んで、テストされていないコードのマージを許すようになったからだ(2.6.32.y)。この乱雑な作業の結果、カーネルを解きほぐして適切なレベルにまで安定させるのに数カ月を要した。
コミュニティはこの問題について年次会議で話し合い、4.4.yカーネルをLTSカーネルのリリースとしてマークした。関係者全てが驚いたが、その目的は次のLTSカーネルが2016年の最新カーネルを土台にすることにより、次のホリデーシーズン(2017)に余裕を持ってこのLTSをベースにした製品をリリースしてもらいたいからだ。これは4.9.yと4.14.yカーネルがLTSとして選定された方法でもある。
このプロセスはうまく行ったように思われる。16, 000の変更が行われ、過去最大のカーネルになったにもかかわらず4.9.yではそれほど多くの問題は報告されていない。
今後もLTSカーネルは同じサイクルで予定される(その年の最後のカーネルを使う)。これはSoCベンダが前もって開発計画を立てる際、新しいチップセットにまもなく廃止されるような古いLTSカーネルをベースにしないように促すものとなるだろう。
安定版カーネルのパッチルール
安定版カーネルに加える修正はどうあるべきかというルールはこの12年間ほとんど変わらずに残ってきた。安定版カーネルリリースに受け入れられるパッチのルールはここで読める。以下は要約となる。
安定版カーネルに加えられる変更は:
- 明らかに正しく、テスト済みであること。
- 100行を超えないこと。
- 一つの修正のみであること。
- 報告された問題のみを修正すること。
- 新たなデバイス定義、ハードウェア変更であることは許されるが、新たに大きな機能を付加しないこと。
- Linusのツリー(=rc. リリース候補版)にマージ済みであること。
最後のルール「Linusのツリーにマージ済みであること」は、修正を失うことを防ぐためのものだ。コミュニティとしてはLinusのツリーに無い修正を安定版カーネルリリースに突っ込む事は避けたい。アップグレード時にリグレッションが起きる人を見たくないからだ。これは他の安定版と開発版を持つプロジェクトで起こりうるたくさんの問題を防いできた。
カーネルのアップデートについて
Linuxカーネルコミュニティはユーザベースに対して「現在動いているのが直前のリリースであるなら、それをアップグレードしても何も破壊しない」ということを約束してきた。この約束はイギリス・ケンブリッジで開かれた2007年のカーネル開発者年次会議でされたものだ。そしてこれは現在でも正しい。たしかにリグレッションが生じることもあるが、それらは最優先として扱われ修正されるか、カーネルツリーから速やかにリバートされる。
この約束は一つづつ番号が進んでいく安定版カーネルアップデートと、3ヶ月ごとに起こるもっと大きなメジャーアップデートに関して真実だ。
カーネルコミュニティはLinuxカーネルツリーにマージ済みのコードだけ保証できる。デバイスのカーネルにはマージされているが、kernel.orgのリリースではないもの[公式リリースではないもの]については不明であり、対応を計画したり考慮してはいない。大量のパッチセットを持つデバイスのLinuxは、新しいカーネルにアップデートする際に、顕著な問題をいくつも抱えている。大量の変更がそれぞれのリリースで生じているからだ。SoCパッチセットは特にアーキテクチャの仕様により、巨大かつ重大な変更が行われており、それは時としてコアのカーネルコードにまで及んでいる。
大部分のSoCベンダはリリース前に上流カーネルにマージしたいと思っているが、プロジェクト計画の現実と最終的なビジネスの優先順位により十分なリソースを割くことができないでいる。これには組み込みデバイスにアップデートをかけることの歴史的な難しさがあり、製品寿命の間特定のカーネルリリースをずっと使い続ける結果になっている。
カーネルツリー外のパッチセットの問題のため、多くのSoCベンダはLTSリリースを自分たちの製品として使うよう標準化し始めた。これにより、バグやセキュリティアップデートがLinuxカーネルコミュニティから直接受け取れるようになる。伝統的に対応がとても遅い、SoCベンダのバックポートのリレーなんてしなくてもよいのだ。
AndroidプロジェクトがLTSカーネルを「最低要求カーネルバージョン」として標準化してるのは良いことだ。SoCベンダーがユーザにより安全なデバイスを提供するために、アップデートを続けるよう促していって欲しい。
セキュリティ
カーネルのリリース時に、Linuxコミュニティは特定の変更を「セキュリティ修正」と宣言することはまずない。変更時にあるバグ修正がセキュリティ修正なのかそうでないのかを決定するのが難しいという根本的な問題のためだ。また、多くのバグ修正はかなり時間が経ってからセキュリティ修正とされることもある。それでパッチを当てないという間違ったセキュリティの感覚をユーザが持たないようにするため、カーネルコミュニティはいつでもすべてのリリース済みのバグ修正を適用する事を強く推奨する。
Linusはこの扱いについての説明を2008年のメーリングリスト上のメールで要約した。
On Wed, 16 Jul 2008, pageexec@freemail.hu wrote:
あなたは直近のいくつかの安定版リリースをチェックするべきだ。
セキュリティバグを修正しているにもかかわらず「セキュリティ」と言う言葉がアナウンスで言及されていないことを知るべきだ。ううむ、君は「これらは通常のバグである」と言うことのどの部分が問題だと思ってるのかな?
はっきり言うと、セキュリティバグだなんて特記すべきじゃないよ、バグはバグだろ。
言葉を変えると、これはセキュリティ問題を解決したってコミットで言うべき理由がある。
ないね。
自分が言いたいのはなんで[セキュリティバグとして]マークするんだ、マークなんて意味がないのに?
そんなこと真に受ける連中は間違っているよ。具体的に言うとどこが間違っているのですか?
以下の2つのケースが考えられる:
皆はマークが何となく信頼に値すると考えている。
皆は間違っている。部分的なマーキングに惑わされてもいる。マークされていないバグ修正は重要性が低い、と考えているからだ。そんなことはない。皆はマーキングを気にしていない
皆は正しい、つまりマーキングは的はずれだ。
どっちにしたってマークするのは馬鹿げている。そんなことしたくない。
「ただの通常のバグフィックス」とセキュリティ修正を分けるべきだなんていう神話の伝承なんかしたくないからね。修正は全部修正だ。どれも重要なんだ。新たな特色であり、問題に対するものだ。
あなたがコミットするときにはこのパッチはセキュリティバグの修正だって気づいているでしょ、なんでそのことをコミット時に言うのが間違ってるのか?
的外れだし間違っている。そんなことしたら利用者は他のバグが重大なセキュリティ修正だと思わなくなるだろ。
何か不明な点でも?
Linus
このEmailはここで読める。この話題に興味がある人はスレッド全体を読むことをおすすめする。
セキュリティ問題がカーネルコミュニティに報告されると、可能な限り迅速に修正され、開発ツリーと安定版リリースに公開される。すでに述べたとおり、ほとんどの変更はセキュリティ修正であるとは記述されず、他のカーネルのバグフィックスと変わらないように見えるだろう。これは問題の報告者が公表する前に、関係者がシステムをアップデート可能にするためである。
Linusは同じEmailのスレッドでこの開発方針について説明した。
On Wed, 16 Jul 2008, pageexec@freemail.hu wrote:
我々はこのことを調査したし、あなた自身はセキュリティバグを普通のバグのように扱っていないと言った。
あなたは現にセキュリティバグ修正時に関連情報を削除しているじゃないか。実際、僕らは根本的な事で同意できていないね。この”関連”って言葉だ。
自分はバグの引き金を明確にすることが役立つとか、必要な関連情報であるなんて思えないよ。
バグを追いかけて退治してる最中だったらそりゃ有用だし関連情報だよ。
でも修正された途端に無関係になる。君は、これはセキュリティ問題であると明確に表明するのが大事だ、とか思ってるから必要な関連情報だって思うんだよ。
自分の意見は正反対だ。セキュリティ問題を表明するのは現実的に言って、逆効果になると思う。例えば、自分としては修正のパッチとカーネルのリストを送ってくれて、直ちに非公開のemailで脆弱性の例をセキュリティメーリングリストへ送る人たちと作業したいよ。
(これは非公開リストだ。だって大学の連中がこぞってテストしだす、なんてことは避けたいからね)。
これが正しいやり方だ。コミットメッセージにセキュリティ攻撃の記述をしなきゃいけないって?
ゴメンだね。たとえ実際の情報であったとしても、理由があって非公開にしてるんだ。
開発者たちにとってはなぜこのパッチが必要か説明するのに必要な実際の情報であっても、一度説明したなら、不必要に拡散されるべきではない。Linus
セキュリティバグを可能な限り迅速に解決・修正するためにカーネルコミュニティに報告する方法の詳細はここで読める。
セキュリティバグがカーネルのチームからは公表されないため、Linuxカーネルに関連したCVE番号は安定版ブランチと開発版ブランチに修正がマージされてから数週間・数か月・ある場合には数年後に発行されることだってある。
システムを安全に保つ
Linuxデバイスはデプロイに際し、すべてのLTSカーネルのアップデートが製造元によって取得されており, 適切な動作検証の後にユーザにアップデートを配信する事を強く推奨する。上記でも説明したが、LTSリリースから雑多なパッチを選ぶことは下記理由から賢明とは言えない。
- リリース済みカーネルは、カーネル開発者から一部ではなくシステム全体をレビューされている。
- どのパッチがセキュリティ修正かそうでないかを判断するのは難しいし、無理だ。ほとんどすべてのLTSリリースは少なくとも一つはセキュリティ修正を含んでいるし、その他は不明だ。
- もしテストして問題が出たら、カーネル開発者は問題の解決のため迅速に反応するだろう。でも、君が数カ月から数年アップデートを遅らせるなら、カーネル開発者は長い期間にどんな更新があったかを思い出すことができなくなる。
- 君がビルドしたり動かしたりしていない部分への変更は悪いものではなく、システムに何ら問題を引き起こしはしない。一方、動かしている部分についてのみ変更を適応しようとするなら、将来のリリース時にマージ不可能なカーネルツリーが出来上がるだろう。
注釈:著者は上流のLTSリリースから都合よく"cherry-pick"しようとした大量のSoCカーネルを監査してきた。全てのケースにおいて、シビアなセキュリティ修正が無視されてきたし、適用されてもいなかった。
この事の証明として、自分は上で述べたカーネルレシピの講演でデモをした。小さなユーザスペース動作のプログラムを使って、アンドロイドのフラッグシップモデルをクラッシュさせることがいかに簡単か実演した。この問題に関する修正はデバイスのベースとなっているLTSカーネルにおいて6ヶ月前にリリースされたものであったが、いずれのデバイスもアップグレードや修正をしていなかった。この原稿を書いた時点で(5ヶ月後)カーネルを修正し、そのバグに対して脆弱ではないのはたった2台だけだった。
所感
ランダムに見えるLinuxのリリース番号のナンバリングですが、各企業の思惑、ちょっとした買収工作、リーナスの思いつき等魑魅魍魎であり実際複雑であることがわかりました:)。またカーネル開発者の買収にウィスキーは有効であるとの知見を得ました(リンク先のプレゼンによると、日本でのカンファレンスの時に買って数人で飲んだらしい。銘柄が気になる)。