(toppers-users 4731) Re: TINET 1.7のNULLポインタアクセスについて

ABE Tsukasa abe @ tomakomai-ct.ac.jp
2018年 1月 18日 (木) 16:37:26 JST


畑様

苫小牧高専の阿部です。


> 
> 阿部先生
> 
> お世話になっております。畑 尚志と申します。
> TINETの設定で質問があります。
> 
> 質問について:
>  ASP用 TINET 1.7でechos4のサンプルをデフォルト設定でコンパイルすると
> NULLポインタアクセスが検出されます。
> 該当箇所を調べたところ tinet/netinet/in4_subr.cのin_rtnewentry関数
> で発生しているようです。
> 
> tinet/netinet/in4_subr.c
> 
> 129 : T_IN4_RTENTRY *
> 130 : in_rtnewentry (uint8_t flags, uint32_t tmo)
> 131 : {
> 132 :   SYSTIM  now;
> 133 :   T_IN4_RTENTRY   *rt, *frt = NULL;
>           .
>           . (省略)
>           .
> 150 :/* 空きがなければ、有効時間がもっとも短いエントリを空きにする。*/
> 151 :   T_IN4_RTENTRY	*srt = NULL;
> 152 :   int_t		diff, sdiff = INT_MAX;
> 153 :
> 154 :   syscall(wai_sem(SEM_IN4_ROUTING_TBL));
> 155 :   for (ix = NUM_IN4_STATIC_ROUTE_ENTRY; ix < NUM_IN4_ROUTE_ENTRY; ix ++) {
> 156 :       rt = &routing4_tbl[ix];
> 157 :       diff = (int_t)(rt->expire - now);
> 158 :       if (diff <= 0) {	/* rt->expire <= now */
> 159 :                       /* 既に、有効時間が過ぎている。*/
> 160 :                       frt = rt;
> 161 :                       break;
> 162 :                      }
> 163 :       else if (diff < sdiff) {
> 164 :            srt = rt;
> 165 :            sdiff = diff;
> 166 :       }
> 167 :   }
> 168 :   if (frt == NULL)
> 169 :       frt = srt;
> 170 :   frt->flags = 0;
> 171 :   syscall(sig_sem(SEM_IN4_ROUTING_TBL));
> 172 :   }
> 173 :
> 174 : frt->flags  = (uint8_t)(flags | IN_RTF_DEFINED);
> 175 : frt->expire = now + tmo / SYSTIM_HZ;
> 176 : return frt;
> 
>  echos4の初期設定でコンパイルした場合155行目のfor文の条件が常に成立しない
> ため最適化で削除され、170行目のfrt->flagsがNULLポインタアクセスになるよう
> です。
>  NUM_IN4_STATIC_ROUTE_ENTRY、NUM_IN4_ROUTE_ENTRYに関する設定に問題があり
> そうなのですが必要な設定等あるでしょうか?
> 

tinet/netinet/in4_subr.c の 109行

--
#if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0
--

と、tinet/tinet_config.h の 113行からの定義で、

--
/* ルーティング表のエントリ数の定義 */

#define NUM_IN6_ROUTE_ENTRY			\
	(NUM_IN6_STATIC_ROUTE_ENTRY + NUM_IN6_REDIRECT_ROUTE_ENTRY)
					/* ルーティング表のエントリ数	*/

#define NUM_IN4_ROUTE_ENTRY		\
	(NUM_IN4_STATIC_ROUTE_ENTRY + NUM_IN4_REDIRECT_ROUTE_ENTRY)
--

から、

NUM_IN4_STATIC_ROUTE_ENTRY < NUM_IN4_ROUTE_ENTRY

の条件が成立しているはずなので、for文の条件も成立すると思いますが、
そうはなっていないようですね。
こちらで調べてみます。
いずれにしても、

 > 168 :   if (frt == NULL)
 > 169 :       frt = srt;
 > 170 :   frt->flags = 0;

は問題がありそうです。
修正を検討します。

> 
> 質問の背景:
>    rx-elf-gcc 7.2.0+newlibの環境でTINET1.7をコンパイルするとkill、_exit等の
> OS依存の関数がリンクされエラー終了します。
>  調査のため実行ファイルを逆アセンブルすると、NULLポインタアクセスのあとに
> ソースコードに無いabortが挿入されている事がわかりました。どうも最近のgccは
> NULLポインタアクセスを検出するとabortを挿入するようです。
>  OS依存の関数がリンクされるとnewlib_stubが必要になるためabortの除去を行い
> たいです。
> 
> 08002247 <__tinet_in_rtnewentry>:
>     .
>     .
>     .
> 08002279 <.LM18>:
>   8002279: 74 0e ff ff ff 7f  cmp #0x7fffffff, r14
>   800227f: 21 2d              bne.b 80022ac <.LM29>
> 
> 08002281 <.LM19>:
>   8002281: 66 07              mov.l #0, r7
>   8002283: 84 77              mov.b r7, 16[r7]  ; NULL ポインタアクセス
>   8002285: 05 92 dd ff        bsr.a 8000017 <_abort> ; abort挿入
> 
> 以上、よろしくお願いします。
> 

私の開発環境は、主に CS+ に移行しており、
GCC の環境も古いままのため、検出できませんでした。
GCC の開発環境の更新も検討します。

よろしくお願いします。

-- 
.\" 苫小牧工業高等専門学校 創造工学科 情報科学・工学系
.\" 教授 阿部 司
.\" 〒059-1275 北海道苫小牧市字錦岡443番地
.\" E-mail: abe @ tomakomai-ct.ac.jp  TEL/FAX: 0144-67-8937