解き放たれしソフトウェア

GNU/LinuxなどFLOSSについて書いてみるつもり

NVIDIA のビジネスモデルと、ドライバの利用許諾契約の問題

NVIDIA *1が最近、GPUGeForce 用のデバイスドライバの利用許諾契約(End User License Agreement ; EULA)条項を改定してデータセンターでの利用を禁止したことで、一部で騒動になっています*2

GeForce は本来は民生用のグラフィック表示のためのGPUですが、いわゆる「クラスタ」を組んで演算させるという使い方をしている人が結構います。極端な例を挙げれば「仮想通貨の採掘(マイニング)」でしょうがそれはほんの一部で、様々な研究目的や、ソフトウェアの分散コンパイルやクロスコンパイルにもよく用いられています。高速なCPUや専用のプロセッサを導入するよりも廉価に済むからです。

もともと民生用のパソコンのグラフィック表示用、典型的にはゲーマー用である GeForce ですので、メーカーの NVIDIA としては、上記のような使い方は保証していませんでした。 「無保証」ということはつまり、「壊れても交換や修理はしない」ということや、「演算の結果の正確性を保証しない」ということ なのでしょう。

さて、ハードウェアを使うには、デバイスドライバが必要なことが多いです。デバイスドライバは、ハードウェアではなく、ソフトウェアです。 そして、ハードウェアに企業秘密の技術を用いていると、デバイスドライバの方も企業秘密にしたい、する必要がある、ということがよくあります。 ですから、ユーザには利用許諾契約(EULA)に同意させる、それは、製品開封時やドライバのダウンロード時に強制します。いわゆるプロプライエタリドライバです。

GeForce には、標準規格と異なる特殊な技術が使われていて、その技術を活用するには専用のデバイスドライバが必要です。 つまり、 GeForce性能を十分に活用するにはEULAに同意してプロプライエタリのドライバを使わないといけません。

そして今回、EULAを改定して「データセンターでの使用禁止」にしたことで、今後はデータセンターでの新規導入が禁止されるのみならず、デバイスドライバをアップデートするにもダウンロードが必要ですから、既存の導入品に関してもドライバをアップデート不可能、という事態になりました。

ちなみに、ハードウェアを所有しているのにデバイスドライバを使えないので、そのハードウェアすらも使えない、という問題は昔からあります。そしてこれは、フリーソフトウェア運動が始まったきっかけの一つでもあります。 つまり、プロプライエタリドライバの EULA 問題があったからこそ、フリーソフトウェアも出てきましたし、オープンソースデバイスドライバも出てきたわけです。

今回の事件について、NVIDIA の言い分は「もともと無保証だったんだから EULA の方を合わせただけ」ということでしょう。

それは勿論、屁理屈です。「保証しない」と「禁止する」(契約違反で民事罰の対象になる)はまったく異なる次元だからです。 たとえば、文房具のハサミを台所で野菜を切るのに使ったら、メーカーは「保証しません」と言うかもしれませんが、訴えるとかい うアホなことにはならないでしょう。 つまり、EULAで禁止するというのは、「大きく踏み込んだ」実力行使なのです。

NVIDIA のビジネスモデル

NVIDIAプロプライエタリ固執して、以前は Linux に参加することさえ嫌がったので Linus Torvalds が怒ってみせた*3 くらいです。

NVIDIAプロプライエタリ固執するのは、 GeForce のビジネスモデルに必要不可欠だからです。

GeForce の売り方はこうです。

  • GPU に企業機密の特殊な技術を導入していて、性能は規格外の高さ
  • しかし、その性能を引き出すためには、実際にグラフィック表示させるソフトウェア(典型的には 3D ゲーム)*4にも対応が必要
  • そのゲームメーカーなどに技術者を派遣して、見返りに GeForce だと速くなるゲームを造らせる
  • よって、ゲーマーからすると、スムーズにプレイしたいなら GeForce ってことになる
  • GeForce 速えぇえええ」「ゲームをやるなら GeForce 一択」「GeForce を選ばない奴は馬鹿じゃね」って評判になって、製品が売れる

というわけで、秘密の特殊技術なくしては成り立たないビジネスモデルを続けてきました。

他方で、グラフィック表示は、チップセット統合、さらにはCPU統合が一般的な時代になりました。 だから、専用のグラフィックボードを挿すのは、かなり高速な GPU が必要な層、つまりは 高負荷の3D表示≒3Dゲームのゲーマーです。

小売店の現状

ちなみに今、いわゆるパーツショップなどのパソコン店では、取扱商品がGeForceばかりになってきています。

それはもともと AMDGPU搭載のグラフィックボードを売るメーカーが少なかったのに対して、NVIDIA は多メーカーに供給したということもあります。

ですが、今時、「自作PC」や「ショップブランドPC」を選択するのには価格的なメリットが希薄で、高性能パソコンが欲しい人が専門店で買うというパターンになってきたからです。 また、パーツを売っても粗利益がまともに出ないのでパーツショップがまたぞろ潰れたように、高価格の商品を売りたい、ということがあります。

で、わざわざ高性能のパソコン*5を買う人となると、一部の業務用(いわゆる「クリエイターズパソコン」など)を除けば、趣味ですから、大概はゲーミングパソコンって話になってしまいます。

「ゲームやるなら GeForce 」という評判が確立されて久しいうえにこうですから、AMDGPU 搭載のグラフィックボードをほとんど置いていない、そもそも置いていない、という店が増えました。 さらには店員も GeForce をゴリ押ししてくることが少なくありません。売れ筋なので在庫はあり、メーカー展開が多く、在庫がダブついているので。

NVIDIA の、ユーザ無理解(あるいは軽視)

GeForce でデータセンターでクラスタ組む人というと、仮想通貨をマイニングして儲けている人だ、という偏見が少なからずあるのでしょう。

ちなみに私からすると、自分の儲けのために電力を無駄遣いして「マイニング」(実際には資源を掘っているわけではなく、エネルギーの全くの無駄遣いですが)をしているのは、ふざけた話ですが。しかし、まあ、そういう人々もいるのはたしかです。 さらには、本当かどうか判りませんが、VPSの「無料お試し期間」を利用してタダで「マイニング」している人までいるらしいですが*6。 電力の無駄遣いです。限りある資源を無駄遣いして、地球環境破壊と人類滅亡を助長しているわけですが。さらに言えば、その「仮想通貨」に「投資」して儲けようとしている人々もまた、悪に加担しているわけです。*7

ともかく、GeForceクラスタ組んで演算させるといっても、目的は色々あるのです。何を演算させるかには決まりはないのです。

けれどもおそらくは、NVIDIA としては、「GeForceクラスタ組んで儲けているくらいだから、もっと高い製品を買わせたい」という論理なのでしょう

同時に、「GeForce のユーザはゲーマーだから、今回のような EULA 改訂では無関係だし、速いGPUが欲しい彼らからは評判を失わないだろう」と思っているのでしょう。おそらくその通りで、ゲーム中毒者が EULA を気にして NVIDIA から離れるということは、ほとんどないでしょう。

今回煽りを食って大損したのは、研究目的などのさして儲からない目的でクラスタ組んできた個人や中小研究機関なのです。

勿論、GeForce 搭載サーバを提供してきたデータセンター企業も、今まで投資してきたのがパァってことで損したわけでしょうが、「そもそも無保証の使い方を顧客に提供してきたこと自体にも問題があったんじゃないの?」とも私は思います。ねえ、さくら。

*1:私からすると nVIDIA と書いた方が未だにしっくりくるのですが。

*2:さくらの専用サーバ 高火力シリーズ Quad GPUモデルの新規提供一時停止のお知らせ | さくらインターネット

*3:Torvalds が怒るのは戦略的な目的があります。IntelAMD など既に参加しているオープンソース勢にとって自己正当化の理由にもなるからです。

*4:ベンチマークソフトなどもそうです。

*5:企業用のサーバとかは別ですよ

*6:「さくらのVPS」お試し期間中の利用方法についてのお願い | さくらインターネット

*7:フリーソフトウェアの関係者にも「仮想通貨」で寄付を募っているところが少なくありませんが、「仮想通貨」が注目されたのは、既存の通貨だと、国家権力などにコントロールされているということや、送金のトレーサビリティがあって秘匿性がないということがあります。「一山当てよう」といって「マイニング」している人々は、元来の目的を無視しています。

【セキュリティ】Meltdown と Spectre

クリスマス&ニューイヤー休暇返上で Linux カーネルの Kernel Page Table Isolation (KPTI) *1のコミットが物凄い勢いで書かれ、しかもメインラインの RC 版のみならずリリースバージョンにも通常の手続きをバイパスしてマージするという特別なことが起こっていましたが、 ニューイヤー早々に、CPU の深刻なセキュリティバグが公表されました。 通称、 Meltdown と Spectre です。

googleprojectzero.blogspot.jp

これらは、CPU のキャッシュメモリの扱いが原因で、メモリ上の、ソフトウェアが自分と関係ない、OSや他のソフトウェアのデータを読み出せてしまうバグです。 Meltdown はOSのデータを読み出せてしまうバグで、Spectre は他のソフトウェアのデータを読み出せてしまうバグです。

Meltdown は主に Intel 製 CPU *2のバグですが、Spectre はメーカによらず AMD や ARM (Cortex) などにも幅広くあるバグのようです。

メモリキャッシュは演算結果を早く出すために処理済のデータを流用するしくみですが、今回の問題は、データの所有プログラム以外のよそのプログラムが盗聴可能であることです。 さらに近年の CPU は高速化のためにマルチコアマルチスレッドが一般的になってきていますが、つまりそういう CPU は複数のプログラムを同時に実行可能です。それで、キャッシュ上のデータの取扱がずさんだと、よそのプログラムが盗聴可能になってしまうわけです。

今回のバグは、PC のみならず、いわゆるタブレットスマートフォン、そのほか多くの端末と関係があります。 とはいえ、ソフトウェアを追加でインストールしないような端末(例えば既製ルータのようないわゆる「組み込み系」などの一部)は、そもそもマルウェアをインストールしてしまう余地がないので、あまり関係がありません。

裏を返せば、それに該当しない遅い CPU だと今回のバグがありません(例えば Raspberry Pi にはないらしい)。

Meltdown

Meltdown の方は、OS (カーネル)のセキュリティアップグレードでほぼ解決します 。なぜならば、カーネル自身がデータを監査して、よそからのアクセスが禁止可能なところに置けばよいわけですから。 Windows10 や macOSLinux カーネルでは既にセキュリティアップデートがリリースされています。(Linuxカーネルに関しては、使用しているディストリビューションとリリースバージョンによって今回のアップデートが既に流れて来ているか、異なりますが。)

ただし、その監査処理にオーバーヘッドが増えますから、システムの動作がある程度は遅くなってしまいます。 だから端的に言えば、 Meltdown は主に Intel CPUの問題なので、AMD製 CPU にすれば Meltdown 対策不要なため遅くならずに済みます。

なぜ Intel CPU ばかりかというと、 Intel CPU は高速化のために、カーネル所有のデータを読み込もうとするプログラムはエラーで実行中止すべきなのに、先読みしてしまって続きの命令まで実行してしまう(アウトオブオーダ実行)ため、その命令によって間接的にカーネルのデータも読み出せてしまうようなバグった設計になっているからです。

こういう設計思想だから Intel 製はよそより速いわけで、かなりの歳月の間「AMD CPU は遅い」という評価が続いておりました。が、そろそろ AMD にチャンスがめぐってきた予感。偶然にも、GPU方面ではライバルの NVIDIAGeForce のドライバのEULA改訂でデータセンターでの使用不可とか勝手にやりだして悪評だったりしますし*3AMD の APU の時代が来たかも?!

Spectre

Spectre の方は対策がかなり困難です

まず、ウェブブラウザなどのソフトウェア側で自衛をすることが考えられ、 Firefox などでは既にセキュリティアップデートした新バージョンがリリースされています*4なお、今回のバグは、 JavaScript (ECMA Script)のプログラムでも悪用可能です。 このように自衛をするソフトウェアも今後ある程度は増えてくるとは思いますが、それほど期待はしえないでしょう。

つぎに、 既知の マルウェアを防ぐには、マルウェア対策ソフトウェアでスキャンすればよい と考えられます。 しかし、未知のマルウェア、既存のソフトウェアが突然マルウェア化した、といったときには防ぎようがありません。

なぜなら、そのソフトウェアが Spectre を悪用していないことを分析するのはかなり困難だからです。「ウイルス対策ソフト」は、各ウイルスのバイナリコードの既知の特徴(いわば「指紋」)に合致するかをスキャンして分析します。しかし、Spectre は、マルウェア作者が自力でコードを書いたら、リバースエンジニアリングでもして分析しないと判りません。

ですから端的には、少なくともオープンソースで、Gentoo のようにソースコードからビルドするか、DebianFedora などの比較的に信用のおけるディストリビューションを使用する ことが考えられます。 よって、 Windows 界隈のように、インターネット上で、ソースコードのよくわからないビルド済バイナリをもらってくる(「フリーソフト」とか「無料ソフト」とか(笑))いう世界は、本質的にバグっています

つまり、 不要なソフトウェア、うさんくさいソフトウェアは、インストールしない、アンインストールすることが重要 です。

そして、オンラインバンキングとか、クレジットカード情報やプライバシー送信とか、機密文書を開いたりとかいう際には、比較的マシな端末でやる、ということが考えられます。 機密的な作業と、娯楽と、ネットサーフィンと、中身の信用ならないソフトウェアの使用と、一つの端末ですべてやるのは潜在的に危険だ、ということがいえます。

ひとつ、よい報せを言うとすれば、Spectre のバグは、「当てずっぽう」でないと読み出せないことです。 つまり、マルウェアにとって「運がよければ」、つまり被害者にとってみれば「運がなければ」、盗聴されてしまうということです。

参考

【Gentoo】ppp の ip-up / ip-down が異なる

問題

pppd によるPPP接続時に自動でスクリプトを実行させるフックとして、 /etc/ppp/ip-up /etc/ppp/ip-down があります。 しかし、Gentoo の /etc/ppp/ip-up /etc/ppp/ip-down は、net-dialup/ppp-scripts パッケージで提供されており、独自のスクリプト*1になっています。

だから例えばいくつかのウェブサイトに、 「pppd のオプションとして ipparam ipv6default と書いて、/etc/ppp/ipv6-up.d/ 内にシェルスクリプトファイルを作成して

#!/bin/sh
if [ -z "${CONNECT_TIME}" ]; then
    if [ "${PPP_IPPARAM}" = "ipv6default" ]; then
        ip -6 route add default dev ${PPP_IFACE}
    fi
fi

と書いて chmod +x しろ」 という説明が書いてありますが *2、これは Gentoo では動きません。

なお、ipparam というのは ip-up / ip-down のスクリプトに渡すパラメータを増設するための pppd のオプションです。

man 8 pppd

ipparam string
  ip-up と ip-down スクリプト用に余分のパラメータを指定します。 
  このオプションが与えられた場合、 string が 6 番目のパラメータとして、
  これらのスクリプトに与えられます。

解答

ともかく、 Gentoo の ip-up は、

#!/bin/sh

# This script is run by pppd after the link is established.
# It executes all the scripts available in /etc/ppp/ip-up.d directory,
# with the following parameters:
# $1 = interface name (e.g. ppp0)
# $2 = tty device
# $3 = speed
# $4 = local IP address
# $5 = remote IP address
# $6 = ipparam (user specified parameter, see man pppd)

cd /etc/ppp/ip-up.d || exit

for SCRIPT in *.sh ; do
        . ./"${SCRIPT}" "$@"
done

ですので、${PPP_IPPARAM} ではなく ${6} です。 ${PPP_IFACE} ではなく、 ${1} です。

さらに、Gentoo では、

  • /etc/ppp/ipv6-up.d と /etc/ppp/ipv6-down.d はそれぞれ ip-up.d と ip-down.d のシンボリックリンクなので、IPv4 用と IPv6 用にディレクトリが分かれてはいない
  • ip-up と ip-down は、該当ディレクトリの *.sh の中身を読み込むので、 chmod +x は要らない。もしも無効にしたいときはファイル名を変更すればよい

そのため例えば、/etc/ppp/ipv6-up.d/60-routing.sh というファイル名にでもして、

if [ "x${6}" = "xipv6default" ]
then /bin/ip -6 r a default dev "${1}"
fi

と書けばよいわけです。属性は r さえついていれば、x は要りません(あっても動きますが)。shebang も要らない(あっても動きますが)。

This script is run by pppd after the link is established

なので、[ -z "${CONNECT_TIME}" ] も要らないはず。

Gentoo Wiki の情報が全く足りない! たぶん「いまどき PPP なんかせずにルータだろ」or「こんなことしようとする猛者は、読めばわかるだろ、スクリプトなんだから」ということなのでしょう

補足

ちなみに、冒頭の例の [ "${PPP_IPPARAM}" = "ipv6default" ] は厳密には間違え。
参考:

それにまあ、if の入れ子構造でなくとも if [ -z "${CONNECT_TIME}" -a "x${PPP_IPPARAM}" = "xipv6default" ] 〜でいいはずですが、これ。

あ。そもそも iproute2 が無くて net-tools があったらどうなるだろ。ip 無いし(笑)。勿論 route ですが。

オチ

冒頭の例は、 Debian の ppp パッケージに入っている ip-up / ip-down で動かすためのスクリプトです。

#!/bin/sh
#
# This script is run by the pppd after the link is established.
# It uses run-parts to run scripts in /etc/ppp/ip-up.d, so to add routes,
# set IP address, run the mailq etc. you should create script(s) there.
#
# Be aware that other packages may include /etc/ppp/ip-up.d scripts (named
# after that package), so choose local script names with that in mind.
#
# This script is called with the following arguments:
#    Arg  Name                          Example
#    $1   Interface name                ppp0
#    $2   The tty                       ttyS1
#    $3   The link speed                38400
#    $4   Local IP number               12.34.56.78
#    $5   Peer  IP number               12.34.56.99
#    $6   Optional ``ipparam'' value    foo

# The  environment is cleared before executing this script
# so the path must be reset
PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin
export PATH

# These variables are for the use of the scripts run by run-parts
PPP_IFACE="$1"
PPP_TTY="$2"
PPP_SPEED="$3"
PPP_LOCAL="$4"
PPP_REMOTE="$5"
PPP_IPPARAM="$6"
export PPP_IFACE PPP_TTY PPP_SPEED PPP_LOCAL PPP_REMOTE PPP_IPPARAM

Debian の /etc/ppp/ip-up の冒頭は上記のようになっていますです。 シェルスクリプトの読込みも

run-parts /etc/ppp/ip-up.d \
  --arg="$1" --arg="$2" --arg="$3" --arg="$4" --arg="$5" --arg="$6"

run-parts ですんで。

run-parts は、ディレクトリ directory にある、以下に述べる制約による名前を持つ実行ファイルを、すべて実行します。その他のファイルやディレクトリは、黙って無視します

Debian では ip-up / ip-down は run-parts で読み出すので、run-parts では実行ファイルでないと無視するから、 chmod +x が必要

/etc/ppp/ip-up /etc/ppp/ip-down のスクリプトディストリビューションごとに異なるため、気になりだしたら魔界に入れること請け合い。辛い。

Arch

https://git.archlinux.org/svntogit/packages.git/tree/trunk/ip-up?h=packages/ppp

CentOS

#!/bin/bash
# This file should not be modified -- make local changes to
# /etc/ppp/ip-up.local instead

PATH=/sbin:/usr/sbin:/bin:/usr/bin
export PATH

LOGDEVICE=$6
REALDEVICE=$1

[ -f /etc/sysconfig/network-scripts/ifcfg-${LOGDEVICE} ] && /etc/sysconfig/network-scripts/ifup-post --realdevice ${REALDEVICE} ifcfg-${LOGDEVICE}

/etc/ppp/ip-up.ipv6to4 ${LOGDEVICE}

[ -x /etc/ppp/ip-up.local ] && /etc/ppp/ip-up.local "$@"

exit 0