[C/C++] バッファオーバーフロー対策 -fstack-protector-allの実用性を検証

[M1 Mac, Big Sur 11.6.8, clang 13.0.0, NO IDE]

バッファオーバーフロー対策であるclang++の-fstack-protector-allオプションについて実用性を検証しました。

その結果、char変数を複数宣言した場合、その間には空白アドレスが配置されずメモリアドレスの干渉が起こることが判明しました。

配列の文字数を正しく宣言すればいいのかというとそうでもなくて、char変数の数を増やすと下位アドレス側にメモリアドレスが伸びていき、ついにはint変数のメモリ領域が上書きされる可能性があります。

この程度で破綻するようでは、実用性は低いと判断するほかないです。このオプションは使わずに、char配列の文字数を正確に宣言するのが最善かと思います。

そもそも文法的に正しいC言語を書けば問題ないのであって、下手に補完して我々プログラマを甘やかすと余計に状況が悪くなるといった感じがします。

#include <cppstd.h>

int main() {
    int i;
    char c[2];  // ここを変えて検証
    char c2[2];  // ここを変えて検証

    for (i=0;i<5;i++){
        printf("for文先頭直後 printf i: %d\n",i);
        // rewind(stdin); // ストリームバッファをクリア
        scanf("%s", &c);

        cout << "cout c: " << c << endl;
        printf("printf c: %s\n",&c);

        scanf("%s", &c2);

        cout << "cout c2: " << c2 << endl;
        printf("printf c2: %s\n",&c2);

        cout << "2回目cout c: " << c << endl;
        printf("2回目printf c: %s\n",&c);

        printf("printf i: %d\n",i);
    }
    return 0;
}
--------------------------------------------------
出力
--------------------------------------------------
for文先頭直後 printf i: 0
a
cout c: a
printf c: a
b
cout c2: b
printf c2: b
2回目cout c: a
2回目printf c: a
printf i: 0
for文先頭直後 printf i: 1
a
cout c: a
printf c: a
b
cout c2: b
printf c2: b
2回目cout c: a
2回目printf c: a
printf i: 1
for文先頭直後 printf i: 2