lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20080222232350.GA17555@marcant.net>
Date:	Sat, 23 Feb 2008 00:23:50 +0100
From:	Dirk Nehring <dnehring@...cant.net>
To:	netdev@...r.kernel.org
Subject: [Patch] Crash (BUG()) when handling fragmented ESP packets

Most likely all 2.6 series kernels crash with BUG() when receives a
fragmented ESP packet where ESP header and IV are not in the first
fragment. This patches fixes this behaviour by reassembling the
fragmented packet into the sk_buff.

Signed-off-by: Dirk Nehring <dnehring@...cant.net>
Signed-off-by: Andreas Ferber <aferber@...cant.net>



Please apply this patch to 2.6.25. We tested the patch successfully on
production systems which ran into this problem.

Long description:
=================

We have come across (and fixed) a bug in the linux kernel (specifically
in the IPsec code) that has some security concerns attached. On Dec.,
12., 2007, we have contacted security@...nel.org where Herbert was also
informed.

RedHat Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=404291

Future CVE: CVE-2007-6282


BUG DESCRIPTION:
----------------

As you may know, an ESP packet starts with an ESP header (8 Octets),
depending on the encryption algorithm followed by an Initialization
Vector (eg. 16 Octets for AES-CBC, 8 Octets for 3DES-CBC). If the ESP
packet is divided into IP fragments so that the first fragment does not
contain the whole of ESP-Header plus the IV (for example only the first
8 Octets), the kernel runs into a BUG() when decoding the packet and
thus crashes instantly.

HOW TO REPRODUCE:
-----------------

To reproduce the problem you can use the following setup with three
machines:

   +----+         +----+         +----+
   | E1 |---------| IR |---------| E2 |
   +----+         +----+         +----+

 E1, E2: IPsec tunnel endpoints
 IR:     intermediate router

Setup an IPsec tunnel using 3DES-CBC or AES-CBC between E1 and E2 (I
tested it with ISAKMP keying, but it should work with manual keying
also). Now setup "IR" so that it fragments packets going from E1 to E2
into very small fragments (8 Octets each), for example using fragrouter.

Now, when you try to send some traffic through the tunnel from E1 to E2
(thus generating ESP packets), as soon as the last fragment of it has
arrived on E2, it crashes with a BUG().

Note that E1 does not have to be a linux machine, any IPsec capable
device will do.

ANALYSIS:
---------

All line numbers refer to kernel version 2.6.24-rc4.

Have a look at net/ipv4/esp4.c, function esp_input(). Starting at line
195, it tries to get the IV from the ESP packet, however it does not
take into account that the sk_buff it is handling may be paged or
fragmented. This may result in an out of bounds memory read access if
the head of the sk_buff does not contain the full ESP header plus the
IV.

Then at the end of the function, at line 268, it tries to __skb_pull()
the ESP header and IV of the packet. This is where the BUG() is
triggered, since __skb_pull() checks that there is enough data in the
sk_buff head to fulfill the pull.

When reassembling fragmented IP packets, the kernel does so using a
fragmented sk_buff (using skb->frag_list). If the first fragment is
shorter than the ESP header plus the IV, the condition to trigger the
BUG() in esp_input() is satisfied by the resulting sk_buff, thus
crashing the kernel.

The relevant code for IPv6 ESP (in net/ipv6/esp6.c) is mostly the same
as the IPv4 code, so this is affected, too.

The bug most likely exists in all 2.6 kernel versions up till today. I
explicitly checked 2.6.18 (my vendors version of that I first
encountered the bug on a few days ago) and 2.6.0. Although the code of
esp_input() changed in between, the relevant code lines exist in almost
identical form since 2.6.0 up to the latest development versions, so it
is unlikely that some version in between is unaffected by the bug.

BUGFIX:
-------

Attached you can find a patch against stable 2.6.24.1 and 2.6.25-rc2
(there are some bigger changes between 2.6.24 and 2.6.25 is the
responsible code segment). This patch modify the code in question to
correctly deal with a fragmented or paged sk_buff.

We did not test the IPv6 part of the patch, but since it is almost the
same as the IPv4 part, we are pretty confident that it will work as
advertised.

SECURITY CONCERNS:
------------------

In order to reach the code path that crashes the machine, the fragmented
ESP packet has to contain a valid SPI and must be correctly
authenticated (if authentication is used on the Policy).

Thus, you can remotely crash a vulnerable machine, if you

  (a) have control of an IPsec peer connected to it (with a valid SA
      existing)

or

  (b) have the ability to manipulate (fragment) packets going from a
      peer to the machine (note that you do not have to crack the
      encryption to do this)

An example of (b) is that if you are connecting to your company network
using an IPsec VPN from an internet cafe or WiFi hotspot, the owner of
the cafe or access point can crash your central company VPN gateway if
it is running a vulnerable version of the linux kernel.


Dirk

View attachment "2.6.24.1_esp_iv_bug.patch" of type "text/plain" (843 bytes)

View attachment "2.6.25-rc2_esp_iv_bug.patch" of type "text/plain" (901 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ