ルール
防止 共通 セグメンテーション フォールト パターン
ヌル ポインタ を参照しない、 バッファ オーバーフロー、
そして 後フリー使用 エラー 原因 クラッシュ そして セキュリティの脆弱性 脆弱性の原因となります。
対応言語 C/C++はじめに
セグメンテーション・フォールトは、C/C++アプリケーションのクラッシュや悪用可能な脆弱性の最も一般的な原因である。これらのメモリ・アクセス違反は、コードが所有していないメモリを読み書きしようとしたときに発生します。一般的には、ヌル・ポインタ・デリファレンス、バッファ・オーバーフロー、ダングリング・ポインタ、解放されたメモリへのアクセスなどです。単一のセグメ ント・フォールトが本番サーバーをダウンさせることもありますが、さらに悪いことに、多くのセグメ ント・フォールト・パターンが任意のコード実行に悪用可能です。
なぜそれが重要なのか
セキュリティへの影響バッファ・オーバーフローとuse-after-free脆弱性は、ほとんどのメモリ破壊悪用の基盤である。攻撃者はこれらを利用して、リターンアドレスを上書きしたり、シェルコードを注入したり、プログラムの制御フローを操作したりする。2014年のHeartbleed脆弱性はバッファ・オーバーリードだった。現代のエクスプロイトは、攻撃者に直接メモリ・アクセスを提供するため、依然としてこれらのパターンを標的にしている。
システムの安定性: セグメンテーション・フォールトは、アプリケーションを即座にクラッシュさせる。本番システムでは、これはリクエストの取りこぼし、トランザクションの中断、状態の破損を意味する。捕捉可能な高レベル言語の例外とは異なり、セグメンテーション・フォールトはプロセスを終了させるため、再起動やリカバリ手順が必要になります。攻撃対象の拡大: チェックされていないポインタの再参照、 strcpy, memcpyまた、境界チェックを行わない配列アクセスは、悪用の入り口となる可能性がある。攻撃者はこれらの脆弱性を連鎖的に利用し、ある脆弱性を利用して別の脆弱性を悪用できるようにメモリを破壊する。
コード例
非準拠:
void process_user_data(const char* input) {
char buffer[64];
strcpy(buffer, input); // No bounds checking
char* token = strtok(buffer, ",");
while (token != NULL) {
process_token(token);
token = strtok(NULL, ",");
}
}
int* get_config_value(int key) {
int* value = (int*)malloc(sizeof(int));
*value = lookup_config(key);
return value; // Caller must free, but no documentation
}なぜ危険なのか: 会社情報 strcpy() の呼び出しは、入力が63バイトを超えるとバッファオーバーフローを引き起こし、攻撃者にスタックメモリを上書きさせる。そのため get_config_value() 関数が呼び出されるたびにメモリがリークし、他のコードがまだそのメモリを参照している間に呼び出し元がメモリを解放すると、ぶら下がりポインタのリスクが発生する。
✅ 準拠:
void process_user_data(const char* input) {
if (!input) return;
size_t input_len = strlen(input);
char* buffer = malloc(input_len + 1);
if (!buffer) return;
strncpy(buffer, input, input_len);
buffer[input_len] = '\0';
char* token = strtok(buffer, ",");
while (token != NULL) {
process_token(token);
token = strtok(NULL, ",");
}
free(buffer);
}
int get_config_value(int key, int* out_value) {
if (!out_value) return -1;
*out_value = lookup_config(key);
return 0; // Caller owns out_value memory
}なぜ安全なのか: ヌル・ポインタのチェックにより、非参照クラッシュを防止。動的アロケーションにより、固定バッファサイズの制限を排除。による境界チェック付きコピー strncpy() はオーバーフローを防ぐ。の所有権セマンティクスをクリアする。 get_config_value() 呼び出し元がメモリを提供する場合、割り当ての混乱やリークを避けることができる。
結論
CとC++におけるメモリ安全性は、ポインタ操作とメモリ割り当てのたびに防御的なプログラミングを必要とする。セグメンテーション・フォールトは避けられないものではなく、一貫したヌル・チェック、境界の検証、明確なメモリ所有権のパターンによって防ぐことができる。これらのパターンを本番前にキャッチすることで、クラッシュと悪用可能な脆弱性の両方を防ぐことができる。
.avif)
