Received: by 2002:a05:6a10:a0d1:0:0:0:0 with SMTP id j17csp2292573pxa; Mon, 24 Aug 2020 10:06:44 -0700 (PDT) X-Google-Smtp-Source: ABdhPJywcuAIdRYoCn/jV/78azMyULYaZlSHkkZPn40zEewZbjY4jrrJG3MDiDDSKzqqnlNiu71f X-Received: by 2002:a50:b946:: with SMTP id m64mr6494570ede.92.1598288804645; Mon, 24 Aug 2020 10:06:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598288804; cv=none; d=google.com; s=arc-20160816; b=F7bnX8Gp8KGlbuHqcWsQ0q8P+UH0hKWwKniJIZkAr88o22kqr9FyQ5YW+9AipUi8r+ qsoYR4fC+35qZk8IYoVKm1beSlmHdvAKncXof3nmL8DAhG8uiUynEAiIC6723rRH5hYX loC7RhSILXUeGhvjUa20lfUt+Czv130WptzqTgeo48HOny5xAMHeDnygOzNTlo1VnzOL TqfBN2NlHNKv0Q3Hn34vVl8OQRVGWsKysfKlMJP6k9nhFSFYE1nvkZPI7fqJ8ZF0jM9J MD3s+pUcjsvf8UZh6CMbVRgfq3YO9gOuJJzAUlkhxB33Z6qLBD3JmlxPtytFiGo0/t3/ q6qw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=fgZwZCIujuxzzLKMoK4XwDwGpdA2x4tRAfT7RbGfEyE=; b=nT0QtFN2zRs4YHwwqDTF/zshbE32c2KswX6WZg9Ky2NCS5s4pTldboODgcxks0v4mp MBJ/rImNCjBSAUkXRwJNI31vybD0+ATHrsJxGkqWQk/jsqWsn0vUfkD+L0I1LX+aOQgl efivc9nSAE+NmeWstaBpRbFtQgvljJV0JCEIUPOEpnAdagUHowT0Cb1OtE/DOZWTCsI5 YAgRnTLw2QFLWhIGLwuJ4uyVUhq+GG++UqBSPSNmbS+B9920ubNE5gAoAGDYJ4/PX5IL 9nIGMx3Iw3ERtG4LN9f9uMZL9/c7hQiAWjhmvfZt0xHsVy1syQ+etGtymgTbw5GNvOzH VqRA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=aRAELLIL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id m19si6863353edq.355.2020.08.24.10.06.21; Mon, 24 Aug 2020 10:06:44 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=aRAELLIL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726964AbgHXRFe (ORCPT + 99 others); Mon, 24 Aug 2020 13:05:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58166 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726650AbgHXRE4 (ORCPT ); Mon, 24 Aug 2020 13:04:56 -0400 Received: from mail-io1-xd42.google.com (mail-io1-xd42.google.com [IPv6:2607:f8b0:4864:20::d42]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5B4B3C061574 for ; Mon, 24 Aug 2020 10:04:55 -0700 (PDT) Received: by mail-io1-xd42.google.com with SMTP id b16so9449147ioj.4 for ; Mon, 24 Aug 2020 10:04:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=fgZwZCIujuxzzLKMoK4XwDwGpdA2x4tRAfT7RbGfEyE=; b=aRAELLILR7Gs8V4eWNB5DkiYJqrocT3AqS8Ka1bV4Lunz/lpBe3Q/4QBC2lSVFQoOF 5gT0i3tjDPI/8YDJDT1Tnd/Jqq3UuVfHh7a0GpqfoATt3p6OKIzOb68H9KfZ3dSBcWLj YL17yEVwNe2Ewm76W1ny8icHTAXNFuYgOHh1LMrlKaF767Xpxro52LA+Ag2/fSL/fkI3 JBKkduITmseGjItU/x66Re4EF06ascn5lIVigOIH5ftzgNKeRmWO/2UnVVY3nTQ9ZQoZ aGh5T093QSyYTiTVk+xC7rWQ54FtV3MZo1Gw173JUG8s34BT3HMgAeCkirvYvnMme0VX JWlw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=fgZwZCIujuxzzLKMoK4XwDwGpdA2x4tRAfT7RbGfEyE=; b=FhGMNhZ42BYo92JfV0aglTKQpCCouIb/9S9FhIq7iQNWIlF3fU6PQfKe6kGfPSjh/X nybe8g3uMLP8kFFHR5UMsUbyqVYma9XUsr+dVJcCH1zn7FeBv+iThxxeGcK7ZTIwv4q2 1mpSO2XjA+6QJogv0olsrgPLdX43DBxOuuqSV9lcVD0+8jOI/2T1IafTrEbb5z4oA3oY NLQQeT/Qnxd+xVBdWO3tv1ndNkU/xWS3H1+JBDuECU3zghPaVmKWsxgY+3nXuN7FprDL pRE5WmTzmy3imnbNO26DxbAhs8unMb425FdgCFa7ZYfSGu2CLr8mVAOFfATr/bEsrUJj 3Xyg== X-Gm-Message-State: AOAM533/8qQegWpN6cGe3oBEaqZQtm4Y+bQKPAyxOlciidWPA6qJyw60 bhAOC3ITbauhVx3yGk/bRnerdwbI1R87jqU+OSFYVQ== X-Received: by 2002:a6b:9256:: with SMTP id u83mr5748173iod.194.1598288694363; Mon, 24 Aug 2020 10:04:54 -0700 (PDT) MIME-Version: 1.0 References: <20200820164753.3256899-1-jackmanb@chromium.org> <42fb4180-772c-5579-ef3e-b4003e2b784b@schaufler-ca.com> <66a35f25-53be-17c3-8ab3-7cb32b0bc77a@schaufler-ca.com> In-Reply-To: <66a35f25-53be-17c3-8ab3-7cb32b0bc77a@schaufler-ca.com> From: Brendan Jackman Date: Mon, 24 Aug 2020 19:04:43 +0200 Message-ID: Subject: Re: [RFC] security: replace indirect calls with static calls To: Casey Schaufler Cc: Brendan Jackman , linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-security-module@vger.kernel.org, Paul Renauld , Alexei Starovoitov , Daniel Borkmann , James Morris , Paul Turner , Jann Horn , Peter Zijlstra , rafael.j.wysocki@intel.com, Kees Cook , thgarnie@chromium.org, KP Singh , paul.renauld.epfl@gmail.com Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, 24 Aug 2020 at 18:43, Casey Schaufler wrote: > > On 8/24/2020 8:20 AM, Brendan Jackman wrote: > > On Fri, 21 Aug 2020 at 00:46, Casey Schaufler wrote: > >> On 8/20/2020 9:47 AM, Brendan Jackman wrote: > > [...] > >> What does NOP really look like? > > The NOP is the same as a regular function call but the CALL > > instruction is replaced with a NOP instruction. The code that sets up > > the call parameters is unchanged, and so is the code that expects to > > get the return value in eax or whatever. > > Right. Are you saying that NOP is in-line assembler in your switch? That's right - although it's behind the static_call API that the patch depends on ([5] in the original mail). > > That means we cannot actually > > call the static_calls for NULL slots, we'd get undefined behaviour > > (except for void hooks) - this is what Peter is talking about in the > > sibling thread. > > Referring to the "sibling thread" is kinda confusing, and > assumes everyone is one all the right mailing lists, and knows > which other thread you're talking about. Sure, sorry - here's the Lore link for future reference: https://lore.kernel.org/lkml/20200820164753.3256899-1-jackmanb@chromium.org/T/#m5a6fb3f10141049ce43e18a41f154796090ae1d5 > > > > For this reason, there are _no gaps_ in the callback table. For a > > given LSM hook, all the slots after base_slot_idx are filled, > > Why go to all the trouble of maintaining the base_slot_idx > if NOP is so cheap? Why not fill all unused slots with NOP? > Worst case would be a hook with no users, in which case you > have 11 NOPS in the void hook case and 11 "if (ret != DEFAULT_RET)" > and 11 NOPS in the int case. No switch magic required. Even > better, in the int case you have two calls/slot, the first is the > module supplied function (or NOP) and the second is > int isit(int ret) { return (ret != DEFAULT_RET) ? ret : 0; } > (or NOP). > > The no security module case degenerates to 22 NOP instructions > and no if checks of any sort. I'm not the performance guy, but > that seems better than maintaining and checking base_slot_idx > to me. The switch trick is not really motivated by performance. I think all the focus on the NOPs themselves is a bit misleading here - we _can't_ execute the NOPs for the int hooks, because there are instructions after them that expect a function to have just returned a value, which NOP doesn't do. When there is a NOP in the slot instead of a CALL, it would appear to "return" whatever value is leftover in the return register. At the C level, this is why the static_call API doesn't allow static_call_cond to return a value (which is what PeterZ is referring to in the thread I linked above). So, we could drop the switch trick for void hooks and just use static_call_cond, but this doesn't work for int hooks. IMO that variation between the two hook types would just add confusion. > >>> +#define __UNROLL_MACRO_LOOP_20(MACRO, ...) \ > >>> + __UNROLL_MACRO_LOOP_19(MACRO, __VA_ARGS__) \ > >>> + MACRO(19, __VA_ARGS__) > >>> + > >> Where does "20" come from? Why are you unrolling beyond 11? > > It's just an arbitrary limit on the unrolling macro implementation, we > > aren't actually unrolling beyond 11 where the macro is used (N is set > > to 11). > > I'm not a fan of including macros you can't use, especially > when they're just obvious variants of other macros. Not sure what you mean here - is there already a macro that does what UNROLL_MACRO_LOOP does?