From patchwork Fri Jan 12 00:47:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 10160263 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 17C7E60327 for ; Fri, 12 Jan 2018 11:30:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0612028987 for ; Fri, 12 Jan 2018 11:30:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EE8B02898F; Fri, 12 Jan 2018 11:30:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id EE78C28987 for ; Fri, 12 Jan 2018 11:30:27 +0000 (UTC) Received: (qmail 20092 invoked by uid 550); 12 Jan 2018 11:29:10 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Delivered-To: moderator for kernel-hardening@lists.openwall.com Received: (qmail 24447 invoked from network); 12 Jan 2018 00:56:01 -0000 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,346,1511856000"; d="scan'208";a="166114769" From: Dan Williams To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, kernel-hardening@lists.openwall.com, Jan Kara , tglx@linutronix.de, torvalds@linux-foundation.org, akpm@linux-foundation.org, Elena Reshetova , alan@linux.intel.com Date: Thu, 11 Jan 2018 16:47:35 -0800 Message-ID: <151571805555.27429.728109914195885407.stgit@dwillia2-desk3.amr.corp.intel.com> In-Reply-To: <151571798296.27429.7166552848688034184.stgit@dwillia2-desk3.amr.corp.intel.com> References: <151571798296.27429.7166552848688034184.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.17.1-9-g687f MIME-Version: 1.0 Subject: [kernel-hardening] [PATCH v2 13/19] udf: prevent bounds-check bypass via speculative execution X-Virus-Scanned: ClamAV using ClamSMTP Static analysis reports that 'eahd->appAttrLocation' and 'eahd->impAttrLocation' may be a user controlled values that are used as data dependencies for calculating source and destination buffers for memmove operations. In order to avoid potential leaks of kernel memory values, block speculative execution of the instruction stream that could issue further reads based on invalid 'aal' or 'ial' values. Based on an original patch by Elena Reshetova. Cc: Jan Kara Signed-off-by: Elena Reshetova Signed-off-by: Dan Williams --- fs/udf/misc.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/fs/udf/misc.c b/fs/udf/misc.c index 401e64cde1be..693e24699928 100644 --- a/fs/udf/misc.c +++ b/fs/udf/misc.c @@ -22,6 +22,7 @@ #include "udfdecl.h" #include +#include #include #include @@ -51,6 +52,8 @@ struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size, int offset; uint16_t crclen; struct udf_inode_info *iinfo = UDF_I(inode); + uint8_t *ea_dst, *ea_src; + uint32_t aal, ial; ea = iinfo->i_ext.i_data; if (iinfo->i_lenEAttr) { @@ -100,33 +103,34 @@ struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size, offset = iinfo->i_lenEAttr; if (type < 2048) { - if (le32_to_cpu(eahd->appAttrLocation) < - iinfo->i_lenEAttr) { - uint32_t aal = - le32_to_cpu(eahd->appAttrLocation); - memmove(&ea[offset - aal + size], - &ea[aal], offset - aal); + aal = le32_to_cpu(eahd->appAttrLocation); + ea_dst = array_ptr(ea, offset - aal + size, + iinfo->i_lenEAttr); + ea_src = array_ptr(ea, aal, iinfo->i_lenEAttr); + if (ea_dst && ea_src) { + memmove(ea_dst, ea_src, offset - aal); offset -= aal; eahd->appAttrLocation = cpu_to_le32(aal + size); } - if (le32_to_cpu(eahd->impAttrLocation) < - iinfo->i_lenEAttr) { - uint32_t ial = - le32_to_cpu(eahd->impAttrLocation); - memmove(&ea[offset - ial + size], - &ea[ial], offset - ial); + + ial = le32_to_cpu(eahd->impAttrLocation); + ea_dst = array_ptr(ea, offset - ial + size, + iinfo->i_lenEAttr); + ea_src = array_ptr(ea, ial, iinfo->i_lenEAttr); + if (ea_dst && ea_src) { + memmove(ea_dst, ea_src, offset - ial); offset -= ial; eahd->impAttrLocation = cpu_to_le32(ial + size); } } else if (type < 65536) { - if (le32_to_cpu(eahd->appAttrLocation) < - iinfo->i_lenEAttr) { - uint32_t aal = - le32_to_cpu(eahd->appAttrLocation); - memmove(&ea[offset - aal + size], - &ea[aal], offset - aal); + aal = le32_to_cpu(eahd->appAttrLocation); + ea_dst = array_ptr(ea, offset - aal + size, + iinfo->i_lenEAttr); + ea_src = array_ptr(ea, aal, iinfo->i_lenEAttr); + if (ea_dst && ea_src) { + memmove(ea_dst, ea_src, offset - aal); offset -= aal; eahd->appAttrLocation = cpu_to_le32(aal + size);