[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[FDclone-users:00243] SEGV caused by group lookups



 FD 2.0x のいつ頃からか、ディレクトリを移ったときに不意に SEGV
することがあり、なかなか再現できず気になっていたのですが、今回
FD 2.04c で手元の環境限定ながら再現手順が分かり、コアも取れました。

 以下のような感じです。

Program received signal SIGSEGV, Segmentation fault.
0x281b4992 in strcmp () from /lib/libc.so.5
(gdb) bt
#0  0x281b4992 in strcmp () from /lib/libc.so.5
#1  0x080524fa in isgroupmember (gid=135030560) at pathname.c:2937
#2  0x08070bc7 in logical_access (mode=135002640, uid=0, gid=135002112) at file.c:138
#3  0x08070d5e in getstatus (list=0x80d48e4) at file.c:181
#4  0x080a263a in browsedir (file=0xbfbff0a0 "..", def=0xbfbfefa0 ".emacsen") at browse.c:1345
#5  0x080a3313 in main_fd (path=0x80c6720 "knu") at browse.c:1681
#6  0x0804b519 in main (argc=2, argv=0xbfbff200, envp=0xbfbff20c) at main.c:1165
#7  0x08049eb8 in _start ()
(gdb) f 1
#1  0x080524fa in isgroupmember (gid=135030560) at pathname.c:2937
2937                            if (!strpathcmp(up -> name, gp -> gr_mem[i])) {
(gdb) li
2932            if (!(gp = findgid(gid, NULL))) return(0);
2933            if (!(gp -> ismem)) {
2934                    gp -> ismem++;
2935                    if ((up = finduid(geteuid(), NULL)))
2936                    for (i = 0; gp -> gr_mem[i]; i++) {
2937                            if (!strpathcmp(up -> name, gp -> gr_mem[i])) {
2938                                    gp -> ismem++;
2939                                    break;
2940                            }
2941                    }
(gdb) p *gp
$1 = {gid = 0, name = 0x80c6830 "wheel", gr_mem = 0x80c581c, ismem = 1 '\001'}
(gdb) p *(gp->gr_mem)
$2 = 0x6c006168 <Error reading address 0x6c006168: Bad address>

 どうやら、 findgid() がキャッシュしている group が何らかの理由・
タイミングで壊れているようで、試しに、以下のようにキャッシュを使わ
ないようにすると SEGV しなくなります。

--- pathname.c.orig	Wed Oct 15 00:00:00 2003
+++ pathname.c	Tue Nov 18 23:06:20 2003
@@ -2882,9 +2882,11 @@
 	int i;
 
 	if (name) {
+#if 0
 		for (i = 0; i < maxgid; i++)
 			if (!strpathcmp(name, gidlist[i].name))
 				return(&(gidlist[i]));
+#endif
 # ifdef	DEBUG
 		_mtrace_file = "getgrnam(start)";
 		grp = getgrnam(name);
@@ -2898,8 +2900,10 @@
 # endif
 	}
 	else {
+#if 0
 		for (i = 0; i < maxgid; i++)
 			if (gid == gidlist[i].gid) return(&(gidlist[i]));
+#endif
 # ifdef	DEBUG
 		_mtrace_file = "getgrgid(start)";
 		grp = getgrgid(gid);


 私の環境では fd ~/.emacsen としてから .. へ移動すると、上記の
ように必ず落ちます。最近の FreeBSD 4-STABLE および 5-CURRENT です。
たぶん、 group のキャッシュの具合なんでしょうが、正確な再現条件は
不明です。Linux でもたまに落ちるような気がしますが、再現できない
ので、同じ原因なのかはわかりません。

 ちなみに、上のバックトレースで gid がおかしいように見えますが、
引数に表示されているのはポインタ値で、指す先は 1001 などの正しい
GID になっています。関数の中で p gid してもそう出るので、そこは
大丈夫そうです。


 上記で何かわかるでしょうか。さらに必要な情報があれば提供します
ので、よろしくお願いします。

-- 
                     /
                    /__  __            Akinori.org / MUSHA.org
                   / )  )  ) )  /     FreeBSD.org / Ruby-lang.org
Akinori MUSHA aka / (_ /  ( (__(  @ iDaemons.org / and.or.jp

"It seems to me as we make our own few circles 'round the sun
          We get it backwards and our seven years go by like one"