Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932322AbbGOKGJ (ORCPT ); Wed, 15 Jul 2015 06:06:09 -0400 Received: from youngberry.canonical.com ([91.189.89.112]:44973 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752677AbbGOJNs (ORCPT ); Wed, 15 Jul 2015 05:13:48 -0400 From: Luis Henriques To: linux-kernel@vger.kernel.org, stable@vger.kernel.org, kernel-team@lists.ubuntu.com Cc: Lennert Buytenhek , Marcel Holtmann , Luis Henriques Subject: [PATCH 3.16.y-ckt 047/185] ieee802154: Fix sockaddr_ieee802154 implicit padding information leak. Date: Wed, 15 Jul 2015 10:10:42 +0100 Message-Id: <1436951580-15977-48-git-send-email-luis.henriques@canonical.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1436951580-15977-1-git-send-email-luis.henriques@canonical.com> References: <1436951580-15977-1-git-send-email-luis.henriques@canonical.com> X-Extended-Stable: 3.16 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2961 Lines: 82 3.16.7-ckt15 -stable review patch. If anyone has any objections, please let me know. ------------------ From: Lennert Buytenhek commit 8a70cefa3037d62e7c0b6068a66675def1a330c9 upstream. The AF_IEEE802154 sockaddr looks like this: struct sockaddr_ieee802154 { sa_family_t family; /* AF_IEEE802154 */ struct ieee802154_addr_sa addr; }; struct ieee802154_addr_sa { int addr_type; u16 pan_id; union { u8 hwaddr[IEEE802154_ADDR_LEN]; u16 short_addr; }; }; On most architectures there will be implicit structure padding here, in two different places: * In struct sockaddr_ieee802154, two bytes of padding between 'family' (unsigned short) and 'addr', so that 'addr' starts on a four byte boundary. * In struct ieee802154_addr_sa, two bytes at the end of the structure, to make the structure 16 bytes. When calling recvmsg(2) on a PF_IEEE802154 SOCK_DGRAM socket, the ieee802154 stack constructs a struct sockaddr_ieee802154 on the kernel stack without clearing these padding fields, and, depending on the addr_type, between four and ten bytes of uncleared kernel stack will be copied to userspace. We can't just insert two 'u16 __pad's in the right places and zero those before copying an address to userspace, as not all architectures insert this implicit padding -- from a quick test it seems that avr32, cris and m68k don't insert this padding, while every other architecture that I have cross compilers for does insert this padding. The easiest way to plug the leak is to just memset the whole struct sockaddr_ieee802154 before filling in the fields we want to fill in, and that's what this patch does. Signed-off-by: Lennert Buytenhek Acked-by: Alexander Aring Signed-off-by: Marcel Holtmann [ luis: backported to 3.16: - file rename: net/ieee802154/socket.c -> net/ieee802154/dgram.c ] Signed-off-by: Luis Henriques --- net/ieee802154/dgram.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c index 4f0ed8780194..9c9b27be78e7 100644 --- a/net/ieee802154/dgram.c +++ b/net/ieee802154/dgram.c @@ -330,6 +330,12 @@ static int dgram_recvmsg(struct kiocb *iocb, struct sock *sk, sock_recv_ts_and_drops(msg, sk, skb); if (saddr) { + /* Clear the implicit padding in struct sockaddr_ieee802154 + * (16 bits between 'family' and 'addr') and in struct + * ieee802154_addr_sa (16 bits at the end of the structure). + */ + memset(saddr, 0, sizeof(*saddr)); + saddr->family = AF_IEEE802154; ieee802154_addr_to_sa(&saddr->addr, &mac_cb(skb)->source); *addr_len = sizeof(*saddr); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/