(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