mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
xen/evtchn: CFI hardening
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>
This commit is contained in:
1 parent
15268d2ea3
commit
fcbae94ea4
3 files changed
+30
-24
No files matched your search
+12
-9
@@ -16,7 +16,8 @@
|
||||
|
||||
#include <asm/guest_atomics.h>
|
||||
|
||||
static void evtchn_2l_set_pending(struct vcpu *v, struct evtchn *evtchn)
|
||||
static void cf_check evtchn_2l_set_pending(
|
||||
struct vcpu *v, struct evtchn *evtchn)
|
||||
{
|
||||
struct domain *d = v->domain;
|
||||
unsigned int port = evtchn->port;
|
||||
@@ -41,12 +42,14 @@ static void evtchn_2l_set_pending(struct vcpu *v, struct evtchn *evtchn)
|
||||
evtchn_check_pollers(d, port);
|
||||
}
|
||||
|
||||
static void evtchn_2l_clear_pending(struct domain *d, struct evtchn *evtchn)
|
||||
static void cf_check evtchn_2l_clear_pending(
|
||||
struct domain *d, struct evtchn *evtchn)
|
||||
{
|
||||
guest_clear_bit(d, evtchn->port, &shared_info(d, evtchn_pending));
|
||||
}
|
||||
|
||||
static void evtchn_2l_unmask(struct domain *d, struct evtchn *evtchn)
|
||||
static void cf_check evtchn_2l_unmask(
|
||||
struct domain *d, struct evtchn *evtchn)
|
||||
{
|
||||
struct vcpu *v = d->vcpu[evtchn->notify_vcpu_id];
|
||||
unsigned int port = evtchn->port;
|
||||
@@ -64,8 +67,8 @@ static void evtchn_2l_unmask(struct domain *d, struct evtchn *evtchn)
|
||||
}
|
||||
}
|
||||
|
||||
static bool evtchn_2l_is_pending(const struct domain *d,
|
||||
const struct evtchn *evtchn)
|
||||
static bool cf_check evtchn_2l_is_pending(
|
||||
const struct domain *d, const struct evtchn *evtchn)
|
||||
{
|
||||
evtchn_port_t port = evtchn->port;
|
||||
unsigned int max_ports = BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d);
|
||||
@@ -75,8 +78,8 @@ static bool evtchn_2l_is_pending(const struct domain *d,
|
||||
guest_test_bit(d, port, &shared_info(d, evtchn_pending)));
|
||||
}
|
||||
|
||||
static bool evtchn_2l_is_masked(const struct domain *d,
|
||||
const struct evtchn *evtchn)
|
||||
static bool cf_check evtchn_2l_is_masked(
|
||||
const struct domain *d, const struct evtchn *evtchn)
|
||||
{
|
||||
evtchn_port_t port = evtchn->port;
|
||||
unsigned int max_ports = BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d);
|
||||
@@ -86,8 +89,8 @@ static bool evtchn_2l_is_masked(const struct domain *d,
|
||||
guest_test_bit(d, port, &shared_info(d, evtchn_mask)));
|
||||
}
|
||||
|
||||
static void evtchn_2l_print_state(struct domain *d,
|
||||
const struct evtchn *evtchn)
|
||||
static void cf_check evtchn_2l_print_state(
|
||||
struct domain *d, const struct evtchn *evtchn)
|
||||
{
|
||||
struct vcpu *v = d->vcpu[evtchn->notify_vcpu_id];
|
||||
|
||||
|
||||
@@ -99,7 +99,8 @@ static xen_event_channel_notification_t __read_mostly
|
||||
xen_consumers[NR_XEN_CONSUMERS];
|
||||
|
||||
/* Default notification action: wake up from wait_on_xen_event_channel(). */
|
||||
static void default_xen_notification_fn(struct vcpu *v, unsigned int port)
|
||||
static void cf_check default_xen_notification_fn(
|
||||
struct vcpu *v, unsigned int port)
|
||||
{
|
||||
/* Consumer needs notification only if blocked. */
|
||||
if ( test_and_clear_bit(_VPF_blocked_in_xen, &v->pause_flags) )
|
||||
|
||||
+16
-14
@@ -78,7 +78,7 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
|
||||
return d->evtchn_fifo->event_array[p] + w;
|
||||
}
|
||||
|
||||
static void evtchn_fifo_init(struct domain *d, struct evtchn *evtchn)
|
||||
static void cf_check evtchn_fifo_init(struct domain *d, struct evtchn *evtchn)
|
||||
{
|
||||
event_word_t *word;
|
||||
|
||||
@@ -158,7 +158,8 @@ static bool_t evtchn_fifo_set_link(struct domain *d, event_word_t *word,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
|
||||
static void cf_check evtchn_fifo_set_pending(
|
||||
struct vcpu *v, struct evtchn *evtchn)
|
||||
{
|
||||
struct domain *d = v->domain;
|
||||
unsigned int port;
|
||||
@@ -317,7 +318,8 @@ static void evtchn_fifo_set_pending(struct vcpu *v, struct evtchn *evtchn)
|
||||
evtchn_check_pollers(d, port);
|
||||
}
|
||||
|
||||
static void evtchn_fifo_clear_pending(struct domain *d, struct evtchn *evtchn)
|
||||
static void cf_check evtchn_fifo_clear_pending(
|
||||
struct domain *d, struct evtchn *evtchn)
|
||||
{
|
||||
event_word_t *word;
|
||||
|
||||
@@ -334,7 +336,7 @@ static void evtchn_fifo_clear_pending(struct domain *d, struct evtchn *evtchn)
|
||||
guest_clear_bit(d, EVTCHN_FIFO_PENDING, word);
|
||||
}
|
||||
|
||||
static void evtchn_fifo_unmask(struct domain *d, struct evtchn *evtchn)
|
||||
static void cf_check evtchn_fifo_unmask(struct domain *d, struct evtchn *evtchn)
|
||||
{
|
||||
struct vcpu *v = d->vcpu[evtchn->notify_vcpu_id];
|
||||
event_word_t *word;
|
||||
@@ -350,32 +352,32 @@ static void evtchn_fifo_unmask(struct domain *d, struct evtchn *evtchn)
|
||||
evtchn_fifo_set_pending(v, evtchn);
|
||||
}
|
||||
|
||||
static bool evtchn_fifo_is_pending(const struct domain *d,
|
||||
const struct evtchn *evtchn)
|
||||
static bool cf_check evtchn_fifo_is_pending(
|
||||
const struct domain *d, const struct evtchn *evtchn)
|
||||
{
|
||||
const event_word_t *word = evtchn_fifo_word_from_port(d, evtchn->port);
|
||||
|
||||
return word && guest_test_bit(d, EVTCHN_FIFO_PENDING, word);
|
||||
}
|
||||
|
||||
static bool_t evtchn_fifo_is_masked(const struct domain *d,
|
||||
const struct evtchn *evtchn)
|
||||
static bool cf_check evtchn_fifo_is_masked(
|
||||
const struct domain *d, const struct evtchn *evtchn)
|
||||
{
|
||||
const event_word_t *word = evtchn_fifo_word_from_port(d, evtchn->port);
|
||||
|
||||
return !word || guest_test_bit(d, EVTCHN_FIFO_MASKED, word);
|
||||
}
|
||||
|
||||
static bool_t evtchn_fifo_is_busy(const struct domain *d,
|
||||
const struct evtchn *evtchn)
|
||||
static bool cf_check evtchn_fifo_is_busy(
|
||||
const struct domain *d, const struct evtchn *evtchn)
|
||||
{
|
||||
const event_word_t *word = evtchn_fifo_word_from_port(d, evtchn->port);
|
||||
|
||||
return word && guest_test_bit(d, EVTCHN_FIFO_LINKED, word);
|
||||
}
|
||||
|
||||
static int evtchn_fifo_set_priority(struct domain *d, struct evtchn *evtchn,
|
||||
unsigned int priority)
|
||||
static int cf_check evtchn_fifo_set_priority(
|
||||
struct domain *d, struct evtchn *evtchn, unsigned int priority)
|
||||
{
|
||||
if ( priority > EVTCHN_FIFO_PRIORITY_MIN )
|
||||
return -EINVAL;
|
||||
@@ -390,8 +392,8 @@ static int evtchn_fifo_set_priority(struct domain *d, struct evtchn *evtchn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void evtchn_fifo_print_state(struct domain *d,
|
||||
const struct evtchn *evtchn)
|
||||
static void cf_check evtchn_fifo_print_state(
|
||||
struct domain *d, const struct evtchn *evtchn)
|
||||
{
|
||||
event_word_t *word;
|
||||
|
||||
|
||||