From patchwork Tue Jan 9 20:55:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 10153429 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 82DAF60223 for ; Tue, 9 Jan 2018 21:04:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 779FE2040D for ; Tue, 9 Jan 2018 21:04:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 67CFB2097A; Tue, 9 Jan 2018 21:04:35 +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=-2.4 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, URIBL_BLACK 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 8E5682040D for ; Tue, 9 Jan 2018 21:04:33 +0000 (UTC) Received: (qmail 10175 invoked by uid 550); 9 Jan 2018 20:57:54 -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 Received: (qmail 9513 invoked from network); 9 Jan 2018 20:57:31 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=2oFLI4X1ilmxemH/4XjXppVnrV7fjSHhztuC+ulSYuk=; b=TQoGVYbJthHZoqJHs2EN/3r1Kexh55hQKSXUqAYd/e8qjvp+nWqZxggHkYJsEl7kHm OAqWc02RvnFgw9UKnzxkLL7d9dZF51K9CI1j9gjGkCueSf8eLtWNUTDkncL5w3Awtx7I hMQ67CkXKFMYKzBrBXM3UJZra2UF535zjKMRc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=2oFLI4X1ilmxemH/4XjXppVnrV7fjSHhztuC+ulSYuk=; b=MLfMcH7hMPkrR91IqrMHUrm14M8oBjsO+Ojf8kd+J8Vi4cpXpWaHon0VT6wkNgyen9 3DnvnlM6kViwO0oSF1BfOnF/Jx0eib7frqNLoXvmJ7wFkXOCPF7Z3e5+yQLQvcA7LRwE 7t3Q+HFlhSp0cLLoZ30lFf8CUv0GB2sILYmpfgYBuYDx0IAaiP3js+FB3h+C/EBoaU4N A0bntNStF3BDPClHG5MC9imJhxNAFiqvTxHP4zxHfiLiIrp394iQhcveex5kQQbWnSzy JP+qAMvh1wCtynJiALILfduSZfLixHnenqX2+Jbu2ZwvoN0wmURXrRDkDouO0DXNM/R2 4Qjw== X-Gm-Message-State: AKGB3mK8VxuqSZLNIlJ2J+RUVMmhQCjUCHD2ZnYEr9zq6ZwcNMH8AvgE eiLRBZ2/wZ8Dl6fFhN55baJ/QQ== X-Google-Smtp-Source: ACJfBotOrZsehmHNiN1yMFB82lLcJvQFgDtlu6xe5rZYYKz8yPHQvtpuFx7a/kU8DtwJ8vqlfjN+PQ== X-Received: by 10.84.241.12 with SMTP id a12mr9012356pll.115.1515531439841; Tue, 09 Jan 2018 12:57:19 -0800 (PST) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , David Windsor , "Theodore Ts'o" , Andreas Dilger , linux-ext4@vger.kernel.org, Linus Torvalds , Alexander Viro , Andrew Morton , Andy Lutomirski , Christoph Hellwig , Christoph Lameter , "David S. Miller" , Laura Abbott , Mark Rutland , "Martin K. Petersen" , Paolo Bonzini , Christian Borntraeger , Christoffer Dall , Dave Kleikamp , Jan Kara , Luis de Bethencourt , Marc Zyngier , Rik van Riel , Matthew Garrett , linux-fsdevel@vger.kernel.org, linux-arch@vger.kernel.org, netdev@vger.kernel.org, linux-mm@kvack.org, kernel-hardening@lists.openwall.com Date: Tue, 9 Jan 2018 12:55:39 -0800 Message-Id: <1515531365-37423-11-git-send-email-keescook@chromium.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515531365-37423-1-git-send-email-keescook@chromium.org> References: <1515531365-37423-1-git-send-email-keescook@chromium.org> Subject: [kernel-hardening] [PATCH 10/36] ext4: Define usercopy region in ext4_inode_cache slab cache X-Virus-Scanned: ClamAV using ClamSMTP From: David Windsor The ext4 symlink pathnames, stored in struct ext4_inode_info.i_data and therefore contained in the ext4_inode_cache slab cache, need to be copied to/from userspace. cache object allocation: fs/ext4/super.c: ext4_alloc_inode(...): struct ext4_inode_info *ei; ... ei = kmem_cache_alloc(ext4_inode_cachep, GFP_NOFS); ... return &ei->vfs_inode; include/trace/events/ext4.h: #define EXT4_I(inode) \ (container_of(inode, struct ext4_inode_info, vfs_inode)) fs/ext4/namei.c: ext4_symlink(...): ... inode->i_link = (char *)&EXT4_I(inode)->i_data; example usage trace: readlink_copy+0x43/0x70 vfs_readlink+0x62/0x110 SyS_readlinkat+0x100/0x130 fs/namei.c: readlink_copy(..., link): ... copy_to_user(..., link, len) (inlined into vfs_readlink) generic_readlink(dentry, ...): struct inode *inode = d_inode(dentry); const char *link = inode->i_link; ... readlink_copy(..., link); In support of usercopy hardening, this patch defines a region in the ext4_inode_cache slab cache in which userspace copy operations are allowed. This region is known as the slab cache's usercopy region. Slab caches can now check that each dynamically sized copy operation involving cache-managed memory falls entirely within the slab's usercopy region. This patch is modified from Brad Spengler/PaX Team's PAX_USERCOPY whitelisting code in the last public patch of grsecurity/PaX based on my understanding of the code. Changes or omissions from the original code are mine and don't reflect the original grsecurity/PaX code. Signed-off-by: David Windsor [kees: adjust commit log, provide usage trace] Cc: "Theodore Ts'o" Cc: Andreas Dilger Cc: linux-ext4@vger.kernel.org Signed-off-by: Kees Cook --- fs/ext4/super.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 7c46693a14d7..57a8fa451d3e 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1036,11 +1036,13 @@ static void init_once(void *foo) static int __init init_inodecache(void) { - ext4_inode_cachep = kmem_cache_create("ext4_inode_cache", - sizeof(struct ext4_inode_info), - 0, (SLAB_RECLAIM_ACCOUNT| - SLAB_MEM_SPREAD|SLAB_ACCOUNT), - init_once); + ext4_inode_cachep = kmem_cache_create_usercopy("ext4_inode_cache", + sizeof(struct ext4_inode_info), 0, + (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD| + SLAB_ACCOUNT), + offsetof(struct ext4_inode_info, i_data), + sizeof_field(struct ext4_inode_info, i_data), + init_once); if (ext4_inode_cachep == NULL) return -ENOMEM; return 0;