2014-09-05 2 views
0

이 코드의 목적은 sigterm/sigint/sigsegv/etc가 잡힐 때마다 스택 추적을 생성하는 것입니다. sigsegv의 경우 C++ 코드 내부의 메모리 관리에 의존하지 않기 위해 추적 배열에 PID 및 메모리 주소를받을 bash 스크립트를 작성하기로 결정했습니다. Sig 이벤트가 발견되었습니다. 내가 bash는 스크립트 아래아파치가 실행중인 C++ 코드에서 bash 스크립트 호출하기

trace_size = backtrace(trace, 16); 
trace[1] = (void *)ctx->rsi; 
messages = backtrace_symbols(trace, trace_size); 

char syscom[356] = {0}; 
sprintf(syscom,"bash_crash_supp.sh %d", getpid()); 
for (i=1; i<(trace_size-1) && i < 10; ++i) 
{ 
    sprintf(syscom,"%s %p",syscom,trace[i]); 
} 

내 문제가 발생하는 곳이다에 대한 호출을 생성하는 곳 바로 아래

이다. syscom의 명령이 올바르게 생성됩니다. 다음 popen 전에 코드를 중지하고 터미널에서 명령을 실행하면 올바르게 작동합니다. 그러나 C++ 코드에서 직접 스크립트를 실행해도 작동하지 않는 것 같습니다.

setuid(0); 
FILE *bashCommand = popen(syscom,"r"); 

char buf[256] = {0}; 
while(fgets(buf,sizeof(buf),bashCommand) != 0) { 
    LogMessage(LOG_WARNING, "%s\n", buf); 
} 
pclose(bashCommand); 
exit(sig); 

bash는 스크립트의 목적은/proc 디렉토리/PID /지도로부터의 오프셋 (offset), 다음 파일 이름/행 번호를 얻을은 addr2line을 실행하는 데 그것을 사용 얻을 것입니다. 나는 C++ 코드에서 실행할 때

strResult=$(sudo cat /proc/"$1"/maps | grep "target_file" | grep -m 1 '[0-9a-fA-F]') 

offset=$(cut -d '-' -f 1 <<< "$strResult"); 

는 그러나 0을 받고 오프셋,하지만 난 똑같은 명령을 실행할 때 터미널에서 (즉,이 C++ 코드에서 SYSCOM에 저장되어있는) 내가 예상되는 출력을 얻을.

나는 이것을 잠시 동안 고치려고 노력해 왔습니다. 권한은 대부분 문제가 될 수 있지만 Google을 통해 본 모든 방식으로 해결해야했습니다. 스크립트를 실행하려는 사용자 (현재 C++ 코드를 실행 중)는 apache입니다.

수정 프로그램은 상자의 보안에 대해 걱정할 필요가 없습니다. "chmod 777/proc -r"과 같이 간단한 것이 있다면, 해결책이 될 것입니다 (슬프게도 OS는/proc 명령으로 그런 명령을 내버려 두지 않습니다).

것 이미 시도했다 :

  • 가 bash_crash_supp.sh 스크립트에
  • chmod를 4755을 아파치 스크립트를 chown하지는 C++ 코드
  • 에서 SYSCOM에 저장된 명령 주위에``추가 , 루트로서 항상 발사되도록합니다.
  • 나는
  • I 상기와 같은 않는 그들을
  • 내가 (단지의 경우) sudoers.d하는 하위 파일을 추가 한 암호를 사용하지 않고는 sudo를 실행할 수 있도록의 sudoers (visudo를)에 아파치를 추가 한 objdump를 살펴 봤지만 오프셋이나 파일/줄 번호를 addr (내가 볼 수있는 것)으로 보지 않았습니다.
  • 현재 사용자를 root로 설정하는 C++ 코드에 setuid (0)가 있습니다.

C++에서 생성 된 명령
bash_crash_supp.SH 25817 bash는 0x7f4bfe600ec8 0x7f4bf28f7400 0x7f4bf28f83c6 0x7f4bf2904f02 0x7f4bfdf0fbb0 0x7f4bfdf1346e 0x7f4bfdf1eb30 0x7f4bfdf1b9a8 0x7f4bfdf176b8

에 Params를 :
25,817 0x7f4bfe600ec8 0x7f4bf28f7400 0x7f4bf28f83c6 0x7f4bf2904f02 0x7f4bfdf0fbb0 0x7f4bfdf1346e 0x7f4bfdf1eb30 0x7f4bfdf1b9a8 0x7f4bfdf176b8

사람은이 문제를 해결하기 위해 다른 방법을 생각 할 수 있습니까?

+0

1) shabang는 무엇과 2)'에코 같습니다!

자세한 내용은 유닉스 StackExchange에이 질문을 참조 $ * "'를 쉘 스크립트에 입력하고 결과를 게시하십시오. –

+0

#!/bin/bash는 맨 위에있는 shabang입니다. params의 메아리와 C++ 코드에서 생성되는 명령을 추가했습니다. – rebnat

+0

'strResult'에는 무엇이 들어 있습니까? 'echo "$ {strResult}"'를 실행하고 게시 할 수 있습니까? 문제가 잘못된 명령을 실행하거나 잘못된 결과를 얻는 경우 범위를 좁히기 위해 노력하고 있습니다. –

답변

1

거의 모든 유닉스 기반 시스템은 보안상의 이유로 모든 인터프리터 스크립트 (shebang이 인 것)에서 setuid을 무시합니다.

실제 실행 파일에는 setuid을 사용할 수 있지만 셸 스크립트 자체는 사용할 수 없습니다. 을 방치하여 보안 위험이있는 경우 랩퍼 을 실행하여 셸 스크립트를 실행하고 실행 파일 setuid을 제공 할 수 있습니다. "는`bash_crash_supp.sh` 스크립트)`(라인이`#을 시작 https://unix.stackexchange.com/a/2910

관련 문제