プロプライエタリモジュールをさらに使いにくくする Linux カーネルパッチ
(lwn.net)- Linux カーネルコミュニティはプロプライエタリなカーネルモジュールを以前から好んでおらず、Christoph Hellwig のパッチはその抜け道を再び狭めようとする措置である
- カーネルはプロプライエタリモジュールの読み込み自体を禁止してはいないが、GPL-only exports によって一部のカーネルシンボルへのアクセスを GPL 互換モジュールのみに許可している
- 2020年には、GPL モジュールがプロプライエタリモジュールとカーネルの間をつなぐ GPL condom 方式が明らかになり、その後はプロプライエタリシンボルを使うモジュールもプロプライエタリとして扱われるようになった
- 新たな抜け道は
symbol_get()により、通常の import 手順を経ずにプロプライエタリモジュール内部のシンボルアドレスを取得する方法であり、Hellwig は NVIDIA がこの方法を使うようコードを変更したと見ている - 提案されたパッチは、
symbol_get()が GPL-only ではないシンボル の検索に失敗するようにして抜け道を塞ぐが、モジュールがカーネルアドレス空間で動作する以上、アクセス制御を完全に安全なものにするのは難しい
プロプライエタリなカーネルモジュールをめぐる長年の緊張
- Linux カーネルコミュニティは、プロプライエタリなカーネルモジュールの提供者と円滑な関係を築けてこなかった
- こうしたモジュールは、作成者以外にはデバッグや修正が難しい
- 多くの開発者は、これをカーネルライセンスやコード著作権の侵害とみなしている
- それでもプロプライエタリモジュールは一定の範囲で許容されてきた
- Christoph Hellwig の最近のパッチは、その許容範囲をもう少し狭めようとする動きである
2006年の読み込み禁止の試みと GPL-only exports
- 2006年には、プロプライエタリなカーネルモジュールの読み込みを全面的に禁止しようとする短い試みがあった
- Linus Torvalds は複数の理由からその試みを止めた
- プロプライエタリモジュールを Linux カーネルに単に読み込む行為自体は著作権侵害ではない
- Linux ユーザーはそのような行為を行える
- Torvalds は、そのような禁止が技術改善よりライセンス論争に関心があるというシグナルになりかねないと考えた
- プロプライエタリモジュールの配布は、そのモジュールがカーネルコードの派生著作物であるなら著作権侵害になりうる
- しかし派生著作物かどうかは曖昧であり、カーネル自体が実際にその判断を下すのは難しい
- カーネルには、侵害の可能性があるモジュールを妨げるための古くからの仕組みとして GPL-only exports がある
- カーネルモジュールは、カーネルが export した関数やデータ構造のシンボルにアクセスできて初めて有用な仕事ができる
- 多くのシンボルは GPL 互換ライセンスを宣言したモジュールにのみ許可されている
- この方式は、プロプライエタリモジュールをカーネル機能のかなりの部分から切り離している
GPL-only 表示の意図と現実
- 理論上、GPL-only の表示は、あるシンボルがカーネル内部と深く結び付いており、それを使うコードが必然的にカーネルの派生著作物であることを意味する
- 実際の開発者は、そのような法的分析を行っていない
- たいてい、そのような分析を行う資格もない
- 現実には、シンボルを GPL-only として表示することは、プロプライエタリモジュール全般をより難しくする手段としてしばしば使われている
2020年に明らかになった仲介型の回避手法
- プロプライエタリモジュールの作者たちは、以前から GPL-only exports の制限を回避する方法を探してきた
- GPL 互換ライセンスを偽って宣言する方法もあるが、これは明白な不正の自認のように見えるため、企業は本能的に避ける
- より巧妙な方法の1つが、2020年の peer-to-peer DMA 関連パッチセットの過程で明らかになった
- この構成では、GPL 互換ライセンスを宣言したモジュールが仲介役になる
- そのモジュールは、カーネルが export したすべてのシンボルにアクセスできる
- さらにプロプライエタリモジュールのシンボルを import すると、プロプライエタリコードが必要なカーネル機能にアクセスできる
- これは、いわゆる GPL condom 方式の変形である
2020年の対策パッチ
- 当時 Hellwig は、この方式をより難しくする パッチ をマージした
- 現在のカーネルでは、プロプライエタリモジュールのシンボルを使うモジュールもプロプライエタリとして扱われる
- その時点で GPL-only シンボルにアクセスする能力を失う
- すでに GPL-only シンボルを使った状態でプロプライエタリモジュールのシンボルを import しようとすると失敗する
- このチェックにより、GPL モジュールがプロプライエタリモジュールとカーネルの間で仲介役を果たす経路が塞がれた
symbol_get() による新たな抜け道
- カーネルは
symbol_get()マクロを提供しており、実際の処理は__symbol_get()が行う - この機能は、カーネルシンボルに対応するアドレスを見つける
symbol_get()は 2002年の 2.5.48 リリースからカーネルに存在し、モジュールローダーを大規模に置き換える過程で追加された- 重要な制限もある
- 検索対象は、ロード可能なモジュールが提供するシンボルだけである
- 密接に連携するモジュール同士が参照ループなしで、一方のモジュールがまだロードされていない可能性を扱うために使われる用途である
- 表面的には GPL-only のカーネルシンボルの位置を見つけるためには使えないため、規則を回避したいプロプライエタリモジュールベンダーにはあまり役立たないように見える
symbol_get() が2020年の防御を回避する仕組み
symbol_get()は、通常の import メカニズムとその制限を通らずにプロプライエタリモジュールのアドレスを取得するために使える- このため、2020年の修正は再び回避されうる
- 名目上 GPL ライセンスのモジュールがプロプライエタリモジュールを呼び出せる
- そのプロプライエタリモジュールは必要なカーネル機能にアクセスできる
- Hellwig は、NVIDIA がこの回避手法を使うようコードを変更したと 判断 している
新しいパッチセットによる動作変更
- Hellwig はこの穴を再び塞ぐために パッチセット を投稿し、その後 改訂版 も提出した
- 中核となる変更は、
symbol_get()の動作を変えることにある- 検索しようとしているシンボルが GPL-only として表示されていなければ失敗する
- 通常は GPL-only と表示されたシンボルへのアクセスを拒否するのとは逆向きのチェックである
- 理由は、
symbol_get()がもともとカーネル深部の低レベルな協調のための機能であり、その領域ではすべてが GPL-only であることが期待されるからである - カーネル内の一部の既存用途では、GPL-only として表示されていないシンボルを対象にしていた
- パッチセットには、その場合のシンボルを GPL-only に変更する修正も含まれている
想定される影響と限界
- 今回の
symbol_get()の変更により、GPL ライセンスのカーネルモジュールがsymbol_get()を使ってプロプライエタリモジュール内部のシンボルを解決することは不可能になる - この変更が mainline リリースに入り、ディストリビューションにも降りていけば、プロプライエタリモジュール開発者は必要なカーネル内部アクセスを得る別の方法を探さなければならない
- モジュールメンテナーの Luis Chamberlain がこの変更を 適用 したため、最終的に mainline に入る可能性はかなり高そうだ
- この対立は長く続いており、プロプライエタリモジュールの作者たちがカーネルコミュニティの意図を回避する別の方法を見つける可能性は低くない
- プロプライエタリかどうかに関係なく、モジュールはカーネルアドレス空間で実行される
- カーネルのシンボルアクセス方針を回避しようとするモジュールが利用できる攻撃面は広い
- この領域を完全に保護するのは難しい
- 現実的にできる最善策は、バイナリ専用カーネルモジュールの配布者に対し、自由ライセンスのソリューションを作るよう引き続き不便を強いることだ
- この方法は完全ではないが、これまでの年月の中でしばしば効果を上げてきた
1件のコメント
Hacker News の意見
Linux カーネルのリンカーコードは、GPL とシステムコール例外がどう機能すべきかについての Linus Torvalds の解釈を強制するように設計されているので、Nvidia が著作権保護の回避(DMCA 1201)をしたと主張できる法的余地はありそうです
Linus が実際にそうすることはないでしょうし、そうなれば FOSS エコシステム全体にとってもかなりひどいことになりますが、Nvidia がこれまでやってきたことを考えると、一度くらい見てみたい気もします
部屋の中の800ポンドのゴリラである Linux ですら法廷に出る意思がないなら、ほかのプロジェクトの見通しも明るくは見えません
Linux が大企業による露骨なライセンス・著作権違反に「穏やかな」技術的圧力だけで対応するつもりなら、むしろ GPL は終わったものと見て、BSD3 や MIT+Apache のような方向へ移るほうがよいのではないかとも思います
LLVM は強いコピーレフトを使わず、API の変動や非常に速い開発速度といった純粋に技術的な手段でアップストリームへの協力を促していますが、選んだライセンスを薄めることなく、かなりうまく機能しています
Nvidia の事業機会に実質的な打撃を与え得る反訴は、今後の問題を防ぐ抑止力としてうまく働く可能性があります
「symbol_get はもともと、非常に内部的なシンボルを使う密接に協力するモジュールだけのためのものだったので、EXPORY_SYMBOL_GPL にだけ使うよう制限し、Nvidia が高額な DMCA のアクセス制御回避訴訟を避けられるようにするのが論理的だ」という趣旨で、Nvidia が意図と配慮を露骨に無視して好き勝手していることを皮肉る、とても見事な表現です
夢を見ることはできます :)
[1]: https://www.youtube.com/watch?v=tQIdxbWhHSM
Linus に特別な権限があるわけではありません
このパッチの作者が残したコメントは本当に独特です
https://lore.kernel.org/lkml/20230731083806.453036-6-hch@lst...
「symbol_get はもともと、非常に内部的なシンボルを使う密接に協力するモジュールだけのためのものだったので、EXPORY_SYMBOL_GPL にだけ使うよう制限し、nvidia が高額な DMCA のアクセス制御回避訴訟を避けられるようにするのが論理的だ」と書かれています
これは文字どおり、オープンソースプロジェクトである Linux カーネルについて、DRM 回避を違法化する DMCA の迂回禁止条項による保護を主張しようとする試みです
同時に、EXPORT_SYMBOL_GPL が明白に DRM 体系であることを暗黙に認めていることにもなります
個人的には NVIDIA が嫌いですし、彼らの行動を特に擁護するつもりもありませんが、Linux プロジェクトが DRM 回避禁止法はオープンソースプロジェクトにも適用されると主張するのは驚きです
これはオープンソースコミュニティがほぼ普遍的に反対している法律の一つであり、どんな DRM 体系であれ FOSS の価値観とはかなり相いれないように見えます
GPL の中心的な目標そのものが、著作権法を著作権法に対抗する形で使うこと、つまりコピーレフトでした
著作権法が強くなるほど GPL の保護も強くなるので、オープンソースソフトウェアを守るために追加的な著作権法制を活用するのは、GPL の精神にかなり沿っていると思います
GPL はパーミッシブライセンスではなく、強いコピーレフトライセンスであり、実際の執行力があります
汚染メカニズムは偽善ではなくオープンソースであり、コードが GPL なら望むようにできます
文字どおり GPL ライセンスのリンク条項を強制する仕組みです
必要なときにはその法律を使うべきなので、まったく変には感じません
怪しいことをしたのに、これほど穏やかに面子を保たせてもらえるなら、運が良いほうです
GPL の盗用を防ぐための DRM は、論理的な次の一手に見えます
なぜプロプライエタリなドライバーが自由なカーネルと相互作用してはいけないのか分からない
Linux は文字どおりカーネルレベルの DRM を実装しているわけで、それは自由ソフトウェアが破壊すると誓っていたまさにその対象だ
少なくとも、プロプライエタリなドライバーが GPL 専用コードと相互作用できないようにする要求は、私の見方では EULA に近いと思う
GPLv2 だけなら、プロプライエタリなモジュールはおそらく侵害になっていただろう
しかし Linus が、システムコールは GPL のコピーレフトを発動しないと明示したため、システムコールに相当するカーネルシンボルも GPL のコピーレフトを発動しない
そのため、Linus の GPL 例外の解釈に従ってライセンス違反を避けるには、どのシンボルにリンクでき、どのシンボルにリンクできないかというライセンスデータを確認するローダーが必要になる
これはカーネルレベルの DRM で間違いなく[0]、Linus が Nvidia の複製保護回避について法的主張を行う余地もあるかもしれない
GPLv3 は対象コード内のいかなる複製保護も明示的に否認しているため、理論上はこのような訴訟を防げるが、その条項は法廷で検証されておらず、Linus は TiVo 条項を追加したという理由で GPLv3 を特に嫌っている[1]
この機能は数十年前に実装されたもので、当初の目的は、修正できないプロプライエタリなモジュールのせいで Linux カーネルがクラッシュしたというバグ報告を受けたくない、というものだった
GPL の執行は副作用だった
[0] カーネル内の別の DRM である Direct Rendering Manager と混同してはいけない
[1] TiVo 条項そのものが嫌いというより、v2 ソフトウェアに遡及して条件を追加し、取引条件を変えることを嫌っている。Linux が FSF に掌握されるように感じるからだ
ただし、複数の類似カーネルで見られるかなり一般的な OS 機能だけを使う必要がある
Linux 固有の機能に依存しないそのようなドライバーは、Linux カーネルの「派生著作物」とは見なせないため、好きなライセンスを選べる
逆に、他の OS、さらには他の Unix 系カーネルにも存在しない Linux カーネル固有のインターフェースを使うドライバーは、定義上カーネルの「プログラムに基づく著作物」に近く、したがって同様の形でライセンスされるべきだ
カーネルが従っている GPL-2 の文言を見ればよい
https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
LGPL は、自由ソフトウェアとプロプライエタリソフトウェアの分離されたリンクを認めるために別途存在しており、GPL では禁止されている
しかし Linux は GPL-2 なので、そのような追加の許可は適用されない
Nvidia ドライバーが一般的なカーネル API だけを使うなら問題ないだろうが、実際にはそうではない
GPL 互換ライセンスのドライバーが使うように示された Linux 専用 API を、GPL ではない状態で使おうとしているため、Linux が提供されている自由ソフトウェアライセンスの明白な違反だ
なぜプロプライエタリソフトウェアは自由ソフトウェアの利益をすべて享受しながら何の規則にも従わなくてよく、自由ソフトウェアはただ我慢しなければならないのか?
民主社会にも、自らを守るために表現をある程度制限する仕組みがある
プロプライエタリな OS はすでに多くあり、そういうものはまったく気にしていない
そうした原則を気にする OS があってはいけないのか? すべてが人間的配慮のない、冷たく産業寄りの道具でなければならないのか?
ライセンスの意図は、カーネルにリンクされロードされるすべてのものが、互換性のあるコピーレフトライセンスで配布されることにある
プロプライエタリコードが GPL コードを「含んでは」ならないという要求は GPL そのものであり、GPL の中心的な目的だ
ただし、単に API にリンクすることがどの程度まで侵害なのかについては争う余地がある
どちらの判決もあり得そうで、その判断は GPL に大きな影響を与えるだろう
Nvidia のコードは ring0 で動くので、経験上、Nvidia が使えるもっと面白い小細工ははるかに多いが、今はおそらく自制しているのだろう
Linux 開発者たちも同じだ
こんな愚かな DRM 争いは誰のためにもならず、全員の時間を浪費するいたちごっこをさらに助長するだけだ
「みんな、仲良くしろ」
Nvidia がなぜドライバーをプロプライエタリなバイナリの塊として維持することにそこまで多大な労力をかけるのか理解できない
ソフトウェアが彼らの防御力の中核というわけでもなく、Nvidia はハードウェア企業だ
カーネルモジュールを公開してもハードウェア売上には影響しないどころか、安定性は向上し、AMD GPU を買おうとわざわざ方向転換する開発者たちからの好感も得られるはずだ
コモディティ化は厚い利益率とは正反対だからだ
GPU 市場の約 80% を占めている状態で利益率をさらに高めるには、価格をより強気に設定するか、スタック全体のより上位レイヤーを支配するほうが容易になる
例えば主要な汎用 GPU 言語が自社の GPU アーキテクチャ中心に作られていれば有利だ
あるいはまったく別の分野へ拡張する必要があり、Nvidia が AI に強く踏み込んでいるのも、GPU での支配力を活用してその分野で序盤の優位を確保できるからだ
ただし根拠はない
「違法」というのは、法廷で立証されるまではあくまで理論にすぎない
ここで言っているのは本質的にはカーネルコード内のDRMで、ロード可能なカーネルモジュールが、カーネルのデータ構造がメモリ上のどこにあるのかを推測できないようにするもの
人々が限界を押し広げようとする可能性があると分かっているので、抑止策としてできるだけ難しくしようとしている
しかし「shim」があろうとなかろうと、すべてのクローズドソースのロード可能カーネルモジュールは同じようにGPLに違反している、と主張することもできるし、実際にそういう主張もあった。ただ多くの人はそれを忘れ、このDRMというフィクションを法的フィクションの代替物のように使っている
あるいは、カーネル内のGPLタグ付き関数がGoogle対Oracle事件で言われた意味でのAPIに当たるなら、この議論全体にあまり意味はないのかもしれない
ほとんどのロード可能カーネルモジュールはカーネルのソースツリー内にあり、GPLで提供されている
次の段階として、ユーザーモードでバイナリの塊をロードする小さな仮想マシンを含む、オープンソースのロード可能モジュールを作ればよい
NVIDIAが持つ非公開鍵で署名されたバイナリの塊だけを実行し、公開鍵はオープンソースモジュールに含める、という形だ
あるいはLinuxを仮想化するハイパーバイザーを作って、カーネルの大部分を迂回するとか……
方法は常にある
これは単に面倒にして、Linux向けのまともなドライバを得るコストを引き上げるだけなので、そこに投入される労力は減るだろう
それが大きな損失なのかは明らかではない
この戦いが最終的に、Linux向けNvidiaドライバがなくなったり、さらに悪くなったりする結果につながらないでほしい
そのドライバがないと、私の好きなOSがゲームとAIのせいで急にあまり役に立たなくなる
10年前は違った
当時は主に、Linuxでゲームをしたい少数のLinux好きが気にしていただけで、彼らは売上の中では小さな割合だった
今では事実上、NVIDIAの企業価値全体がAIの上に築かれており、そのハードウェアを大量購入する主要プレイヤーのほぼ全員がLinux上で使っている
NVIDIAがLinuxを切ることは選択肢ではない
そうならないように何でもする可能性が高い
nVidiaが公開されるまで、すべてのサポートを削除するのだ
ただ最近では、われわれではなく商業企業のほうが、Linuxでハードウェアをどう使いサポートするかについて、より大きな発言権を持っている
Nvidiaはドライバ、あるいはその一部をオープンソースとして公開し、今では再配布可能なファームウェアバイナリも提供している
さらに一部の古いカードではファームウェア認証も破られている
だから時間がたつにつれて、プロプライエタリドライバの重要性が下がることを期待している
カーネルレベルで「君のビットは何色か」[1]になったということか……いいね?
[1] https://ansuz.sooke.bc.ca/entry/23