GW (1) 甲州街道〜笹子峠〜甲府 🚴‍♂️

5/4(日) 甲州街道を西に向かってひたすら走り、笹子峠を超えて甲府まで走り一泊した

GW 後半の好天に恵まれ ( 笹子峠を超えたあたりで雷雨に遭遇したけど ⛈ ) 名峰を眺めつつ新緑を全身で浴びる旅になった

走行距離 144km, 獲得標高 1650m

続きを読む

羽村堰〜奥多摩 🚴‍♂️

4/13 (土) 羽村堰に立ち寄って、奥多摩までのぼってきた

都内では桜の満開を過ぎてしまい、西部の山中の桜がこれから満開を迎えるという頃合いだった。奥多摩湖の桜を見るつもりで出かけたが帰りが遅くなりそうだったので途中で下山して終わり. 128km で finish

続きを読む

荒川〜吉見さくら堤公園〜川越 🚴‍♂️

4/5(金) 吉見の桜を見にいった

去年、一昨年も似たようなコースを走っている

hiboma.hatenadiary.jp

hiboma.hatenadiary.jp

シーズン到来に備えて、車体のオーバーホールとパーツ交換 ( クランクの52-36 化、 9000系と8000系の mixed 構成 にした ) も済ませたし、暖かく走りやすい季節にもなったので日記も再開

続きを読む

Linux Kernel CVE-2019-9857 の PoC を書いて検証・観察した

表題の通り CVE-2019-9857 が出ており、その PoC を書いてどのような影響があるのを検証・観察した.

CVE-2019-9857 の概要

nvd.nist.gov

In the Linux kernel through 5.0.2, the function inotify_update_existing_watch() in fs/notify/inotify/inotify_user.c neglects to call fsnotify_put_mark() with IN_MASK_CREATE after fsnotify_find_mark(), which will cause a memory leak (aka refcount leak). Finally, this will cause a denial of service.

ローカルの攻撃者により inotify でDoS を引き起こせる 脆弱性です.

続きを読む

さよなら和敬塾南寮

技術の話はない、プライベートな日記です

寮をみてきた

私が大学生の時に住んでいた和敬塾南寮 <わけいじゅく みなみりょう> が今期を持って学生の入塾をやめるとのことで、友人と連れ添って見学にいってきた。

結局取り壊しするんだっけ? 大事な点を確認し忘れた

和敬塾とは

公益財団法人和敬塾は、東京都文京区目白台にある男子大学生・大学院生向けの学生寮。1955年、前川製作所の創業者である前川喜作によって創設された。

文京区 目白台に位置する学生寮で、ホテル椿山荘や東京カテドラル、日本女子大が立ち並ぶ目白通り沿に広大な敷地を確保して建っている.

続きを読む

Linux 版の Sysinternals ProcDump を試す (2)

前回の続きです

hiboma.hatenadiary.jp

実装の話

本エントリでは ProcDump が コアダンプをどのように採取するかを調べていく.

(現状の) Linux ProcDump は gcore を薄くラップして扱うバイナリと理解した

ダンプの採取方法を調べる 🔍

github.com

ソースコードの量は大したことないので git clone してざっと斜め読みするといい. スレッドを積極的に使う設計は Windows な流儀なのかな?

CoreDumpWriter.c が肝 📖

ファイルの量も少ないの順番に眺めていって、CoreDumpWriter.c がコアダンプ採取の責務を負っているソースだと判別をつけた.

詳細はすっ飛ばして、以下の行を見れば gcorepopen2() で呼び出しているのが確認できる

int WriteCoreDumpInternal(struct CoreDumpWriter *self)
{

// ...

    // assemble the command
    if(sprintf(command, "gcore -o %s_%s_%s %d 2>&1", name, desc, date, pid) < 0){
        Log(error, INTERNAL_ERROR);
        Trace("WriteCoreDumpInternal: failed sprintf gcore command");        
        exit(-1);
    }


    // generate core dump for given process
    commandPipe = popen2(command, "r", &gcorePid);
    self->Config->gcorePid = gcorePid;

popen2 はシェルを fork(2) して pipe(2) で結果を受け取る関数である. PythonRuby のインタフェースを真似た感じかな? (この関数の実装も同ファイルに載っているが、冗長なので省略する)

gcore とは何ですか?

gcore の中身はシェルスクリプトで、 gdb をラップしたコマンドである. gdb をインストールすると付属してくるコマンド

🔗 gcore のソースを載せた gist

gcore を呼び出すと、結局は gdb を呼びだすことになる. ProcDump 独自の実装でコアダンプを採取しているのかと思ったが、そんなことなかった 🙃 すでに gdb で出来ることを作り直すのは、大車輪の再実装になるもんね

プロセスをどのように見張っているのか?

前回のエントリでは CPU 使用率やメモリ(RSS) を閾値にしてコアダンプをとってみたが、どういった仕組みなのだろうか?

f:id:hiboma:20190217121748g:plain

ProcDump プロセスを strace すると /proc/$pid/stats を 1秒ごとに open(2), read(2) しているスレッドがトレースできる

# 💤  1秒ブロックすることを示す

[pid  3073] futex(0x60b5bc, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 25, {1550324077, 477259191}, ffffffff) = -1 ETIMEDOUT (Connection timed out) 💤
[pid  3073] futex(0x60b590, FUTEX_WAKE_PRIVATE, 1) = 0
[pid  3073] kill(3060, SIG_0)           = 0
[pid  3073] open("/proc/3060/stat", O_RDONLY) = 3 👈
[pid  3073] fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
[pid  3073] read(3, "3060 (a.out) S 2854 3060 2854 34"..., 1024) = 301
[pid  3073] close(3)                    = 0
[pid  3073] kill(3060, SIG_0)           = 0
[pid  3073] futex(0x60b5bc, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 27, {1550324078, 479654480}, ffffffff) = -1 ETIMEDOUT (Connection timed out) 💤
[pid  3073] futex(0x60b590, FUTEX_WAKE_PRIVATE, 1) = 0
[pid  3073] kill(3060, SIG_0)           = 0
[pid  3073] open("/proc/3060/stat", O_RDONLY) = 3 👈
[pid  3073] fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
[pid  3073] read(3, "3060 (a.out) S 2854 3060 2854 34"..., 1024) = 301
[pid  3073] close(3)                    = 0
[pid  3073] kill(3060, SIG_0)           = 0
[pid  3073] futex(0x60b5bc, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 29, {1550324079, 503662811}, ffffffff) = -1 ETIMEDOUT (Connection timed out) 💤
[pid  3073] futex(0x60b590, FUTEX_WAKE_PRIVATE, 1) = 0
[pid  3073] kill(3060, SIG_0)           = 0
[pid  3073] open("/proc/3060/stat", O_RDONLY) = 3 👈
[pid  3073] fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
[pid  3073] read(3, "3060 (a.out) S 2854 3060 2854 34"..., 1024) = 301
[pid  3073] close(3)                    = 0
[pid  3073] kill(3060, SIG_0)           = 0

ここらの実装は TriggerThreadProcs.c に書いてある

github.com

初見で「phtread を抽象化して扱ってるし、難しいのかな ...? 」と身構えてしまったが、詳細を読んでいくと思ったよりも素朴な実装 + 設計である.

感想

/proc/$pid/stat や cgroup の値を閾値 最新のメトリクスだと PSI なんかを見張ったりすると、より精緻なトリガーを作れたりするのかなと思った

udzura.hatenablog.jp

コアダンプ採取のコードは gcore だった

  • バックトレースだけ獲れりゃ十分なケースもあると思うので gstack に置き換えられるといいかなぁ
  • プロセスのメトリクスをとってコマンドをトリガーするコードと、コアダンプを採取するコードとを分離すると汎用的なツールに消化できそうだが ( それ、monit じゃね??? とか ... )