
2025.03.07
メール対応担当の8割以上が「カスハラ被害」に クレームのハード化・長期化を防ぐ4つの対策
eBPFを使ったオレオレカーネル拡張入門(全1記事)
リンクをコピー
記事をブックマーク
西村啓佑氏:あらためまして、mumumuです。「eBPFを使ったオレオレカーネル拡張入門」というタイトルで発表を始めます。今日の発表の目次は(スライドを示して)こんな感じです。
まず、eBPF(extended Berkeley Packet Filter)がけっこう背景になってくるのですが、概要としては、カーネルの中で動いているVM。Kernel/VMの両方を回収できるすごいやつなんですね。こいつは実行前にバイトコードを検証するので、安全に実行できるというのが売りです。基本的には、イベントトリガーで動作するプログラムになっていて、それぞれのイベントに対応するプログラムをProgram Typeと呼称しています。
ユースケースとしては、モニタリング、パケット処理、システムコールのフィルタなどがありますが、実はこれだけじゃないと。
例えば、MemcachedのキャッシュをeBPFでカーネルに移植するとか、eBPFでスケジューラのカスタマイズをするとか、eBPFを用いてストレージをXDPのストレージ版みたいなことをするとか。
あるいはロック機構をアプリケーションごとにカスタマイズして、eBPFで実装して、カーネルに埋め込むとか、そういうことをやっていて、僕もeBPFを使ってオレオレカーネル拡張を作りたいなと思ったわけです。僕は大学院生なので、あわよくば研究になって、「USENIX」に通したいんですけどね。それは将来の話として、とりあえずカーネル拡張を作りたくない? という話になってきます。
今回の発表は、ここからがメインになりますが、「カーネルを拡張できるおもちゃを作ってみた」というところになります。Program Typeは、BPF_PROG_OREOREというタイトルを付けて、いろいろと仕様を書いていますが、loaderでbpfのプログラムをロードする。ロードして、かつ、/ -> /sys以下にoreore/bpfというファイルを生やして、それに数字を書き込むとそれに対して演算してu32を返すと。
それをcatすると出力できる。この場合、42を足すというBPFのコードを書いてロードすると、(スライドを示して)こんな感じになるというのが目標です。
eBPFの機能追加のレシピは、大きく分けてこの4つです。1つ目、BPF_PROG_TYPEというマクロを使って、bpfの新しいタイプを定義していくのですが、(スライドを示して)今回はこういう感じになります。
それぞれちょっと説明します。まず、このBPF_PROG_TYPEというマクロは、トリッキーってほどでもないですが、若干普通じゃない使われ方をするマクロになっています。
最初の引数が、追加したいProgram Typeですね。これは、こちらのenumに適宜生やせば大丈夫です。2個目がちょっと複雑で、詳しくは後で話しますが、マクロを文字列として合体させたような、この2つの構造体を参照する引数がカーネル内に存在する必要があります。
最後がeBPFのプログラムの引数の型です。この型の情報は、左側がeBPFから見たもので、右側がカーネルから見たものになります。複雑な場合はコンバートが必要になりますが、今回の場合は自動の変換で事足りるので、特に扱いません。先ほどちょっと触れたbpf_verifier_opsというオペレーションのstructがたくさんありますが、この2つを設定すれば最小なbpfの独自機能は動きます。
2つあるので、それぞれを簡単に紹介します。まず、is_valid_accessというやつが、引数の中からどれぐらいのメモリサイズがvalidかを返す関数で、もう1つがヘルパー関数に関するものです。ここは僕も詳しくないので省略させてください。もう1つオペレーションがありましたが、これは空で大丈夫です。
諸々まとめると、まず、BPF_PROG_TYPEマクロで宣言をする必要がありました。
次に、アタッチする機構を用意します。今回の場合は、先ほどと同じ場所にbpf_attach_typeがあるので、基本的にはこれにBPF_OREORE_ATTACHというフラグを適当に付け足すと、よしなに動きます。
これはすぐにできるのですが、もう1つ、bpfシステムコールの中にいくつか機能を追加する必要があるんですね。ここに挙げた4つの関数を変更する必要があるんです。そのうちの最初の2つはけっこう自明な変更ですね。BPF_PROG_TYPE_OREOREというProgram TypeとBPF_OREORE_ATTACHという関係を定義します。
その後のこちらのほうが本質的なところで、BPF_PROG_TYPE_OREOREでアタッチが呼ばれると、そのアタッチは何に対してアタッチするかという操作になります。これは基本的にファイルディスクリプタに対して動作するのですが、今回はファイルディスクリプタのうんぬんかんぬんの操作を全部無視して、この変数をエクスポートして、これを今度カーネルモジュールから参照してこのプログラムを実行するというだけの機能を付け足しています。
ただ、オレオレ機能を拡充させていくには、たぶんこのattachという関数をちょっとリッチにしないといけないかなと思います。detachは、attachの逆をするので問題ないと思います。
ここまでお話ししましたが、2個目のアタッチする機能を用意するというところでは、基本的にこのシステムコールに使われる関数を拡張してやると良いということがわかりました。
これらのカーネルに対する変更は以上なので、変更したカーネルをコンパイルして実行してください。
次にそのカーネル上で、カーネルモジュールを書いていきます。カーネルモジュールは、基本的には/sys/oreore/bpfへのwriteというものをトリガーしたいので、トリガーします。トリガーして、その中でbpf_prog_run()という関数を呼び出すと、よしなにBPFのプログラムが走る感じになります。
このbpf_prog_run()は、sysfsのshow/storeの機能を使って、storeされた後にbpf_prog_run()というのが実行されるように書いているのですが、本当はきちんとアタッチされているかとか、いろいろエラーハンドリングがあります。ただ、いったん無視してこういう感じのプログラムを書けば、カーネルの中からすぐに実行されます。
ちなみに僕は、showすると結果を見たいので、oreore_resultというのをsnprintfで載せてほしい。これはどこから来たかというと、(スライドを示して)このbpf_prog_run()の結果を、oreore_resultに代入しています。この関数は、この実行したbpfの結果をu32にそのまま代入しています。
まとめです。まず、bpf_prog_run()をコールすればいいということがわかりました。
最後に、ユーザーランドから登録します。今回は、このbpfの命令は何でもいいのですが、入力をu32と仮定しているので、それに42を足すbpf命令を錬成して、それをロードしてアタッチしてみます。
bpfの命令は、気合いで手動でやってください。本当はllvmでバイトコードを生成すればいいのですが、そのインフラを説明すると、時間が足りないので……というかもうすでにちょっとヤバいので(割愛します)。手動で大丈夫だし、まぁそんなに難しくなく、libbpfのコードなどを読めば拡張できると思います。
bpf_prog_load()という関数を呼び出すことで、先ほどの命令をロードできます。このオプションも指定が必要ですが、これを忘れると謎にうまく動かないことになるので、ちょっとここはハマりポイントでした。最後にアタッチをします。アタッチをすると、ターゲットのfdを通知することになりますが、今回の実装に限って言えば、fdは何でもいいので今回は0を指定しています。たぶんここのフラグは0で大丈夫です。
最後に、bpfプログラムをロードしてアタッチします。以上のものを組み合わせて、こんな感じで先ほど書いたモジュールを読み込んで、ローダーを起動すると、(スライドを示して)こんな感じの実行結果が得られます。ここから先は、たぶんエラーハンドリング、libbpf、サポート、ヘルパー関数の定義など、ありますが、それは自由ということで。
まとめです。eBPF=In-Kernel VMで、eBPFを使ってカーネルを拡張するのは最近熱いらしいと。やってみると意外と簡単にeBPFでカーネルを拡張できることがわかったので遊んでみたいと思います。発表は以上です。ありがとうございました。
(会場拍手)
2025.03.12
SNSで炎上している研究者は「研究者として正しい」 人文学のプロ・阿部幸大氏が説く“強い意見を出せない時代”に対する考え方
2021.09.30
「なぜセーラー服で出社してはいけないの?」 さくらインターネット・江草陽太氏の自由な発想の源
2025.03.11
自分よりできる人を採用し、ゴリ押しで権限委譲 東大発スタートアップに学ぶ、組織を伸ばすマネジメント
2025.03.13
改正後のiDeCoと退職金の受け取り方の事例 「改悪」は本当か? プロが真相と狙いを解説
2025.03.12
新規事業を継続するかどうかを見極める2パターンの判断軸 会社の規模別「撤退基準」の設け方
2025.01.07
1月から始めたい「日記」を書く習慣 ビジネスパーソンにおすすめな3つの理由
2025.03.14
三流の上司と一流の上司の違い 部下の心を動かす科学的アプローチ
2025.03.12
年収別iDeCoの税制メリット 1年で軽減される税負担をプロが試算
2015.11.24
人は食事をしないとどうなるか 餓死に至る3つのステップ
2015.03.12
【全文】「行かないで」瓦礫の下に母親を残し… 菅原彩加さんによる遺族代表スピーチ
2025.03.12
SNSで炎上している研究者は「研究者として正しい」 人文学のプロ・阿部幸大氏が説く“強い意見を出せない時代”に対する考え方
2021.09.30
「なぜセーラー服で出社してはいけないの?」 さくらインターネット・江草陽太氏の自由な発想の源
2025.03.11
自分よりできる人を採用し、ゴリ押しで権限委譲 東大発スタートアップに学ぶ、組織を伸ばすマネジメント
2025.03.13
改正後のiDeCoと退職金の受け取り方の事例 「改悪」は本当か? プロが真相と狙いを解説
2025.03.12
新規事業を継続するかどうかを見極める2パターンの判断軸 会社の規模別「撤退基準」の設け方
2025.01.07
1月から始めたい「日記」を書く習慣 ビジネスパーソンにおすすめな3つの理由
2025.03.14
三流の上司と一流の上司の違い 部下の心を動かす科学的アプローチ
2025.03.12
年収別iDeCoの税制メリット 1年で軽減される税負担をプロが試算
2015.11.24
人は食事をしないとどうなるか 餓死に至る3つのステップ
2015.03.12
【全文】「行かないで」瓦礫の下に母親を残し… 菅原彩加さんによる遺族代表スピーチ