2016-06-07 1 views
0

저급 소켓 작업을 많이하는 iOS 앱이 있으며 최근에 IPv6 지원을 추가 한 후 앱을 실행할 때 가끔씩 발생하는 커널 패닉이 있음을 알게되었습니다. 전체 장치가 재부팅, 나는 (내 응용 프로그램에서 스택 프레임을 포함하지 않음) 비밀 정보가 많이있다 공황 파일을 얻을 수 있지만, 같은 몇 가지 중요한 일들이 여기에 표시 :소켓에 관련된 iOS 커널 패닉을 단계적으로 처리합니다.

panic(cpu 0 caller 0xffffff800f15fba0): assertion failed: se->se_flags & SEF_ATTACHED, file: /SourceCache/xnu/xnu-2784.30.7/bsd/kern/uipc_socket.c, line:  6228 
Debugger message: panic 

다행히이 모듈은 오픈 소스이며, 기본적으로 어설 인 I()가 먼저 VERIFY 확신

void 
sockaddrlist_remove(struct sockaddr_list *sl, struct sockaddr_entry *se) 
{ 
    VERIFY(se->se_flags & SEF_ATTACHED); 
    se->se_flags &= ~SEF_ATTACHED; 
    VERIFY(sl->sl_cnt != 0); 
    sl->sl_cnt--; 
    TAILQ_REMOVE(&sl->sl_head, se, se_link); 
} 

: http://opensource.apple.com//source/xnu/xnu-2782.1.97/bsd/kern/uipc_socket.c

오류가이 함수와 일치하는 것 같다 내가 여기에 가까운 버전의 코드를 발견 실패하고있다.

그러나 이것은 약간의 메모리가이 코드가 실행되기 전에 내 프로그램에 의해 손상되었을 가능성이 있음을 알려줍니다. 따라서 대부분의 메모리 손상과 마찬가지로 원인을 찾는 것이 매우 어렵습니다.

내 로깅에 따라 socket(), connect(), read() 및 write()를 비롯한 대략적인 네트워킹 호출 이후에 이런 현상이 발생하지만이 코드를 여기에 제공 할 수는 없습니다.

또 다른 정보는 IPv6에서만 발생합니다. IPv4에서는 모든 것이 문제없이 작동합니다. 그러나 나는 IPv6 코드를 문질렀으며 분명히 잘못된 것을 발견하지 못했습니다. 또한 사용자 공간에서 메모리 손상 문제로 인해 커널이 실패하게되는 것을 혼동합니다. 어쩌면 이런 일이 일어날 지 이해하면 문제를 추적하는 데 도움이 될 것입니다.

대부분의 사람들이 guard malloc을 시도하는 것이지만, 불행하게도 다른 문제가 생기면 불행히도 malloc을 사용할 수 없다고 가정합니다.

실행 중에 충돌이 발생했지만 디버거에서 멈추지 않고 전체 장치 (iPad)를 재부팅합니다.

누구든지이 까다로운 버그에 대한 검색 아이디어가있는 경우 알려 주시기 바랍니다.

편집 : 답변 중 하나의 의견에 따라

, 내가 관련 소켓 API 호출에 대한 모든 길이를 확인했고 사람들은 올바른 것 같다. 그래서 여기에 다른 문제가있는 것처럼 보입니다. 아마도 메모리를 덮어 씁니다.

"Malloc Guard Edges"를 사용해 볼 수 있었지만 문제가 발생하지 않았습니다. "Guard Malloc"은 시뮬레이터에서 작동하기 때문에 사용할 수 없으며 하드웨어와 상호 작용하는 방식 때문에 시뮬레이터에서 제대로 실행되지 않습니다.

다른 사람이 있다면 아이디어를 알려주세요.

+0

Apple에 로그인하고 'TSI'중 하나를 사용하십시오. https://developer.apple.com/support/technical/ –

+0

제안 해 주셔서 감사합니다. 나는 그것을 시도 할지도 모르지만, 그것들이 제한되어 있기 때문에 (또는 더 많은 것을 얻기 위해 돈이 드는), 나는 다른 모든 아이디어를 먼저 다 써 버리고 싶다. – Locksleyu

+0

사용자 모드에서 패닉이 발생할 수있는 경우 커널 버그입니다. 그것을보고하십시오. –

답변

2

iOS 앱의 IPv6 변경 사항이 부적절하게 발생하여 전체 휴대 전화가 재부팅됩니다.

필자의 경우 시스템 호출을 sendto() (잘못된 번호 dest_len)으로 지정했는데, 하나는 dest_addr이 가리키는 구조체의 크기와 일치하지 않습니다.이런 종류의 문제는 모든 것이 IPv4 일 때 sockaddr 구조가 모두 sockaddr_in이고 하드 코딩 할 수있는 크기가 같기 때문에 IPv6에 대한 지원을 추가 할 때 가능하지만 IPv4 및 IPv6 주소를 사용할 수있는 경우 다른 크기의 구조를 가지며 전달 된 구조에 해당하는 올바른 길이를 전달해야합니다. 특정 문제는 정확히 sendto()이 아니지만 유사한 문제 일 수 있으므로 bind()connect()을 포함하여 socklen_t을 전달해야하는 모든 시스템 호출을 확인합니다.

나는 애플의 코드가 전화를 재부팅시킬 수 있어야하고 이것이 가능하다는 사실이 애플 버그라는 것에 동의한다.

디버거가 커널 패닉에서 멈출 수는 없지만 (장치가 연결 해제되어 디버거가 중지됨) 디버깅이 중지 될 수는 있지만 디버깅을 대략적으로 알 수 있다면 단계별로 수행 할 수 있습니다 디버거에서 한 줄씩 살펴보고 커널 패닉이 발생하는 줄을 확인하십시오. 패닉이 발생하는 줄은 함수 호출이 될 것이고 (호출 내에서 패닉이 발생 함) 특정 함수 호출로 좁힐 때까지 함수 호출 내부로 들어갈 수 있고 반복 할 수 있습니다.

+0

잘못된 길이가 가능성에 대한 힌트를 주셔서 대단히 감사드립니다. 나는 벌써 벌레가 있었지만, 더 많은 거짓말이있을 수 있습니다. 그러나 마지막 단락에 대해서는 원래 게시물을 기반으로 어떤 패닉이 발생했는지 알 것 같지만 소켓 관련 변수의 상태가 그다지 중요하지 않기 때문입니다. 공황은 시간과 코드에서 임의적으로 떨어져서 실제적인 원인에서 벗어날 수 있다고 생각했습니다. – Locksleyu

+0

한 가지 질문 : 매번 struct (sockaddr_storage)를 bind()와 같은 함수에 전달할 때 X.ss_len을 사용하면 길이가 정확해야합니다. – Locksleyu

+0

@Locksleyu : 제 경우에는 문제가 시스템 호출에 대한 논쟁이었습니다. 그래서 어디에서 공황이 발생했는지 알면 유용합니다. 문제가 시스템 호출에 대한 논쟁 이외의 다른 것이라는 말입니까? – user102008

관련 문제