[tomoyo-users 520] Re: ccs_free のバグ?

Back to archive index

Tetsuo Handa from-****@I-lov*****
2008年 11月 30日 (日) 23:04:23 JST


 熊猫です。

> とりあえず objdump とってみましたがソースコードは入ってないみたいです。
> CONFIG_DEBUG_INFO というのは .config に見つからなかったのですが、
> CONFIG_DEBUG_KERNEL が not set のせいでしょうか?
そうですね。
# CONFIG_DEBUG_KERNEL is not set. だと CONFIG_DEBUG_INFO は設定できません。


http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/fs/realpath.c#L619 と
比較しながら推測してみました。(まったく自信ありません。)
−−−−−
00000000000001b0 <ccs_free>:
/*
    if (!p)
        goto 1e8;
*/
 1b0:	48 85 ff             	test   %rdi,%rdi
 1b3:	53                   	push   %rbx
 1b4:	74 32                	je     1e8 <ccs_free+0x38>

/*
    v = &cache_list->next;
*/
 1b6:	48 8b 1d 00 00 00 00 	mov    0x0(%rip),%rbx        # 1bd <ccs_free+0xd>
/*
    goto 1c9;
*/
 1bd:	eb 0a                	jmp    1c9 <ccs_free+0x19>
 1bf:	90                   	nop    

/*
    if (entry->ptr == p)
        goto 1f0;
*/
 1c0:	48 39 7b 10          	cmp    %rdi,0x10(%rbx)
 1c4:	74 2a                	je     1f0 <ccs_free+0x40>

/*
    v = v->next;
*/
 1c6:	48 89 f3             	mov    %rsi,%rbx
 1c9:	48 8b 33             	mov    (%rbx),%rsi
/*
    if (v)
        goto 1c0;
*/
 1cc:	48 81 fb 00 00 00 00 	cmp    $0x0,%rbx
/*
    prefetch(v->next),
*/
 1d3:	0f 18 0e             	prefetcht0 (%rsi)
 1d6:	75 e8                	jne    1c0 <ccs_free+0x10>

 1d8:	5b                   	pop    %rbx

/*
    entry = NULL;
*/
 1d9:	48 c7 c7 00 00 00 00 	mov    $0x0,%rdi
 1e0:	31 c0                	xor    %eax,%eax
 1e2:	e9 00 00 00 00       	jmpq   1e7 <ccs_free+0x37>
 1e7:	90                   	nop    

/*
    return;
*/
 1e8:	5b                   	pop    %rbx
 1e9:	c3                   	retq   
 1ea:	66 0f 1f 44 00 00    	nopw   0x0(%rax,%rax,1)

/*
    list_del(&entry->list);
*/
 1f0:	48 8b 43 08          	mov    0x8(%rbx),%rax
 1f4:	48 89 46 08          	mov    %rax,0x8(%rsi)
 1f8:	48 89 30             	mov    %rsi,(%rax)
 1fb:	48 c7 43 08 00 02 20 	movq   $0x200200,0x8(%rbx)
 202:	00 
 203:	48 c7 03 00 01 10 00 	movq   $0x100100,(%rbx)

/*
    dynamic_memory_size -= entry->size;
*/
 20a:	8b 43 18             	mov    0x18(%rbx),%eax
 20d:	29 05 00 00 00 00    	sub    %eax,0x0(%rip)        # 213 <ccs_free+0x63>

 213:	e8 00 00 00 00       	callq  218 <ccs_free+0x68>
 218:	48 89 de             	mov    %rbx,%rsi
 21b:	48 8b 3d 00 00 00 00 	mov    0x0(%rip),%rdi        # 222 <ccs_free+0x72>
 222:	5b                   	pop    %rbx
 223:	e9 00 00 00 00       	jmpq   228 <ccs_free+0x78>
 228:	0f 1f 84 00 00 00 00 	nopl   0x0(%rax,%rax,1)
 22f:	00 
−−−−−

ccs_free+0x19/0x80 でこけるということは、 1c9 の位置ですね。
list_for_each(v, &cache_list) マクロの中の pos = (head)->next あるいは
pos = pos->next を処理する箇所だと思われます。
何かの拍子に %rbx が 0xffffffffffffffff になってしまい、そのまま
(%rbx) (読み出しアクセス)を実行したことで
BUG: unable to handle kernel paging request at ffffffffffffffff
となったのでしょうが、何故 %rbx に 0xffffffffffffffff が入ったのかは
特定できませんでした。誰かが %rip の指す領域に 0xffffffffffffffff と
書きこんでいたのであれば 1b6 で%rbx に 0xffffffffffffffff が入るので
納得ですが、これ以上の解析はできそうにないです。

spin_lock() / spin_unlock() / kfree() / kmem_cache_free() / printk() を
呼んでいる気配がしないのが何とも不気味ですね。

%rip には cache_list とか dynamic_memory_size とかのアドレスを
代入する必要があるのに、それらしき箇所も見当たりません。

# CONFIG_DEBUG_KERNEL is not set. なのに CONFIG_DEBUG_LIST=y なのか、
LIST_POISON1 ( $0x100100 )や LIST_POISON2 ( $0x200200 )を代入している
ように見えます。

1cc の箇所が pos != (head) ではなく pos != NULL のように見えるのも
変な気がします。

う〜ん、どうやって動いているんでしょうねぇ?




tomoyo-users メーリングリストの案内
Back to archive index