家族百景

Posted on September, 24 at 6:32 pm

長男を寝かしつける前に、久しぶりにお話を聞かせる。今回は息子がベッドの上、父ちゃんは横に立ってコントをやっている。

太郎「どうもー、リーマン太郎です!」
次郎「どうもー、リーマン次郎です!」
二人「リーマン・ブラザーズで~す!」

音:ガラガラガラ、金融ショック!

父「やあ、わたしが父さんだよ」
太郎、次郎「わぁい、リーマン・ブラザーズ倒産だ!」

息子の反応:なし。

次のお話。昔々、あるところにお腹をすかせたかわいそうな兄弟がいました。兄弟は悪い人たちにさんざんいじめられて、冷たい雪の降る寒い冬だというのに、隙間風の吹き込む暗い部屋で、薄い布団一枚に身を寄せ合ってガタガタ震えています。

お兄さんは弟をはげまそうとして言いました。おいしい食べ物のことを考えよう。きっと体があったかくなるよ。弟は言いました。おいら、腹いっぱい天丼が食べたいなあ。えび天、いも天、なんでもいいよ。ああ、天丼ってうまいんだろうなあ。

すると、薄い壁を蹴破って、大きな筆を抱えた弘法大師があらわれました。

「やあ兄弟、腹へってんだってな。なんか空海?違うか」

あっけにとられる兄弟を尻目に、弘法大師は懐から墨汁のパックを取り出すと、大きな筆の先にじょぼじょぼ振りかけて、さっと構えます。

「わがなしそめし技を、よおく見ろ!」

弘法大師は筆をぐわりと一閃させると、兄弟の部屋の天井の真ん中に、大きな点をひとつ描き入れて叫びました。

「天丼!」

もう雪が吹き込むのを防いでくれる壁はありません。兄弟は、しんしんと降りしきる雪の音を聞きながら、やがてゆっくりと、暖かい眠りに就きましたとさ。おしまい。

反応:長男は天井っていう字を知らない。

Posted in Family | No Comments »

The Chameleons

Posted on September, 20 at 2:20 am

若い頃。

そうでもない頃。

なぜ聴かない?


Posted in Music | No Comments »

ヤクルト対読売

Posted on September, 19 at 1:03 am

先発投手は川島亮バーンサイド。この時点で、好みの投手戦は期待できそうもない。きっとぬるい展開のゲームになるのだろう。

投手戦の素晴らしさは、それがプロフェッショナルとしての選手やベンチの力量を際立たせ、厳しい展開の中でようやく飛び出すヒットの価値を否応無しに高めるところ、また一瞬の隙が生むミスに勝負の厳しさを思い知らされるなど、個々のプレーの質的問題の重要性が増す様に興奮させられる点にこそある。10本も20本もヒットが出る試合はその価値も急激なインフレーションを起こして魅力が褪せてしまう。

さて、ゲームの方は、中継ぎ投手の登板過多という問題を抱えたチームとして、今日のヤクルトの攻撃は素晴らしかった。相手にも同じ目に遭わせてやろうとチーム一丸となっていたからだ。バーンサイドが3回1アウト時点で70球を費やし、5回までで降板せざるを得ない状況を作り出したのは見事としかいいようがない。その一方で、中継ぎ投手の出し惜しみから先発投手を引っ張りすぎて8失点したのは悲劇を通り越して喜劇となってしまったが。

6回まで、両チームともヒット数と得点が同じか、またはヒット数から1を引いた数が得点というのは変わらず、奇妙な均衡を保ったままゲームは進んだ。その均衡が破れたのは、次のイニングが9番バッターからということで中継ぎピッチャーの交替が後手に回って、読売が5点差を追いつかれたときで、ヤクルトは以降得点よりヒット数が1多いまま試合が終わってしまった。残念。

試合の決着がついたのは8回。ひさしぶりに見る五十嵐は、そこそこの球を投げているようには見えたが、やはり全盛期ほどではない。これまで新聞で成績をみる限りでは、三振は奪うがホームランも打たれるようで、いまいち復活したのかどうかわからなかったが、今日ではっきりとわかった。阿部のホームランで1点差。去年神宮でもらった背番号53のヤクルトのユニフォームを着ている自分を幽体離脱してしばし眺める。

9回、クルーンは投球練習から154キロを計測。以前日本ハムの試合を観たときより調子はよさそうだった。が、ファーボールの連続でノーアウト満塁に。1点差でこの展開、しびれる。ここで阿部がクルーンのボールを捕球したまま返球しないという荒技を繰り出した。マウンドとホームベースの間あたりで話し込む阿部、クルーン、あとついでに近寄ってきた小笠原。何を話していたのかはわからないが、ヒーローインタビューの阿部はかなり態度が悪かったので、たぶんあまりのクルーンの情けなさにブチ切れたのだろう。ある意味でいいものをみた。

Posted in Baseball | No Comments »

MySQLのカラム複製脆弱性

Posted on September, 12 at 3:45 pm

昨日書いたMySQLの脆弱性ですが、手元の環境で見事に再現しました。MySQLのバージョンはCentOSでyumからインストールしたmysql-4.1.20-3.RHEL4.1.el4_6.1です。

手順は以下の通り。まずデータベース、テーブルを作成します。

mysql> create database sec_test;
Query OK, 1 row affected (0.02 sec)

mysql> use sec_test
Database changed
mysql> create table test (username char(16));
Query OK, 0 rows affected (0.01 sec)

ご覧の通り、char(16)でusernameというカラムを持つテーブルを作成します。

まず「admin」というusernameを持つ行を作ります。

mysql> insert into test (username) values ('admin');
Query OK, 1 row affected (0.00 sec)

mysql> select count(*) from test where username = 'admin';
+----------+
| count(*) |
+----------+
|        1 |
+----------+
1 row in set (0.00 sec)

出来ています。

次に、問い合わせの文字列部分の後ろに空白を追加してみます。全部で16文字になるようにしました。

mysql> select count(*) from test where username = 'admin           ';
+----------+
| count(*) |
+----------+
|        1 |
+----------+
1 row in set (0.00 sec)

後ろの空白が無視されているのがわかります。update:正確にいえば、char型なので指定された長さ未満の文字列は空白文字で埋められるみたいです。null文字とかじゃないんですね。

次に、char(16)の範囲を超えたところで「x」を追加して検索してみます。

mysql> select count(*) from test where username = 'admin           x';
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)

さすがにヒットしませんでしたが、そもそもカラムの制限長を超えているのにエラーにはなりません。

では、この値をINSERTしてみます。

mysql> insert into test (username) values ('admin           x');
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> select count(*) from test where username = 'admin';
+----------+
| count(*) |
+----------+
|        2 |
+----------+
1 row in set (0.01 sec)

「admin」としてINSERT出来てしまいました

これで、(1)既存のデータに重複行があるかチェック(2)なければINSERT、という処理で重複登録を防ごうとしてもダメなことがわかります。

ちなみにPostgreSQL 7.4.19でテストすると

db_test=# create table security_test (username char(16));
CREATE TABLE
db_test=# INSERT INTO security_test (username) VALUES ('admin');
INSERT 0 1
db_test=# SELECT COUNT(*) FROM security_test WHERE username = 'admin';
 count
-------
     1
(1 row)

db_test=# SELECT COUNT(*) FROM security_test WHERE username = 'admin           ';
 count
-------
     1
(1 row)

db_test=# SELECT COUNT(*) FROM security_test WHERE username = 'admin           x';
 count
-------
     0
(1 row)

db_test=# SELECT COUNT(*) FROM security_test WHERE username = 'admin            ';
 count
-------
     1
(1 row)

db_test=# INSERT INTO security_test (username) VALUES ('admin           x');
ERROR:  value too long for type character(16)
db_test=# SELECT COUNT(*) FROM security_test WHERE username = 'admin';
 count
-------
     1
(1 row)

db_test=#

INSERTはできません。8.3.3でも。

db_test=# create table test (username char(16));
CREATE TABLE
db_test=# INSERT INTO test (username) VALUES ('admin');
INSERT 0 1
db_test=# SELECT count(*) FROM test WHERE username = 'admin';
 count
-------
     1
(1 row)

db_test=# SELECT count(*) FROM test WHERE username = 'admin           ';
 count
-------
     1
(1 row)

db_test=# SELECT count(*) FROM test WHERE username = 'admin           x';
 count
-------
     0
(1 row)

db_test=# SELECT count(*) FROM test WHERE username = 'admin            ';
 count
-------
     1
(1 row)

db_test=# INSERT INTO test (username) VALUES ('admin           x');
ERROR:  value too long for type character(16)

INSERT時にあふれた分が勝手にカットされることはありませんでした。

Posted in MySQL, PHP, PostgreSQL, Security, WordPress | 1 Comment »

WordPress 2.6.2はセキュリティ修正

Posted on September, 10 at 6:06 pm

WordPress2.6.2が出たのでさっそく更新したが、今回のリリースにはセキュリティ関連の修正が入っていた。

1 推測されやすい乱数生成の問題

PHPのrand関数はlibcのrandのラッパで、mt_randはメルセンヌ・ツイスタ擬似乱数生成装置の実装なのだが、どちらも32ビット型符号なし整数をシードにしている。しかし、実装の問題により実際にはそれ以下の強度にしかならないそうだ。そのため、暗号化に際してこれらの関数を利用するのは不適切ということになる。それに対処したようだ。

2 MySQLのクエリの長さ制限の問題

MySQLではデフォルトでサーバとクライアント間で送信されるクエリとその応答の長さがmax_packet_sizeディレクティブ(っていうのかな?それはApacheだけ?)で1MBに制限されている。もし1MBを超えたクエリがクライアントから送信された場合、MySQLサーバ側でエラーとして処理してしまう。

たとえば、期限の切れたセッションデータをDBから削除するようなクエリがあり、意図的にこのクエリが長くなるようなデータをセッションに埋め込むことができれば、クエリはいつまでも実行されず、何かしら問題が起きることになる。

update: もっとすごい問題があった。

3 MySQLのダメダメな文字列比較ルール

MySQLにこんなクエリを投げる。

SELECT * FROM user WHERE username = 'admin';

たとえば、ユーザ登録の際に登録名の重複チェックをしているとしよう。WordPressのように、そのサイトにはadminという名のユーザが必ず存在するとして考える。新規のユーザが登録時に「admin」という名前を使おうとすると、上のようなクエリでチェックが行われ、すでに登録されている名前であるとしてアプリケーションによって登録がはじかれる。まあ、そういう仕組みのウェブアプリがあるものと思ってもらいたい。

このusernameというカラムが、たとえばchar(16)だったとする。MySQLではSELECTによる比較時にクエリ内の文字列の後ろの空白は無視されるようになっている。「admin           」だと、

SELECT * FROM user WHERE username = 'admin           ';

こうなるが、実際には最初のクエリと同じ扱いになる。

ところで、じゃあ「admin           x」という名前を使おうとしたらどうなるだろう。ここでは意図的に名前をchar(16)から外れるようにした。数えにくいかもしれないが、17文字ある。

SELECT * FROM user WHERE username = 'admin           x';

MySQLでは、比較の際にはカラムの型を無視してくれるので、上のSQLは何も返ってこない。つまり、新規登録可能なユーザ名として認識される。そこで、INSERET処理を実行すると、今度はカラムの型をみて余分なところはカットし、さらに後ろの空白を取り除くので、あれま、「admin」という名前でユーザ登録が完了してしまう。

これでadminアカウントの乗っ取りが完了する。ひええ。

もちろん、UNIQUE INDEXで対処することは可能だが、そうでないアプリケーションなら困ったことになる。

未検証なのでなんともいえないが、本当だったらこわい。

update:再現しますた

Posted in PHP, Security, WordPress | 1 Comment »

男脳、女脳

Posted on September, 9 at 8:09 pm

http://d.hatena.ne.jp/pollyanna/20080903/p1

男脳とか女脳とかいわれると反発を覚えるのは、当然のことだ。というのも、なんとか脳というのが、あるときは環境により決定される、またあるときは遺伝により決定される器質的問題であるかのように語られるのは、ちょっと考えればどちらも正しいとはいえないのに、まるで何かの決定論みたいに語られるとむかつくのは当然だからだ。

環境により決定される、というのは、たとえばゲーム脳とかがそうだが、周囲の環境によって脳がある決まったパターンの働きをするようになってしまうというもの。暴力的なゲームをやりすぎることにより、脳が現実とゲームの違いをきちんと認識できなくなって現実社会で暴力を起こすようになるのだ、とかなんとか。

もちろん、人間の行動は環境に影響される。しかし、相関関係と因果関係を綿密に調べるなら、それが脳の器質的問題となることはめったにない。そもそも、脳はそんなに単純なものではなく、また一見単純に思われる人間の行動も、その動機や背景となる理由には様々な要素が絡み合っている。

ゲーム脳の明らかな間違いには、この説を唱える学者自身の偏見がそのまま反映されているのが興味深い。ある人間の行動が環境により影響されるという、これ自体はごく当たり前の考え方と偏見とが科学の名前で結びつくと、単なる偏向以上の強い影響力をもった学説として立ち現れるのは、たとえば「人間の測りまちがい」を読んだ人にはなじみ深いものだろう。

遺伝的な決定論として男脳や女脳を唱える人は、古典的優生学の生き残りの差別主義者であるのはもちろんだが、たとえば貧困が絶望を生むとか女性の置かれた社会的なプレッシャーが女性の行動を限定しがちであるとか、そういった社会的要因を全て逆転させてしまって、女がこれこれなのは生まれつき脳がこれこれだからだ、という決定論に胡坐をかいて何も見ようとしない愚か者でしかない。

しかし、経験的に女性がこうでありがちだ、という特徴が全く存在しないわけではない。たとえば、上のリンクの日記に書かれたようなことが、実際に統計をとったら事実として認められることもあるかもしれない。解決方法を提示されるより共感されることを好む女性の方が多いという結果を生む調査だってやればできる可能性はある。

しかし、ここまで述べたように、それが遺伝的な器質的問題であったり、単純な環境の問題であると決定したりするのは同じレベルの誤りである。相関関係と因果関係はよく取り違えられる仲の悪い双子のようなもので、ある傾向(女性は共感されるのが好き)をとらえることができれば、たちまちのうちに因果関係(女性の社会的地位による、女性の脳の器質による、などなど)を説明できてしまうと考えるのは愚かな行為以外の何物でもない。

でも、ある意味ではそれも健康な反応であるともいえなくはない。だって、女性の行動についてその原因を探ろうと思ったら、簡単に見えたとしても実際にはとても難しく、問題をとらえる視点によって結論も左右されてしまうような、決定的な手段もいまだ提供されていない未開拓の分野なので、ひどい泥沼にはまることになるだろう。生兵法は怪我のもと。他にやらなければいけないことがたくさんある人なら、ひょっとしたら「ああ、まあそれが女ってもんだよ」と片付けてしまいたくなるのも当然だからだ。

なので、男脳とか女脳とかいうのは、知りたくても知ることができないものについて、手が届きそうで届かないまま、どうにかおのれを納得させうようとする人々の哀れな最後っ屁ととらえるのが最も慈悲深いやり方なのだろう。もちろん、それが実害をもたらすレベル、たとえばあなたの前にいる人が本気で男脳とか女脳とか言い出してあなたを責める、貶める、蔑むような状況でない限り、ほっときゃいい。そういう状況なら、存分に罵倒すればいい。ネタならいくらでもある。

自分自身についていえば、こういう「女とは」みたいな話をするときは、かみさんが何かしたりしてイライラしたときだけで、それを読んでかみさんが激怒したらちょっとだけすかっとするから、という不純な動機による言明でしかなく、科学的な厳密さについては全く考慮していない。夫婦円満を目指す手段のひとつにすぎない。

納得できない人は、アパッチ加山もやってみたBBCのSEXテストをどうぞ。階級差は知能の差であり、階級の低い人間は教育しても決して理解はできないという強い偏見に長いこと苛まれてきたイギリスの考える性差についていろいろ面白いことがわかるかもしれない。

Posted in Family, Fun, life | 3 Comments »

taspo申し込んだ

Posted on September, 8 at 10:55 pm

ケープリというサービスがあったので、携帯のカメラで撮った画像を送ってtaspo用の写真にした。なかなか便利だし、1回200円だから証明写真の機械より安い。

というわけで、とうとうtaspoに申し込んだ。あんなのすぐなくなるに決まってる、自販機の中のFOMAカードをテロリストに盗まれてデータ通信し放題にされるに違いない、という楽観的な予想は中毒症状の前にあえなく敗れ去ったのだ。

さっそく申込用紙を記入した。よく宛先の「行」を二重線で消して「御中」に直す人がいるが、効率を大事にする現代人なら

こうやっておくのが正しい。

*これの元ネタはどこかのサイトにあったはずなのだが思い出せない。誰か教えて。

Posted in Fun, life | No Comments »

PHPのsplit関数

Posted on September, 8 at 10:07 pm

Ruby、Perl、Pythonのsplit関数の挙動をまとめたページをつらつらと読んでいたのだが、そういえばPHPはどうなっているか気になったのでちょっと試してみた。

まずPHPのsplit関数だが、マニュアルによれば

説明
array split ( string $pattern , string $string [, int $limit ] )

string を、正規表現によって配列に分割します。

となっている。つまり、splitの第一引数は正規表現しかない。

$str = "a,b,c";
print_r(split(",", $str));
/*当然下のようになる。
Array
(
    [0] => a
    [1] => b
    [2] => c
)
*/

$str = "a,,c,,";
print_r(split(",", $str));
/* 末尾の空要素は無視されない。
Array
(
    [0] => a
    [1] =>
    [2] => c
    [3] =>
    [4] =>
)
*/

$str = "";
print_r(split(",", $str));
/* 空文字を分割すると空の配列が返る
Array
(
    [0] =>
)
*/

$str = "";
print_r(split("", $str));
/*
分割パターンが空だとエラーになって実行できない。
*/

$str = "a:b;c.d";
print_r(split("\.", $str));
/* 文字列では指定できないので意地になってみる。
Array
(
    [0] => a:b;c
    [1] => d
)
*/

$str = "a:b;c.d";
print_r(split("[:;.]", $str));
/* 正規表現だから範囲指定で。
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
)
*/

$str = "a.b.c";
print_r(split("[.]", $str));
/* これも同じ。
Array
(
    [0] => a
    [1] => b
    [2] => c
)
*/

$str = "a;b;c";
print_r(split(":", $str));
/* どれにもマッチしない。
Array
(
    [0] => a;b;c
)
*/

と、まあここまではいい。正規表現なのか文字列なのか区別がないので、正規表現しか受け付けないという潔さも、まあいいだろう。文字列が使いたいならexplodeすればいいじゃない、と王妃もおっしゃってましたし。

ところが、納得できないのはこれだ。

$str = "a.b.c";
print_r(split(".", $str));
/* 全部空文字で返ってきたよ。。。
Array
(
    [0] =>
    [1] =>
    [2] =>
    [3] =>
    [4] =>
    [5] =>
)
*/

$ret = split(".", $str);
var_dump($ret);
/* 文字列だって言い張るんだよ。。。
array(6) {
  [0]=>
  string(0) ""
  [1]=>
  string(0) ""
  [2]=>
  string(0) ""
  [3]=>
  string(0) ""
  [4]=>
  string(0) ""
  [5]=>
  string(0) ""
}
*/

直感的には、空の配列かFALSEが返ってくるような気がするのだが、こういうことらしい。ううむ。

Posted in PHP | 2 Comments »

夏休み最後の日は親も大変

Posted on September, 1 at 4:10 pm

今の小学校では、夏休みの宿題、たとえば算数とか漢字のドリルなどは、親が採点するようになっている。厚紙に印刷されたカードにドリルをやった日付と点数を記入する欄があり、そちらに親が点数を書いて提出するのだ。

20年くらい前は、採点するのは教員の仕事だったはずだ。ずいぶんと世の中も変わったものである。

こうなると、8月31日までめいっぱい遊んでいた子供を持つ親は大変である。夜遅くまでなんとか宿題を終わらせても、その後でこのたまりにたまった宿題を採点をしてやらないといけないのだ。うちの場合、なんだかんだと採点できるようになったのが夜遅かったので、結局夜中の2時までマルやバツをつけるはめになった。

確かに30人もの生徒の宿題を採点するのも大変だろうが、仕事なのだから可能なスケジュールを引っ張って作業すればいいことだし、これがいったいなぜ親の仕事になっているのかよくわからない。ゆとり教育とはよくいったものである。

Posted in Education, Family | No Comments »

fshの代わりにsshを使う

Posted on September, 1 at 5:23 am

fshがpython-2.4以降にちゃんと対応していないので、fshを使ったシステム構成は後で困ることになるなあ、となんとなく悩んでいたのだが、ふと調べてみると「Speeding up SSH: fsh vs. OpenSSH v4 」という記事を見つけた。そのエントリにリンクされている「Quick-Tip: Reusing OpenSSH connections to the same host 」という記事によれば、OpenSSHのバージョン4以降であればfshのようなコネクションプーリング用のプログラムなしでもコネクションの再利用が出来るらしい。やり方はいたって簡単。$HOME/.ssh/configを編集して下のような行を追加する。

Host *
ControlMaster auto
ControlPath /tmp/%r@%h:%p

意味は、全てのホストでControlMasterを利用するように指定して、接続情報は/tmpに保存する、というものになる。いきなり/tmpだとマルチユーザのシステムではいかがなものかと思われるので、$HOME以下に適当な場所を指定する方がいいとのこと。まあ、その通りだ。autoのかわりにautoaskにすると、毎回接続を試みるたびにセッションを使い回すかどうか質問される。
実際に接続すると、ControlPathで指定した箇所に「リモートユーザ名@ホスト:ポート番号=」という名前のファイルが出来上がる。手元の環境でfsh、ssh共に適当な回数で実行してみたが、こんな結果になった。
まずはfsh:

localhost:~ yagi$ time fsh 192.168.x.xx ls > /dev/null
real 0m0.607s
user 0m0.039s
sys 0m0.021s

localhost:~ yagi$ time fsh 192.168.x.xx ls > /dev/null
real 0m0.121s
user 0m0.038s
sys 0m0.020s

localhost:~ yagi$ time fsh 192.168.x.xx ls > /dev/null

real 0m0.117s
user 0m0.035s
sys 0m0.019s

localhost:~ yagi$ time fsh 192.168.x.xx ls > /dev/null

real 0m0.130s
user 0m0.036s
sys 0m0.021s

初回の接続だけ0.06秒かかったが、あとはおおむね0.01秒くらい。
続いてssh:
何もしないとおよそ0.3秒くらいかかる。ところが、ControlPathで指定したディレクトリにファイルが出来ると一気に

real 0m0.054s
user 0m0.004s
sys 0m0.005s

こんなスコアになってしまった。fshより早いってのはどういうことだ?

Posted in Linux | No Comments »