Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp6672703imu; Wed, 30 Jan 2019 20:26:29 -0800 (PST) X-Google-Smtp-Source: ALg8bN4GR4lXckCtqVYxkyVR7xq9FtuPUGafOkIixwVp/5w1oLzKk2MIOlaFGfWt+/sjpAHMgQUT X-Received: by 2002:a17:902:8a8a:: with SMTP id p10mr33698432plo.50.1548908789520; Wed, 30 Jan 2019 20:26:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548908789; cv=none; d=google.com; s=arc-20160816; b=Qc++6ar3deoOUgCM0iGCTSy4wGdxY8rmTLFpjTUyKGNBlAg+w3HccVr3ctXj2p/Ayz kzCKYsAllsIIgLfqTTtPZCdTwsRhxPLZFu/K+eniXDK2N7r56LECVHQ3IGXrcDSk8NVp qESUmBJxagRn1EYw7PMotGAVTKxo7TBhlihfDlc5bdhvoAB+XANyT5Lf6xGmAHBnzKaA 5ZNPKmZOTdmCOI/38QdbQDiylNjXTRrRzfSHBMatPnf01v8YZcFjLd5cH5SHcbMbe95D aCpJjuT2eUGlwPtbkphRyyElofKpMd2aOoabaoJCX21lnsq7HD0JyEM+3ZjF4c4pspCB Tejg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:message-id:date:references :in-reply-to:subject:cc:to:from; bh=QHsp2UHGS9osXy7Vsw7jDvPjlMCIj2rnsb3EltN5wDo=; b=ZhdZzjDENQszhJt2i8teRwz/kUw5UMxQ3uoPiFc0ILvtSG7Fs0noXxLScdhVES2oXw teEXRXLlHweeFu+ADTtQPbkzi5uRFTNrhNxDLAviLJU7LdObjbqYxyPiRCTyqYlSrVX5 E34tNx/czJMH5VhYYrUJZrGxncSq0s05C9WElvzx4EFcEHnDABU636TcJVUUi1bc7BHU cpiQQxHmDF+E62Wd/CRML86dykXvUevxF74ZyLbGujbSNVejwDddu200oeAC2Bdcb3Tw Mo735plmGzp7CNGkf3zUeApzW7hZJadBzZF5DLElrcUVilQMHjJwGy7NYPq6JpfFB5Xr Aq1Q== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 11si385369pgy.408.2019.01.30.20.26.13; Wed, 30 Jan 2019 20:26:29 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727869AbfAaE0H (ORCPT + 99 others); Wed, 30 Jan 2019 23:26:07 -0500 Received: from ozlabs.org ([203.11.71.1]:42289 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726193AbfAaE0G (ORCPT ); Wed, 30 Jan 2019 23:26:06 -0500 Received: from authenticated.ozlabs.org (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPSA id 43qnGz6QyHz9sBb; Thu, 31 Jan 2019 15:26:03 +1100 (AEDT) From: Michael Ellerman To: Christophe Leroy , Kees Cook , Andrew Morton , Benjamin Herrenschmidt , Paul Mackerras , Mike Rapoport Cc: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-mm@kvack.org Subject: Re: [PATCH v3 1/2] mm: add probe_user_read() In-Reply-To: <39fb6c5a191025378676492e140dc012915ecaeb.1547652372.git.christophe.leroy@c-s.fr> References: <39fb6c5a191025378676492e140dc012915ecaeb.1547652372.git.christophe.leroy@c-s.fr> Date: Thu, 31 Jan 2019 15:26:03 +1100 Message-ID: <875zu5pi5g.fsf@concordia.ellerman.id.au> MIME-Version: 1.0 Content-Type: text/plain Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Christophe Leroy writes: > In powerpc code, there are several places implementing safe > access to user data. This is sometimes implemented using > probe_kernel_address() with additional access_ok() verification, > sometimes with get_user() enclosed in a pagefault_disable()/enable() > pair, etc. : > show_user_instructions() > bad_stack_expansion() > p9_hmi_special_emu() > fsl_pci_mcheck_exception() > read_user_stack_64() > read_user_stack_32() on PPC64 > read_user_stack_32() on PPC32 > power_pmu_bhrb_to() > > In the same spirit as probe_kernel_read(), this patch adds > probe_user_read(). > > probe_user_read() does the same as probe_kernel_read() but > first checks that it is really a user address. > > The patch defines this function as a static inline so the "size" > variable can be examined for const-ness by the check_object_size() > in __copy_from_user_inatomic() > > Signed-off-by: Christophe Leroy > --- > v3: Moved 'Returns:" comment after description. > Explained in the commit log why the function is defined static inline > > v2: Added "Returns:" comment and removed probe_user_address() > > include/linux/uaccess.h | 34 ++++++++++++++++++++++++++++++++++ > 1 file changed, 34 insertions(+) > > diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h > index 37b226e8df13..ef99edd63da3 100644 > --- a/include/linux/uaccess.h > +++ b/include/linux/uaccess.h > @@ -263,6 +263,40 @@ extern long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count); > #define probe_kernel_address(addr, retval) \ > probe_kernel_read(&retval, addr, sizeof(retval)) > > +/** > + * probe_user_read(): safely attempt to read from a user location > + * @dst: pointer to the buffer that shall take the data > + * @src: address to read from > + * @size: size of the data chunk > + * > + * Safely read from address @src to the buffer at @dst. If a kernel fault > + * happens, handle that and return -EFAULT. > + * > + * We ensure that the copy_from_user is executed in atomic context so that > + * do_page_fault() doesn't attempt to take mmap_sem. This makes > + * probe_user_read() suitable for use within regions where the caller > + * already holds mmap_sem, or other locks which nest inside mmap_sem. > + * > + * Returns: 0 on success, -EFAULT on error. > + */ > + > +#ifndef probe_user_read > +static __always_inline long probe_user_read(void *dst, const void __user *src, > + size_t size) > +{ > + long ret; > + I wonder if we should explicitly switch to USER_DS here? That would be sort of unusual, but the whole reason for this helper existing is to make sure we safely read from user memory and not accidentally from kernel. cheers > + if (!access_ok(src, size)) > + return -EFAULT; > + > + pagefault_disable(); > + ret = __copy_from_user_inatomic(dst, src, size); > + pagefault_enable(); > + > + return ret ? -EFAULT : 0; > +} > +#endif > + > #ifndef user_access_begin > #define user_access_begin(ptr,len) access_ok(ptr, len) > #define user_access_end() do { } while (0) > -- > 2.13.3