問題タブ [buffer-overflow]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - gets 関数が非常に危険なため、使用すべきではないのはなぜですか?
GCC で関数を使用する C コードをコンパイルしようとすると、次のgets()
警告が表示されます。
(.text+0x34): 警告: `gets' 関数は危険なので使用しないでください。
これはスタック保護とセキュリティに関係していることを覚えていますが、正確な理由はわかりません。
この警告を削除するにはどうすればよいですか?また、使用に関する警告が表示されるのはなぜgets()
ですか?
そんなに危険ならgets()
、なぜ私たちはそれを取り除けないのですか?
windows - Visual C++ ランタイムでバッファ オーバーフロー チェックを無効にする方法は?
私、および他の数千人の人々は、Microsoft Visual C++ ランタイムによってスローされるエラーを取得しています。
検索エンジンの利益のために、次のように述べています。
これで、バッファ オーバーランとは何か、なぜそれが悪いことなのかを理解できました。Microsoft が新たに「壊れただけだ」と強調したことを考えると、 MSVCRTの追加のバッファ チェックは便利な機能です。
一方、私は気にしません。プログラムが続行できないのではなく、プログラムが安全に続行できないということです。それは何もないよりはましだからです。私は危険な生活を楽しんでいます。
誰でも何か提案できますか?私は次のようなことを考えていました:
- MSVCRT が実行を停止しないようにするためのレジストリ キー
- 以前のオペレーティング システム (Windows 7 より前) との互換性でアプリケーションを実行する
- アセンブリ マニフェストを実行可能フォルダーに追加して、このオーバーフロー チェックを実行しない古いバージョンの MSVCRT を使用するようにします。
- オーバーフロー チェックを行わない MSVCRT のコピーのバージョン番号またはダウンロード場所
Microsoft Visual C++ ランタイム ライブラリを作成した会社のサポート サイトを検索してみましたが、どの関数がオーバーフローする可能性があるか、またはオーバーフロー チェックを無効にする方法については言及されていません。
c - メモリ上書きの問題
Cコードアプリが1つあります。MS-VS2005を使用して構築していました。mallocを使用して動的に割り当てられていた1つの出力データバッファーがありました。
一部のテストケースでは、mallocされていたメモリサイズが、生成された実際の出力サイズ(バイト単位)よりも不足していました。その大きいサイズの出力が小さいサイズのバッファに書き込まれ、バッファオーバーフローが発生しました。その結果、テスト実行がクラッシュし、MSVS-2005に「ヒープの破損...」というウィンドウが表示されました。
動的メモリ割り当てに関係していることはわかっていましたが、出力に必要な十分なサイズを割り当てていたため、メモリ割り当てを疑うことなく、実際に根本的な原因を見つけるのに長い時間がかかりました。しかし、ある特定のテストケースでは、私が計算したよりも多くの出力が生成されたため、クラッシュが発生しました。
私の質問は:
1.)このような動的メモリバッファのオーバーフロー状態を検出するために使用できるツール。また、バッファオーバーフロー状態の検出にも役立ちますか(バッファ/アレイがヒープ、スタック、グローバルメモリ領域にあるかどうかに関係なく)?
2.)メモリリークツール(Purifyなど)またはlint、klocworksなどのコード分析ツールは特定の場合に役立ちますか?ランタイム分析ツールでなければならないと思います。
ありがとうございました。
-広告。
c - scanf("%8s", string) オーバーフロー?
通常のコードがオーバーフローする可能性があることはわかっています。
文字列[9];
scanf("%s", 文字列)。
しかし、scanf("%8s", string) をオーバーフローさせることは可能ですか? 8はほんの一例です。
「%8s」が区切りのように機能することは知っていますが、8 文字を超える文字列を入力すると、次の理由でプログラムが終了することにも気付きました。
* スタック破壊が検出されました * : ./a.out が終了しました
======= バックトレース: =========
...
明らかに、GCC によってデフォルトでオンになっているスタック破壊を検出するフラグがあります。これはスタック破壊であるため、オーバーフローして任意のコードを実行する可能性はまだあると思います。
scanf("%s") の呼び出し元を台無しにする通常のオーバーフローとは対照的に、scanf("%8s") がオーバーフローする可能性がある場合は、scanf 関数内でオーバーフローするため、scanf が戻ろうとすると制御が取得されます。
しかし、scanf はモード切り替え (ユーザー モードからカーネル モードへの切り替え) を必要とする syscall であり、内部的には標準入力への読み取りなどを呼び出します。そのため、カーネル モードなどでオーバーフローする可能性があるかどうかはわかりません。
コメント大歓迎です!!
更新 >>
上記の例では、char string[9] が想定されています。次の実際のコードの char string[8]。
問題は、スタック破壊による安全な scanf("%8s") と GCC の中止の間の矛盾するように見える話についてです。
簡略化されたコード:
ノート:
- foo は他の誰かによって呼び出されます。
- string は実際のコードでは "%8s" で 8 バイトですが、これがスマッシングにつながることはないと思います。
c - printf api をこのように使用すると、より安全になりますか?
** もちろん、それらのバッファ、文字列はまだ適切にターゲットされていません
c++ - 整数にアクセスするときに、バッファ オーバーランによってセグメンテーション違反が発生するのはなぜですか?
関数 A() から関数 B() への呼び出し中に、B() は 100 文字の配列を割り当て、101 文字の文字列で 1 回、110 文字の文字列で 1 回など、数回入力します。これは明らかな間違いです。
その後、関数 A() がまったく関係のない int 変数 i にアクセスしようとすると、セグメンテーション違反が発生します。
バッファ オーバーランが発生する理由は理解できましたが、この整数にアクセスするとセグメンテーション エラーが発生するのはなぜですか? 単純にガベージ データを取得しないのはなぜですか?
c - バッファ オーバーフロー メモリ マップの解釈
ささいなバッファ オーバーフローに取り組んでいます (はい、悪用ですが、問題とは無関係です)。GCC のスタック プロテクターが有効になっているときに、メモリ マップ内のフィールドを把握しようとしています。例として:
ご覧のとおりです。バックトレースがあり、次にメモリ マップがあり、5 つのフィールドがあり、オプションで .so.1 (共有ライブラリ?) を含む 6 つ目のフィールドがあります。 16 進フィールド、および rw-p の意味など。
私はグーグルに行って検索しましたが、このようなものは何も出てきません。
ありがとう。
c++ - sprintf(buf、 "%.20g"、x)// bufの大きさはどれくらいですか?
私は次のようにdouble値を文字列に変換しています:
バッファサイズを30にハードコーディングしましたが、これがすべての場合に十分な大きさであるかどうかはわかりません。
- 必要な最大バッファーサイズを確認するにはどうすればよいですか?
- 32ビットから64ビットに切り替えると、精度が高くなりますか(したがって、バッファーを増やす必要がありますか)?
PS:使用できない、ostringstream
またはboost::lexical_cast
パフォーマンス上の理由(これを参照)
c - SecureCおよびSecureCイディオムの作成
「平均的な人は自由になりたくない。彼は単に安全になりたいだけだ。」-HLメンケン
私は非常に安全なCを書き込もうとしています。以下に、私が使用しているテクニックのいくつかをリストし、私が思うほど安全であるかどうかを尋ねます。私のコード/先入観を細かく裂くことを躊躇しないでください。最も些細な脆弱性を見つけたり、新しいアイデアを教えてくれたりする答えは、高く評価されます。
ストリームからの読み取り:
GNU Cプログラミングチュートリアルgetlineによると:
getline関数は、realloc関数を介して、必要に応じてメモリのブロックを自動的に拡大するため、スペースが不足することはありません。getlineが非常に安全である理由の1つです。[..] getlineは、入力行の長さに関係なく、入力行を安全に処理できることに注意してください。
getlineは、すべての入力で、ストリームからの読み取り時にバッファオーバーフローが発生しないようにする必要があると思います。
- 私の仮定は正しいですか?これがエクスプロイトにつながる可能性のある入力および/または割り当てスキームはありますか?たとえば、ストリームの最初の文字が奇妙な制御文字である場合、おそらく0x08 BACKSPACE(ctl-H)です。
- getlineが安全であることを数学的に証明するために何か作業が行われましたか?
Mallocは失敗時にNullを返します:
mallocでエラーが発生した場合、mallocはNULLポインターを返します。NULL(0x0)ポインターにポインター演算を適用できるため、これにはセキュリティ上のリスクがあります。したがって、ウィキペディアでは
安全なsscanf:
sscanfを使用するとき、オーバーランの可能性を回避するために、抽出する文字列のサイズを入力文字列のサイズに割り当てる習慣があります。例えば:
str1とstr2はinputStrのサイズであり、inputStrからstrlen(inputStr)を超える文字を読み取ることはできないため、inputStrのすべての可能な値がバッファオーバーフローを引き起こすことを考えると、不可能のように思われますか?
- 私は正しいですか?思いもよらなかった奇妙なコーナーケースはありますか?
- これを書くためのより良い方法はありますか?すでにそれを解決した図書館?
一般的な質問:
私はたくさんの質問を投稿しましたが、誰もがそれらすべてに答えることは期待していません。質問は、私が探している種類の回答へのガイドラインです。私は本当に安全なCの考え方を学びたいです。
- 他にどのような安全なCイディオムがありますか?
- 常にチェックする必要があるコーナーケースは何ですか?
- これらのルールを適用するための単体テストを作成するにはどうすればよいですか?
- どうすればテスト可能性または証明可能な正しい方法で制約を適用できますか?
- Cに推奨される静的/動的分析技術またはツールはありますか?
- どのような安全なCプラクティスに従い、自分自身や他の人にそれらをどのように正当化しますか?
資力:
リソースの多くは回答から借りたものです。
- DavidWheelerによるLinuxおよびUnix用の安全なプログラミングHOWTO
- セキュアCプログラミング-SUNMicrosystems
- 例による安全でないプログラミング
- NOPSをさらに追加-これらの問題をカバーするブログ
- CERTセキュアコーディングイニシアチブ
- flawfinder-静的分析ツール
- ヤニック・モイによる安全性を証明するためのThmProversの使用
- libsafe