Blogs

ファイルの読み込みの方法によっては脆弱性が発生しうる

ちゃんと考えれば分かる話なんですが。 struct stat statbuf; if (stat (filename, &statbuf) != 0) { /* stat できなかったら終了 */ return; } if ((statbuf.st_mode & S_IFMT) == S_IFREG) { /* regular file じゃなかったら終了 */ return; } char *buf = malloc (statbuf.st_size); if (buf == NULL) { /* malloc できなかったら終了 */ reutrn; } int fd = open (filename, O_RDONLY); if (fd < 0) { /* open できなかったら終了 */ return; } char tmpbuf[4096]; ssize_t nread; size_t off = 0; while ((nread = read (fd, tmpbuf, 4096)) > 0) { memcpy (buf + off, tmpbuf, nread); off += (size_t)nread; } close (fd); って書くと脆弱性を埋めます(自戒を込めて)。 どこかというと,stat してから open するまでの間にファイルが変更されているかもしれないので, バッファオーバーランやメモリ領域を初期化せずに使うとかいうことになります。

GNOME 3.36 に更新したら ibus-mozc が動かなくなったので対処した

ibus-daemon(1) が起動していないことが原因らしい。 ビルドし直せば治るかなと思って GNOME の設定から mozc を消してしまったので デバッグできなくなっていた。 とりあえず,これが解消するまでは自分で systemd のユニットファイルを作って 自動起動してやることにした。 ちゃんと起動するようになったらバグるかもしれんが, まあそのときはなんとかして disable すればなんとかなるやろ。 https://gist.github.com/kofuk/4ef7b0baec48f1af2e6f5561fda89f98

マップ画像生成の最近の更新など

最近全然書いてなかったけど,いろいろ変えたのでまとめておくことにしました。 最近の更新はおおまかに分けて次の3点です。 パフォーマンスの改善 処理のパイプライン化 その他機能追加 パフォーマンスの改善 やることを減らすってのが一番の高速化の方法なので,いろいろ処理を省けるようにしました。 最初の愚直な実装から4つくらいやることを減らしています。 1つ目が更新していないチャンクを再描画しないというもので,これはチャンクの LastUpdate というタグを見て判定しています。LastUpdate の値を region ファイルごとに ファイルにダンプしておいて,次の再描画の時に LastUpdate の値がそれよりも 大きくなっていたら再描画して,そうでなかったら省くという感じになっています。 前の描画内容に上書きするために,もとのファイルを読むという処理が追加されているので, PNG のデコードとか走るんですが,チャンクを再描画するほうがずっと遅いので 問題ないです。あと,更新されているチャンクがあって初めてもとのファイルを開く ことにしているので,画像の範囲の中で更新されているチャンクが1つもない場合は 画像ファイルに触りもしないということになっています。

比較演算の結果の値

C の比較演算の結果で,true の場合は 1 で false の場合は 0 っていうのが常識的な 挙動のような気がするけど,未規定とかじゃなくてちゃんと決まっているのか, 前から気になっていたのでちゃんと調べた。 素直に検索しても出なかったけど,ちゃんと規格(に近いもの)を見に行ったら 簡単に書いてあるのが見つかって,どうやら true が 1 で false が 0 になるってのは 決まってるっぽい。 つまり,以下のコードは環境に依存せずに 2 を出力する。 #include <stdio.h> int main(void) { int num = (0 == 0) + (0 == 0); printf ("%d\n", num); return 0; } あと,結果の型は int。 参考 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf

C で Hello, world!

なんじゃこりゃ %:include <stdio.h> int main(void) <% char str<::> = "Hello, world!"; printf("%s\n", str); return 0; %> これが $ gcc main.c コンパイルすると $ ./a.out Hello, world 動いてしまう。 <:, :>, <%, %>, %:, %:%: の6つのトークンは, [, ], {, }, #, ## と同じように解釈されるらしい。 なんじゃそりゃ。 参照 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf

SVG でターミナルを録画できる termtosvg

いろんなワードで pacman -Ss してみて眺めていたら,termtosvg というやつを 見つけたので試してみた。 結論:すごい。ただ alternative screen buffer ができないみたい。 ソース見たら CSS で表示位置をずらしてアニメーションしているように見せているっぽい? よくわからぬ。

new と malloc(3) を混在させていいのか

という議論が ここ にあったけど(2007 年……古い……!),malloc(3) で取ってきたメモリを delete(もしくは delete[])に渡してはいけないとか,new で取ってきた メモリを free(3) に渡してはいけないのに malloc(3) を読んだり new したり しても問題ないってのはなんか奇妙な話な気がしてきた。 (普通に C++ 書いていれば malloc には用がないけど)。 なぜかというと,どちらのメモリも malloc(3) が管理していないと, 同じ領域が別の用途で使われてしまうということになるので。 で,new で取ってきたのも malloc が管理しているんだったら, delete しても free(3) に渡されるだけだから, デストラクタとかがなければ問題にならない気がする。 と思って gdb でアタッチして試したら実際に malloc が呼ばれてるっぽい。 まあ仕様上未定義ってだけだよね。

rootfs に NTFS を使う?

しかも ArchLinux でやってる。エモい。 https://github.com/nikp123/ntfs-rootfs/wiki 正気か?POSIX のパーミッションをサポートしてないので無理な気がしたけど 非公式のサポートがあるらしい。誰得なんだろ。 安定しているの? シャットダウンできないことを除けばとても安定している。 :thinking_face: パーミッション周りをゴニョゴニョやってるせいでパフォーマンスは悪いらしい。