From patchwork Thu Nov 30 17:43:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kleber Sacilotto de Souza X-Patchwork-Id: 843128 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 3ynlB74cXSz9t2x; Fri, 1 Dec 2017 04:43:27 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1eKSrr-0005DA-DA; Thu, 30 Nov 2017 17:43:23 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1eKSrp-0005Co-Tb for kernel-team@lists.ubuntu.com; Thu, 30 Nov 2017 17:43:21 +0000 Received: from mail-wr0-f197.google.com ([209.85.128.197]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1eKSrp-0007Q8-MR for kernel-team@lists.ubuntu.com; Thu, 30 Nov 2017 17:43:21 +0000 Received: by mail-wr0-f197.google.com with SMTP id v69so4325302wrb.3 for ; Thu, 30 Nov 2017 09:43:21 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=jSiLSpwkuV0vAjwRkozRGMbrTKZEgRG45DbSxx39nFo=; b=aJilnPRIk/OkypN3H6kP73hgKiayh1syb4tfXh/OXIyc4Y0bQwgyZPE7yfweGW2hjW u7T3+GGrz0o9IPwDE2zWcwIs5Xq8QKFleSgg9VVbK8/4MlX4tBOV4aWSzxuq3UGxQo96 edPhQ8noDTLK/+ORl4vFWt4TGng5JNgZFWJs7R5GYtpUDAyz24ZWWqDEcrBDZqgzOQS6 undSBFp+Q64xbWcj1BEisepGwFDummKXzhCx+AVwR1lXiFzhLPhYIYd0efBSRtj5fLl6 shDA6UxdQMjwBYHQeGiN8EjU6PkTYXwJfY/32SVXZwdOgHFU9NhvwFBxyZpsAYmwEuxL V0kA== X-Gm-Message-State: AJaThX7LygLJvksGaUail7L34fIW/+caFc8Jc5/N9NVlZM2hgNimMgji PQ0MkC+AsPddmCgsTYW13d3ZKb+RuCxk8olL7Tgk7tqTD6sy2QjIdyizb9FOMXYWf1ig8IRxtIt xxIKORqcEe3RBgokVymDRjIw/ZcGxe7F5MZKKu395aA== X-Received: by 10.80.224.65 with SMTP id g1mr14225612edl.264.1512063801053; Thu, 30 Nov 2017 09:43:21 -0800 (PST) X-Google-Smtp-Source: AGs4zMYsL7oydTHyyN8SBHnTidIgtc82naWjxZqQAq2MSDCyzNpS7zd+4kYivprSGX11HYchIKD1ww== X-Received: by 10.80.224.65 with SMTP id g1mr14225589edl.264.1512063800812; Thu, 30 Nov 2017 09:43:20 -0800 (PST) Received: from localhost ([2a02:8109:98c0:1604:d93c:6a88:7e3b:ea29]) by smtp.gmail.com with ESMTPSA id f9sm2841620edm.83.2017.11.30.09.43.19 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 30 Nov 2017 09:43:19 -0800 (PST) From: Kleber Sacilotto de Souza To: kernel-team@lists.ubuntu.com Subject: [SRU][Trusty][PATCH 1/1] ipc/shm: Fix shmat mmap nil-page protection Date: Thu, 30 Nov 2017 18:43:15 +0100 Message-Id: <20171130174315.2101-2-kleber.souza@canonical.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171130174315.2101-1-kleber.souza@canonical.com> References: <20171130174315.2101-1-kleber.souza@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Davidlohr Bueso The issue is described here, with a nice testcase: https://bugzilla.kernel.org/show_bug.cgi?id=192931 The problem is that shmat() calls do_mmap_pgoff() with MAP_FIXED, and the address rounded down to 0. For the regular mmap case, the protection mentioned above is that the kernel gets to generate the address -- arch_get_unmapped_area() will always check for MAP_FIXED and return that address. So by the time we do security_mmap_addr(0) things get funky for shmat(). The testcase itself shows that while a regular user crashes, root will not have a problem attaching a nil-page. There are two possible fixes to this. The first, and which this patch does, is to simply allow root to crash as well -- this is also regular mmap behavior, ie when hacking up the testcase and adding mmap(... |MAP_FIXED). While this approach is the safer option, the second alternative is to ignore SHM_RND if the rounded address is 0, thus only having MAP_SHARED flags. This makes the behavior of shmat() identical to the mmap() case. The downside of this is obviously user visible, but does make sense in that it maintains semantics after the round-down wrt 0 address and mmap. Passes shm related ltp tests. Link: http://lkml.kernel.org/r/1486050195-18629-1-git-send-email-dave@stgolabs.net Signed-off-by: Davidlohr Bueso Reported-by: Gareth Evans Cc: Manfred Spraul Cc: Michael Kerrisk Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds CVE-2017-5669 (cherry picked from commit 95e91b831f87ac8e1f8ed50c14d709089b4e01b8) Signed-off-by: Kleber Sacilotto de Souza Acked-by: Colin Ian King Acked-by: Po-Hsu Lin --- ipc/shm.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/ipc/shm.c b/ipc/shm.c index d7805acb44fd..06ea9ef7f54a 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -1091,8 +1091,8 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) * "raddr" thing points to kernel space, and there has to be a wrapper around * this. */ -long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, - unsigned long shmlba) +long do_shmat(int shmid, char __user *shmaddr, int shmflg, + ulong *raddr, unsigned long shmlba) { struct shmid_kernel *shp; unsigned long addr; @@ -1113,8 +1113,13 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, goto out; else if ((addr = (ulong)shmaddr)) { if (addr & (shmlba - 1)) { - if (shmflg & SHM_RND) - addr &= ~(shmlba - 1); /* round down */ + /* + * Round down to the nearest multiple of shmlba. + * For sane do_mmap_pgoff() parameters, avoid + * round downs that trigger nil-page and MAP_FIXED. + */ + if ((shmflg & SHM_RND) && addr >= shmlba) + addr &= ~(shmlba - 1); else #ifndef __ARCH_FORCE_SHMLBA if (addr & ~PAGE_MASK)