diff mbox series

[v3,29/70] xen/misc: CFI hardening

Message ID 20220222152645.8844-10-andrew.cooper3@citrix.com (mailing list archive)
State New, archived
Headers show
Series x86: Support for CET Indirect Branch Tracking | expand

Commit Message

Andrew Cooper Feb. 22, 2022, 3:26 p.m. UTC
Control Flow Integrity schemes use toolchain and optionally hardware support
to help protect against call/jump/return oriented programming attacks.

Use cf_check to annotate function pointer targets for the toolchain.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
v3
 * Annotations for gcov
---
 xen/arch/x86/mm.c                        | 6 ++++--
 xen/arch/x86/setup.c                     | 4 ++--
 xen/common/coverage/gcov.c               | 8 ++++----
 xen/common/domain.c                      | 2 +-
 xen/common/gdbstub.c                     | 5 ++---
 xen/common/livepatch.c                   | 7 +++----
 xen/common/memory.c                      | 4 ++--
 xen/common/page_alloc.c                  | 2 +-
 xen/common/radix-tree.c                  | 4 ++--
 xen/common/rangeset.c                    | 2 +-
 xen/common/spinlock.c                    | 6 +++---
 xen/common/vm_event.c                    | 6 +++---
 xen/common/xmalloc_tlsf.c                | 4 ++--
 xen/drivers/passthrough/amd/iommu_init.c | 2 +-
 xen/include/xen/domain.h                 | 2 +-
 15 files changed, 32 insertions(+), 32 deletions(-)

Comments

Jan Beulich Feb. 23, 2022, 10:25 a.m. UTC | #1
On 22.02.2022 16:26, Andrew Cooper wrote:
> Control Flow Integrity schemes use toolchain and optionally hardware support
> to help protect against call/jump/return oriented programming attacks.
> 
> Use cf_check to annotate function pointer targets for the toolchain.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Acked-by: Jan Beulich <jbeulich@suse.com>
> ---
> v3
>  * Annotations for gcov

Hmm, ...

> ---
>  xen/arch/x86/mm.c                        | 6 ++++--
>  xen/arch/x86/setup.c                     | 4 ++--
>  xen/common/coverage/gcov.c               | 8 ++++----

... what about llvm.c then?

Jan
Andrew Cooper Feb. 23, 2022, 10:34 a.m. UTC | #2
On 23/02/2022 10:25, Jan Beulich wrote:
> On 22.02.2022 16:26, Andrew Cooper wrote:
>> Control Flow Integrity schemes use toolchain and optionally hardware support
>> to help protect against call/jump/return oriented programming attacks.
>>
>> Use cf_check to annotate function pointer targets for the toolchain.
>>
>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
>> Acked-by: Jan Beulich <jbeulich@suse.com>
>> ---
>> v3
>>  * Annotations for gcov
> Hmm, ...
>
>> ---
>>  xen/arch/x86/mm.c                        | 6 ++++--
>>  xen/arch/x86/setup.c                     | 4 ++--
>>  xen/common/coverage/gcov.c               | 8 ++++----
> ... what about llvm.c then?

Good point.  I'll fix up.

There's currently no Clang toolchain capable of spotting/complaining at
this, but the Clang devs are working on this.

~Andrew
diff mbox series

Patch

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index a1b8737096c4..0665095d2309 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -835,7 +835,8 @@  struct mmio_emul_range_ctxt {
     unsigned long mfn;
 };
 
-static int print_mmio_emul_range(unsigned long s, unsigned long e, void *arg)
+static int cf_check print_mmio_emul_range(
+    unsigned long s, unsigned long e, void *arg)
 {
     const struct mmio_emul_range_ctxt *ctxt = arg;
 
@@ -4606,7 +4607,8 @@  static int _handle_iomem_range(unsigned long s, unsigned long e,
     return 0;
 }
 
-static int handle_iomem_range(unsigned long s, unsigned long e, void *p)
+static int cf_check handle_iomem_range(
+    unsigned long s, unsigned long e, void *p)
 {
     int err = 0;
 
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 3a4ec1fcfd04..a9a371336b36 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -2021,8 +2021,8 @@  int __hwdom_init xen_in_range(unsigned long mfn)
     return 0;
 }
 
-static int __hwdom_init io_bitmap_cb(unsigned long s, unsigned long e,
-                                     void *ctx)
+static int __hwdom_init cf_check io_bitmap_cb(
+    unsigned long s, unsigned long e, void *ctx)
 {
     struct domain *d = ctx;
     unsigned int i;
diff --git a/xen/common/coverage/gcov.c b/xen/common/coverage/gcov.c
index 3cc98728bfce..327bf8d646c0 100644
--- a/xen/common/coverage/gcov.c
+++ b/xen/common/coverage/gcov.c
@@ -120,7 +120,7 @@  static int gcov_info_dump_payload(const struct gcov_info *info,
 
 }
 
-static uint32_t gcov_get_size(void)
+static uint32_t cf_check gcov_get_size(void)
 {
     uint32_t total_size = sizeof(uint32_t); /* Magic number XCOV */
     struct gcov_info *info = NULL;
@@ -140,7 +140,7 @@  static uint32_t gcov_get_size(void)
     return total_size;
 }
 
-static void gcov_reset_all_counters(void)
+static void cf_check gcov_reset_all_counters(void)
 {
     struct gcov_info *info = NULL;
 
@@ -172,8 +172,8 @@  static int gcov_dump_one_record(const struct gcov_info *info,
     return gcov_info_dump_payload(info, buffer, off);
 }
 
-static int gcov_dump_all(XEN_GUEST_HANDLE_PARAM(char) buffer,
-                         uint32_t *buffer_size)
+static int cf_check gcov_dump_all(
+    XEN_GUEST_HANDLE_PARAM(char) buffer, uint32_t *buffer_size)
 {
     uint32_t off;
     uint32_t magic = XEN_GCOV_FORMAT_MAGIC;
diff --git a/xen/common/domain.c b/xen/common/domain.c
index f3d06df76c33..351029f8b239 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -1803,7 +1803,7 @@  static void cf_check _free_pirq_struct(struct rcu_head *head)
     xfree(container_of(head, struct pirq, rcu_head));
 }
 
-void free_pirq_struct(void *ptr)
+void cf_check free_pirq_struct(void *ptr)
 {
     struct pirq *pirq = ptr;
 
diff --git a/xen/common/gdbstub.c b/xen/common/gdbstub.c
index 079c3ca9616a..d6872721dc0d 100644
--- a/xen/common/gdbstub.c
+++ b/xen/common/gdbstub.c
@@ -69,7 +69,7 @@  static void gdb_smp_resume(void);
 static char __initdata opt_gdb[30];
 string_param("gdb", opt_gdb);
 
-static void gdbstub_console_puts(const char *str, size_t nr);
+static void cf_check gdbstub_console_puts(const char *str, size_t nr);
 
 /* value <-> char (de)serialzers */
 static char
@@ -546,8 +546,7 @@  __gdb_ctx = {
 };
 static struct gdb_context *gdb_ctx = &__gdb_ctx;
 
-static void
-gdbstub_console_puts(const char *str, size_t nr)
+static void cf_check gdbstub_console_puts(const char *str, size_t nr)
 {
     const char *p;
 
diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
index e8714920dc8f..ec301a9f120c 100644
--- a/xen/common/livepatch.c
+++ b/xen/common/livepatch.c
@@ -157,10 +157,9 @@  unsigned long livepatch_symbols_lookup_by_name(const char *symname)
     return 0;
 }
 
-static const char *livepatch_symbols_lookup(unsigned long addr,
-                                            unsigned long *symbolsize,
-                                            unsigned long *offset,
-                                            char *namebuf)
+static const char *cf_check livepatch_symbols_lookup(
+    unsigned long addr, unsigned long *symbolsize, unsigned long *offset,
+    char *namebuf)
 {
     const struct payload *data;
     unsigned int i, best;
diff --git a/xen/common/memory.c b/xen/common/memory.c
index ede45c4af9db..69b0cd1e50de 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -1051,8 +1051,8 @@  struct get_reserved_device_memory {
     unsigned int used_entries;
 };
 
-static int get_reserved_device_memory(xen_pfn_t start, xen_ulong_t nr,
-                                      u32 id, void *ctxt)
+static int cf_check get_reserved_device_memory(
+    xen_pfn_t start, xen_ulong_t nr, u32 id, void *ctxt)
 {
     struct get_reserved_device_memory *grdm = ctxt;
     uint32_t sbdf = PCI_SBDF3(grdm->map.dev.pci.seg, grdm->map.dev.pci.bus,
diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
index 3caf5c954b24..46357182375a 100644
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -1238,7 +1238,7 @@  struct scrub_wait_state {
     bool drop;
 };
 
-static void scrub_continue(void *data)
+static void cf_check scrub_continue(void *data)
 {
     struct scrub_wait_state *st = data;
 
diff --git a/xen/common/radix-tree.c b/xen/common/radix-tree.c
index 33b47748ae49..adc3034222dc 100644
--- a/xen/common/radix-tree.c
+++ b/xen/common/radix-tree.c
@@ -52,7 +52,7 @@  struct rcu_node {
 	struct rcu_head rcu_head;
 };
 
-static struct radix_tree_node *rcu_node_alloc(void *arg)
+static struct radix_tree_node *cf_check rcu_node_alloc(void *arg)
 {
 	struct rcu_node *rcu_node = xmalloc(struct rcu_node);
 	return rcu_node ? &rcu_node->node : NULL;
@@ -65,7 +65,7 @@  static void cf_check _rcu_node_free(struct rcu_head *head)
 	xfree(rcu_node);
 }
 
-static void rcu_node_free(struct radix_tree_node *node, void *arg)
+static void cf_check rcu_node_free(struct radix_tree_node *node, void *arg)
 {
 	struct rcu_node *rcu_node = container_of(node, struct rcu_node, node);
 	call_rcu(&rcu_node->rcu_head, _rcu_node_free);
diff --git a/xen/common/rangeset.c b/xen/common/rangeset.c
index 885b6b15c229..a6ef2640462a 100644
--- a/xen/common/rangeset.c
+++ b/xen/common/rangeset.c
@@ -384,7 +384,7 @@  int rangeset_consume_ranges(struct rangeset *r,
     return rc;
 }
 
-static int merge(unsigned long s, unsigned long e, void *data)
+static int cf_check merge(unsigned long s, unsigned long e, void *data)
 {
     struct rangeset *r = data;
 
diff --git a/xen/common/spinlock.c b/xen/common/spinlock.c
index 25bfbf3c47f7..62c83aaa6a73 100644
--- a/xen/common/spinlock.c
+++ b/xen/common/spinlock.c
@@ -375,7 +375,7 @@  static void spinlock_profile_iterate(lock_profile_subfunc *sub, void *par)
     spin_unlock(&lock_profile_lock);
 }
 
-static void spinlock_profile_print_elem(struct lock_profile *data,
+static void cf_check spinlock_profile_print_elem(struct lock_profile *data,
     int32_t type, int32_t idx, void *par)
 {
     struct spinlock *lock = data->lock;
@@ -404,7 +404,7 @@  void cf_check spinlock_profile_printall(unsigned char key)
     spinlock_profile_iterate(spinlock_profile_print_elem, NULL);
 }
 
-static void spinlock_profile_reset_elem(struct lock_profile *data,
+static void cf_check spinlock_profile_reset_elem(struct lock_profile *data,
     int32_t type, int32_t idx, void *par)
 {
     data->lock_cnt = 0;
@@ -428,7 +428,7 @@  typedef struct {
     int                      rc;
 } spinlock_profile_ucopy_t;
 
-static void spinlock_profile_ucopy_elem(struct lock_profile *data,
+static void cf_check spinlock_profile_ucopy_elem(struct lock_profile *data,
     int32_t type, int32_t idx, void *par)
 {
     spinlock_profile_ucopy_t *p = par;
diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
index 70ab3ba406ff..84cf52636bc4 100644
--- a/xen/common/vm_event.c
+++ b/xen/common/vm_event.c
@@ -523,21 +523,21 @@  int __vm_event_claim_slot(struct domain *d, struct vm_event_domain *ved,
 
 #ifdef CONFIG_MEM_PAGING
 /* Registered with Xen-bound event channel for incoming notifications. */
-static void mem_paging_notification(struct vcpu *v, unsigned int port)
+static void cf_check mem_paging_notification(struct vcpu *v, unsigned int port)
 {
     vm_event_resume(v->domain, v->domain->vm_event_paging);
 }
 #endif
 
 /* Registered with Xen-bound event channel for incoming notifications. */
-static void monitor_notification(struct vcpu *v, unsigned int port)
+static void cf_check monitor_notification(struct vcpu *v, unsigned int port)
 {
     vm_event_resume(v->domain, v->domain->vm_event_monitor);
 }
 
 #ifdef CONFIG_MEM_SHARING
 /* Registered with Xen-bound event channel for incoming notifications. */
-static void mem_sharing_notification(struct vcpu *v, unsigned int port)
+static void cf_check mem_sharing_notification(struct vcpu *v, unsigned int port)
 {
     vm_event_resume(v->domain, v->domain->vm_event_share);
 }
diff --git a/xen/common/xmalloc_tlsf.c b/xen/common/xmalloc_tlsf.c
index e3f6886e6b62..d2ad909502d0 100644
--- a/xen/common/xmalloc_tlsf.c
+++ b/xen/common/xmalloc_tlsf.c
@@ -512,13 +512,13 @@  int xmem_pool_maxalloc(struct xmem_pool *pool)
 
 static struct xmem_pool *xenpool;
 
-static void *xmalloc_pool_get(unsigned long size)
+static void *cf_check xmalloc_pool_get(unsigned long size)
 {
     ASSERT(size == PAGE_SIZE);
     return alloc_xenheap_page();
 }
 
-static void xmalloc_pool_put(void *p)
+static void cf_check xmalloc_pool_put(void *p)
 {
     free_xenheap_page(p);
 }
diff --git a/xen/drivers/passthrough/amd/iommu_init.c b/xen/drivers/passthrough/amd/iommu_init.c
index 06b4d2b1fea0..cebcd68a6c04 100644
--- a/xen/drivers/passthrough/amd/iommu_init.c
+++ b/xen/drivers/passthrough/amd/iommu_init.c
@@ -1073,7 +1073,7 @@  static void * __init allocate_ppr_log(struct amd_iommu *iommu)
 #define IVRS_MAPPINGS_DEVTAB(m) (m)[ivrs_bdf_entries].intremap_table
 
 /* Gets passed to radix_tree_destroy(), so its param needs to be void *. */
-static void __init free_ivrs_mapping_callback(void *ptr)
+static void __init cf_check free_ivrs_mapping_callback(void *ptr)
 {
     const struct ivrs_mappings *ivrs_mappings = ptr;
 
diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h
index 24eb4cc7d37e..1c3c88a14d6f 100644
--- a/xen/include/xen/domain.h
+++ b/xen/include/xen/domain.h
@@ -52,7 +52,7 @@  void free_vcpu_struct(struct vcpu *v);
 #ifndef alloc_pirq_struct
 struct pirq *alloc_pirq_struct(struct domain *);
 #endif
-void free_pirq_struct(void *);
+void cf_check free_pirq_struct(void *);
 
 /*
  * Initialise/destroy arch-specific details of a VCPU.