質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.32%

  • C

    3997questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C言語で明示的なバッファオーバーラン記述を見つける方法について

解決済

回答 7

投稿

  • 評価
  • クリップ 3
  • VIEW 1,859

GuielNo4

score 64

前提・実現したいこと

明示的なバッファオーバーラン記述を見つけるための方法を知りたいと考えております。

発生している問題・エラーメッセージ

コードの保守を行っているのですが、記述で明示的に
char buffer[5];
buffer[10] = 0x01;
...
と、ワーニングがでないコードを見つけたのですが、
ソース全体が同じ手法でコーディングされており、
ファイル数、行数の多さから目視で確認することを諦めました。

試したこと

ルネサスのマイコンのソースで、HEW を利用しているのですが、
オプション等でワーニングを出せないか確認しているのですが、
見つけられませんでした。

アドバイスをお願い致します。

何か別のツールでも、ソース解析ツールでも構いませんので、
このような明示的な記述ミスを洗い出す方法をご存知の方がいらっしゃいましたら
アドバイス頂けると助かります。

宜しくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 7

checkベストアンサー

+2

静的解析ツールというのがあります。おそらく仕事で行われてることでしょうから、商用を含めこのようなツールの導入を検討してみてはいかがでしょうか。

オープンソースの物ではcppcheckClang Static Analyzerがあります。
手元で確認したところ、質問者さんの例はClang Static Analyzerでは検出できませんでした。というか、Analyzerの前にclang自身が警告してくれます。

$ cat hoge.c
int main(void)
{
        char buffer[5];
        buffer[10] = 0x01;
}
$ scan-build clang hoge.c
scan-build: Using '/usr/bin/clang-3.9' for static analysis
hoge.c:4:2: warning: array index 10 is past the end of the array (which contains 5 elements) [-Warray-bounds]
        buffer[10] = 0x01;
        ^      ~~
hoge.c:3:2: note: array 'buffer' declared here
        char buffer[5];
        ^
1 warning generated.
scan-build: Removing directory '/tmp/scan-build-2017-02-21-150029-11072-1' because it contains no reports.
scan-build: No bugs found.

cppcheckでは検出できるようです。

$ cat hoge.c
int main(void)
{
        char buffer[5];
        buffer[10] = 0x01;
}
$ cppcheck hoge.c
Checking hoge.c ...
[hoge.c:4]: (error) Array 'buffer[5]' accessed at index 10, which is out of bounds.

商用のものではCoverityが有名です。以前組織で使っていましたが、これは・・・スゴイです。そしてお高いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/22 02:09

    早速利用致しました。
    望んでいた解析に一番近いことが出来ました。
    アドバイス有難うございました。

    キャンセル

  • 2017/02/22 02:24

    解析結果として
    [main.c:9]: (error) Array 'buffer[5]' accessed at index 10, which is out of bounds.
    以上の内容が表示されました。
    今回の分析にはこのツールを利用させて頂こうと思います。
    ありがとうございました。

    キャンセル

+2

何か別のツールでも、ソース解析ツールでも構いませんので、

他サイトの回答丸投げですが、以下に挙げられているものをいくつか実際に試してみるとよいかと思います。
静的コード解析ツールについて質問です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/21 17:06

    ツールの御紹介ありがとうございます。
    大変助かります。
    記載のあるツールを調べて試してみたいと思います。
    アドバイス有難うございました。

    キャンセル

+2

私もHEWを使っていますが、そのような検出ができる設定は見当たりませんでした。
静的解析ツールの出番ですね。
フリーで使えそうなのはsplintでしょうか。
http://www.splint.org/

あとは市販製品ではESCRに準拠したチェックができるものがいくつかあります。
PGRelief
http://www.fujitsu.com/jp/group/fst/products/pgr/
C++ test
https://www.techmatrix.co.jp/product/ctest/staticanalysis/ipa_sec.html

参考まで。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/21 17:09

    HEWの情報有難うございます。大変助かります。
    まず、splint を試してみたいと思います。
    アドバイス有難うございました。

    キャンセル

+1

すでに出ていますが、静的コード解析ツールの利用をお勧めします。バッファオーバーランだけでなく、様々な「怪しい」記述の検出やコーディングルールの徹底など、うまく使えばとても有用です。無料で公開されているものもありますので、試してみると良いかもしれません。

もしVisual Studioをお使いなら、「コード分析」という名前で同様の機能が提供されています。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/22 02:05

    アドバイス有難うございます。
    これを機に解析ツールをいろいろ調べてみたいと思います。

    キャンセル

+1

例に挙げられた様な静的なアクセス範囲違反であれば gcc の -Warray-bounds と -O2 を同時に指定すれば検出可能です。6行目に buffer[10] = 0x01; と同様のエラーがあるとわかります。

$ gcc -O2 -Warray-bounds main.c
main.c: In function 'main':
main.c:6: warning: array subscript is above array bounds

これに -Werror など付けて警告をエラーとして扱い全ての類似エラーが修正できるまでコンパイルできない様にするのも良いかもしれません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/22 02:14

    アドバイス有難うございます。
    コンパイラオプションの情報有難うございました。

    キャンセル

+1

他の方も紹介されていますが、個人的には cppcheckをよく使用しています。

基本的にはファイル単位のチェックとなり高度なチェックは出来ませんが、逆にコンパイルに必要なファイルが揃っていなくてもチェックが手軽に出来る点が逆に気に入っています。

Coverityなどは、コンパイル可能な状態にしないとチェックできないですが、他人の作成したファイルをレビューなどでチェックする場合など、コンパイル必要なファイルが揃っていない(揃ええるのが大変)という事がよくあるので。

ただし、cppcheck は日本語に対応できていないので、その点だけは注意が必要でです。
(ツールのメニューなどは日本語化されているのですが・・・)

ご参考:CppCheck 1.61 のWindows日本語パス対応

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/22 02:18

    アドバイス有難うございます。
    日本語対応の情報有難うございました。

    キャンセル

  • 2017/02/22 06:14 編集

    マルチバイト文字に対応できていないための、いわゆる「 SJIS の\(0x5C)問題」なので、「ソースコードはEUCコード(※1)に変換」、「ファイルの存在するディレクトリ(フルパス)をASCII文字のディレクトリに移動する」などすれば、ツール本体を改造しなくても対応できます。(なのでWindowsで問題になってLinuxだと問題になりにくい)

    「ソ」が問題となる対象文字なので、ディレクトリ名などで「xxxのソース」なんてフォルダに置いてあってよくハマります。

    ソースコード自体の文字コードについては、SJISのままでも、問題文字が含まれる対象個所の部分だけにチェックミスが限定され、他の部分のチェックは正常に行える事ががほとんどなので、SJISコードのソースだからチェックは出来ないという事はありません。

    ※1 UTF-8などへの変換でも「\(0x5C)問題」自体は回避できますが、SJIS->UTF8だと文字列のバイト数が変化してしまい、strcpyやsprintfにおけるバッファオーバーランチェック時などで間違ったチェック結果になる事になるので、文字列のバイト数の変化しないSJIS->EUC変換が有効な対処となります。

    キャンセル

  • 2017/02/22 13:13

    リポジトリとの絡みもありますので UTF-8 で済ませたいところですが、
    マイコンのファームだとコンパイラがUTFに対応していないこともあったりして、
    対象ソースの多くがSJISだったりしますので、ぜひこの情報を生かして作業を行いたいと思います。
    マルチバイト文字の情報ありがとうございました。

    キャンセル

-1

出せません。それはシンタックスエラーではないからです。
自分で注意するしかないですね。

このようなコードも書けるのがCの特徴でもありますね。

buffer[10] = 0x01;
これが

buffer[i] = 0x01;
こうなら、目視でも発見不可能ではないでしょうか。

どうしてもやるなら、配列を扱うのに関数を通せばできない事もないですね。

char GetValue(int index)
{
    assert(index < 10);

    return buffer[index];
}


とか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/21 16:56

    アドバイス有難うございます。
    確かにご指摘の通り、変数で配列を変更する場合は検出できないですね…
    c#を勉強していまして、勉強がてら、
    全ての変数をピックアップしてカッコ内の数値と変数名コレクションして、
    コード上にアサートを入れて、コンパイルでワーニングが出るようにソースを加工するプログラムを組んでみて、他の方にアドバイス頂きました解析ツールの結果と比較してみようと思います。
    アドバイス有難うございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.32%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C

    3997questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。