Armadilloフォーラム

SNMP のSetについて

yue110

2022年10月11日 11時42分

まいどお世話になっております。
SNMPで少し悩んでおりますのでご教授願います。

現在、SNMPでデータをSetしているのですが、データ数が多いとゴミデータ(0x99)が
Setしたデータの最後に入ってしまう現象がでています。
特に、44byteをSetするとSNMPのプロセスが落ちてしまいます。
何かこの現象で分かる方おりましたら、アドバイス、ご教授願います。

よろしくお願い致します。

※ソース載せたいのですが、現在作成中、動作検証中のため、また、
 社外秘の製品でもありますので、公にできませんので、ソースも載せることができないことをご了承ください。

※使用しているArmadilloは420ですが、460でも同様の現象が出ることが確認できました。

※製品製作によりゴタゴタしておりますので、返信が遅くなるかもしれません。
 ご了承ください。

コメント

at_shiita.ishigaki

2022年10月12日 14時22分

石垣です。

> 現在、SNMPでデータをSetしているのですが、データ数が多いとゴミデータ(0x99)が
> Setしたデータの最後に入ってしまう現象がでています。
> 特に、44byteをSetするとSNMPのプロセスが落ちてしまいます。

・SNMP マネージャと SNMP エージェントはどのような構成でしょうか?
・この現象は Armadillo を使用せずに、パソコンで行った場合も起こるのでしょうか?
・再現するために必要最低限のコマンド・ソースコード等可能でしたら教えて頂けますでしょうか?

at_shiita.ishigaki

2022年10月12日 15時09分

石垣です。

申し訳ございません。先程のコメントで文章が抜けていましたので、再度コメントさせて頂きます。

> 現在、SNMPでデータをSetしているのですが、データ数が多いとゴミデータ(0x99)が
> Setしたデータの最後に入ってしまう現象がでています。
> 特に、44byteをSetするとSNMPのプロセスが落ちてしまいます。

いくつか確認させていただきたいのですが、

・SNMP マネージャと SNMP エージェントはどのような構成でしょうか?
・この現象は Armadillo を使用せずに、パソコンで行った場合も起こるのでしょうか?
・再現するために必要最低限のコマンド・ソースコード等教えて頂けますでしょうか?

ご確認の程宜しくお願い致します。

ym1909

2022年10月12日 17時54分

石垣 様 コメントありがとうございます。
yue110の同僚のym1909と申します。

・SNMP マネージャと SNMP エージェントはどのような構成でしょうか?
  SNMPマネージャー : NET-SNMP Version5.7(Windows 32bit版)
  SNMP エージェント : NET-SNMP Version5.0.9 (Armadillo420)

・この現象は Armadillo を使用せずに、パソコンで行った場合も起こるのでしょうか?
  SNMP エージェントはArmadillo420のみだったため、PC同士での確認はできておりません。
  ただ、wiresharkで通信パケットを確認すると、SNMPマネージャー側は44BYTEデータの文字列を送信しているようでした。

・再現するために必要最低限のコマンド・ソースコード等教えて頂けますでしょうか
  マネージャー側は以下のコマンドで44BYTEの文字列をセットしての確認をしておりました。
  snmpset -v 2c -c (コミュニティ名) 192.168.1.3 1.3.6.1.4.1.(独自OID).2.5.5.0 s "aaaaaaaaaa,aaaaaaaaa,aaaaaaaaaa,aaaaaaaaaaab"

  ソースコードは展開できないのですが(申し訳ありません)、該当のOIDは以下のように文字列型に設定しています。
struct variable7 test_value_variables[] = {
{ EX_MIB_TEST, ASN_OCTET_STR, RWRITE, var_setting, 3, { 2, 5, 5 } }
}

at_shiita.ishigaki

2022年10月21日 12時50分

石垣です。

原因をマネージャとエージェントで切り分けるために、
Armadillo420上で snmpset コマンドを実行して、ローカルの SNMP にセットしてみてはいかがでしょうか。

以上宜しくお願い致します。

yue110

2022年10月21日 13時48分

> 原因をマネージャとエージェントで切り分けるために、
> Armadillo420上で snmpset コマンドを実行して、ローカルの SNMP にセットしてみてはいかがでしょうか。
>

石垣様
コメントありがとうございます
ここでおっしゃっていますローカルというのは
データをArmadillo自身のローカルデータにSetして確認してみるという
自己Armadillo内でやり取りをしてどこでおかしくなっているのかを確認してみる
という事でよろしいでしょうか?

確認してみたいと思います。
確認したら結果を記載いたします。
よろしくお願い致します。

at_shiita.ishigaki

2022年10月21日 13時56分

> ここでおっしゃっていますローカルというのは
> データをArmadillo自身のローカルデータにSetして確認してみるという
> 自己Armadillo内でやり取りをしてどこでおかしくなっているのかを確認してみる
> という事でよろしいでしょうか?

はい、そのご認識のとおりです。
通信を挟まないことで、同様の症状が起こるかというところを試していただきたかったです。

> 確認してみたいと思います。
> 確認したら結果を記載いたします。
> よろしくお願い致します。

宜しくお願い致します。

ym1909

2022年10月24日 10時23分

お世話になっております。ym1909です。
Armadillo側のSNMP SETを有効化して、ローカルで確認してみました。
同様に44byteの文字列setでnet-snmpのプロセスが落ちる現象が発生したため、原因としてはエージェント側にありそうです。

at_shiita.ishigaki

2022年10月25日 15時34分

石垣です。

以下の方法で原因を探せないかと考えました。

1. SNMP のプロセスが落ちるときのログを確認する
snmpd を使用している場合は、/usr/sbin/snmpd -Lf [ファイル名] で snmpd を実行した場合はファイルにログが出力されます。

2. gdb を使用して snmpset をデバッグする
ATDE を使用する場合は以下の手順で実行できます。
[ATDE ~]$ git clone https://github.com/net-snmp/net-snmp.git
[ATDE ~]$ cd net-snmp
[ATDE ~/net-snmp]$ git checkout [バージョン]
[ATDE ~/net-snmp]$ ./configure
[ATDE ~/net-snmp]$ make
[ATDE ~/net-snmp]$ gdb --args apps/snmpset -v 2c -c (コミュニティ名) (Armadillo IPアドレス) 1.3.6.1.4.1.(独自OID).2.5.5.0 s "aaaaaaaaaa,aaaaaaaaa,aaaaaaaaaa,aaaaaaaaaaab"

3. gdb を使用して snmpd をデバッグする
gdbserverの使い方については以下の記事が参考になると思います。
・Armadillo-440(Linux-3.14):gdbserverを使ってみました
また、snmpd に gdb を使用する方法は以下の記事が参考になると思います。
https://net-snmp.sourceforge.io/wiki/index.php/Debugger

以上、よろしくお願いいたします。

ym1909

2022年10月27日 11時48分

ym1909です。
複数の検証案をご提案いただきありがとうございます。
まず案1で確認をしてみました。

1. SNMP のプロセスが落ちるときのログを確認する
---snmpエージェント(Armadillo420)-------------------
コマンド: /sbin/snmpd -c /etc/config/snmpd.conf -Lf
実行結果:
NET-SNMP version 5.0.9
** glibc detected ** /sbin/snmpd: free(): invalid next size (fast): 0x00069b38 ***
Aborted
----------------------------------
ログの内容から見ると、確保しているメモリサイズの範囲外を参照しようとして
snmpdプロセスが落ちているのでしょうか?

この時のsnmpマネージャ側の実行結果は以下の通りです。
Armadillo420はSETされた文字列のGETレスポンス送信まではできていますが、その後ログにある通り範囲外のメモリ参照が発生してしまっているかもしれません。

---snmpマネージャ(NET-SNMP Windows 32bit版)-------------------
コマンド:snmpset -v 2c -c test_name 192.168.1.2 1.3.6.1.4.1.(独自OID).2.5.5.0 s "aaaaaaaaaaa,aaaaaaaaa,aaaaaaaaaa,aaaaaaaaaab"
実行結果:
SNMPv2-SMI::enterprises.(独自OID).4.2136.2.5.5.0 = STRING: "aaaaaaaaaaa,aaaaaaaaa,aaaaaaaaaa,aaaaaaaaaab"
----------------------------------------------------------------------

ym1909

2022年10月28日 15時26分

ym1909です。
案2の確認を実施してみました。
ATDE5でArmadillo420に向けて、snmp setをおこなった時のgdbによるデバック結果です。コマンドは正常に終了(exited normally)し、特にエラーは発生していないようです。

2. gdb を使用して snmpset をデバッグする
-----------------------------------------
・コマンド:
gdb -q /home/atmark/net-snmp/apps/snmpset

・gdbで実行したコマンド:
(gdb) r -v 2c -c test_name 192.168.1.2 1.3.6.1.4.1.(独自OID).2.5.5.0 s "aaaaaaaaaaa,aaaaaaaaa,aaaaaaaaaa,aaaaaaaaaab"

・実行結果:
Starting program: /home/atmark/net-snmp/apps/snmpset -v 2c -c test_name 192.168.1.2 1.3.6.1.4.1.(独自OID).2.5.5.0 s "aaaaaaaaaaa,aaaaaaaaa,aaaaaaaaaa,aaaaaaaaaab"
iso.3.6.1.4.1.(独自OID).2.5.5.0 = STRING: "aaaaaaaaaaa,aaaaaaaaa,aaaaaaaaaa,aaaaaaaaaab"
[Inferior 1 (process 3983) exited normally]
----------------------------------------

at_shiita.ishigaki

2022年10月31日 19時06分

石垣です。

> ログの内容から見ると、確保しているメモリサイズの範囲外を参照しようとして
> snmpdプロセスが落ちているのでしょうか?

なぜエラーが起きるのか原因は特定できませんが、free 関数を実行した時にメモリに関してエラーが起きているようです。

こちらの Armadillo-420 上で NET-SNMP version: 5.4.3 を使用して、以下のコマンドのように適当な OID に 44 byte の文字列をセットしてみましたが、エラーは発生しませんでした。

[Armadillo ~]# snmpset -v 2c -c public localhost .1.3.6.1.2.1.1.5.0 s "aaaaaaaaaaa,aaaaaaaaa,aaaaaaaaaa,aaaaaaaaaab"

一度、独自 OID を使用しなかった場合にエラーが発生するか確認して頂けないでしょうか。
上記の snmpset コマンドを実行するには、OID に書き込みの許可が必要なため、
/etc/snmp/snmpd.conf に下記行を追加する必要が有ります。

[Armadillo ~]# vi /etc/snmp/snmpd.conf
 
rwcommunity public localhost # この行を追加

二転三転して申し訳ございませんが、確認の程よろしくお願いいたします。

at_shinya.koga

2022年11月1日 11時51分

アットマークテクノの古賀です。

ym1909さん(2022年10月28日 15時26分):
>案2の確認を実施してみました。
>ATDE5でArmadillo420に向けて、snmp setをおこなった時のgdbによるデバック結果です。コマンドは正常に終了(exited normally)し、特にエラーは発生していないようです。
>
>2. gdb を使用して snmpset をデバッグする

gdb でデバッグ実行することにより、動作のタイミングが変わって不具合が出なくなったのかも知れませんね。

ym1909さん(2022年10月27日 11時48分):
>まず案1で確認をしてみました。
>
>1. SNMP のプロセスが落ちるときのログを確認する
>---snmpエージェント(Armadillo420)-------------------
>コマンド: /sbin/snmpd -c /etc/config/snmpd.conf -Lf
>実行結果:
>NET-SNMP version 5.0.9
>** glibc detected ** /sbin/snmpd: free(): invalid next size (fast): 0x00069b38 ***
>Aborted
>----------------------------------
>ログの内容から見ると、確保しているメモリサイズの範囲外を参照しようとして
>snmpdプロセスが落ちているのでしょうか?

このエラーメッセージが出るのは、malloc() で確保した領域に対して領域サイズを超えた書込みが行われて領域の管理情報が壊れてしまい、その後の free() でエラーになる場合や、既に free() で解放済みの領域を、再度 free() で解放しようとした場合など、いくつかの可能性があるようです。何かしら、メモリ周りの不具合があると思われます:
 https://stackoverflow.com/a/4729416
 http://dqn.sakusakutto.jp/2013/10/free_invalid_next_size_fast.html

>この時のsnmpマネージャ側の実行結果は以下の通りです。
>Armadillo420はSETされた文字列のGETレスポンス送信まではできていますが、その後ログにある通り範囲外のメモリ参照が発生してしまっているかもしれません。

GET レスポンスを送信する前後で、メモリ内容を壊してしまっている可能性が高そうですね。
 
ということで、 'snmpd free(): invalid next size (fast)' で検索してみたところ、net-snmp に関する、次のバグ報告が見つかりました:

 Bug 1366282 - Double free or corruption when use net-snmp snmp_sess_open() with several threads
 https://bugzilla.redhat.com/show_bug.cgi?id=1366282

ym1909さん(2022年10月12日 17時54分):
>・SNMP マネージャと SNMP エージェントはどのような構成でしょうか?
>   SNMPマネージャー : NET-SNMP Version5.7(Windows 32bit版)
>   SNMP エージェント : NET-SNMP Version5.0.9 (Armadillo420)

上で紹介した、net-snmp のバグ報告は、net-snmp-5.7.3-13 で修正されたもののようですが、修正箇所と内容は、こちらで見れます:
 https://sourceforge.net/p/net-snmp/code/ci/315a9dfeddbad9c611833c9625d6…

net-snmp のソースの snmplib/snmp_transport.c で実装されている domain_transport_full() で、strtok() の代わりに strtok_r() を使うようにして修正したようです。もし、お使いの net-snmp をソースコードからビルド可能であれば、domain_transport_full() の実装を、5.7.3-13 の修正後のものと比べてみて、修正を取り込み可能そうであれば取り込んでみることで不具合を解消できるかも知れません。

以上、もし参考になりましたら幸いです。

ym1909

2022年11月1日 15時07分

お世話になっております。ym1909です。

石垣様
>一度、独自 OID を使用しなかった場合にエラーが発生するか確認して頂けないでしょうか。

実行した所、汎用のOIDでは正常にSET可能でした。
/sbin/snmpd -c /etc/config/snmpd.conf -Lf コマンドでログも確認しましたが、エラー発生はしておりませんでした。
------実行結果----------------
snmpset -v 2c -c public localhost .1.3.6.1.2.1.1.5.0 s "aaaaaaaaaaa,aaaaaaaaa,aaaaaaaaaa,aaaaaaaaaab"
iso.3.6.1.2.1.1.5.0 = STRING: "aaaaaaaaaaa,aaaaaaaaa,aaaaaaaaaa,aaaaaaaaaab"
----------------------

古賀様
バージョン5.0.9のsnmplib/snmp_transport.c とも比較しましたが、ソースコードにかなりの差分がありnetsnmp_tdomain_transport_full処理自体が未実装のようでした。
後々、修正の取り込みかNET-SNMP自体のバージョンアップで解決するかも試みたいと思います。
情報ありがとうございます。