Received: by 2002:a4a:be92:0:0:0:0:0 with SMTP id o18csp3116617oop; Mon, 18 Feb 2019 18:36:20 -0800 (PST) X-Google-Smtp-Source: AHgI3IZY7i8/WHBB69bATAyySULkzsYWph9j2Cz9CkSWq/lbn/2UFMT4fOKE2Vaieol39EUqALf5 X-Received: by 2002:a63:3548:: with SMTP id c69mr22164367pga.256.1550543780830; Mon, 18 Feb 2019 18:36:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550543780; cv=none; d=google.com; s=arc-20160816; b=GlINDh7v2q0hYJV8OdwFRgtWo2baFqB15+tktWaOjvBmp/6lo0AW5hhl7HktdlA/C8 cvDCb7nDWM3laRtcJ8pvuKZAASkU7m8P2XGuX9uH6f9hIRxbk8qKtCrTqwRTWiIfaJM9 1YqBwQqWijEhm9XJVOFE4ToOyxqGTyz9otb5VW0RmtMAIwHPlkI4mIbyP9h9cZHA9f3d 2/BN+VSgCtVGZJHv4YpSl1ZPsiGo7xiwu3yMAIHzd49PvQJJgWkEyD6CbLz56vfcn49M f4zhi43kk48DxKCwH246ts29SuaTXdbgmxSK371Odz5wJm2LOCYPyzwHH2wffCPjESDl KRcg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=8pVz6FJ96A6Mg/efqtfL2WLsrGV40vW25C2TmBPmZUU=; b=XzxUqBPKp4EUoPGdfTahSotYPCLjyeGFXPSjM6UswYICTlvbUQmzAMv1amm/K44cjx upATSCn6F/PpncA7VVTnXGNn9LkY+uios53xiAVbRyEVMgPTLyNWBpnMcE+zNP5/MSjt z3SxZ4GAKeRPpUKt+r1W0Kb1Mx/B4O23sS21aV0VKB8IyeC6is+Bi7AB10Uu3hFo9cQV VrY8ik+Mp/Jz0oATFLW0mcqTrY5jczcxxtMHagkz+Grr3wekykSgeV+Tp3sopZi0PtQ2 ayDfc6IfwddNx9o8eIYW1imY+4bcxtMXKVCZ+PH2tW6ONr00hftxYCf23nE+qXGMXze6 B/nw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b="YT1/bCEe"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e4si17259133plk.300.2019.02.18.18.36.05; Mon, 18 Feb 2019 18:36:20 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b="YT1/bCEe"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730393AbfBRVNk (ORCPT + 99 others); Mon, 18 Feb 2019 16:13:40 -0500 Received: from mail-ot1-f68.google.com ([209.85.210.68]:42018 "EHLO mail-ot1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726302AbfBRVNk (ORCPT ); Mon, 18 Feb 2019 16:13:40 -0500 Received: by mail-ot1-f68.google.com with SMTP id i5so30614285oto.9 for ; Mon, 18 Feb 2019 13:13:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=8pVz6FJ96A6Mg/efqtfL2WLsrGV40vW25C2TmBPmZUU=; b=YT1/bCEeB16qk/gFF6vwA2aVnGQ83rJp49XSYWfgdjGU0f+1WL+MwOHRQR5+XF5MvB YnEfUTVQc6GQy5Om4T7RDoO4SG4pvomT+iGeoPdR1K0mpG3LWFQP+OOkVxLYb2h0v+wj Y57ZYR0HZV2Jcw46SjcQW6qlEiN90TD37S+dhvLIhChwag91vwAg/X0pSwFXngAB+UUB 03FHfyMtXJbqVtTACMi8pu/evwpCzF2hXk5VAMCsu2G6m62/6ZZJejm/QNmb6v+hT/Rd Gwpvt4BuAtumx7lG2I6wlH6dC7jYYmkdUUG4abb8Y//zHKyuBI6Gb9RFNOicDGEaQ2Wc tX9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=8pVz6FJ96A6Mg/efqtfL2WLsrGV40vW25C2TmBPmZUU=; b=j/6+vvHc8S0KhjhS2ERUT6p7A+T9kgWnRQSdmJWQgUlUayZ05sRqEcjTAnTqyg/W2U l5NH2v6tfoscRGX6PjnBKKeFvgRnsvVcL6D/K/EMdukcn0bOKmMoFAxdwG1JDk8FzHMO wsOcnf/mf0tkQWYKSK43/N1d8bPbRfF5m51fMeQ4/MUV3tt30bH2NCiPrJ9K5aSQ9vO1 wUoYbHvhVQqfN8UOFtA3eNGrI6CNL9+sur43/FgqqnYJL49XxkSPEXxoNHWwcacHxyke aK4rhJmRBx8N6P0edCUW7QuLJAudgd8JKBwEOtjdHagamU120VnQMH9+Gj0PoX52kk4S 6kSQ== X-Gm-Message-State: AHQUAuZAsYdeYYOFxJW1FoD3OibpM2I2KoMu8DOvMSg+XN/+9V55Jo8G s3RN5F7/1xt2JNqiUvaxGG0vK0qB0ZK9OQurNmlD+g== X-Received: by 2002:a9d:6c84:: with SMTP id c4mr8819071otr.242.1550524418806; Mon, 18 Feb 2019 13:13:38 -0800 (PST) MIME-Version: 1.0 References: <20190215235901.23541-1-baloo@gandi.net> <4F2693EA-1553-4F09-9475-781305540DBC@amacapital.net> <20190216234702.GP2217@ZenIV.linux.org.uk> <20190217034121.bs3q3sgevexmdt3d@khany> <20190217042201.GU2217@ZenIV.linux.org.uk> In-Reply-To: From: Jann Horn Date: Mon, 18 Feb 2019 22:13:12 +0100 Message-ID: Subject: Re: [PATCH] x86: uaccess: fix regression in unsafe_get_user To: Andy Lutomirski Cc: Thomas Gleixner , Al Viro , Arthur Gautier , "the arch/x86 maintainers" , Ingo Molnar , Borislav Petkov , kernel list , Pascal Bouchareine Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Feb 18, 2019 at 8:15 PM Andy Lutomirski wrote: > On Mon, Feb 18, 2019 at 5:04 AM Thomas Gleixner wrote: > > > Another would be to have the buffer passed to flush_buffer() (i.e. > > > the callback of decompress_fn) allocated with 4 bytes of padding > > > past the part where the unpacked piece of data is placed for the > > > callback to find. As in, > > > > > > diff --git a/lib/decompress_inflate.c b/lib/decompress_inflate.c > > > index 63b4b7eee138..ca3f7ecc9b35 100644 > > > --- a/lib/decompress_inflate.c > > > +++ b/lib/decompress_inflate.c > > > @@ -48,7 +48,7 @@ STATIC int INIT __gunzip(unsigned char *buf, long len, > > > rc = -1; > > > if (flush) { > > > out_len = 0x8000; /* 32 K */ > > > - out_buf = malloc(out_len); > > > + out_buf = malloc(out_len + 4); > > > > +8 actually. > > > > > } else { > > > if (!out_len) > > > out_len = ((size_t)~0) - (size_t)out_buf; /* no limit */ > > > > > > for gunzip/decompress and similar ones for bzip2, etc. The contents > > > layout doesn't have anything to do with that... > > > > Right. That works nicely. > > > > This seems like it's just papering over the underlying problem: with > Jann's new checks in place, strncpy_from_user() is simply buggy. Does > the patch below look decent? It's only compile-tested, but it's > conceptually straightforward. Nit: The "This could be optimized" comment has unbalanced parentheses around it. Nit: Maybe switch the order of "max" and "IS_UNALIGNED(src+res)" in the loop for unaligned prefix, or tell the compiler that "max" is likely to be non-zero? That might be a tiny bit more efficient in the aligned case? But I don't know much about making code fast, so feel free to ignore this. I think there is still similar code in some other places in arch/x86; back when I did the conversion to _ASM_EXTABLE_UA, I stumbled over a few similar-looking things. In particular: load_unaligned_zeropad() (used in some VFS code that looks pretty performance-critical) still uses _ASM_EXTABLE for reading from kernel memory; it has a comment saying: /* * Load an unaligned word from kernel space. * * In the (very unlikely) case of the word being a page-crosser * and the next page not being mapped, take the exception and * return zeroes in the non-existing part. */ csum_partial_copy_generic() uses PREFETCHT0 together with the following macro; I think this can be used on both kernel and user addresses? /* * No _ASM_EXTABLE_UA; this is used for intentional prefetch on a * potentially unmapped kernel address. */ .macro ignore L=.Lignore 30: _ASM_EXTABLE(30b, \L) .endm (That comment says "kernel address", but I wrote that, and I think what I really meant is "kernel or userspace address".) > I was hoping I could get rid of the > check-maximum-address stuff, but it's needed for architectures where > the user range is adjacent to the kernel range (i.e. not x86_64). > Jann, I'm still unhappy that this code will write up to sizeof(long)-1 > user-controlled garbage bytes in-bounds past the null-terminator in > the kernel buffer. Do you think that's worth changing, too? I don't > think it's a bug per se, but it seems like a nifty little wart for an > attacker to try to abuse. Hm. I guess it might be interesting if some code path first memsets a kernel buffer to all-zeroes, then uses strncpy_from_user() to copy into it, and then exposes the entire buffer to a different user task (or, if strncpy_from_user() was called on kernel memory, to any user task). And if the source is kernel memory (might happen e.g. via splice, there are VFS write handlers that use strncpy_from_user()), it could potentially be used to make an uninitialized memory read bug (constrained to a specific field in some slab object, or something like that) more powerful, by shoving out-of-bounds kernel data around such that it is aligned properly for the leak. So, yeah, I think if it's not too much trouble, changing that would be nice.