All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] Add support for using the Undefined Behaviour Sanitizer
@ 2017-10-09 14:11 Wei Liu
  2017-10-09 14:11 ` [PATCH v2 1/3] xen/ubsan: Import ubsan implementation from Linux 4.13 Wei Liu
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Wei Liu @ 2017-10-09 14:11 UTC (permalink / raw)
  To: Xen-devel
  Cc: Andrew Cooper, Julien Grall, Stefano Stabellini, Wei Liu, Jan Beulich

Andrew Cooper (2):
  xen/ubsan: Import ubsan implementation from Linux 4.13
  xen/ubsan: Implement __ubsan_handle_nonnull_arg()

Wei Liu (1):
  xen: hook up UBSAN with CONFIG_UBSAN

Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Julien Grall <julien.grall@arm.com>

 xen/Kconfig               |   6 +
 xen/Kconfig.debug         |  10 +
 xen/Rules.mk              |   4 +
 xen/arch/x86/Kconfig      |   2 +
 xen/common/Kconfig        |   3 +
 xen/common/Makefile       |   1 +
 xen/common/ubsan/Makefile |   1 +
 xen/common/ubsan/ubsan.c  | 480 ++++++++++++++++++++++++++++++++++++++++++++++
 xen/common/ubsan/ubsan.h  |  84 ++++++++
 9 files changed, 591 insertions(+)
 create mode 100644 xen/common/ubsan/Makefile
 create mode 100644 xen/common/ubsan/ubsan.c
 create mode 100644 xen/common/ubsan/ubsan.h

-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 1/3] xen/ubsan: Import ubsan implementation from Linux 4.13
  2017-10-09 14:11 [PATCH v2 0/3] Add support for using the Undefined Behaviour Sanitizer Wei Liu
@ 2017-10-09 14:11 ` Wei Liu
  2017-10-09 14:11 ` [PATCH v2 2/3] xen/ubsan: Implement __ubsan_handle_nonnull_arg() Wei Liu
  2017-10-09 14:11 ` [PATCH v2 3/3] xen: hook up UBSAN with CONFIG_UBSAN Wei Liu
  2 siblings, 0 replies; 11+ messages in thread
From: Wei Liu @ 2017-10-09 14:11 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Wei Liu

From: Andrew Cooper <andrew.cooper3@citrix.com>

A future change will adjust it to compile in Xen.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Wei Liu <wei.liu2@citrix.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/ubsan/Makefile |   1 +
 xen/common/ubsan/ubsan.c  | 456 ++++++++++++++++++++++++++++++++++++++++++++++
 xen/common/ubsan/ubsan.h  |  84 +++++++++
 3 files changed, 541 insertions(+)
 create mode 100644 xen/common/ubsan/Makefile
 create mode 100644 xen/common/ubsan/ubsan.c
 create mode 100644 xen/common/ubsan/ubsan.h

diff --git a/xen/common/ubsan/Makefile b/xen/common/ubsan/Makefile
new file mode 100644
index 0000000000..e6b85ea187
--- /dev/null
+++ b/xen/common/ubsan/Makefile
@@ -0,0 +1 @@
+obj-y += ubsan.o
diff --git a/xen/common/ubsan/ubsan.c b/xen/common/ubsan/ubsan.c
new file mode 100644
index 0000000000..fb0409df1b
--- /dev/null
+++ b/xen/common/ubsan/ubsan.c
@@ -0,0 +1,456 @@
+/*
+ * UBSAN error reporting functions
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Author: Andrey Ryabinin <ryabinin.a.a@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/bitops.h>
+#include <linux/bug.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+
+#include "ubsan.h"
+
+const char *type_check_kinds[] = {
+	"load of",
+	"store to",
+	"reference binding to",
+	"member access within",
+	"member call on",
+	"constructor call on",
+	"downcast of",
+	"downcast of"
+};
+
+#define REPORTED_BIT 31
+
+#if (BITS_PER_LONG == 64) && defined(__BIG_ENDIAN)
+#define COLUMN_MASK (~(1U << REPORTED_BIT))
+#define LINE_MASK   (~0U)
+#else
+#define COLUMN_MASK   (~0U)
+#define LINE_MASK (~(1U << REPORTED_BIT))
+#endif
+
+#define VALUE_LENGTH 40
+
+static bool was_reported(struct source_location *location)
+{
+	return test_and_set_bit(REPORTED_BIT, &location->reported);
+}
+
+static void print_source_location(const char *prefix,
+				struct source_location *loc)
+{
+	pr_err("%s %s:%d:%d\n", prefix, loc->file_name,
+		loc->line & LINE_MASK, loc->column & COLUMN_MASK);
+}
+
+static bool suppress_report(struct source_location *loc)
+{
+	return current->in_ubsan || was_reported(loc);
+}
+
+static bool type_is_int(struct type_descriptor *type)
+{
+	return type->type_kind == type_kind_int;
+}
+
+static bool type_is_signed(struct type_descriptor *type)
+{
+	WARN_ON(!type_is_int(type));
+	return  type->type_info & 1;
+}
+
+static unsigned type_bit_width(struct type_descriptor *type)
+{
+	return 1 << (type->type_info >> 1);
+}
+
+static bool is_inline_int(struct type_descriptor *type)
+{
+	unsigned inline_bits = sizeof(unsigned long)*8;
+	unsigned bits = type_bit_width(type);
+
+	WARN_ON(!type_is_int(type));
+
+	return bits <= inline_bits;
+}
+
+static s_max get_signed_val(struct type_descriptor *type, unsigned long val)
+{
+	if (is_inline_int(type)) {
+		unsigned extra_bits = sizeof(s_max)*8 - type_bit_width(type);
+		return ((s_max)val) << extra_bits >> extra_bits;
+	}
+
+	if (type_bit_width(type) == 64)
+		return *(s64 *)val;
+
+	return *(s_max *)val;
+}
+
+static bool val_is_negative(struct type_descriptor *type, unsigned long val)
+{
+	return type_is_signed(type) && get_signed_val(type, val) < 0;
+}
+
+static u_max get_unsigned_val(struct type_descriptor *type, unsigned long val)
+{
+	if (is_inline_int(type))
+		return val;
+
+	if (type_bit_width(type) == 64)
+		return *(u64 *)val;
+
+	return *(u_max *)val;
+}
+
+static void val_to_string(char *str, size_t size, struct type_descriptor *type,
+	unsigned long value)
+{
+	if (type_is_int(type)) {
+		if (type_bit_width(type) == 128) {
+#if defined(CONFIG_ARCH_SUPPORTS_INT128) && defined(__SIZEOF_INT128__)
+			u_max val = get_unsigned_val(type, value);
+
+			scnprintf(str, size, "0x%08x%08x%08x%08x",
+				(u32)(val >> 96),
+				(u32)(val >> 64),
+				(u32)(val >> 32),
+				(u32)(val));
+#else
+			WARN_ON(1);
+#endif
+		} else if (type_is_signed(type)) {
+			scnprintf(str, size, "%lld",
+				(s64)get_signed_val(type, value));
+		} else {
+			scnprintf(str, size, "%llu",
+				(u64)get_unsigned_val(type, value));
+		}
+	}
+}
+
+static bool location_is_valid(struct source_location *loc)
+{
+	return loc->file_name != NULL;
+}
+
+static DEFINE_SPINLOCK(report_lock);
+
+static void ubsan_prologue(struct source_location *location,
+			unsigned long *flags)
+{
+	current->in_ubsan++;
+	spin_lock_irqsave(&report_lock, *flags);
+
+	pr_err("========================================"
+		"========================================\n");
+	print_source_location("UBSAN: Undefined behaviour in", location);
+}
+
+static void ubsan_epilogue(unsigned long *flags)
+{
+	dump_stack();
+	pr_err("========================================"
+		"========================================\n");
+	spin_unlock_irqrestore(&report_lock, *flags);
+	current->in_ubsan--;
+}
+
+static void handle_overflow(struct overflow_data *data, unsigned long lhs,
+			unsigned long rhs, char op)
+{
+
+	struct type_descriptor *type = data->type;
+	unsigned long flags;
+	char lhs_val_str[VALUE_LENGTH];
+	char rhs_val_str[VALUE_LENGTH];
+
+	if (suppress_report(&data->location))
+		return;
+
+	ubsan_prologue(&data->location, &flags);
+
+	val_to_string(lhs_val_str, sizeof(lhs_val_str), type, lhs);
+	val_to_string(rhs_val_str, sizeof(rhs_val_str), type, rhs);
+	pr_err("%s integer overflow:\n",
+		type_is_signed(type) ? "signed" : "unsigned");
+	pr_err("%s %c %s cannot be represented in type %s\n",
+		lhs_val_str,
+		op,
+		rhs_val_str,
+		type->type_name);
+
+	ubsan_epilogue(&flags);
+}
+
+void __ubsan_handle_add_overflow(struct overflow_data *data,
+				unsigned long lhs,
+				unsigned long rhs)
+{
+
+	handle_overflow(data, lhs, rhs, '+');
+}
+EXPORT_SYMBOL(__ubsan_handle_add_overflow);
+
+void __ubsan_handle_sub_overflow(struct overflow_data *data,
+				unsigned long lhs,
+				unsigned long rhs)
+{
+	handle_overflow(data, lhs, rhs, '-');
+}
+EXPORT_SYMBOL(__ubsan_handle_sub_overflow);
+
+void __ubsan_handle_mul_overflow(struct overflow_data *data,
+				unsigned long lhs,
+				unsigned long rhs)
+{
+	handle_overflow(data, lhs, rhs, '*');
+}
+EXPORT_SYMBOL(__ubsan_handle_mul_overflow);
+
+void __ubsan_handle_negate_overflow(struct overflow_data *data,
+				unsigned long old_val)
+{
+	unsigned long flags;
+	char old_val_str[VALUE_LENGTH];
+
+	if (suppress_report(&data->location))
+		return;
+
+	ubsan_prologue(&data->location, &flags);
+
+	val_to_string(old_val_str, sizeof(old_val_str), data->type, old_val);
+
+	pr_err("negation of %s cannot be represented in type %s:\n",
+		old_val_str, data->type->type_name);
+
+	ubsan_epilogue(&flags);
+}
+EXPORT_SYMBOL(__ubsan_handle_negate_overflow);
+
+
+void __ubsan_handle_divrem_overflow(struct overflow_data *data,
+				unsigned long lhs,
+				unsigned long rhs)
+{
+	unsigned long flags;
+	char rhs_val_str[VALUE_LENGTH];
+
+	if (suppress_report(&data->location))
+		return;
+
+	ubsan_prologue(&data->location, &flags);
+
+	val_to_string(rhs_val_str, sizeof(rhs_val_str), data->type, rhs);
+
+	if (type_is_signed(data->type) && get_signed_val(data->type, rhs) == -1)
+		pr_err("division of %s by -1 cannot be represented in type %s\n",
+			rhs_val_str, data->type->type_name);
+	else
+		pr_err("division by zero\n");
+
+	ubsan_epilogue(&flags);
+}
+EXPORT_SYMBOL(__ubsan_handle_divrem_overflow);
+
+static void handle_null_ptr_deref(struct type_mismatch_data *data)
+{
+	unsigned long flags;
+
+	if (suppress_report(&data->location))
+		return;
+
+	ubsan_prologue(&data->location, &flags);
+
+	pr_err("%s null pointer of type %s\n",
+		type_check_kinds[data->type_check_kind],
+		data->type->type_name);
+
+	ubsan_epilogue(&flags);
+}
+
+static void handle_missaligned_access(struct type_mismatch_data *data,
+				unsigned long ptr)
+{
+	unsigned long flags;
+
+	if (suppress_report(&data->location))
+		return;
+
+	ubsan_prologue(&data->location, &flags);
+
+	pr_err("%s misaligned address %p for type %s\n",
+		type_check_kinds[data->type_check_kind],
+		(void *)ptr, data->type->type_name);
+	pr_err("which requires %ld byte alignment\n", data->alignment);
+
+	ubsan_epilogue(&flags);
+}
+
+static void handle_object_size_mismatch(struct type_mismatch_data *data,
+					unsigned long ptr)
+{
+	unsigned long flags;
+
+	if (suppress_report(&data->location))
+		return;
+
+	ubsan_prologue(&data->location, &flags);
+	pr_err("%s address %p with insufficient space\n",
+		type_check_kinds[data->type_check_kind],
+		(void *) ptr);
+	pr_err("for an object of type %s\n", data->type->type_name);
+	ubsan_epilogue(&flags);
+}
+
+void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
+				unsigned long ptr)
+{
+
+	if (!ptr)
+		handle_null_ptr_deref(data);
+	else if (data->alignment && !IS_ALIGNED(ptr, data->alignment))
+		handle_missaligned_access(data, ptr);
+	else
+		handle_object_size_mismatch(data, ptr);
+}
+EXPORT_SYMBOL(__ubsan_handle_type_mismatch);
+
+void __ubsan_handle_nonnull_return(struct nonnull_return_data *data)
+{
+	unsigned long flags;
+
+	if (suppress_report(&data->location))
+		return;
+
+	ubsan_prologue(&data->location, &flags);
+
+	pr_err("null pointer returned from function declared to never return null\n");
+
+	if (location_is_valid(&data->attr_location))
+		print_source_location("returns_nonnull attribute specified in",
+				&data->attr_location);
+
+	ubsan_epilogue(&flags);
+}
+EXPORT_SYMBOL(__ubsan_handle_nonnull_return);
+
+void __ubsan_handle_vla_bound_not_positive(struct vla_bound_data *data,
+					unsigned long bound)
+{
+	unsigned long flags;
+	char bound_str[VALUE_LENGTH];
+
+	if (suppress_report(&data->location))
+		return;
+
+	ubsan_prologue(&data->location, &flags);
+
+	val_to_string(bound_str, sizeof(bound_str), data->type, bound);
+	pr_err("variable length array bound value %s <= 0\n", bound_str);
+
+	ubsan_epilogue(&flags);
+}
+EXPORT_SYMBOL(__ubsan_handle_vla_bound_not_positive);
+
+void __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data,
+				unsigned long index)
+{
+	unsigned long flags;
+	char index_str[VALUE_LENGTH];
+
+	if (suppress_report(&data->location))
+		return;
+
+	ubsan_prologue(&data->location, &flags);
+
+	val_to_string(index_str, sizeof(index_str), data->index_type, index);
+	pr_err("index %s is out of range for type %s\n", index_str,
+		data->array_type->type_name);
+	ubsan_epilogue(&flags);
+}
+EXPORT_SYMBOL(__ubsan_handle_out_of_bounds);
+
+void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data,
+					unsigned long lhs, unsigned long rhs)
+{
+	unsigned long flags;
+	struct type_descriptor *rhs_type = data->rhs_type;
+	struct type_descriptor *lhs_type = data->lhs_type;
+	char rhs_str[VALUE_LENGTH];
+	char lhs_str[VALUE_LENGTH];
+
+	if (suppress_report(&data->location))
+		return;
+
+	ubsan_prologue(&data->location, &flags);
+
+	val_to_string(rhs_str, sizeof(rhs_str), rhs_type, rhs);
+	val_to_string(lhs_str, sizeof(lhs_str), lhs_type, lhs);
+
+	if (val_is_negative(rhs_type, rhs))
+		pr_err("shift exponent %s is negative\n", rhs_str);
+
+	else if (get_unsigned_val(rhs_type, rhs) >=
+		type_bit_width(lhs_type))
+		pr_err("shift exponent %s is too large for %u-bit type %s\n",
+			rhs_str,
+			type_bit_width(lhs_type),
+			lhs_type->type_name);
+	else if (val_is_negative(lhs_type, lhs))
+		pr_err("left shift of negative value %s\n",
+			lhs_str);
+	else
+		pr_err("left shift of %s by %s places cannot be"
+			" represented in type %s\n",
+			lhs_str, rhs_str,
+			lhs_type->type_name);
+
+	ubsan_epilogue(&flags);
+}
+EXPORT_SYMBOL(__ubsan_handle_shift_out_of_bounds);
+
+
+void __noreturn
+__ubsan_handle_builtin_unreachable(struct unreachable_data *data)
+{
+	unsigned long flags;
+
+	ubsan_prologue(&data->location, &flags);
+	pr_err("calling __builtin_unreachable()\n");
+	ubsan_epilogue(&flags);
+	panic("can't return from __builtin_unreachable()");
+}
+EXPORT_SYMBOL(__ubsan_handle_builtin_unreachable);
+
+void __ubsan_handle_load_invalid_value(struct invalid_value_data *data,
+				unsigned long val)
+{
+	unsigned long flags;
+	char val_str[VALUE_LENGTH];
+
+	if (suppress_report(&data->location))
+		return;
+
+	ubsan_prologue(&data->location, &flags);
+
+	val_to_string(val_str, sizeof(val_str), data->type, val);
+
+	pr_err("load of value %s is not a valid value for type %s\n",
+		val_str, data->type->type_name);
+
+	ubsan_epilogue(&flags);
+}
+EXPORT_SYMBOL(__ubsan_handle_load_invalid_value);
diff --git a/xen/common/ubsan/ubsan.h b/xen/common/ubsan/ubsan.h
new file mode 100644
index 0000000000..b2d18d4a53
--- /dev/null
+++ b/xen/common/ubsan/ubsan.h
@@ -0,0 +1,84 @@
+#ifndef _LIB_UBSAN_H
+#define _LIB_UBSAN_H
+
+enum {
+	type_kind_int = 0,
+	type_kind_float = 1,
+	type_unknown = 0xffff
+};
+
+struct type_descriptor {
+	u16 type_kind;
+	u16 type_info;
+	char type_name[1];
+};
+
+struct source_location {
+	const char *file_name;
+	union {
+		unsigned long reported;
+		struct {
+			u32 line;
+			u32 column;
+		};
+	};
+};
+
+struct overflow_data {
+	struct source_location location;
+	struct type_descriptor *type;
+};
+
+struct type_mismatch_data {
+	struct source_location location;
+	struct type_descriptor *type;
+	unsigned long alignment;
+	unsigned char type_check_kind;
+};
+
+struct nonnull_arg_data {
+	struct source_location location;
+	struct source_location attr_location;
+	int arg_index;
+};
+
+struct nonnull_return_data {
+	struct source_location location;
+	struct source_location attr_location;
+};
+
+struct vla_bound_data {
+	struct source_location location;
+	struct type_descriptor *type;
+};
+
+struct out_of_bounds_data {
+	struct source_location location;
+	struct type_descriptor *array_type;
+	struct type_descriptor *index_type;
+};
+
+struct shift_out_of_bounds_data {
+	struct source_location location;
+	struct type_descriptor *lhs_type;
+	struct type_descriptor *rhs_type;
+};
+
+struct unreachable_data {
+	struct source_location location;
+};
+
+struct invalid_value_data {
+	struct source_location location;
+	struct type_descriptor *type;
+};
+
+#if defined(CONFIG_ARCH_SUPPORTS_INT128) && defined(__SIZEOF_INT128__)
+typedef __int128 s_max;
+typedef unsigned __int128 u_max;
+#else
+typedef s64 s_max;
+typedef u64 u_max;
+#endif
+
+#endif
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 2/3] xen/ubsan: Implement __ubsan_handle_nonnull_arg()
  2017-10-09 14:11 [PATCH v2 0/3] Add support for using the Undefined Behaviour Sanitizer Wei Liu
  2017-10-09 14:11 ` [PATCH v2 1/3] xen/ubsan: Import ubsan implementation from Linux 4.13 Wei Liu
@ 2017-10-09 14:11 ` Wei Liu
  2017-10-09 14:11 ` [PATCH v2 3/3] xen: hook up UBSAN with CONFIG_UBSAN Wei Liu
  2 siblings, 0 replies; 11+ messages in thread
From: Wei Liu @ 2017-10-09 14:11 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper

From: Andrew Cooper <andrew.cooper3@citrix.com>

This hook appears to be missing from the Linux ubsan implemention.  This patch
is a forward port of https://lkml.org/lkml/2014/10/20/182

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
 xen/common/ubsan/ubsan.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/xen/common/ubsan/ubsan.c b/xen/common/ubsan/ubsan.c
index fb0409df1b..685b4de0d6 100644
--- a/xen/common/ubsan/ubsan.c
+++ b/xen/common/ubsan/ubsan.c
@@ -328,6 +328,25 @@ void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
 }
 EXPORT_SYMBOL(__ubsan_handle_type_mismatch);
 
+void __ubsan_handle_nonnull_arg(struct nonnull_arg_data *data)
+{
+	unsigned long flags;
+
+	if (suppress_report(&data->location))
+		return;
+
+	ubsan_prologue(&data->location, &flags);
+
+	pr_err("null pointer passed as argument %d, declared with nonnull attribute\n",
+	       data->arg_index);
+
+	if (location_is_valid(&data->attr_location))
+		print_source_location("nonnull attribute declared in ",
+				      &data->attr_location);
+
+	ubsan_epilogue(&flags);
+}
+
 void __ubsan_handle_nonnull_return(struct nonnull_return_data *data)
 {
 	unsigned long flags;
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 3/3] xen: hook up UBSAN with CONFIG_UBSAN
  2017-10-09 14:11 [PATCH v2 0/3] Add support for using the Undefined Behaviour Sanitizer Wei Liu
  2017-10-09 14:11 ` [PATCH v2 1/3] xen/ubsan: Import ubsan implementation from Linux 4.13 Wei Liu
  2017-10-09 14:11 ` [PATCH v2 2/3] xen/ubsan: Implement __ubsan_handle_nonnull_arg() Wei Liu
@ 2017-10-09 14:11 ` Wei Liu
  2017-10-09 14:23   ` Andrew Cooper
  2017-10-09 14:36   ` Jan Beulich
  2 siblings, 2 replies; 11+ messages in thread
From: Wei Liu @ 2017-10-09 14:11 UTC (permalink / raw)
  To: Xen-devel
  Cc: Andrew Cooper, Julien Grall, Stefano Stabellini, Wei Liu, Jan Beulich

Make the following changes:

1. Introduce CONFIG_UBSAN and other auxiliary options.
2. Introduce Build system rune to filter objects.
3. Make ubsan.c build.

Currently only x86 is supported. All init.o's are filtered out because
of limitation in the build system. There is no user of noubsan-y yet
but it is worth keeping to ease future development.

Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Julien Grall <julien.grall@arm.com>
---
 xen/Kconfig              |  6 ++++++
 xen/Kconfig.debug        | 10 ++++++++++
 xen/Rules.mk             |  4 ++++
 xen/arch/x86/Kconfig     |  2 ++
 xen/common/Kconfig       |  3 +++
 xen/common/Makefile      |  1 +
 xen/common/ubsan/ubsan.c | 19 ++++++++++++-------
 7 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/xen/Kconfig b/xen/Kconfig
index 65d491d776..ea7229ad1f 100644
--- a/xen/Kconfig
+++ b/xen/Kconfig
@@ -38,4 +38,10 @@ config LTO
 
 	  If unsure, say N.
 
+#
+# For architectures that know their compiler __int128 support is sound
+#
+config ARCH_SUPPORTS_INT128
+	bool
+
 source "Kconfig.debug"
diff --git a/xen/Kconfig.debug b/xen/Kconfig.debug
index 195d504147..3329c75bfd 100644
--- a/xen/Kconfig.debug
+++ b/xen/Kconfig.debug
@@ -121,6 +121,16 @@ config SCRUB_DEBUG
 	  Verify that pages that need to be scrubbed before being allocated to
 	  a guest are indeed scrubbed.
 
+config UBSAN
+	bool "Undefined behaviour sanitizer"
+	depends on HAS_UBSAN
+	---help---
+	  Enable undefined behaviour sanitizer. It uses compiler to insert code
+	  snippets so that undefined behaviours in C are detected during runtime.
+	  This requires a UBSAN capable compiler and it is a debug only feature.
+
+	  If unsure, say N here.
+
 endif # DEBUG || EXPERT
 
 endmenu
diff --git a/xen/Rules.mk b/xen/Rules.mk
index cafc67b86e..2659f8a4d1 100644
--- a/xen/Rules.mk
+++ b/xen/Rules.mk
@@ -119,6 +119,10 @@ ifeq ($(CONFIG_GCOV),y)
 $(filter-out %.init.o $(nogcov-y),$(obj-y) $(obj-bin-y) $(extra-y)): CFLAGS += -fprofile-arcs -ftest-coverage
 endif
 
+ifeq ($(CONFIG_UBSAN),y)
+$(filter-out %.init.o $(noubsan-y),$(obj-y) $(obj-bin-y) $(extra-y)): CFLAGS += -fsanitize=undefined
+endif
+
 ifeq ($(CONFIG_LTO),y)
 CFLAGS += -flto
 LDFLAGS-$(clang) += -plugin LLVMgold.so
diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig
index 30c2769684..64955dc017 100644
--- a/xen/arch/x86/Kconfig
+++ b/xen/arch/x86/Kconfig
@@ -5,6 +5,7 @@ config X86
 	def_bool y
 	select ACPI
 	select ACPI_LEGACY_TABLES_LOOKUP
+	select ARCH_SUPPORTS_INT128
 	select COMPAT
 	select CORE_PARKING
 	select HAS_ALTERNATIVE
@@ -21,6 +22,7 @@ config X86
 	select HAS_PASSTHROUGH
 	select HAS_PCI
 	select HAS_PDX
+	select HAS_UBSAN
 	select NUMA
 	select VGA
 
diff --git a/xen/common/Kconfig b/xen/common/Kconfig
index e9bb849298..103ef44cb5 100644
--- a/xen/common/Kconfig
+++ b/xen/common/Kconfig
@@ -32,6 +32,9 @@ config HAS_MEM_SHARING
 config HAS_PDX
 	bool
 
+config HAS_UBSAN
+	bool
+
 config HAS_KEXEC
 	bool
 
diff --git a/xen/common/Makefile b/xen/common/Makefile
index 39e2614546..66cc2c8995 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -75,6 +75,7 @@ tmem-$(CONFIG_COMPAT) += compat/tmem_xen.o
 obj-$(CONFIG_TMEM) += $(tmem-y)
 
 subdir-$(CONFIG_GCOV) += gcov
+subdir-$(CONFIG_UBSAN) += ubsan
 
 subdir-y += libelf
 subdir-$(CONFIG_HAS_DEVICE_TREE) += libfdt
diff --git a/xen/common/ubsan/ubsan.c b/xen/common/ubsan/ubsan.c
index 685b4de0d6..fbe568562a 100644
--- a/xen/common/ubsan/ubsan.c
+++ b/xen/common/ubsan/ubsan.c
@@ -10,13 +10,18 @@
  *
  */
 
-#include <linux/bitops.h>
-#include <linux/bug.h>
-#include <linux/ctype.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/sched.h>
+#include <xen/spinlock.h>
+#include <xen/percpu.h>
+
+#define __noreturn    noreturn
+#define pr_err(...) printk(XENLOG_ERR __VA_ARGS__)
+struct xen_ubsan { int in_ubsan; };
+static DEFINE_PER_CPU(struct xen_ubsan[1], in_ubsan);
+#undef current
+#define current this_cpu(in_ubsan)
+#define dump_stack dump_execution_state
+#define u64 long long unsigned int
+#define s64 long long int
 
 #include "ubsan.h"
 
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 3/3] xen: hook up UBSAN with CONFIG_UBSAN
  2017-10-09 14:11 ` [PATCH v2 3/3] xen: hook up UBSAN with CONFIG_UBSAN Wei Liu
@ 2017-10-09 14:23   ` Andrew Cooper
  2017-10-09 14:28     ` Wei Liu
  2017-10-09 14:31     ` Julien Grall
  2017-10-09 14:36   ` Jan Beulich
  1 sibling, 2 replies; 11+ messages in thread
From: Andrew Cooper @ 2017-10-09 14:23 UTC (permalink / raw)
  To: Wei Liu, Xen-devel; +Cc: Julien Grall, Stefano Stabellini, Jan Beulich

On 09/10/17 15:11, Wei Liu wrote:
> diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig
> index 30c2769684..64955dc017 100644
> --- a/xen/arch/x86/Kconfig
> +++ b/xen/arch/x86/Kconfig

Based on Julien's testing, shouldn't ARM64 also select HAS_UBSAN? 
Otherwise, LGTM.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 3/3] xen: hook up UBSAN with CONFIG_UBSAN
  2017-10-09 14:23   ` Andrew Cooper
@ 2017-10-09 14:28     ` Wei Liu
  2017-10-09 14:31     ` Julien Grall
  1 sibling, 0 replies; 11+ messages in thread
From: Wei Liu @ 2017-10-09 14:28 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: Xen-devel, Julien Grall, Stefano Stabellini, Wei Liu, Jan Beulich

On Mon, Oct 09, 2017 at 03:23:37PM +0100, Andrew Cooper wrote:
> On 09/10/17 15:11, Wei Liu wrote:
> > diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig
> > index 30c2769684..64955dc017 100644
> > --- a/xen/arch/x86/Kconfig
> > +++ b/xen/arch/x86/Kconfig
> 
> Based on Julien's testing, shouldn't ARM64 also select HAS_UBSAN? 
> Otherwise, LGTM.

IIRC there is an issue with the size of the image being larger than 2MB.

I will let Julien decide. I can't test ARM support anyway.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 3/3] xen: hook up UBSAN with CONFIG_UBSAN
  2017-10-09 14:23   ` Andrew Cooper
  2017-10-09 14:28     ` Wei Liu
@ 2017-10-09 14:31     ` Julien Grall
  1 sibling, 0 replies; 11+ messages in thread
From: Julien Grall @ 2017-10-09 14:31 UTC (permalink / raw)
  To: Andrew Cooper, Wei Liu, Xen-devel
  Cc: Julien Grall, Stefano Stabellini, Jan Beulich



On 09/10/17 15:23, Andrew Cooper wrote:
> On 09/10/17 15:11, Wei Liu wrote:
>> diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig
>> index 30c2769684..64955dc017 100644
>> --- a/xen/arch/x86/Kconfig
>> +++ b/xen/arch/x86/Kconfig
> 
> Based on Julien's testing, shouldn't ARM64 also select HAS_UBSAN?

I tested it with some patches on top. Currently, the size of Xen Arm is 
limited to 2MB. That limit will be exploded when building with UBSAN.

So for now, I will leave that unselectable for both Arm32 and Arm64.

Cheers,

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 3/3] xen: hook up UBSAN with CONFIG_UBSAN
  2017-10-09 14:11 ` [PATCH v2 3/3] xen: hook up UBSAN with CONFIG_UBSAN Wei Liu
  2017-10-09 14:23   ` Andrew Cooper
@ 2017-10-09 14:36   ` Jan Beulich
  2017-10-09 14:38     ` Andrew Cooper
  1 sibling, 1 reply; 11+ messages in thread
From: Jan Beulich @ 2017-10-09 14:36 UTC (permalink / raw)
  To: Wei Liu; +Cc: AndrewCooper, Julien Grall, Stefano Stabellini, Xen-devel

>>> On 09.10.17 at 16:11, <wei.liu2@citrix.com> wrote:
> --- a/xen/common/ubsan/ubsan.c
> +++ b/xen/common/ubsan/ubsan.c
> @@ -10,13 +10,18 @@
>   *
>   */
>  
> -#include <linux/bitops.h>
> -#include <linux/bug.h>
> -#include <linux/ctype.h>
> -#include <linux/init.h>
> -#include <linux/kernel.h>
> -#include <linux/types.h>
> -#include <linux/sched.h>
> +#include <xen/spinlock.h>
> +#include <xen/percpu.h>
> +
> +#define __noreturn    noreturn
> +#define pr_err(...) printk(XENLOG_ERR __VA_ARGS__)
> +struct xen_ubsan { int in_ubsan; };
> +static DEFINE_PER_CPU(struct xen_ubsan[1], in_ubsan);
> +#undef current
> +#define current this_cpu(in_ubsan)
> +#define dump_stack dump_execution_state
> +#define u64 long long unsigned int
> +#define s64 long long int

Wasn't it agreed to make these uint64_t and int64_t?

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 3/3] xen: hook up UBSAN with CONFIG_UBSAN
  2017-10-09 14:36   ` Jan Beulich
@ 2017-10-09 14:38     ` Andrew Cooper
  2017-10-09 14:41       ` Wei Liu
  2017-10-09 14:55       ` Jan Beulich
  0 siblings, 2 replies; 11+ messages in thread
From: Andrew Cooper @ 2017-10-09 14:38 UTC (permalink / raw)
  To: Jan Beulich, Wei Liu; +Cc: Xen-devel, Julien Grall, Stefano Stabellini

On 09/10/17 15:36, Jan Beulich wrote:
>>>> On 09.10.17 at 16:11, <wei.liu2@citrix.com> wrote:
>> --- a/xen/common/ubsan/ubsan.c
>> +++ b/xen/common/ubsan/ubsan.c
>> @@ -10,13 +10,18 @@
>>   *
>>   */
>>  
>> -#include <linux/bitops.h>
>> -#include <linux/bug.h>
>> -#include <linux/ctype.h>
>> -#include <linux/init.h>
>> -#include <linux/kernel.h>
>> -#include <linux/types.h>
>> -#include <linux/sched.h>
>> +#include <xen/spinlock.h>
>> +#include <xen/percpu.h>
>> +
>> +#define __noreturn    noreturn
>> +#define pr_err(...) printk(XENLOG_ERR __VA_ARGS__)
>> +struct xen_ubsan { int in_ubsan; };
>> +static DEFINE_PER_CPU(struct xen_ubsan[1], in_ubsan);
>> +#undef current
>> +#define current this_cpu(in_ubsan)
>> +#define dump_stack dump_execution_state
>> +#define u64 long long unsigned int
>> +#define s64 long long int
> Wasn't it agreed to make these uint64_t and int64_t?

Sadly that doesn't work, because of the explicit casts used in the
sprintf().

Depending on how much we tolerate modifying the Linux code, these can be
removed if we change to using appropriate PRIx64 formatters instead. 
However, I would prefer to avoid changing the Linux code if possible.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 3/3] xen: hook up UBSAN with CONFIG_UBSAN
  2017-10-09 14:38     ` Andrew Cooper
@ 2017-10-09 14:41       ` Wei Liu
  2017-10-09 14:55       ` Jan Beulich
  1 sibling, 0 replies; 11+ messages in thread
From: Wei Liu @ 2017-10-09 14:41 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: Xen-devel, Julien Grall, Stefano Stabellini, Wei Liu, Jan Beulich

On Mon, Oct 09, 2017 at 03:38:55PM +0100, Andrew Cooper wrote:
> On 09/10/17 15:36, Jan Beulich wrote:
> >>>> On 09.10.17 at 16:11, <wei.liu2@citrix.com> wrote:
> >> --- a/xen/common/ubsan/ubsan.c
> >> +++ b/xen/common/ubsan/ubsan.c
> >> @@ -10,13 +10,18 @@
> >>   *
> >>   */
> >>  
> >> -#include <linux/bitops.h>
> >> -#include <linux/bug.h>
> >> -#include <linux/ctype.h>
> >> -#include <linux/init.h>
> >> -#include <linux/kernel.h>
> >> -#include <linux/types.h>
> >> -#include <linux/sched.h>
> >> +#include <xen/spinlock.h>
> >> +#include <xen/percpu.h>
> >> +
> >> +#define __noreturn    noreturn
> >> +#define pr_err(...) printk(XENLOG_ERR __VA_ARGS__)
> >> +struct xen_ubsan { int in_ubsan; };
> >> +static DEFINE_PER_CPU(struct xen_ubsan[1], in_ubsan);
> >> +#undef current
> >> +#define current this_cpu(in_ubsan)
> >> +#define dump_stack dump_execution_state
> >> +#define u64 long long unsigned int
> >> +#define s64 long long int
> > Wasn't it agreed to make these uint64_t and int64_t?
> 

No, not yet.

> Sadly that doesn't work, because of the explicit casts used in the
> sprintf().
> 
> Depending on how much we tolerate modifying the Linux code, these can be
> removed if we change to using appropriate PRIx64 formatters instead. 
> However, I would prefer to avoid changing the Linux code if possible.

+1 for this.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 3/3] xen: hook up UBSAN with CONFIG_UBSAN
  2017-10-09 14:38     ` Andrew Cooper
  2017-10-09 14:41       ` Wei Liu
@ 2017-10-09 14:55       ` Jan Beulich
  1 sibling, 0 replies; 11+ messages in thread
From: Jan Beulich @ 2017-10-09 14:55 UTC (permalink / raw)
  To: Andrew Cooper, Wei Liu; +Cc: Xen-devel, Julien Grall, Stefano Stabellini

>>> On 09.10.17 at 16:38, <andrew.cooper3@citrix.com> wrote:
> On 09/10/17 15:36, Jan Beulich wrote:
>>>>> On 09.10.17 at 16:11, <wei.liu2@citrix.com> wrote:
>>> --- a/xen/common/ubsan/ubsan.c
>>> +++ b/xen/common/ubsan/ubsan.c
>>> @@ -10,13 +10,18 @@
>>>   *
>>>   */
>>>  
>>> -#include <linux/bitops.h>
>>> -#include <linux/bug.h>
>>> -#include <linux/ctype.h>
>>> -#include <linux/init.h>
>>> -#include <linux/kernel.h>
>>> -#include <linux/types.h>
>>> -#include <linux/sched.h>
>>> +#include <xen/spinlock.h>
>>> +#include <xen/percpu.h>
>>> +
>>> +#define __noreturn    noreturn
>>> +#define pr_err(...) printk(XENLOG_ERR __VA_ARGS__)
>>> +struct xen_ubsan { int in_ubsan; };
>>> +static DEFINE_PER_CPU(struct xen_ubsan[1], in_ubsan);
>>> +#undef current
>>> +#define current this_cpu(in_ubsan)
>>> +#define dump_stack dump_execution_state
>>> +#define u64 long long unsigned int
>>> +#define s64 long long int
>> Wasn't it agreed to make these uint64_t and int64_t?
> 
> Sadly that doesn't work, because of the explicit casts used in the
> sprintf().
> 
> Depending on how much we tolerate modifying the Linux code, these can be
> removed if we change to using appropriate PRIx64 formatters instead. 
> However, I would prefer to avoid changing the Linux code if possible.

Ah, yes, that's good enough a reason. Together with Julien's
reply then
Acked-by: Jan Beulich <jbeulich@suse.com>

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2017-10-09 14:55 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-09 14:11 [PATCH v2 0/3] Add support for using the Undefined Behaviour Sanitizer Wei Liu
2017-10-09 14:11 ` [PATCH v2 1/3] xen/ubsan: Import ubsan implementation from Linux 4.13 Wei Liu
2017-10-09 14:11 ` [PATCH v2 2/3] xen/ubsan: Implement __ubsan_handle_nonnull_arg() Wei Liu
2017-10-09 14:11 ` [PATCH v2 3/3] xen: hook up UBSAN with CONFIG_UBSAN Wei Liu
2017-10-09 14:23   ` Andrew Cooper
2017-10-09 14:28     ` Wei Liu
2017-10-09 14:31     ` Julien Grall
2017-10-09 14:36   ` Jan Beulich
2017-10-09 14:38     ` Andrew Cooper
2017-10-09 14:41       ` Wei Liu
2017-10-09 14:55       ` Jan Beulich

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.