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 X-Spam-Level: X-Spam-Status: No, score=-3.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F0E62C4338F for ; Fri, 13 Aug 2021 20:18:39 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 79D476109E for ; Fri, 13 Aug 2021 20:18:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 79D476109E Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=xmission.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=kvack.org Received: by kanga.kvack.org (Postfix) id D430E6B006C; Fri, 13 Aug 2021 16:18:38 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id CF3076B0071; Fri, 13 Aug 2021 16:18:38 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id BBB586B0072; Fri, 13 Aug 2021 16:18:38 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0118.hostedemail.com [216.40.44.118]) by kanga.kvack.org (Postfix) with ESMTP id A3B8F6B006C for ; Fri, 13 Aug 2021 16:18:38 -0400 (EDT) Received: from smtpin02.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with ESMTP id 19DC41E090 for ; Fri, 13 Aug 2021 20:18:38 +0000 (UTC) X-FDA: 78471170316.02.11FF9EB Received: from out02.mta.xmission.com (out02.mta.xmission.com [166.70.13.232]) by imf01.hostedemail.com (Postfix) with ESMTP id 886F050280D4 for ; Fri, 13 Aug 2021 20:18:37 +0000 (UTC) Received: from in01.mta.xmission.com ([166.70.13.51]:34538) by out02.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1mEddH-004ThL-Mz; Fri, 13 Aug 2021 14:18:23 -0600 Received: from ip68-227-160-95.om.om.cox.net ([68.227.160.95]:44050 helo=email.xmission.com) by in01.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1mEddF-000OMb-Aj; Fri, 13 Aug 2021 14:18:23 -0600 From: ebiederm@xmission.com (Eric W. Biederman) To: David Laight Cc: Linus Torvalds , Andy Lutomirski , David Hildenbrand , Linux Kernel Mailing List , Andrew Morton , Thomas Gleixner , "Ingo Molnar" , Borislav Petkov , "H. Peter Anvin" , Al Viro , Alexey Dobriyan , Steven Rostedt , "Peter Zijlstra \(Intel\)" , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , "Namhyung Kim" , Petr Mladek , "Sergey Senozhatsky" , Andy Shevchenko , Rasmus Villemoes , Kees Cook , Greg Ungerer , Geert Uytterhoeven , "Mike Rapoport" , Vlastimil Babka , "Vincenzo Frascino" , Chinwen Chang , Michel Lespinasse , "Catalin Marinas" , "Matthew Wilcox \(Oracle\)" , Huang Ying , Jann Horn , Feng Tang , Kevin Brodsky , Michael Ellerman , "Shawn Anastasio" , Steven Price , "Nicholas Piggin" , Christian Brauner , Jens Axboe , "Gabriel Krisman Bertazi" , Peter Xu , "Suren Baghdasaryan" , Shakeel Butt , "Marco Elver" , Daniel Jordan , Nicolas Viennot , Thomas Cedeno , Collin Fijalkovich , Michal Hocko , Miklos Szeredi , Chengguang Xu , Christian =?utf-8?Q?K=C3=B6nig?= , "linux-unionfs\@vger.kernel.org" , Linux API , "the arch\/x86 maintainers" , , Linux-MM , Florian Weimer , "Michael Kerrisk \(man-pages\)" References: <20210812084348.6521-1-david@redhat.com> <87o8a2d0wf.fsf@disp2133> <60db2e61-6b00-44fa-b718-e4361fcc238c@www.fastmail.com> <87lf56bllc.fsf@disp2133> <87eeay8pqx.fsf@disp2133> <5b0d7c1e73ca43ef9ce6665fec6c4d7e@AcuMS.aculab.com> Date: Fri, 13 Aug 2021 15:17:51 -0500 In-Reply-To: <5b0d7c1e73ca43ef9ce6665fec6c4d7e@AcuMS.aculab.com> (David Laight's message of "Fri, 13 Aug 2021 09:05:43 +0000") Message-ID: <87h7ft2j68.fsf@disp2133> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-XM-SPF: eid=1mEddF-000OMb-Aj;;;mid=<87h7ft2j68.fsf@disp2133>;;;hst=in01.mta.xmission.com;;;ip=68.227.160.95;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX1+iDYiD++UzCTsjGR/882Huiq/xHcX9pek= X-SA-Exim-Connect-IP: 68.227.160.95 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: Re: [PATCH v1 0/7] Remove in-tree usage of MAP_DENYWRITE X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in01.mta.xmission.com) X-Rspamd-Server: rspam03 X-Rspamd-Queue-Id: 886F050280D4 X-Stat-Signature: 16bf99kqf36dymgh91xsm59as1z1k8c7 Authentication-Results: imf01.hostedemail.com; dkim=none; dmarc=pass (policy=none) header.from=xmission.com; spf=pass (imf01.hostedemail.com: domain of ebiederm@xmission.com designates 166.70.13.232 as permitted sender) smtp.mailfrom=ebiederm@xmission.com X-HE-Tag: 1628885917-146620 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: David Laight writes: > From: Eric W. Biederman >> Sent: 12 August 2021 19:47 > ... >> So today the best advice I can give to userspace is to mark their >> executables and shared libraries as read-only and immutable. Otherwise >> a change to the executable file can change what is mapped into memory. >> MAP_PRIVATE does not help. > > While 'immutable' might be ok for files installed by distributions > it would be a PITA in development. For development simply making the files read-only should be sufficient. What I think should happen is when a new binary is installed it should always be placed in a new file and renamed to the old name, rather than copied over the old file. That can be added to a makefile by writing to a temporary file name and then using "mv" to the final name. I tried to look at which options I would need to give to install to implement that pattern but I don't see it. Perhaps -b for backup. I thought I could overcome the feature of CAP_DAC_OVERRIDE where read-only files can be over-written by adding the immutable attribute. I just tested and reread the code and I see that using immutable has a couple of problems. Only root is allowed to set immutable, and not even root is allowed to rename or delete immutable files while the immutable attribute is set. > ETXTBUSY is a useful reminder that the file you are copying from > machine A to machine B (etc) is still running and probably ought > to be killed/stopped before you get confused. That is true. > I've never really understood why it doesn't stop shared libraries > being overwritten - but they do tend to be updated less often. The problem is that MAP_DENYWRITE can be applied to any file. Which makes it another kind of mandatory file lock, and it allows blocking preventing all writes to any file you can read/mmap. Which creates all kinds of denial-of service opportunities. A nasty example would be using mmap MAP_DENYWRITE on /var/log/messages. Which a hostile actor could use to hide traces of their presence on a machine. So far no one has pointed out how to abuse denying writes to /proc/self/exe so we can keep the denywrite behavior there for now. > Overwriting an in-use shared library could be really confusing. > It is likely that all the code is actually in memory. > So everything carries on running as normal. > Until the kernel gets under memory pressure and discards a page. > Then a page from the new version is faulted in and random > programs start getting SEGVs. > This could be days after the borked update. This should actually happen quite quickly after a borked update. The pages in the page cache are cache coherent so as soon as you get a cpu cache flush the new contents of the overwritten page will be visible. Which gets to half of the confusion with this. Long ago and far away rtld in glibc was written with the assumption that something called MAP_COPY existed (I think it exists on hurd?). On Linux at one point it was emulated with MAP_PRIVATE | MAP_DENYWRITE. Then we made MAP_DENYWRITE a noop. This was probably 20 years ago now. The glibc rtld implementation is still written using MAP_COPY with MAP_COPY defined to MAP_PRIVATE | MAP_DENYWRITE on linux. Even with all of the improvements to the linux mm subsystem since the year 2000. Linux the linux mm code does not have the infrastructure to support MAP_COPY. Semantically MAP_COPY sounds nice. An implementation unfortunately would require that anyone who performs a write(2) to a file mapped MAP_COPY would require walking the file mapping data structures and creating one copy of the page for each place that page is mapped MAP_COPY. Which in the case of someone overwriting rtld would require one copy of ld.so in memory for each program running on the system. A 457 * 162KiB = 74MiB increase on my little system that has been up for a while. Where libc would require something like 457 * 1.8MiB = 822.6MiB. The performance of creating those copies would likely also be atrocious. Anything short of performing copy-on-write when a file is written using write(2) would not provide the protection for programs. Florian Weimer, would it be possible to get glibc's ld.so implementation to use MAP_SHARED? Just so people reading the code know what to expect of the kernel? As far as I can tell there is not a practical difference between a read-only MAP_PRIVATE and a read-only MAP_SHARED. Michael Kerrisk, is there any change we can document that in linux for MAP_PRIVATE mappings the mapped pages will match the underlying file unless a value is written to a page through the mapping? Eric