1

次のスニペットを試すと、stack smashing detected というエラーが表示されます。この潜在的なバグの理由は何ですか? 誰か説明できますか?

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int glob=88;
int main()
{
    int loc=2;
    pid_t pid=vfork();
    if(pid==0)
    {
        printf("Inside child");
        glob++;
        loc++;
        printf("%d %d" ,glob,loc);
    }
    else
    {
        printf("Inside parent");
        glob++;
        loc++;
        printf("%d %d",glob,loc);
    }
}

このコードを実行したときの出力はそのようなものです

user018@sshell ~ $ gcc one.c
user018@sshell ~ $ ./a.out
Inside child89 3Inside parent90 945733057*** stack smashing detected ***: a.out
- terminated
a.out: stack smashing attack in function <unknown> - terminated
KILLED
4

3 に答える 3

1

Linux の man ページ(および POSIX)から:

vfork() 関数は fork(2) と同じ効果がありますが、vfork() によって作成されたプロセスが vfork() からの戻り値を格納するために使用される pid_t 型の変数以外のデータを変更した場合の動作は未定義です。 、または vfork() が呼び出された関数から戻るか、または _exit(2) または関数の exec(3) ファミリの 1 つを正常に呼び出す前に、他の関数を呼び出します。

データを変更し、呼び出された関数から戻っていvforkます。これらは両方とも、未定義の動作につながります。vforkは と同等ではありません。d 子forkでできることの数はvfork非常に限られています。これは、非常に特殊な状況でのみ使用する必要があります。基本的に、子供に対して行う必要があるのは他のことだけである場合execです。

詳細については、オペレーティング システムのマニュアル ページを参照してください。

于 2013-07-29T05:39:11.663 に答える
1

vfork()親プロセスのページテーブルをコピーせずに新しいプロセスを作成するために使用されます。したがって、子プロセスの変数はもう存在しないため、変更できません。fork()代わりに使用してください。

もう 1 つ、行はデフォルトでバッファリングされるため\n、末尾にa を追加することをお勧めします。printf()stdout

于 2013-07-29T05:39:37.423 に答える
0

1)「int main()」を宣言したので、間違いなく「return 0」を追加します。

2) 警告を無効にしたい場合-fno-stack-protectorは、コンパイル行で使用します。

3) エラーの原因をデバッグしたい場合は、コンパイル行で「-g」を使用し、(./a.out を実行する代わりに) gdb からプログラムを実行します。

「何が問題なのか」に最も近いのは、vfork() に関する次の man ページです。

http://linux.die.net/man/3/vfork

vfork() 関数は、vfork() によって作成されたプロセスが、vfork() からの戻り値を格納するために使用されるタイプ pid_t の変数以外のデータを変更する場合の動作が未定義であることを除いて、fork() と同等でなければなりません。 vfork() が呼び出された関数から戻るか、_exit() または関数の exec ファミリの 1 つを正常に呼び出す前に、他の関数を呼び出します。

Linux の場合は、「fork()」を使用するだけで、満足していただけると思います :)

于 2013-07-29T05:39:44.100 に答える