トップ «前の日記(01/31/2013) 最新 次の日記(05/01/2013)» 編集

本 日 の h o g e

hogeとはワイルドカードのようなものです。日々起こった、さまざまなこと −すなわちワイルドカード− を取り上げて日記を書く、という意味で名付けたのかというとそうでもありません。適当に決めたらこんな理由が浮かんできました。

更新情報の取得には rdflirs を使ってもらえると嬉しいです.


04/18/2013 ふむ [長年日記]

tDiary 3829日目

[Linux] RHEL6 ファミリーで veth を使う時に注意したいこと

Linux には veth という仮想 L2 デバイスを作ることができるモジュールがあって,以下のような感じで相互に接続された 2 つのインタフェースを作ることができる.

# ip link add vethXX type veth peer name vethYY

これは結構便利な機能で,例えば 2 つの bridge を繋ぐ等の用途にも使うことができたりするのだけれど,現状 RHEL6 ファミリーで採用されている 2.6.32 の veth には,ある条件で kernel が crash してしまう致命的なバグがある.

このバグが修正されたのは このパッチ. 一体どういうことかと言うと,要は「veth デバイスが受信したフレームを drop するとき,double-free が発生して panic してしまう」ということ. これは恐ろしい.つまり veth の受信キューが溢れるくらいのトラフィックを流せば OS が落ちるということだ. 実際,手元で tcpreplay を使って試してみたところ,さくっと落ちてしまった.

例えば veth が外界と繋がっている環境,例えば 1 つの Linux 箱の中で以下のような構成を取った時を考える.

[eth0]--[br0]--[veth0]--[veth1]

ここで eth0 から猛烈な勢いで veth1 宛または broadcast/multicast フレームが入ってくると,veth1 の受信キューが溢れた段階で OS が落ちる. つまりリモートからの DoS が可能だということ.

難儀なのは,例えば以下のような構成を取ったときでも発生してしまうということ.

[eth0]--[br0]--[veth0]--[veth1]--[br1]--[vnet1]--(qemu-kvm)

この場合 veth はただ 2 つの br0 と br1 を繋ぐ役割をしているだけだけれど,例えば qemu-kvm が猛烈な勢いでトラフィックを流せば veth0 の受信キューが溢れてホストごとお亡くなりになるだろう.

veth の仕組みは至って単純で,ある veth デバイスは対となるデバイスの構造体への参照を相互に持っている.送信処理は対となるデバイスの受信処理 (受信キューにデータを積む処理) を直接呼び出すというものなので,なるほどさもありなん,というわけだ.

どのくらいの pps で発生するかは,マシンの状態と性能に依存する.受信キューに積む処理よりも受信キューから出す処理の方が遅くなるような状態になればすぐ発生する. 通常受信キューの長さは 1000 になっている*1 けれど,これを何らかの理由で短くしているような場合はさらに発生しやすい.

一応 Red Hat には連絡したのだけれど,1 ヶ月放置されたので,パッチは大昔にもう出てるんだし早く対応してーという意味を込めて書いてみた.

追記

Red Hat の Bugzilla に載りました. 近いうちに fix されるようです.

*1 /proc/sys/net/core/netdev_max_backlog を参照