2012-06-26 2 views
2

네트워크 통신 관련 시스템 호출을 수정하는 Java 인터 포저를 작성 중입니다. 기본적으로 의도 한 수신자의 IP 및 포트를 수정하려고합니다.Java Interposer에서 스택 스매싱

코드는 내 컴퓨터에서 제대로 작동하지만 대학 PC에이 같은 오류을 스매싱 스택 제공 : 다음과 같이

*** stack smashing detected ***: java terminated 
======= Backtrace: ========= 
/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x45)[0xb7702dd5] 
/lib/i386-linux-gnu/libc.so.6(+0xffd8a)[0xb7702d8a] 
/home/mwaqar/vibe/ldinterposer_2.so(+0x28e4)[0xb77c98e4] 
/home/mwaqar/vibe/ldinterposer_2.so(connect+0x9c5)[0xb77c9093] 
/usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/libnet.so(+0xceff)[0x8b226eff] 
/usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/libnet.so(Java_java_net_PlainSocketImpl_socketConnect+0x4c1)[0x8b227c51] 

관련 코드를 (의 개재 시스템 호출을 연결)입니다 : 여기

int connect(int fd, const struct sockaddr *sk, socklen_t sl) 
{ 
struct sockaddr_in  *lsk_in = (struct sockaddr_in *) sk; 
struct sockaddr_in6  *lsk_in6 = (struct sockaddr_in6 *) sk; 

struct sockaddr_in  addr4; 

unsigned int   len; 
int      nbytes, oport, tport, ret, i; 
char     ip_address[30]; 
char     buffer[1024]; 
char     tempBuffer[1024]; 

if((lsk_in->sin_family == AF_INET) || (lsk_in->sin_family == AF_INET6)) 
{ 
    if(lsk_in->sin_family == AF_INET) 
    { 
     oport = ntohs(lsk_in->sin_port); 
     memcpy(&addr4.sin_addr.s_addr, &lsk_in->sin_addr.s_addr, sizeof(addr4.sin_addr.s_addr)); 
    } 
    else if(lsk_in->sin_family == AF_INET6) 
    { 
     oport = ntohs(lsk_in6->sin6_port); 
     memcpy(&addr4.sin_addr.s_addr, lsk_in6->sin6_addr.s6_addr+12, sizeof(addr4.sin_addr.s_addr)); 
    } 

    memset(buffer, '\0', sizeof(buffer)); 
    sprintf(buffer, "%s%c%s%c%i", NAT_VM_CONNECT_RULE, NAT_VM_DELIMITER, (char *)inet_ntoa(addr4.sin_addr), NAT_VM_DELIMITER, oport); 

    nbytes = send(sock, buffer, strlen(buffer), 0); 
    if(DEBUG_MODE) 
     fprintf(stdout, "[LD_INTERPOSER] Sent[%s]\n", buffer); 

    memset(buffer, '\0', sizeof(buffer)); 
    nbytes = recv(sock, buffer, sizeof(buffer), 0); 

    fprintf(stderr, "[LD_INTERPOSER] Received CONNECT [%s]\n", buffer); 

    memset(ip_address, '\0', sizeof(ip_address)); 
    int pos = strrchr(buffer, NAT_VM_DELIMITER) - buffer; 

    strncpy(ip_address, buffer, pos); 
    ip_address[pos] = '\0'; 
    tport = atoi(buffer + pos + 1); 

    if(lsk_in->sin_family == AF_INET) 
    { 
     lsk_in->sin_addr.s_addr = inet_addr(ip_address + 7); 
     lsk_in->sin_port = htons(tport); 
    } 
    else if(lsk_in->sin_family == AF_INET6) 
    { 
     inet_pton(AF_INET6, ip_address, &(lsk_in6->sin6_addr)); 
     lsk_in6->sin6_port = htons(tport); 
    } 

    fprintf(stderr, "[LD_INTERPOSER] IP[%s], Port[%d] for VM[%s]\n", ip_address, tport, vm_ip); 
} 

int my_ret = real_connect(fd, sk, sl); 
fprintf(stderr, "Done\n"); 
return my_ret; 
} 

, 양말 내가 공유 라이브러리의 "생성자"에서 초기화 한 소켓입니다.

프로그램이 올바르게 작동하고 이 출력됩니다.이 출력됩니다. 마지막 (return) 행에서 스택 스매싱 오류를 제공합니다. 나는 이것이 무엇을 일으키는 지 전혀 모른다.

+0

여기서'buffer'는 선언 되었습니까? – hmjd

+0

죄송합니다. 코드가 업데이트되었습니다. –

+0

스택 스매싱 오류는 가능한 버퍼 오버플로 오류를 확인하는 기본 제공 메커니즘으로 인해 발생합니다. 각각의 크기 인'buffer' 나'tempBuffer'에 더 많은 바이트를 쓰지 않는지 확인하십시오. – buc

답변

0

나는 줄

int pos = strrchr(buffer, NAT_VM_DELIMITER) - buffer; 

다음 pos가 큰 것에 그 strrcr 반환을 NULL 의심, 다음과 같은 라인을 읽고 잘못된 주소를 작성합니다.

항상 함수의 반환 값을 검사하십시오 (특히 프로그램 외부에서받은 데이터를 실행할 때).

또한 내 의견에 쓴대로 sprintf을 사용하지 마십시오. NAT_VM_CONNECT_RULE이 무엇인지 모르기 때문에 실패했는지 알 수 없습니다. 바이트 수를 계산해도 문제가 없다고 판단하더라도 여전히주의해야하며 snprintf을 사용해야합니다.

+0

내가 언급 한 라인이 문제라고 생각하지 않습니다. 수신 된 응답은'IP | port' 형식입니다 ('NAT_VM_DELIMITER'는 문자 '|'입니다). 나는 이것을 분리해야한다. 그 문장에 문제가 있다면, VM '[% s] \ n ", ip_address, tport, vm_ip);에 대한'fprintf (stderr,"[LD_INTERPOSER] IP [% s], 포트 [% d] 올바른 (별도의) IP 및 포트를 인쇄하십시오. 또한, 그 문장이 문제라면, 프로그램의 두 번째 마지막 문장 인'fprintf (stderr, "Done \ n");이 끝날 때까지 프로그램이 거기에서 끝났을 것이라고 생각합니다. –

+0

아마도 이것이 문제의 원인이 아니지만 버그 일 수 있습니다. 내가 보여준 두 가지 버그를 수정하고 디버깅을 시도해야합니다. – ugoren

+0

내가 언급 한 모든 버그를 수정했습니다. 여전히 똑같은'*** stack smashing detected ***'결과가 출력됩니다. –

관련 문제