[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[debian-devel:15289] dpkg.cfg での指定
川辺と申します。
/etc/dpkg/dpkg.cfg で、パス名(などの文字列)を伴うオプション(--rootや--
admindir)を指定した場合、dpkg が誤動作しました。
dpkgのバージョンは、1.10.6 で、アーキは、x86 です。
そこで、指定の問題なのか dpkg側の問題なのかをソースから調べたところ、
dpkg-1.10.6/lib/myopt.c でコンフィグレーションファイルを解析し、
cmdinfo に従ってオプション処理を行う際に、オプションに付随する値が文字
列であるにも関わらず、その関数のスタック内の領域のポインタをそのまま渡
しており、渡された側もそのまま静的変数(例えば、dpkgコマンドでは、
main.cのinstdir)に設定してしまっています。
このため、ケースバイケースで、パス名などが壊れてしまい、おかしな文字列
をパス名として使っていたりします。
# バッファがそれなりに大きいため、最終オプションの場合、うまくいってしま
# うこともあります。(スタックの伸長方向が逆のアーキでは、すぐに壊されそ
# うですが)
これは、このオプションの値を受け取った側で適切に処理すればいいのでしょ
うが、直接 cmdinfo のメンバの差す先に代入する場合には、あてはまりませ
ん。
そこで、大変安易な変更を行って見ました。
加えて、/etc/dpkg/dpkg.cfg で、--rootや--admindir、--instdirを指定して
も、dpkg -l を実行する dpkg-query には、渡りませんでした。で、調べてみ
ると dpkg-query は、standard_startup にコンフィグレーションのロードを
しない指定で呼び出しておりました。そこで、これも、ちょっと変更してみま
した。
本来なら、直接本家に報告するものだと思うのですが、何かのポリシー(メモ
リーアロケーションの方針とか)でこうなっている(??)のかどうかよく分から
なかったので、取り敢えずこのMLに送らせて頂きました。
# 英語力の問題できちんと伝えられるか不明と言うこともあったので。
何か、ご存じの方がいらっしゃれば、リプライして頂けると助かります。
--- myopt.c.ORIG 2002-07-02 19:39:55.000000000 +0900
+++ myopt.c 2002-09-03 20:47:12.000000000 +0900
@@ -69,12 +69,22 @@
}
}
- if (!cip->olong) ohshite(_("configuration error: unknown option %s"), linebuf);
+ if (!cip->olong) {
+ /* ohshite(_("configuration error: unknown option %s"), linebuf); */
+ continue; /* ignore unknown option */
+ }
if (cip->takesvalue) {
+ char* x;
+ size_t l;
if (!opt) ohshite(_("configuration error: %s needs a value"), linebuf);
- if (cip->call) cip->call(cip,opt);
- else *cip->sassignto= opt;
+ l = strlen(opt);
+ x = malloc(l+1);
+ if (!x) ohshite(_("configuration error: %s not enough memory"), linebuf);
+ memcpy(x,opt,l);
+ x[l] = '\0';
+ if (cip->call) cip->call(cip,x);
+ else *cip->sassignto= x;
} else {
if (opt) ohshite(_("configuration error: %s does not take a value"), linebuf);
if (cip->call) cip->call(cip,NULL);
--- query.c.ORIG 2002-09-01 13:47:05.000000000 +0900
+++ query.c 2002-09-03 18:47:02.000000000 +0900
@@ -537,7 +537,7 @@
jmp_buf ejbuf;
static void (*actionfunction)(const char *const *argv);
- standard_startup(&ejbuf, argc, &argv, NULL, 0, cmdinfos);
+ standard_startup(&ejbuf, argc, &argv, DPKG, 1, cmdinfos);
if (!cipaction) badusage(_("need an action option"));
setvbuf(stdout,0,_IONBF,0);