***stack smashing detected**:terminated(コアダンプ)スタックオーバーフロー


ファイルgdb test coreに次の問題が発生しました.
Program terminated with signal SIGABRT, Aborted. #0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 51    ../sysdeps/unix/sysv/linux/raise.c:そのファイルやディレクトリはありません.
btを入力して詳細を表示し、上から下へ順に下位から上位へ
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007f08657c8801 in __GI_abort () at abort.c:79
#2  0x00007f0865811897 in __libc_message (action=action@entry=do_abort, 
    fmt=fmt@entry=0x7f086593e988 "*** %s ***: %s terminated
")     at ../sysdeps/posix/libc_fatal.c:181 #3  0x00007f08658bccd1 in __GI___fortify_fail_abort (     need_backtrace=need_backtrace@entry=false,      msg=msg@entry=0x7f086593e966 "stack smashing detected")     at fortify_fail.c:33 #4  0x00007f08658bcc92 in __stack_chk_fail () at stack_chk_fail.c:29 #5  0x0000560a26821d5a in updateIp () #6  0x0000560a26821efc in verifyPassword () Backtrace stopped: Cannot access memory at address 0x27313131273d77

最後に、スタックオーバーフローの開始時にこの文字列を次のように定義します.
select_userinfo_query[] ="select * from userinfo where user_no='";
strcatが追加されたときにオーバーフローする可能性があります
select_に変更userinfo_Query[200]は問題を解決することができる.
もう一つの原因は不明です.
ソースプログラムは、この関数を実行するときに終了時にのみエラーが発生し、関数体の部分が正常に動作し、関数体が実行した後に主関数が崩壊する.
理由:
gccのマニュアルを参照すると、この報告メカニズムはgccの-fstack-protectorの一連のオプションによって提供されるバッファオーバーフロー検出メカニズムである.
-fstack-protectorが有効になっている場合、バッファオーバーフローが検出されると、実行中のプログラムが直ちに終了し、バッファにオーバーフローが検出されたという問題をプロンプトします.このメカニズムは,関数内の攻撃を受けやすいターゲットコンテキストに保護変数を追加することによって達成される.これらの関数にはallcoa関数とバッファサイズが8 bytesを超える関数が含まれます.これらの保護変数は、関数に入ると初期化され、関数が終了すると検出され、一部の変数が検出に失敗すると、エラーメッセージが印刷され、現在のプロセスが終了します.
void selectUserinfo(char* user_no,Userinfo *userinfo){
    
    char select_userinfo_query[200] 
    ="select * from userinfo where user_no='";
    
	strcat(select_userinfo_query,user_no);
	strcat(select_userinfo_query,"'");
	printf("SQL  : %s
", select_userinfo_query); if(mysql_query(&conn,select_userinfo_query)!=0){ fprintf(stderr," "); }else{ if((result=mysql_store_result(&conn))==NULL){ fprintf(stderr," mysql_store_result !
"); }else{ while((row=mysql_fetch_row(result))!=NULL) { transferUserinfo(row,userinfo); showUserinfo(userinfo);// } } } }