Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp2516576imm; Thu, 7 Jun 2018 12:00:32 -0700 (PDT) X-Google-Smtp-Source: ADUXVKLhG0a9kC+abwAiqqOvZCKNMia54hhu/dJJHXnbPsamXdndPCK5ReZJ0dkhxoTVz21DFXyx X-Received: by 2002:a62:9652:: with SMTP id c79-v6mr2893271pfe.114.1528398032406; Thu, 07 Jun 2018 12:00:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528398032; cv=none; d=google.com; s=arc-20160816; b=spulF96jX7iivWXGWW+800tP0bDj7sJ/W7KEpAvt/dnHxAK4hX7GI+dXRZR8exQHq4 IRLycpENqyCFFMx9NY413GMFs/AdjiqMb49KAw9L0jwcAmsDodjwydWbp/+c+Rw/+aAy bsLckPM+ZqkS8MqYri10++SchDPcJEHSEp9uO41ICSAFvjGWeSYfCUnr6RA6E2aGTkNx JbNsswh1BjlwyZwktlKLL+04YXj/oXlxWCz3szS2CfyzQZW/VLiKHooVOkvehzV6vQU6 0SKEbSwUVK/WftLdc0s/Ly18yHXEUy8BfCvEkbfcCQImMGS6DUEIUvEz4wpIEH16oSZI 8SJw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:to:from:cc:content-transfer-encoding :mime-version:message-id:in-reply-to:subject:date:dkim-signature :arc-authentication-results; bh=Xn02O5djQDNFxsk7RsRBFdSObjD98lZpBFuszQMeurk=; b=jAfbzWmTrjb62ZvpbUrEuSr0PO5UWHKZV5gRQzHR92GwA8f2MYhEWHr7ORLxs/grme z0u07PzRgtOXwqQ9P9TRjHnSYHcj8or/R8w4HNJXKQ/8AZ/OUAkmpj3Ch4V4DepDzG2a pEPvf+jagn6ySKls+oMc3ZIRchCI9GgsvhOiofJMWEBBN3DdYP8H/T/098To22rs1tIV YONcgI9MrL5+kNgv6uQpfNCSuBnCH+rbcxSfj7TBUGKKjaQJPIypezWrdV73RRS7MWJ1 vVrMItHD5vTMTSM0RXUfPbgUW2UK53r81ae6IDG142F36851RyN638aqua/u9+ZEpsQa WpGQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sifive.com header.s=google header.b=AgUhX7lR; 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 f9-v6si2632151pgt.128.2018.06.07.12.00.18; Thu, 07 Jun 2018 12:00:32 -0700 (PDT) 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=@sifive.com header.s=google header.b=AgUhX7lR; 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 S932765AbeFGQa0 (ORCPT + 99 others); Thu, 7 Jun 2018 12:30:26 -0400 Received: from mail-pl0-f67.google.com ([209.85.160.67]:38993 "EHLO mail-pl0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753879AbeFGQaV (ORCPT ); Thu, 7 Jun 2018 12:30:21 -0400 Received: by mail-pl0-f67.google.com with SMTP id f1-v6so6465980plt.6 for ; Thu, 07 Jun 2018 09:30:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; h=date:subject:in-reply-to:message-id:mime-version :content-transfer-encoding:cc:from:to; bh=Xn02O5djQDNFxsk7RsRBFdSObjD98lZpBFuszQMeurk=; b=AgUhX7lR0sYdhNvb/lEKO+I0Vlf1pdaPyP4XuK4iiJTvdhdkfPIh4Atjve27nc7gcu ZcQpNcidSe6sEfFguyrr0zfDhTRFVfko8gkaxVFP6uX9Svj8wzzmJG84N7OqK8GX/nlg bkwP0j9PpErNdqhNR1jKElaC/LiaA5BC4xi0BxJX53KIeogjhqAfWGIeuIs0fYBhkQ7q uJj1lzzr29n7tHBFEckoTWurNFNyTzqG4vDygw3VyH7FiYXWp/HLoS4WgNA9wtFMWeH4 u+Cyuh0bhUCO7SvbtQDS3vrxuYSVIqeTuXvYTE05d5tu6dypuKhJQOWnSOa/zungLNUF /8mA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:subject:in-reply-to:message-id:mime-version :content-transfer-encoding:cc:from:to; bh=Xn02O5djQDNFxsk7RsRBFdSObjD98lZpBFuszQMeurk=; b=dwGxv25qfRegKbKW9inF1n5+PclnpOQkfoSLiGKu2g9k1H6rE1CpKWB14Z6DTM3p/R ClekJSofuFnucOvJWVb7aEnk7jdPb5y6DKefcgEI2SfUVJ/Y4Mhxr1RV9KIxLC2hSy2n U7VFmt3vWwaIlUYi7xc4DRzJ+4wXvIfO1Q/cUy95l4dFfz5drj2nmYfuidAKKkQxpWdA V5k35BtP6itKqQe2c01Ec2zKkYG7v6p/OrPc5uI55pmbkUF56ijddZWSZ3C9SbuUmMgk obdEBo2EGi9xKSeo8GBa3USDz9vuhXHXGGA7b51h9tAw6Qr3AY/tceZ2pxd2U7K0JAJ0 FsWw== X-Gm-Message-State: APt69E3pWYDLaaRYaqmYMkqeB2UjgbiDp65W+BTub/yYdfD6o8vcYZNv BEwYXthEMirmD3N6zoIkqbvJyA== X-Received: by 2002:a17:902:380c:: with SMTP id l12-v6mr2768314plc.19.1528389021013; Thu, 07 Jun 2018 09:30:21 -0700 (PDT) Received: from localhost ([12.206.222.5]) by smtp.gmail.com with ESMTPSA id e189-v6sm14927902pfc.134.2018.06.07.09.30.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Jun 2018 09:30:19 -0700 (PDT) Date: Thu, 07 Jun 2018 09:30:19 -0700 (PDT) X-Google-Original-Date: Thu, 07 Jun 2018 09:29:48 PDT (-0700) Subject: Re: [PATCH 3/3] riscv: fix __user annotation for __copy_user() In-Reply-To: <6a0ab99d-6e4d-eb80-bc4d-854d154ae827@wdc.com> Message-ID: Mime-Version: 1.0 (MHng) Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit CC: luc.vanoostenryck@gmail.com, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, albert@sifive.com From: Palmer Dabbelt To: atish.patra@wdc.com Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, 04 Jun 2018 12:28:47 PDT (-0700), atish.patra@wdc.com wrote: > On 6/4/18 12:09 PM, Luc Van Oostenryck wrote: >> On Mon, Jun 04, 2018 at 11:46:50AM -0700, Atish Patra wrote: >>> On 6/1/18 8:22 AM, Luc Van Oostenryck wrote: >>>> __copy_user() is a function, written in assembly, used to copy >>>> memory between kernel & user space. As such its to & from args >>>> may both take a user pointer or a kernel pointer. >>>> >>>> However the prototype for this function declare these two args >>>> as 'void __user *', which is no more & no less correct than >>>> declaring them as 'void *'. In fact theer is no possible correct >>> >>> /s/theer/there >>> >>>> annotation for such a function. >>>> >>>> The problem is worked around here by declaring these args as >>>> unsigned long and casting them to the right type in each of >>>> two callers raw_copy_{to,from}_user() as some kind of cast would >>>> be needed anyway. >>>> >>>> Note: another solution, maybe cleaner but slightly more complex, >>>> would be to declare two version of __copy_user, >>>> either in the asm file or via an alias, each having already >>>> the correct typing for raw_copy_{to,from}_user(). >>>> >>> >>> I feel that would be a better solution as it is implemented similarly >>> in ARM as well. >>> >>> I am unable to understand how "unsigned long" is better than "void*". >>> x86 implementation has both arguments as void*. Can you please clarify ? >> >> "better" is quite relative and it must be understood that sparse >> allow to cast pointers o fany kinds to and from unsigned long >> without any warnings (while doing a cast between different address >> space will emit a warning unless you use '__force'). >> > > Got it. >> As I tried to explain here above, the fact that this function is >> declared as taking 2 __user pointers requires to use of casts >> (ugly casts with __force) to get over the __user. By declaring >> them as taking unsigned long, you still have to use casts but, IMO, >> it's cleaner >> > > Thanks for the detailed explanation. > >> Note: they're generic pointers/addresses anyway, they can't be >> dereferenced anyway so unsigned is as good as a plain void* >> or a void __user* >> Note: using unsigned long here, fundamentally to bypass the __user, >> is the same as casting a const pointer back to a plain pointer >> via an intermediate cast to unsigned long. People can argue >> that's kinda cheating, and they would be right of course, but >> using __force or declaring twice the function with two different >> names and prototype is also a form of cheating. >> Note: if this would be my code, I would choose the solution with >> two declarations. > > I prefer that as well. I haven't compiled this, but I think it should work. It's on the fix-sparse branch of kernel.org/palmer/linux.git . commit 88ffc46f92c16db0fa37edb79038d37ced0a8b41 gpg: Signature made Thu 07 Jun 2018 09:29:02 AM PDT gpg: using RSA key 00CE76D1834960DFCE886DF8EF4CA1502CCBAB41 gpg: issuer "palmer@dabbelt.com" gpg: Good signature from "Palmer Dabbelt " [ultimate] gpg: aka "Palmer Dabbelt " [ultimate] Author: Palmer Dabbelt Date: Thu Jun 7 09:20:57 2018 -0700 RISC-V: Split the definition of __copy_user We use a single __copy_user assembly function to copy memory both from and to userspace. While this works, it triggers sparse errors because we're implicitly casting between the kernel and user address spaces by calling __copy_user. This patch splits the C declaration into a pair of functions, __asm_copy_{to,from}_user, that have sane semantics WRT __user. This split tricks sparse into treating these function calls as safe. The assembly implementation then just aliases these two symbols to __copy_user, which I renamed to __asm_copy_tofrom_user. The result is an spare-safe implementation that pays to performance or code size penalty. Signed-off-by: Palmer Dabbelt diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h index 14b0b22fb578..0dbbbab05dac 100644 --- a/arch/riscv/include/asm/uaccess.h +++ b/arch/riscv/include/asm/uaccess.h @@ -392,19 +392,21 @@ do { \ }) -extern unsigned long __must_check __copy_user(void __user *to, +extern unsigned long __must_check __asm_copy_from_user_user(void *to, const void __user *from, unsigned long n); +extern unsigned long __must_check __asm_copy_to_user_user(void __user *to, + const void *from, unsigned long n); static inline unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n) { - return __copy_user(to, from, n); + return __asm_copy_from_user(to, from, n); } static inline unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n) { - return __copy_user(to, from, n); + return __asm_copy_to_user(to, from, n); } extern long strncpy_from_user(char *dest, const char __user *src, long count); diff --git a/arch/riscv/lib/uaccess.S b/arch/riscv/lib/uaccess.S index 58fb2877c865..bd51e47ebd44 100644 --- a/arch/riscv/lib/uaccess.S +++ b/arch/riscv/lib/uaccess.S @@ -13,7 +13,15 @@ _epc: .previous .endm -ENTRY(__copy_user) +/* __asm_copy_to_user and __asm_copy_from_user are actually the same function, + * they're just provided as two different symbols to C code so sparse doesn't + * yell about casting between two different address spaces. */ +.global __asm_copy_to_user +.set __asm_copy_to_user,__asm_copy_tofrom_user +.global __asm_copy_from_user +.set __asm_copy_from_user,__asm_copy_tofrom_user + +ENTRY(__asm_copy_tofrom_user) /* Enable access to user memory */ li t6, SR_SUM