From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B10DCFA373D for ; Tue, 1 Nov 2022 12:21:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:In-Reply-To:References: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=FlWOI/uAfrePRtAmraDh487sqUps7pHl6USpfsOLD84=; b=RumZx3kIdx9Dzy 0VVtq/zsV/otxrPSlwf2N6zlW29mFSv9O/LDKYOb3bmY+62mjPtHOjw5muISBVfj7NvsH4ezXVvt3 caoGPYVkTnuHgUg8TuDvwh4dV83MMzgpdFFH/IRxLVIUVtIzT8OapaVU+/gqO5s7i4zdEQTferQWt XNYMZwXu1cKeYsHjqLPLDFfrJaD8JRtx1/3FSiw07bUB+lz/pi9EVd1hquCktpFexjUkF0+MudiEe JcVdda0oAvGOAdYnkeoGtEDzxRJjLvGeZFLVvx9fLXQ9ZAl2YoRS5mU59ovW4+XHJSxDcv+1DA93n ohiR3MGttv77yKML9WGw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1opqFM-0050xL-T7; Tue, 01 Nov 2022 12:20:00 +0000 Received: from eu-smtp-delivery-151.mimecast.com ([185.58.86.151]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1opqFJ-0050wl-8G for linux-arm-kernel@lists.infradead.org; Tue, 01 Nov 2022 12:19:59 +0000 Received: from AcuMS.aculab.com (156.67.243.121 [156.67.243.121]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id uk-mta-321-cgaiRFvXNJ2qCkCMR_nIOQ-1; Tue, 01 Nov 2022 12:19:53 +0000 X-MC-Unique: cgaiRFvXNJ2qCkCMR_nIOQ-1 Received: from AcuMS.Aculab.com (10.202.163.6) by AcuMS.aculab.com (10.202.163.6) with Microsoft SMTP Server (TLS) id 15.0.1497.42; Tue, 1 Nov 2022 12:19:51 +0000 Received: from AcuMS.Aculab.com ([::1]) by AcuMS.aculab.com ([::1]) with mapi id 15.00.1497.042; Tue, 1 Nov 2022 12:19:51 +0000 From: David Laight To: 'Szabolcs Nagy' CC: Theodore Ts'o , "linux-api@vger.kernel.org" , "linux-kernel@vger.kernel.org" , "linux-arm-kernel@lists.infradead.org" Subject: RE: linux interprets an fcntl int arg as long Thread-Topic: linux interprets an fcntl int arg as long Thread-Index: AQHY7dH4b5GlkmHz9EyVI+/nub6Ts64p0qEQgAAgcACAAAds0A== Date: Tue, 1 Nov 2022 12:19:51 +0000 Message-ID: <0030a20a94cd49628c5461d044bb28ed@AcuMS.aculab.com> References: In-Reply-To: Accept-Language: en-GB, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [10.202.205.107] MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: aculab.com Content-Language: en-US X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221101_051957_598415_6EF29866 X-CRM114-Status: GOOD ( 40.31 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: 'Szabolcs Nagy' > Sent: 01 November 2022 11:45 > > The 11/01/2022 10:02, David Laight wrote: > > From: Szabolcs Nagy > > > Sent: 01 November 2022 09:11 > > > > > > The 10/31/2022 21:46, Theodore Ts'o wrote: > > > > On Mon, Oct 31, 2022 at 12:44:59PM +0000, Szabolcs Nagy wrote: > > > > > and such fcntl call can happen with c code that just passes > > > > > F_SEAL_WRITE since it is an int and e.g. with aarch64 pcs rules > > > > > it is passed in a register where top bits can be non-zero > > > > > (unlikely in practice but valid). > > > > > > > > In Linux's aarch64 ABI, an int is a 4-byte value. It is *not* an > > > > 8-byte value. So passing in "F_SEAL_WRITE | 0xF00000000" as an int > > > > (as in your example) is simply not valid thing for the userspace > > > > program to do. > > > > > > > > Now, if there is a C program which has "int c = F_SEAL_WRITE", if the > > > > PCS allows the compiler to pass a function paramter c --- for example > > > > f(a, b, c) --- where the 4-byte paramter 'c' is placed in a 64-bit > > > > register where the high bits of the 64-bit register contains non-zero > > > > garbage values, I would argue that this is a bug in the PCS and/or the > > > > compiler. > > > > > > the callee uses va_arg(ap, type) to get the argument, > > > and if the type is wider than what was actually passed > > > then anything can happen. in practice what happens is > > > that the top bits can be non-zero. > > > > > > many pcs are affected (aarch64 is the one i know well, > > > but at least x86_64, arm are affected too). and even if > > > it was aarch64 pcs only, it is incompetent to say that > > > the pcs is wrong: that's a constraint we are working with. > > > > > > the kernel must not read a wider type than what it > > > documents as argument to variadic functions in the c api. > > > (it does not make much sense to expect anything there > > > anyway, but it can break userspace) > > > > The Linux kernel just assumes that the varargs call looks like > > a non-varags call with the same parameters. > > (It doesn't use va_arg()) > > All syscall arguments are passed in registers (unlike BSDs > > where they can also be on the user stack). > > On 64bit systems the same registers are expected to be used > > for 64bit and 32bit integers and for pointers. > > 32bit values usually get masked because they get passed to > > a function with an 'int' argument. > > > > If any fcntl() calls require a 64bit value and the C ABI > > might leave non-zero high bits in an register containing > > a 32bit value (esp. to a varargs function) then the calling > > code will need to cast such arguments to 64 bits. > > the entire point of my mail is that it is not possible > to tell in the libc if the vararg is pointer or int. > > so in case a user passed an int, the libc cannot fix > that up, like it usually does for other cases where > linux syscall abi is incompatible with the c api. > > let me go through step by step what is going on: ... > long internal_syscall(int, long, long, long, long, long, long); > int fcntl(int fd, int cmd, ...) > { > va_list ap; > va_start(ap, cmd); > /* this is non-conforming C: wrong type in va_arg, > but that's not relevant since libc can implement > this as target specific asm, the important bit is > that the correct type is not known: libc cannot > replicate the kernel side dispatch logic because > new cmd can be introduced in the future with > arbitrary type arg. > > top 32bits of arg are non-zero, libc cannot > zero them here as arg may be long or pointer. */ > long arg = va_arg(ap, long); Here libc has to assume that int, long and pointer are passed the same way. This is true for everything Linux actually runs on. But wouldn't be if, for example, a 64bit arch just pushed 32bit arguments on stack. Or if a 32 bit one passed integer and pointer args in different types of registers. But all 64bit ones use the same GP registers for int/long/pointer. > kernel code: > ------------ > SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) > { That is just a wrapper and calls do_fcntl(). which needs changing to be add: arg &= ~0U; before the switch(cmd) { David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales) _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel