seccamp2018とKernel/VM@関西と「やるだけ」

この記事は2018年の10月くらいに投稿しようと思いながらも結局投稿しなかった記事原案を、適当に編集したものです。

セキュリティキャンプ全国大会2018とKernel/VM@関西 9回目とちょっとだけ話題になった「やるだけ」の話をします。

お久しぶりです。艮鮟鱇です。一行目はTwitterのカードに出るので2行目で挨拶です。 Twitter対策大事ですね。あんまりTwitterやらないけど。わくわく鮟鱇ランドはいいぞ。

さて今日は夏休みに圧倒的成長をした話をします。嘘です。でもちょっとくらいは成長した話をします。もっと素朴に言えば、セキュリティキャンプとKernel/VMの話です。夏休みの総仕上げでもあります。予定が立て込んで夏休み中に書けなかったのが少し心残りです。仕方がないので、9月32日の気分で書きます。

セキュリティキャンプ全国大会2018

先日も書きましたが、8月の中旬にセキュリティキャンプ全国大会2018に行って、 Ruiさんとhikaliumさんのご指導の元、セルフホストCコンパイラを作ってきました。1

セキュリティキャンプの全般的な話はいろんな体験記に上がっているので省略することにして2、自分が面白かった話をいくつか書きたいと思います。

プログラミングは孤独な作業です。パソコンに向かってキーボードをカタカタ。特に私はいままで開かれたコミュニティに参加することも無かったため、自分が書いたコードの良し悪し、あるいはコードが綺麗とか汚いといった判断をする人は自分しか居ませんでした。 3

それに対して、セキュリティキャンプでは自分のコードについてRuiさんやhikaliumさんから助言や意見を頂くことができました。この部分のロジックを変えたほうがいいといった指摘から、変数名の英語がおかしいといった細かい問題まで、自分のコードを読んで、コメントしてもらえるというのはとても新鮮で、貴重な経験でした。自分の書いたコードの悪いところ・良いところを客観的に知ることができ、最終的に自分が書いたコードに自信を持つことができました。4

さて、Cコンパイラを作ろうゼミでは、一貫して「インクリメンタルな開発」というものを志向しました。これはつまり、全てを一気に作ろうとするのではなくて、スモールステップで動くものを作るということ。例えばCコンパイラなら、まず整数値を1つ読み込んで、それを返すようなアセンブリを出力する「コンパイラ」から始めます。実際のコードがここから読めますが、たった14行、本質的なところは5行しかありません。これを「コンパイラ」と果たして呼んでいいのか甚だ疑問ですが、しかし全てはここから始まります。そこから演算子+を足し、-を足し、と開発が進みます。重要なことは「動いている」ということです。同時に「テスト」と呼ばれるものを書いて、 Cコンパイラが正しく動いているかを常にチェックします。どのコミットでもこのテストを通っているようにすることで、自分が加えた変更が正しいものであることを保証できます。

つまり金太郎飴みたいなものです。どのコミットを見ても、それがある意味での「完成形」になっていて、限定的な機能しかないかもしれないけれど、ちゃんと動くようになっています。

やっぱりプログラムは動かないと楽しくありません。動くとモチベーションも維持できますし、どれだけ自分が進んだかを実感することもできます。結果として、開発を気分よく進めることができます。

こういった「インクリメンタルな開発」や「テスト」といったものを、耳にすることはあっても実際に自分の開発で意識して使ってみることはありませんでした。セキュリティキャンプによって今後自分がどういったコードを好んで書いていけばいいか、一つの指針が出来たような気がしています。

ところで、セキュリティキャンプでは最後に「成果発表」という時間があります。これは、各人がセキュリティキャンプ中にどのようなことをしたのか、他の参加者に向けて発表する場です。ここでした私の発表がめっちゃ受けました。楽しかったです。発表は面白くてなんぼですね。まぁ多分いちばん感動を呼んだのはuint256_tさんのものなんですが。あれはやばかった。

Kernel/VM@関西 9回目

さてセキュリティキャンプの帰路、TwitterのTLでKernel/VMの話が出たので反応したところ、おるみんさんからすぐにリプライが飛んで来た結果、 Kernel/VM@関西 9回目という勉強会で成果発表のスライドを持って登壇することになりました。

Kernel/VMは低レイヤープログラミングのエキスパートの方々が集まる勉強会だというのはTwitterでちらほら見ていました。ということは、きっとCコンパイラを実際に作ったことはなくても、その作り方は知っているだろうというのも容易に想像がつきます。そこで発表の方針としては、コンパイラの作り方をくどくど説明するようなものではなく、実際にCコンパイラを作ってみてつらかったところや面白かったところを中心に伝えようと考えました。「実際にやってみた」ってやつですね。これなら知識のない自分にもできそうです。

ところがここで問題が浮上しました。セキュリティキャンプの成果発表は7分でした。つまり手元には7分の長さのスライドしかありません。対してKernel/VMは15分〜20分です。なんとかしてこの資料をかさ増しする必要がありますが、生半可なことを書いても面白くありません。

そこで、新しくアセンブラを書くことにしました。これなら、途中で失敗しても「バグった!」というスライドを作れば受けます。どちらに転んでも面白い発表ができそうです。

まずアセンブラが何をやっているか調べなければなりません。コンパイラを書いたときは気軽に質問を投げることができましたが、今回は一人です。まず既存の実装を見てみようと思い、GNU assemblerのソースコード見てみると、大変年季の入ったコードで、3分少々で読むのを諦めました。仕方がないのでGNU assemblerの出力を解読するところから始めました。バイナリをodで16進数に直して、ELFの資料をお供にひたすら読み進めました。アセンブラがやっていることがわかれば、次は実装です。

アセンブラを書き始めてからおおよそ2週間後の9月上旬に、とりあえず動くものができました。安堵したのもつかの間、アセンブラのスライドを書いてみると、どうにもバランスが取れません。通常Cプログラムはコンパイラとアセンブラを経由した後にリンカを通って実行バイナリに変換されます。そう、リンカを書かなければ、スライドの都合上流れが悪いのです。

ということでリンカを書き始めました。Mastodonでsksatさんに勧められて買った『リンカ・ローダ実践開発テクニック』が大いに役に立ちました。リンカを書いている最中に言霊.inを引用するネタと「やるだけツールチェイン」のネタを思いつきました。なんとしてもそのスライドまでこぎつけなければ、死んでも死にきれない。そう思ってリンカの開発を急ぎました。

結果、9月中旬に自作リンカでaqccをセルフホストできるようになりました。そこからスライドを作って、Kernel/VMで発表したところめっちゃ受けました5 とても楽しい経験ができました。

「やるだけ」

そんな発表資料ですが、見ていただくと「やるだけ」というネタを一貫して使っていることが分かります。これは「天丼」的な効果を狙うと同時に、技術的にはやればできるが、実際にやってみるといろいろ面白いことが分かる、という意味も含んだ表現です。また、セキュキャンに参加したことで、「できそうもないこと」を「やるだけ」にすることができた、という意味も含んでいます。

Cコンパイラを書き始めた当初は、どうにも自分がCコンパイラを書けるとは思いませんでした。いってみれば、「やってもできない」感じがしていたわけです。

セキュリティキャンプに参加することによって、「やってもできない」ことを「やるだけ」――より正確に言えば「このようにすればできる」という技術と自信を得ることができました。

まとめ

もっといろいろと書くべきことがあるような気がしますが、うまく文章がまとまらないのでこのへんで筆をおくことにします。書いてる内に頓珍漢なことのように思えてくるし、文章を書くのは難しいですね。

最後になりましたが、セキュキャン講師のRuiさんhikaliumさんをはじめ、多くの方々にお世話になりました。この場を借りてお礼申し上げます。ありがとうございました。


  1. 私のセキュリティキャンプ応募内容と、 Cコンパイラ開発記は各々すでに坩堝に上がっているのでまだ読んでいない方はぜひチェックしてみて下さい。
  2. 講師のRuiさん、hikaliumさん視点でのセキュリティキャンプの感想はTuring Complete FMでポッドキャストとして配信されています。
  3. 形式上過去形になっていますが、今でも基本的にそうです。書くプログラムの多くは人目に触れない気がするし、私に限らず意外とそんなものかもしれない。
  4. もちろん悪い点を指摘されると少々へこむわけですが、「悪いところは直せばいい」というゼミの雰囲気があり、とても開発しやすい環境でした。その辺りの話はRuiさんがnoteに書かれています
  5. 発表資料はSpeakerdeckに上がっています。発表の様子はYouTubeに上がっています