All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kees Cook <keescook@chromium.org>
To: Bjorn Helgaas <helgaas@kernel.org>
Cc: Jess Frazelle <me@jessfraz.com>,
	"K. Y. Srinivasan" <kys@microsoft.com>,
	Haiyang Zhang <haiyangz@microsoft.com>,
	Stephen Hemminger <sthemmin@microsoft.com>,
	Bjorn Helgaas <bhelgaas@google.com>,
	Keith Busch <keith.busch@intel.com>,
	"open list:Hyper-V CORE AND DRIVERS"
	<devel@linuxdriverproject.org>,
	"open list:PCI SUBSYSTEM" <linux-pci@vger.kernel.org>,
	open list <linux-kernel@vger.kernel.org>,
	"kernel-hardening@lists.openwall.com" 
	<kernel-hardening@lists.openwall.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Marc Zyngier <marc.zyngier@arm.com>
Subject: Re: [PATCH v2 3/5] pci: set msi_domain_ops as __ro_after_init
Date: Wed, 15 Feb 2017 12:46:17 -0800	[thread overview]
Message-ID: <CAGXu5jJJMwBU_OyVV5QnrsNZ9Qu2PWSz_H9G4hCGA76NjSGjRg@mail.gmail.com> (raw)
In-Reply-To: <20170215203347.GA6981@bhelgaas-glaptop.roam.corp.google.com>

On Wed, Feb 15, 2017 at 12:33 PM, Bjorn Helgaas <helgaas@kernel.org> wrote:
> [+cc Kees, Thomas, Marc]
>
> Hi Jess,
>
> Thanks for the patch!
>
> On Fri, Feb 10, 2017 at 05:37:56PM -0800, Jess Frazelle wrote:
>> Marked msi_domain_ops structs as __ro_after_init when called only during init.
>> This protects the data structure from accidental corruption.
>>
>> Suggested-by: Kees Cook <keescook@chromium.org>
>> Signed-off-by: Jess Frazelle <me@jessfraz.com>
>> ---
>>  drivers/pci/host/pci-hyperv.c | 2 +-
>>  drivers/pci/host/vmd.c        | 2 +-
>>  drivers/pci/msi.c             | 2 +-
>
> I understand the value of __ro_after_init, but I'm not certain about
> sprinkling it around in seemingly random places because it's hard to
> know where to put it and whether we put it in all the right places.
>
> How did you choose these three files to change?  There are other
> instances of struct msi_domain_ops that use MSI_FLAG_USE_DEF_DOM_OPS.
> Should they be changed, too?  If not, is there a rule to figure out
> which ones should be made __ro_after_init?
>
> I wonder if adding __ro_after_init is really the best solution.  I
> looked at VMD to see how vmd_msi_domain_ops is updated.  Here are the
> definitions:
>
>   static struct msi_domain_ops vmd_msi_domain_ops = {
>     .get_hwirq = vmd_get_hwirq,
>     .msi_init  = vmd_msi_init,
>     ...
>   };
>
>   static struct msi_domain_info vmd_msi_domain_info = {
>     .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
>              MSI_FLAG_PCI_MSIX,
>     .ops = &vmd_msi_domain_ops,
>     ...
>   };
>
> Both vmd_msi_domain_ops and vmd_msi_domain_info are statically
> initialized, but not completely.  Then we pass a pointer to
> pci_msi_create_irq_domain(), which fills in defaults for some of the
> function pointers that weren't statically initialized:
>
>   vmd_enable_domain()
>     pci_msi_create_irq_domain(NULL, &vmd_msi_domain_info, ...)
>       if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS)
>         pci_msi_domain_update_dom_ops(info)
>           if (ops->set_desc == NULL)
>             ops->msi_check = pci_msi_domain_check_cap
>
> We know at build-time what all the function pointers will be, so in
> principle we should be able to make the struct const, which would be
> even better than __ro_after_init.
>
> For example, we could require that callers set every function pointer
> before calling pci_msi_create_irq_domain(), using the default ones
> (pci_msi_domain_set_desc, pci_msi_domain_check_cap,
> pci_msi_domain_handle_error) if it doesn't need to override them,
> e.g.,
>
>   static struct msi_domain_ops vmd_msi_domain_ops = {
>     .get_hwirq = vmd_get_hwirq,
>     .msi_check = pci_msi_domain_check_cap,
>   };
>
> Or we could leave NULL pointers in the structure and have the code
> that calls through the function pointers check for NULL and call the
> default itself, e.g.,
>
>   if (ops->msi_check)
>     ops->msi_check(...)
>   else
>     pci_msi_domain_check_cap(...)
>
> It looks like the "USE_DEF_OPS" framework was added by Jiang Liu with
> the commits below.  I would CC: him for his thoughts, but I don't
> have a current email address.
>
>   aeeb59657c35 ("genirq: Provide default callbacks for msi_domain_ops")
>   3878eaefb89a ("PCI/MSI: Enhance core to support hierarchy irqdomain")

If we can do const, that would be preferred. That's generally easier
to reason about. I ended up doing this to the cdrom ops structure just
the other day:

http://www.openwall.com/lists/kernel-hardening/2017/02/14/2

-Kees

-- 
Kees Cook
Pixel Security

WARNING: multiple messages have this Message-ID (diff)
From: Kees Cook <keescook@chromium.org>
To: Bjorn Helgaas <helgaas@kernel.org>
Cc: Jess Frazelle <me@jessfraz.com>,
	"K. Y. Srinivasan" <kys@microsoft.com>,
	Haiyang Zhang <haiyangz@microsoft.com>,
	Stephen Hemminger <sthemmin@microsoft.com>,
	Bjorn Helgaas <bhelgaas@google.com>,
	Keith Busch <keith.busch@intel.com>,
	"open list:Hyper-V CORE AND DRIVERS"
	<devel@linuxdriverproject.org>,
	"open list:PCI SUBSYSTEM" <linux-pci@vger.kernel.org>,
	open list <linux-kernel@vger.kernel.org>,
	"kernel-hardening@lists.openwall.com"
	<kernel-hardening@lists.openwall.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Marc Zyngier <marc.zyngier@arm.com>
Subject: [kernel-hardening] Re: [PATCH v2 3/5] pci: set msi_domain_ops as __ro_after_init
Date: Wed, 15 Feb 2017 12:46:17 -0800	[thread overview]
Message-ID: <CAGXu5jJJMwBU_OyVV5QnrsNZ9Qu2PWSz_H9G4hCGA76NjSGjRg@mail.gmail.com> (raw)
In-Reply-To: <20170215203347.GA6981@bhelgaas-glaptop.roam.corp.google.com>

On Wed, Feb 15, 2017 at 12:33 PM, Bjorn Helgaas <helgaas@kernel.org> wrote:
> [+cc Kees, Thomas, Marc]
>
> Hi Jess,
>
> Thanks for the patch!
>
> On Fri, Feb 10, 2017 at 05:37:56PM -0800, Jess Frazelle wrote:
>> Marked msi_domain_ops structs as __ro_after_init when called only during init.
>> This protects the data structure from accidental corruption.
>>
>> Suggested-by: Kees Cook <keescook@chromium.org>
>> Signed-off-by: Jess Frazelle <me@jessfraz.com>
>> ---
>>  drivers/pci/host/pci-hyperv.c | 2 +-
>>  drivers/pci/host/vmd.c        | 2 +-
>>  drivers/pci/msi.c             | 2 +-
>
> I understand the value of __ro_after_init, but I'm not certain about
> sprinkling it around in seemingly random places because it's hard to
> know where to put it and whether we put it in all the right places.
>
> How did you choose these three files to change?  There are other
> instances of struct msi_domain_ops that use MSI_FLAG_USE_DEF_DOM_OPS.
> Should they be changed, too?  If not, is there a rule to figure out
> which ones should be made __ro_after_init?
>
> I wonder if adding __ro_after_init is really the best solution.  I
> looked at VMD to see how vmd_msi_domain_ops is updated.  Here are the
> definitions:
>
>   static struct msi_domain_ops vmd_msi_domain_ops = {
>     .get_hwirq = vmd_get_hwirq,
>     .msi_init  = vmd_msi_init,
>     ...
>   };
>
>   static struct msi_domain_info vmd_msi_domain_info = {
>     .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
>              MSI_FLAG_PCI_MSIX,
>     .ops = &vmd_msi_domain_ops,
>     ...
>   };
>
> Both vmd_msi_domain_ops and vmd_msi_domain_info are statically
> initialized, but not completely.  Then we pass a pointer to
> pci_msi_create_irq_domain(), which fills in defaults for some of the
> function pointers that weren't statically initialized:
>
>   vmd_enable_domain()
>     pci_msi_create_irq_domain(NULL, &vmd_msi_domain_info, ...)
>       if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS)
>         pci_msi_domain_update_dom_ops(info)
>           if (ops->set_desc == NULL)
>             ops->msi_check = pci_msi_domain_check_cap
>
> We know at build-time what all the function pointers will be, so in
> principle we should be able to make the struct const, which would be
> even better than __ro_after_init.
>
> For example, we could require that callers set every function pointer
> before calling pci_msi_create_irq_domain(), using the default ones
> (pci_msi_domain_set_desc, pci_msi_domain_check_cap,
> pci_msi_domain_handle_error) if it doesn't need to override them,
> e.g.,
>
>   static struct msi_domain_ops vmd_msi_domain_ops = {
>     .get_hwirq = vmd_get_hwirq,
>     .msi_check = pci_msi_domain_check_cap,
>   };
>
> Or we could leave NULL pointers in the structure and have the code
> that calls through the function pointers check for NULL and call the
> default itself, e.g.,
>
>   if (ops->msi_check)
>     ops->msi_check(...)
>   else
>     pci_msi_domain_check_cap(...)
>
> It looks like the "USE_DEF_OPS" framework was added by Jiang Liu with
> the commits below.  I would CC: him for his thoughts, but I don't
> have a current email address.
>
>   aeeb59657c35 ("genirq: Provide default callbacks for msi_domain_ops")
>   3878eaefb89a ("PCI/MSI: Enhance core to support hierarchy irqdomain")

If we can do const, that would be preferred. That's generally easier
to reason about. I ended up doing this to the cdrom ops structure just
the other day:

http://www.openwall.com/lists/kernel-hardening/2017/02/14/2

-Kees

-- 
Kees Cook
Pixel Security

  reply	other threads:[~2017-02-15 20:46 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-11  1:37 [PATCH v2 1/5] irq: set {msi_domain,syscore}_ops as __ro_after_init Jess Frazelle
2017-02-11  1:37 ` [kernel-hardening] " Jess Frazelle
2017-02-11  1:37 ` [PATCH v2 2/5] time: mark syscore_ops " Jess Frazelle
2017-02-11  1:37   ` [kernel-hardening] " Jess Frazelle
2017-02-11  2:12   ` John Stultz
2017-02-11  2:12     ` [kernel-hardening] " John Stultz
2017-02-11  9:23     ` Thomas Gleixner
2017-02-11  9:23       ` [kernel-hardening] " Thomas Gleixner
2017-02-11  1:37 ` [PATCH v2 3/5] pci: set msi_domain_ops " Jess Frazelle
2017-02-11  1:37   ` [kernel-hardening] " Jess Frazelle
2017-02-12  4:08   ` KY Srinivasan
2017-02-12  4:08     ` [kernel-hardening] " KY Srinivasan
2017-02-12  4:08     ` KY Srinivasan
2017-02-13 18:14   ` Keith Busch
2017-02-13 18:14     ` [kernel-hardening] " Keith Busch
2017-02-15 20:33   ` Bjorn Helgaas
2017-02-15 20:33     ` [kernel-hardening] " Bjorn Helgaas
2017-02-15 20:46     ` Kees Cook [this message]
2017-02-15 20:46       ` Kees Cook
2017-02-15 20:46       ` Kees Cook
2017-02-15 21:16     ` Thomas Gleixner
2017-02-15 21:16       ` [kernel-hardening] " Thomas Gleixner
2017-02-16 14:35       ` Bjorn Helgaas
2017-02-16 14:35         ` [kernel-hardening] " Bjorn Helgaas
2017-02-16 14:38         ` Thomas Gleixner
2017-02-16 14:38           ` [kernel-hardening] " Thomas Gleixner
2017-03-07 19:07           ` Bjorn Helgaas
2017-03-07 19:07             ` [kernel-hardening] " Bjorn Helgaas
2017-03-14 18:50             ` Jessica Frazelle
2017-03-14 18:50               ` [kernel-hardening] " Jessica Frazelle
2017-03-14 19:24               ` Bjorn Helgaas
2017-03-14 19:24                 ` [kernel-hardening] " Bjorn Helgaas
2017-02-11  1:37 ` [PATCH v2 4/5] staging: " Jess Frazelle
2017-02-11  1:37   ` [kernel-hardening] " Jess Frazelle
2017-02-11  1:37 ` [PATCH v2 5/5] x86: " Jess Frazelle
2017-02-11  1:37   ` [kernel-hardening] " Jess Frazelle
2017-02-11  9:14 ` [PATCH v2 1/5] irq: set {msi_domain,syscore}_ops " Thomas Gleixner
2017-02-11  9:14   ` [kernel-hardening] " Thomas Gleixner
2017-02-11  9:23   ` Thomas Gleixner
2017-02-11  9:23     ` [kernel-hardening] " Thomas Gleixner
2017-02-11 10:48   ` Jess Frazelle
2017-02-11 10:48     ` [kernel-hardening] " Jess Frazelle
2017-02-11 12:00     ` Thomas Gleixner
2017-02-11 12:00       ` [kernel-hardening] " Thomas Gleixner
2017-02-11 12:17       ` Jessica Frazelle
2017-02-11 12:17         ` [kernel-hardening] " Jessica Frazelle

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAGXu5jJJMwBU_OyVV5QnrsNZ9Qu2PWSz_H9G4hCGA76NjSGjRg@mail.gmail.com \
    --to=keescook@chromium.org \
    --cc=bhelgaas@google.com \
    --cc=devel@linuxdriverproject.org \
    --cc=haiyangz@microsoft.com \
    --cc=helgaas@kernel.org \
    --cc=keith.busch@intel.com \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=kys@microsoft.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=marc.zyngier@arm.com \
    --cc=me@jessfraz.com \
    --cc=sthemmin@microsoft.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.