Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2001625imu; Sat, 22 Dec 2018 09:53:06 -0800 (PST) X-Google-Smtp-Source: ALg8bN5zlWMEoq4dvGCWbxgM+e3V0qzGqLgPezAVhHlCBe6UcvOLhCAO3jdsqwQs4v4Wt23A6kiU X-Received: by 2002:a63:d70e:: with SMTP id d14mr6905845pgg.159.1545501186802; Sat, 22 Dec 2018 09:53:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1545501186; cv=none; d=google.com; s=arc-20160816; b=UjKBUhDjZaesnqAib0hZBsNvkMFsMGQCqZsk7Jo2nVhhRhvdirNcFY3ifINjZphIx+ HEnewC/39nIFqSJga+H7Hdv2nKKGHcCKhfmhOHT6wvr6AuI5m0kgXf1U7Qj7Zecey2kD Fi7w4XstA+y5Mkf0JX4vyYNVi8fw34hgcotVFYZjyYVOnnGQr4nnTA3gP+84oTWLJu5J MTJE5JjH86F6Hnmn1ian7Jj5iMGGjP0V3cJKpDEN9Q2rF34FiKvHSSQ9QZQukInjNY2p INfb4wU9swE/+ThytnikXMhShly7YzYjMtymMe8aVARerIS8WPVXUZqiAii76LR/xkkq +4Ow== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dkim-signature; bh=z2SMBywYOIKOSn6oMr+BJP7H6vlUilXA4hl4flue3DA=; b=ZjNABnPWCMIKzFMnxLdAS9wbYULslcq1t7hAZAvEOJsTFrgVu1OYRkIgnYSl258yZE sydjz5ScWL5gcXC4bEqjuERpuWyGG9tQYynIf5+yRX2lcw9zn9pId2YSg0FFRYutzPzT 0uK/mbVncyzBcd+yvJzZZV+ELBioFEQOWgLe+/nZj5HpDnfJhB7BAsASOxivtuul9LA9 yTirS0w0jRiZWFkZHzC52PHxpYvzEu9ukkGpxsv3CelLyN9WSiwSJemz2HFwaiZ/MV2L c+LnIHkwEsD9Sf+clUyR+eiOWekYBd7wqlVxM81Vv2ANO4v0AEUdc3q3Kh2+xmfDnher kokw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=EnZveLS4; 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=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j10si5626219plg.123.2018.12.22.09.52.50; Sat, 22 Dec 2018 09:53:06 -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=@gmail.com header.s=20161025 header.b=EnZveLS4; 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=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390749AbeLUVyT (ORCPT + 99 others); Fri, 21 Dec 2018 16:54:19 -0500 Received: from mail-lj1-f193.google.com ([209.85.208.193]:45107 "EHLO mail-lj1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725837AbeLUVyT (ORCPT ); Fri, 21 Dec 2018 16:54:19 -0500 Received: by mail-lj1-f193.google.com with SMTP id s5-v6so5965658ljd.12; Fri, 21 Dec 2018 13:54:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=z2SMBywYOIKOSn6oMr+BJP7H6vlUilXA4hl4flue3DA=; b=EnZveLS445IxGsTr9K+LvxxGCw6xr41iYv7jO10iZ0ddfRIqwhpOaIaUkPnuZFAqVF UTDBz8UGAzXRh3HhlZBEmjbjwrNdtSymNT04wxv1LFbw0UGwCYKeu6d47N3Xk3OSDSfa 4I5REUceAkLs5PhLMefMT1M3Lg6JbOHJQZcYM8GPlYFn3qgllPvc5BBXAe4E3debC9NW H46i6UhyKKruUSU+l/7d1O8pwGjZbmbjLPoZXI4Ut7KB3e72YrViDo2pSqfdif7XHgGt JjjtL0Y8mAlK0oBhDuyyRf9I0v1DCSO+y0/LlreinJEOh8I5PWPE29UfG25toL8vpRgb 9OXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=z2SMBywYOIKOSn6oMr+BJP7H6vlUilXA4hl4flue3DA=; b=BNOSyf4Rc8do4TpHXH0VjgcF3rv+0pVmFDoxI83Ctvy/tyssTfthOr7myEmzgpwihr 9qRliYbOnBnL+UsSotCBxci7wlSkUrLxQUVwEgHD1C3yYzKrKhqZC7IJ2uRYov/nmlwh cA6mXT9Uw6/4EPRyWpiwOoFzfKP5/VPFEbeH2alzLwWmKyNUAPxQXdv0gq0/InbCTPSg AtK107xseyfZKoqkxHP34MDLILyqC1ymUXuElwpqgXDp7vynSRh+9DVq02k1fcXLgHr8 gLsr8RfP19MH/D4L4mDOEhnRdiu4m7KGLnfBTE+Uw9xm3sQFshjn5HMx3ALuqCi65S07 q6dA== X-Gm-Message-State: AJcUukdIW05VxIzgJnzuNiGFZJkzyl+Tv0eUENW0p4JmnNElYBXimN+n 0H/xMVI6TOrzusdq9pahMpGQh9My6iE= X-Received: by 2002:a2e:1603:: with SMTP id w3-v6mr2657904ljd.33.1545429255809; Fri, 21 Dec 2018 13:54:15 -0800 (PST) Received: from [192.168.10.160] (91-159-63-61.elisa-laajakaista.fi. [91.159.63.61]) by smtp.gmail.com with ESMTPSA id u21-v6sm4876877lju.46.2018.12.21.13.54.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 21 Dec 2018 13:54:14 -0800 (PST) Subject: Re: [PATCH 03/12] __wr_after_init: generic functionality To: Matthew Wilcox Cc: Andy Lutomirski , Peter Zijlstra , Dave Hansen , Mimi Zohar , Thiago Jung Bauermann , igor.stoppa@huawei.com, Nadav Amit , Kees Cook , Ahmed Soliman , linux-integrity@vger.kernel.org, kernel-hardening@lists.openwall.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org References: <20181221181423.20455-1-igor.stoppa@huawei.com> <20181221181423.20455-4-igor.stoppa@huawei.com> <20181221184120.GG10600@bombadil.infradead.org> <14487401-dec3-6a7d-a0b1-e369e93aa9c4@gmail.com> <20181221194351.GH10600@bombadil.infradead.org> From: Igor Stoppa Message-ID: <0a154bdf-2d62-f752-82fa-70be6ea8cff5@gmail.com> Date: Fri, 21 Dec 2018 23:54:13 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 MIME-Version: 1.0 In-Reply-To: <20181221194351.GH10600@bombadil.infradead.org> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 21/12/2018 21:43, Matthew Wilcox wrote: > On Fri, Dec 21, 2018 at 09:07:54PM +0200, Igor Stoppa wrote: >> On 21/12/2018 20:41, Matthew Wilcox wrote: >>> On Fri, Dec 21, 2018 at 08:14:14PM +0200, Igor Stoppa wrote: >>>> +static inline int memtst(void *p, int c, __kernel_size_t len) >>> >>> I don't understand why you're verifying that writes actually happen >>> in production code. Sure, write lib/test_wrmem.c or something, but >>> verifying every single rare write seems like a mistake to me. >> >> This is actually something I wrote more as a stop-gap. >> I have the feeling there should be already something similar available. >> And probably I could not find it. Unless it's so trivial that it doesn't >> deserve to become a function? >> >> But if there is really no existing alternative, I can put it in a separate >> file. > > I'm not questioning the implementation, I'm questioning why it's ever > called. If I type 'p = q', I don't then verify that p actually is equal > to q. I just assume that the compiler did its job. Paranoia, probably. My thinking is that, once the data is protected, it could still be attacked through the metadata. A pte, for example. Preventing the setting of a flag, that for example enables a functionality, might be a nice way to thwart all this protection. If I verify that the write was successful, through the read-only address, then I know that the action really completed successfully. There are many more types of attack that one can come up with, but attacking the metadata is probably the most likely next level. So what I'm trying to do is more akin to: p = &d; *p = q; d == q; But in our case there is an indefinite amount of time between the creation of the alternate mapping and its use. Another way could be to check that the mapping is correct before writing to it. Maybe safer? I went for confirming that the end result is correct. Of course it adds overhead, but if the whole thing is already slow and happening not too often, how much does it matter? An alternative approach would be that the code invoking the wr operation performs an explicit test. Would it look better if I implemented this as a wr_assign_verify() inline function? >>>> +#ifndef CONFIG_PRMEM >>> >>> So is this PRMEM or wr_mem? It's not obvious that CONFIG_PRMEM controls >>> wrmem. >> >> In my mind (maybe still clinging to the old implementation), PRMEM is the >> master toggle, for protected memory. >> >> Then there are various types and the first one being now implemented is >> write rare after init (because ro after init already exists). >> >> However, the same levels of protection should then follow for dynamically >> allocated memory (ye old pmalloc). >> >> PRMEM would then become the moniker for the whole shebang. > > To my mind, what we have in this patchset is support for statically > allocated protected (or write-rare) memory. Later, we'll add dynamically > allocated protected memory. So it's all protected memory, and we'll > use the same accessors for both ... right? The static one is only write rare because read only after init already exists. The dynamic one must introduce the same write rare, yes, but it should also introduce read_only (I do not count the destruction of an entire pool as a write rare operation). Ex: SELinux policyDB. write rare, regardless if dynamic or static, is a sub-case of protected memory, hence the differentiation between protected and write rare. I'm not claiming to be particularly skilled at choosing names, so if something better sounding is available, it can be used. This is the best I could come up with. [...] > I don't think there's anything to be done in that case. Indeed, > I think the only thing to do is panic and stop the whole machine if > initialisation fails. We'd be in a situation where nothing can update > protected memory, and the machine just won't work. > > I suppose we could "fail insecure" and never protect the memory, but I > think that's asking for trouble. ok, so init will BUG() if it fails, instead of the current WARN_ONCE() and return. > Anyway, my concern was for a driver which can be built either as a > module or built-in. Its init code will be called before write-protection > happens when it's built in, and after write-protection happens when it's > a module. It should be able to use wr_assign() in either circumstance. > One might also have a utility function which is called from both init > and non-init code and want to use wr_assign() whether initialisation > has completed or not. If the writable mapping is created early enough, the only penalty for using the write-rare function on a writable variable is that it would be slower. Probably there wouldn't be so much data to deal with. If the driver is dealing with some HW, most likely that would make any write rare extra delay look negligible. -- igor