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 kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 60C5AC433F5 for ; Wed, 20 Apr 2022 17:44:08 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id B197D6B0071; Wed, 20 Apr 2022 13:44:07 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id A94646B0073; Wed, 20 Apr 2022 13:44:07 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 8C01A6B0074; Wed, 20 Apr 2022 13:44:07 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (relay.hostedemail.com [64.99.140.27]) by kanga.kvack.org (Postfix) with ESMTP id 7B8886B0071 for ; Wed, 20 Apr 2022 13:44:07 -0400 (EDT) Received: from smtpin21.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 47EE525C44 for ; Wed, 20 Apr 2022 17:44:07 +0000 (UTC) X-FDA: 79377980934.21.D0045EA Received: from mail-pj1-f45.google.com (mail-pj1-f45.google.com [209.85.216.45]) by imf10.hostedemail.com (Postfix) with ESMTP id AF6FCC0019 for ; Wed, 20 Apr 2022 17:44:04 +0000 (UTC) Received: by mail-pj1-f45.google.com with SMTP id j8-20020a17090a060800b001cd4fb60dccso2714714pjj.2 for ; Wed, 20 Apr 2022 10:44:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=Rx+BcE/gSceiKr/zTECjP4EwFSfIzQ9iSKcxGEqhZ8E=; b=S+jeltxbAM3NoFlwTYpJWXeazpb8JERjrM1BTuTkj5LB0pDMpt8FbrJbHowAG9ESGx bF3K1477oF5SMjqvKdyQyw5RvTRXY8zWS3R4UbhQ0goj60wthxhIKo4p3mAIZ3o4hK2S uFVIERf5sWiA4L+yQp4Dau9kCtCAGescfc61A= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=Rx+BcE/gSceiKr/zTECjP4EwFSfIzQ9iSKcxGEqhZ8E=; b=f2gv+kvcVCBFXSrEFDFnLD7T2/GDhZ9N11P9NG+C/5uVAjOQ65M8xX8qqqiTbAkvBH I3eO56nBcWKeAX3dviYzeUuQmZXsOeTEKTGpmiPasASHl+iau2Mh2+IFSYnUwZdb9SB0 +/pcmNOFaYGH+Sb27fLRFBAPHv/QpIIMNLDlqh5LB80jaPqm0ce2nBfNdC3iQ8oZPom9 wWBcv/G0CPKrxoZ7dPA64EUuBTYll0bpnK51i+H1Snv2pgNLWHAhBdKBsA1e0yl9Z5ko 4DopT90UbI/ueid47metRCMd2IFkSpTmqNC8RkiN07zUKHOrqx04ZkLkOXbUGcHN8QYQ IzCA== X-Gm-Message-State: AOAM531DsejDZFrE8xs1OwquYDjLzFdtx2k68Cat6yC2QjrPsIhBi9oG UlUZs6UfMsYmtfDcSJEUDnk6Fw== X-Google-Smtp-Source: ABdhPJzHXgBTMlSzaXENo42O6xuwYeC0Yi0z/Itbb3PnHI+h5sdz1fnNSuD5YgXE9SazzmYGLZ0n/g== X-Received: by 2002:a17:902:c205:b0:15a:2e1b:6360 with SMTP id 5-20020a170902c20500b0015a2e1b6360mr3945500pll.152.1650476645567; Wed, 20 Apr 2022 10:44:05 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id p10-20020a637f4a000000b00373a2760775sm20402378pgn.2.2022.04.20.10.44.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Apr 2022 10:44:05 -0700 (PDT) Date: Wed, 20 Apr 2022 10:44:04 -0700 From: Kees Cook To: Catalin Marinas Cc: Andrew Morton , Christoph Hellwig , Lennart Poettering , Zbigniew =?utf-8?Q?J=C4=99drzejewski-Szmek?= , Will Deacon , Alexander Viro , Eric Biederman , Szabolcs Nagy , Mark Brown , Jeremy Linton , Topi Miettinen , linux-mm@kvack.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-abi-devel@lists.sourceforge.net, linux-hardening@vger.kernel.org, Jann Horn , Salvatore Mesoraca , Igor Zhbanov Subject: Re: [PATCH RFC 0/4] mm, arm64: In-kernel support for memory-deny-write-execute (MDWE) Message-ID: <202204200952.F2B1F58D6B@keescook> References: <20220413134946.2732468-1-catalin.marinas@arm.com> <202204141028.0482B08@keescook> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-Rspamd-Server: rspam10 X-Rspamd-Queue-Id: AF6FCC0019 X-Stat-Signature: bsxtysq8wu6xqt4hm47mbggsp1cbb5qu Authentication-Results: imf10.hostedemail.com; dkim=pass header.d=chromium.org header.s=google header.b=S+jeltxb; spf=pass (imf10.hostedemail.com: domain of keescook@chromium.org designates 209.85.216.45 as permitted sender) smtp.mailfrom=keescook@chromium.org; dmarc=pass (policy=none) header.from=chromium.org X-Rspam-User: X-HE-Tag: 1650476644-536898 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: On Wed, Apr 20, 2022 at 02:01:02PM +0100, Catalin Marinas wrote: > I agree we should look at what we want to cover, though trying to avoid > re-inventing SELinux. With this patchset I went for the minimum that > systemd MDWE does with BPF. Right -- and I don't think we're at any risk of slippery-sloping into a full MAC system. :) I'm fine with doing the implementation in stages, if we've attempted to design the steps (which I think you've got a good start on below). > I think JITs get around it using something like memfd with two separate > mappings to the same page. We could try to prevent such aliases but > allow it if an ELF note is detected (or get the JIT to issue a prctl()). Right -- I'd rather JITs carry some hard-coded property (i.e. ELF note) to indicate the fact that they're expecting to do these kinds of things rather than leaving it open for all processes. > Anyway, with a prctl() we can allow finer-grained control starting with > anonymous and file mappings and later extending to vma aliases, > writeable files etc. On top we can add a seal mask so that a process > cannot disable a control was set. Something like (I'm not good at > names): > > prctl(PR_MDWX_SET, flags, seal_mask); > prctl(PR_MDWX_GET); > > with flags like: > > PR_MDWX_MMAP - basics, should cover mmap() and mprotect() > PR_MDWX_ALIAS - vma aliases, allowed with an ELF note > PR_MDWX_WRITEABLE_FILE The SARA proposal lists a lot of behavioral details to consider. Quoting it[1] here: >> - W^X enforcement will cause problems to any programs that needs >> memory pages mapped both as writable and executable at the same time e.g. >> programs with executable stack markings in the PT_GNU_STACK segment. IMO, executable stack markings should be considered completely deprecated. In fact, we've been warning about it since 2020: 47a2ebb7f505 ("execve: warn if process starts with executable stack") So with execstack, under W^X, I think we should either: - refuse to exec the process (default) - disable W^X for the process (but not its children) >> - W!->X restriction will cause problems to any program that >> needs to generate executable code at run time or to modify executable >> pages e.g. programs with a JIT compiler built-in or linked against a >> non-PIC library. This seems solvable with an ELF flag. >> - Executable MMAP prevention can work only with programs that have at least >> partial RELRO support. It's disabled automatically for programs that >> lack this feature. It will cause problems to any program that uses dlopen >> or tries to do an executable mmap. Unfortunately this feature is the one >> that could create most problems and should be enabled only after careful >> evaluation. This seems like a variation on the execstack case, and we should be able to detect the state and choose a behavior based on system settings, and a smarter version (as SARA has) would track RELRO pages waiting for the loader to make them read-only. SARA was proposed with a set of feature flags[2]; quoting here: >> | W^X | 0x0008 | This is the basic property, refusing PROT_WRITE | PROT_EXEC. I note that SARA also rejects opening /proc/$pid/mem with FMODE_WRITE when this is enabled for a process. (It likely should extend to process_vm_write() too.) >> | W!->X Heap | 0x0001 | >> | W!->X Stack | 0x0002 | >> | W!->X Other memory | 0x0004 | This is for the vma history tracking, and I don't think we need to separate this by memory type? It's nice to have the granularity, but for a first-pass it seems like overkill? Maybe I'm missing some detail. >> | Don't enforce, just complain | 0x0010 | >> | Be Verbose | 0x0020 | Unclear if these would work well with a non-LSM approach. >> | Executable MMAP prevention | 0x0040 | This is the relro detection piece. >> | Trampoline emulation | 0x0100 | This is a more advanced case for emulating execstack, but if we can just ignore execstack entirely, this can go away? >> | Children will inherit flags | 0x0200 | Should a process have that control? >> | Force W^X on setprocattr | 0x0080 | This is a "seal" trigger, which could be done through prctl(). It looks like a bunch of the features are designed around having as much as possible enabled at exec time, and then tightening it further as various things are finished (e.g. execstack, relro, sealing, etc), which is, I think, what would still be needed for a process launcher to be able to enable this kind of protection. (i.e. hoping the process calls a prctl() to enable the protection isn't going to work well with systemd.) So, I *think* we could have a minimal form with these considerations: - execstack: declare it distinctly incompatible. - relro: I think this is solved with BIND_NOW. It's been a while since I looked deeply at this, but I think under BIND_NOW, the (executable) PLT doesn't ever need to be writable (since it points into the GOT), and the (initially writable) GOT is already never executable. This needs to be verified... - JITs can be allowed with a ELF flag and can choose to opt-in with a prctl(). -Kees [1] https://lore.kernel.org/lkml/1562410493-8661-1-git-send-email-s.mesoraca16@gmail.com/ [2] https://lore.kernel.org/lkml/1562410493-8661-2-git-send-email-s.mesoraca16@gmail.com/ -- Kees Cook