All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: igt-dev@lists.freedesktop.org,
	Joonas Lahtinen <joonas.lahtinen@intel.com>
Subject: [Intel-gfx] [PATCH i-g-t] cve: Add checker for cve-2019-0155
Date: Thu, 21 Nov 2019 17:19:30 +0200	[thread overview]
Message-ID: <20191121151930.25464-1-mika.kuoppala@linux.intel.com> (raw)

Add vulnerability checker for cve-2019-0155

v2: sync, bailout early if no parser (Chris)

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Jon Bloomfield <jon.bloomfield@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@intel.com>
References: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-0155
References: https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00242.html
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 Makefile.am          |   2 +-
 configure.ac         |   1 +
 cve/Makefile.am      |  14 ++
 cve/Makefile.sources |   5 +
 cve/cve-2019-0155.c  | 470 +++++++++++++++++++++++++++++++++++++++++++
 cve/meson.build      |  12 ++
 meson.build          |   1 +
 7 files changed, 504 insertions(+), 1 deletion(-)
 create mode 100644 cve/Makefile.am
 create mode 100644 cve/Makefile.sources
 create mode 100644 cve/cve-2019-0155.c
 create mode 100644 cve/meson.build

diff --git a/Makefile.am b/Makefile.am
index 94250964..e139bb44 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -21,7 +21,7 @@
 
 ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4
 
-SUBDIRS = lib tools scripts benchmarks
+SUBDIRS = lib tools scripts benchmarks cve
 
 if BUILD_TESTS
 SUBDIRS += tests
diff --git a/configure.ac b/configure.ac
index f9e4942e..23fd9f30 100644
--- a/configure.ac
+++ b/configure.ac
@@ -311,6 +311,7 @@ AC_CONFIG_FILES([
 		 tools/null_state_gen/Makefile
 		 tools/registers/Makefile
 		 overlay/Makefile
+		 cve/Makefile
 		 ])
 
 AC_CONFIG_FILES([tools/intel_aubdump], [chmod +x tools/intel_aubdump])
diff --git a/cve/Makefile.am b/cve/Makefile.am
new file mode 100644
index 00000000..b8419ecd
--- /dev/null
+++ b/cve/Makefile.am
@@ -0,0 +1,14 @@
+include Makefile.sources
+
+cve_PROGRAMS = $(cve_prog_list)
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/include/drm-uapi \
+	-I$(top_srcdir)/lib \
+	-I$(top_srcdir)/lib/stubs/syscalls
+
+AM_CFLAGS = -I$(top_srcdir)/include/drm-uapi \
+	    $(DRM_CFLAGS) $(CWARNFLAGS) $(CAIRO_CFLAGS) $(LIBUNWIND_CFLAGS) \
+	    $(WERROR_CFLAGS) -D_GNU_SOURCE
+LDADD = $(top_builddir)/lib/libintel_tools.la
diff --git a/cve/Makefile.sources b/cve/Makefile.sources
new file mode 100644
index 00000000..2b02f958
--- /dev/null
+++ b/cve/Makefile.sources
@@ -0,0 +1,5 @@
+cvedir=$(libexecdir)/igt-gpu-tools/cve
+
+cve_prog_list =				\	
+	cve-2019-0155
+	$(NULL)
diff --git a/cve/cve-2019-0155.c b/cve/cve-2019-0155.c
new file mode 100644
index 00000000..5f6ca60a
--- /dev/null
+++ b/cve/cve-2019-0155.c
@@ -0,0 +1,470 @@
+/*
+ * Copyright © 2019 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+/*
+ * Can be compiled with:
+ * gcc -Wall -static -o cve-2019-0155 cve-2019-0155.c
+*/
+
+#define VERSION 1
+#define CHECK_WRITE_BLOCK_WITHOUT_PARSER 0
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#define ASSERT(x, s) do {	\
+	if (!(x)) { \
+		printf("Failed to %s, %s (%d)\n", (s), \
+			       strerror(errno), errno);	\
+		exit(EXIT_FAILURE); \
+		} \
+	} while(0)
+
+static int do_ioctl(const int fd, const unsigned long nr, void *arg)
+{
+	int ret;
+
+	do
+		ret = ioctl(fd, nr, arg);
+	while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+	return ret;
+}
+
+static int is_driver_i915(const int fd)
+{
+	struct _drm_version {
+		int version_major;
+		int version_minor;
+		int version_patchlevel;
+
+		size_t name_len;
+		char *name;
+		size_t date_len;
+		char *date;
+		size_t desc_len;
+		char *desc;
+	} v = { 0, };
+	char name[256] = { 0, };
+	int ret;
+
+	v.name_len = sizeof(name) - 1;
+	v.name = name;
+
+	ret = do_ioctl(fd, _IOWR(0x40, 0x00, struct _drm_version), &v);
+	ASSERT(ret == 0, "get name");
+
+	name[v.name_len] = 0;
+
+	return !strcmp(name, "i915");
+}
+
+static int cmd_parser_version(const int fd)
+{
+	int ret, version = 0;
+	struct _drm_i915_getparam_t {
+		int32_t param;
+		uint64_t value;
+	} q = { 28,
+		(uint64_t)&version };
+
+	ret = do_ioctl(fd, _IOWR(0x40, 0x40 + 0x06, struct _drm_i915_getparam_t), &q);
+	ASSERT(ret == 0, "get param");
+
+	return version;
+}
+
+#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
+#define MI_BATCH_BUFFER_END     MI_INSTR(0x0a, 0)
+#define MI_LOAD_REGISTER_IMM    MI_INSTR(0x22, (3-2))
+
+static int is_write_blocked(const int fd)
+{
+	int ret;
+	uint32_t handle;
+
+	struct _drm_i915_gem_execbuffer2 {
+		uint64_t buffers_ptr;
+		uint32_t buffer_count;
+		uint32_t batch_start_offset;
+		uint32_t batch_len;
+		uint32_t DR1;
+		uint32_t DR4;
+		uint32_t num_cliprects;
+		uint64_t cliprects_ptr;
+		uint64_t flags;
+		uint64_t rsvd1;
+		uint64_t rsvd2;
+	} execbuf = { 0, };
+
+	struct _drm_i915_gem_exec_object2 {
+		uint32_t handle;
+		uint32_t relocation_count;
+		uint64_t relocs_ptr;
+		uint64_t alignment;
+		uint64_t offset;
+		uint64_t flags;
+		uint64_t rsvd1;
+		uint64_t rsvd2;
+	} execobj[1] = { { 0, } };
+
+	struct _drm_i915_gem_create {
+		uint64_t size;
+		uint32_t handle;
+		uint32_t pad;
+	} createobj = { 0, };
+
+	struct _drm_i915_gem_pwrite {
+		uint32_t handle;
+		uint32_t pad;
+		uint64_t offset;
+		uint64_t size;
+		uint64_t data_ptr;
+	} pwrite = { 0, };
+
+	const uint32_t batch[] = {
+		MI_LOAD_REGISTER_IMM,
+		0x2221c,
+		0x0,
+		0,
+		MI_BATCH_BUFFER_END,
+	};
+
+	createobj.handle = 0;
+	createobj.size = 4096;
+
+	ret = do_ioctl(fd, _IOWR(0x40, 0x40+0x1b, struct _drm_i915_gem_create), &createobj);
+	ASSERT(ret == 0, "create object");
+
+	handle = createobj.handle;
+
+	pwrite.handle = handle;
+	pwrite.size = sizeof(batch);
+	pwrite.data_ptr = (uintptr_t)batch;
+
+	ret = do_ioctl(fd, _IOWR(0x40, 0x40+0x1d, struct _drm_i915_gem_pwrite), &pwrite);
+	ASSERT(ret == 0, "write object");
+
+	execobj[0].handle = handle;
+
+	execbuf.buffers_ptr = (uintptr_t)execobj;
+	execbuf.buffer_count = 1;
+	execbuf.flags = 3; /* select blitter engine (bcs0) */
+
+	ret = do_ioctl(fd, _IOWR(0x40, 0x40+0x29, struct _drm_i915_gem_execbuffer2), &execbuf);
+	if (ret) {
+		if (errno == EACCES || errno == EINVAL)
+			return 1;
+	}
+
+	return 0;
+}
+
+#define INTEL_VGA_DEVICE(x, y) (x)
+
+static const uint32_t gen9_ids[] = {
+
+	INTEL_VGA_DEVICE(0x1906, info), /* ULT GT1 */
+
+	INTEL_VGA_DEVICE(0x190E, info), /* ULX GT1 */
+
+	INTEL_VGA_DEVICE(0x1902, info), /* DT  GT1 */
+	INTEL_VGA_DEVICE(0x190B, info), /* Halo GT1 */
+	INTEL_VGA_DEVICE(0x190A, info), /* SRV GT1 */
+
+	INTEL_VGA_DEVICE(0x1916, info), /* ULT GT2 */
+	INTEL_VGA_DEVICE(0x1921, info),  /* ULT GT2F */
+
+	INTEL_VGA_DEVICE(0x191E, info), /* ULX GT2 */
+
+	INTEL_VGA_DEVICE(0x1912, info), /* DT  GT2 */
+	INTEL_VGA_DEVICE(0x191B, info), /* Halo GT2 */
+	INTEL_VGA_DEVICE(0x191A, info), /* SRV GT2 */
+	INTEL_VGA_DEVICE(0x191D, info),  /* WKS GT2 */
+
+	INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */
+
+	INTEL_VGA_DEVICE(0x1923, info), /* ULT GT3 */
+	INTEL_VGA_DEVICE(0x1927, info), /* ULT GT3 */
+	INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */
+	INTEL_VGA_DEVICE(0x192D, info),  /* SRV GT3 */
+
+	INTEL_VGA_DEVICE(0x1932, info), /* DT GT4 */
+	INTEL_VGA_DEVICE(0x193B, info), /* Halo GT4 */
+	INTEL_VGA_DEVICE(0x193D, info), /* WKS GT4 */
+	INTEL_VGA_DEVICE(0x192A, info), /* SRV GT4 */
+	INTEL_VGA_DEVICE(0x193A, info),  /* SRV GT4e */
+
+	INTEL_VGA_DEVICE(0x0A84, info),
+	INTEL_VGA_DEVICE(0x1A84, info),
+	INTEL_VGA_DEVICE(0x1A85, info),
+	INTEL_VGA_DEVICE(0x5A84, info), /* APL HD Graphics 505 */
+	INTEL_VGA_DEVICE(0x5A85, info),  /* APL HD Graphics 500 */
+
+	INTEL_VGA_DEVICE(0x3184, info),
+	INTEL_VGA_DEVICE(0x3185, info),
+
+	INTEL_VGA_DEVICE(0x5906, info), /* ULT GT1 */
+	INTEL_VGA_DEVICE(0x5913, info),  /* ULT GT1.5 */
+
+	INTEL_VGA_DEVICE(0x590E, info), /* ULX GT1 */
+	INTEL_VGA_DEVICE(0x5915, info),  /* ULX GT1.5 */
+
+	INTEL_VGA_DEVICE(0x5902, info), /* DT  GT1 */
+	INTEL_VGA_DEVICE(0x5908, info), /* Halo GT1 */
+	INTEL_VGA_DEVICE(0x590B, info), /* Halo GT1 */
+	INTEL_VGA_DEVICE(0x590A, info), /* SRV GT1 */
+
+	INTEL_VGA_DEVICE(0x5916, info), /* ULT GT2 */
+	INTEL_VGA_DEVICE(0x5921, info),  /* ULT GT2F */
+
+	INTEL_VGA_DEVICE(0x591E, info), /* ULX GT2 */
+
+	INTEL_VGA_DEVICE(0x5917, info), /* Mobile GT2 */
+	INTEL_VGA_DEVICE(0x5912, info), /* DT  GT2 */
+	INTEL_VGA_DEVICE(0x591B, info), /* Halo GT2 */
+	INTEL_VGA_DEVICE(0x591A, info), /* SRV GT2 */
+	INTEL_VGA_DEVICE(0x591D, info), /* WKS GT2 */
+
+	INTEL_VGA_DEVICE(0x5926, info), /* ULT GT3 */
+
+	INTEL_VGA_DEVICE(0x5923, info), /* ULT GT3 */
+	INTEL_VGA_DEVICE(0x5927, info), /* ULT GT3 */
+
+	INTEL_VGA_DEVICE(0x593B, info), /* Halo GT4 */
+
+	INTEL_VGA_DEVICE(0x591C, info),  /* ULX GT2 */
+	INTEL_VGA_DEVICE(0x87C0, info), /* ULX GT2 */
+
+	INTEL_VGA_DEVICE(0x87CA, info),
+
+	INTEL_VGA_DEVICE(0x9B21, info),
+	INTEL_VGA_DEVICE(0x9BAA, info),
+	INTEL_VGA_DEVICE(0x9BAB, info),
+	INTEL_VGA_DEVICE(0x9BAC, info),
+	INTEL_VGA_DEVICE(0x9BA0, info),
+	INTEL_VGA_DEVICE(0x9BA5, info),
+	INTEL_VGA_DEVICE(0x9BA8, info),
+	INTEL_VGA_DEVICE(0x9BA4, info),
+	INTEL_VGA_DEVICE(0x9BA2, info),
+
+	INTEL_VGA_DEVICE(0x9B41, info),
+	INTEL_VGA_DEVICE(0x9BCA, info),
+	INTEL_VGA_DEVICE(0x9BCB, info),
+	INTEL_VGA_DEVICE(0x9BCC, info),
+	INTEL_VGA_DEVICE(0x9BC0, info),
+	INTEL_VGA_DEVICE(0x9BC5, info),
+	INTEL_VGA_DEVICE(0x9BC8, info),
+	INTEL_VGA_DEVICE(0x9BC4, info),
+	INTEL_VGA_DEVICE(0x9BC2, info),
+	INTEL_VGA_DEVICE(0x9BC6, info),
+	INTEL_VGA_DEVICE(0x9BE6, info),
+	INTEL_VGA_DEVICE(0x9BF6, info),
+
+	INTEL_VGA_DEVICE(0x3E90, info), /* SRV GT1 */
+	INTEL_VGA_DEVICE(0x3E93, info), /* SRV GT1 */
+	INTEL_VGA_DEVICE(0x3E99, info),  /* SRV GT1 */
+
+	INTEL_VGA_DEVICE(0x3E91, info), /* SRV GT2 */
+	INTEL_VGA_DEVICE(0x3E92, info), /* SRV GT2 */
+	INTEL_VGA_DEVICE(0x3E96, info), /* SRV GT2 */
+	INTEL_VGA_DEVICE(0x3E98, info), /* SRV GT2 */
+	INTEL_VGA_DEVICE(0x3E9A, info),  /* SRV GT2 */
+
+	INTEL_VGA_DEVICE(0x3E9C, info),
+
+	INTEL_VGA_DEVICE(0x3E9B, info), /* Halo GT2 */
+	INTEL_VGA_DEVICE(0x3E94, info),  /* Halo GT2 */
+
+	INTEL_VGA_DEVICE(0x3EA9, info),
+
+	INTEL_VGA_DEVICE(0x3EA5, info), /* ULT GT3 */
+	INTEL_VGA_DEVICE(0x3EA6, info), /* ULT GT3 */
+	INTEL_VGA_DEVICE(0x3EA7, info), /* ULT GT3 */
+	INTEL_VGA_DEVICE(0x3EA8, info), /* ULT GT3 */
+
+	INTEL_VGA_DEVICE(0x3EA1, info),
+	INTEL_VGA_DEVICE(0x3EA4, info),
+
+	INTEL_VGA_DEVICE(0x3EA0, info),
+	INTEL_VGA_DEVICE(0x3EA3, info),
+
+	INTEL_VGA_DEVICE(0x3EA2, info),
+};
+
+static int is_platform_gen9(void)
+{
+	const char * const id_file =
+		"/sys/bus/pci/drivers/i915/0000:00:02.0/device";
+	char idstr[32] = {0, };
+	uint32_t id = 0;
+	int fd, ret, i;
+
+	fd = open(id_file, O_RDONLY);
+	if (fd == -1)
+		return -1;
+
+	ret = read(fd, idstr, 6);
+	if (ret != 6)
+		return -1;
+
+	close(fd);
+
+	idstr[6] = 0;
+
+	id = strtol(idstr, NULL, 16);
+
+	for (i = 0; i < sizeof(gen9_ids)/sizeof(uint32_t); i++)
+		if (id == gen9_ids[i])
+			return 1;
+
+	return 0;
+}
+
+static int is_fd_safe(const int fd)
+{
+	int parser_version = -1;
+	int write_block = 0;
+
+	parser_version = cmd_parser_version(fd);
+	printf("  Command parser version: %d\n", parser_version);
+	if (parser_version >= 10) {
+		printf("  Command parsing for blt engine supported\n");
+	} else if (!CHECK_WRITE_BLOCK_WITHOUT_PARSER) {
+		printf("  There is no blitter command parser\n");
+		return 0;
+	}
+
+	write_block = is_write_blocked(fd);
+
+	printf("  Unsafe write %s\n", write_block ? "blocked" : "possible!");
+
+	return write_block;
+}
+
+struct stats {
+	int checked;
+	int safe;
+	int failed;
+};
+
+static void check_path(const char *path, struct stats *stats)
+{
+	int fd;
+	int is_safe;
+
+	fd = open(path, O_RDWR);
+	if (fd == -1) {
+		if (errno != ENOENT) {
+			printf("Opening %s failed with %s (%d)\n",
+			       path, strerror(errno), errno);
+			stats->failed++;
+		}
+
+		return;
+	}
+
+	if (!is_driver_i915(fd)) {
+		close(fd);
+		return;
+	}
+
+	printf("Checking %s:\n", path);
+
+	is_safe = is_fd_safe(fd);
+	printf("  Device %s : %s\n\n", path, is_safe ? "SAFE" : "VULNERABLE");
+	if (is_safe)
+		stats->safe++;
+
+	stats->checked++;
+
+	close (fd);
+}
+
+static int check_devices(void)
+{
+	const char * const cardbase = "/dev/dri/card";
+	const char * const renderbase = "/dev/dri/renderD";
+	char path[256];
+	int i;
+	struct stats s = { 0, 0, 0 };
+
+	for (i = 0; i < 16; i++) {
+		sprintf(path, "%s%d", cardbase, i);
+		check_path(path, &s);
+
+		sprintf(path, "%s%d", renderbase, i + 128);
+		check_path(path, &s);
+	}
+
+	if (s.failed && !s.checked) {
+		printf("Failed to open devices, need root?\n");
+		return -1;
+	}
+
+	if (!s.checked) {
+		printf ("Didn't find anything to check\n");
+		return -1;
+	}
+
+	return s.checked == s.safe;
+}
+
+int main(int argc, char *argv[])
+{
+	int safe = 0;
+	int ret;
+
+	printf("Intel cve-2019-0155 (blt mmio vulnerability) checker version %d\n\n", VERSION);
+
+	sync();
+
+	ret = is_platform_gen9();
+	if (ret == 0) {
+		safe = 1;
+		printf("Your platform is not affected\n");
+	} else if (ret == -1) {
+		printf("Unable to determine platform type\n");
+	}
+
+	if (safe != 1)
+		safe = check_devices();
+
+	if (safe < 0) {
+		printf("Unable to determine system state due to errors\n");
+		return EXIT_FAILURE;
+	}
+
+	printf("\nYour system is %s against cve-2019-0155\n", safe ? "SAFE" : "VULNERABLE");
+
+	return safe ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/cve/meson.build b/cve/meson.build
new file mode 100644
index 00000000..990181c6
--- /dev/null
+++ b/cve/meson.build
@@ -0,0 +1,12 @@
+cve_progs = [
+	'cve-2019-0155',
+]
+
+cvedir = join_paths(libexecdir, 'cve')
+
+foreach prog : cve_progs
+	executable(prog, prog + '.c',
+		   install : true,
+		   install_dir : cvedir,
+		   dependencies : igt_deps)
+endforeach
diff --git a/meson.build b/meson.build
index 4d5003ba..27ad9567 100644
--- a/meson.build
+++ b/meson.build
@@ -302,6 +302,7 @@ if libdrm_intel.found()
 endif
 subdir('overlay')
 subdir('man')
+subdir('cve')
 
 gtk_doc = dependency('gtk-doc', required : build_docs)
 python3 = find_program('python3', required : build_docs)
-- 
2.17.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

WARNING: multiple messages have this Message-ID (diff)
From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: igt-dev@lists.freedesktop.org,
	Joonas Lahtinen <joonas.lahtinen@intel.com>
Subject: [PATCH i-g-t] cve: Add checker for cve-2019-0155
Date: Thu, 21 Nov 2019 17:19:30 +0200	[thread overview]
Message-ID: <20191121151930.25464-1-mika.kuoppala@linux.intel.com> (raw)

Add vulnerability checker for cve-2019-0155

v2: sync, bailout early if no parser (Chris)

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Jon Bloomfield <jon.bloomfield@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@intel.com>
References: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-0155
References: https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00242.html
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 Makefile.am          |   2 +-
 configure.ac         |   1 +
 cve/Makefile.am      |  14 ++
 cve/Makefile.sources |   5 +
 cve/cve-2019-0155.c  | 470 +++++++++++++++++++++++++++++++++++++++++++
 cve/meson.build      |  12 ++
 meson.build          |   1 +
 7 files changed, 504 insertions(+), 1 deletion(-)
 create mode 100644 cve/Makefile.am
 create mode 100644 cve/Makefile.sources
 create mode 100644 cve/cve-2019-0155.c
 create mode 100644 cve/meson.build

diff --git a/Makefile.am b/Makefile.am
index 94250964..e139bb44 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -21,7 +21,7 @@
 
 ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4
 
-SUBDIRS = lib tools scripts benchmarks
+SUBDIRS = lib tools scripts benchmarks cve
 
 if BUILD_TESTS
 SUBDIRS += tests
diff --git a/configure.ac b/configure.ac
index f9e4942e..23fd9f30 100644
--- a/configure.ac
+++ b/configure.ac
@@ -311,6 +311,7 @@ AC_CONFIG_FILES([
 		 tools/null_state_gen/Makefile
 		 tools/registers/Makefile
 		 overlay/Makefile
+		 cve/Makefile
 		 ])
 
 AC_CONFIG_FILES([tools/intel_aubdump], [chmod +x tools/intel_aubdump])
diff --git a/cve/Makefile.am b/cve/Makefile.am
new file mode 100644
index 00000000..b8419ecd
--- /dev/null
+++ b/cve/Makefile.am
@@ -0,0 +1,14 @@
+include Makefile.sources
+
+cve_PROGRAMS = $(cve_prog_list)
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/include/drm-uapi \
+	-I$(top_srcdir)/lib \
+	-I$(top_srcdir)/lib/stubs/syscalls
+
+AM_CFLAGS = -I$(top_srcdir)/include/drm-uapi \
+	    $(DRM_CFLAGS) $(CWARNFLAGS) $(CAIRO_CFLAGS) $(LIBUNWIND_CFLAGS) \
+	    $(WERROR_CFLAGS) -D_GNU_SOURCE
+LDADD = $(top_builddir)/lib/libintel_tools.la
diff --git a/cve/Makefile.sources b/cve/Makefile.sources
new file mode 100644
index 00000000..2b02f958
--- /dev/null
+++ b/cve/Makefile.sources
@@ -0,0 +1,5 @@
+cvedir=$(libexecdir)/igt-gpu-tools/cve
+
+cve_prog_list =				\	
+	cve-2019-0155
+	$(NULL)
diff --git a/cve/cve-2019-0155.c b/cve/cve-2019-0155.c
new file mode 100644
index 00000000..5f6ca60a
--- /dev/null
+++ b/cve/cve-2019-0155.c
@@ -0,0 +1,470 @@
+/*
+ * Copyright © 2019 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+/*
+ * Can be compiled with:
+ * gcc -Wall -static -o cve-2019-0155 cve-2019-0155.c
+*/
+
+#define VERSION 1
+#define CHECK_WRITE_BLOCK_WITHOUT_PARSER 0
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#define ASSERT(x, s) do {	\
+	if (!(x)) { \
+		printf("Failed to %s, %s (%d)\n", (s), \
+			       strerror(errno), errno);	\
+		exit(EXIT_FAILURE); \
+		} \
+	} while(0)
+
+static int do_ioctl(const int fd, const unsigned long nr, void *arg)
+{
+	int ret;
+
+	do
+		ret = ioctl(fd, nr, arg);
+	while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+	return ret;
+}
+
+static int is_driver_i915(const int fd)
+{
+	struct _drm_version {
+		int version_major;
+		int version_minor;
+		int version_patchlevel;
+
+		size_t name_len;
+		char *name;
+		size_t date_len;
+		char *date;
+		size_t desc_len;
+		char *desc;
+	} v = { 0, };
+	char name[256] = { 0, };
+	int ret;
+
+	v.name_len = sizeof(name) - 1;
+	v.name = name;
+
+	ret = do_ioctl(fd, _IOWR(0x40, 0x00, struct _drm_version), &v);
+	ASSERT(ret == 0, "get name");
+
+	name[v.name_len] = 0;
+
+	return !strcmp(name, "i915");
+}
+
+static int cmd_parser_version(const int fd)
+{
+	int ret, version = 0;
+	struct _drm_i915_getparam_t {
+		int32_t param;
+		uint64_t value;
+	} q = { 28,
+		(uint64_t)&version };
+
+	ret = do_ioctl(fd, _IOWR(0x40, 0x40 + 0x06, struct _drm_i915_getparam_t), &q);
+	ASSERT(ret == 0, "get param");
+
+	return version;
+}
+
+#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
+#define MI_BATCH_BUFFER_END     MI_INSTR(0x0a, 0)
+#define MI_LOAD_REGISTER_IMM    MI_INSTR(0x22, (3-2))
+
+static int is_write_blocked(const int fd)
+{
+	int ret;
+	uint32_t handle;
+
+	struct _drm_i915_gem_execbuffer2 {
+		uint64_t buffers_ptr;
+		uint32_t buffer_count;
+		uint32_t batch_start_offset;
+		uint32_t batch_len;
+		uint32_t DR1;
+		uint32_t DR4;
+		uint32_t num_cliprects;
+		uint64_t cliprects_ptr;
+		uint64_t flags;
+		uint64_t rsvd1;
+		uint64_t rsvd2;
+	} execbuf = { 0, };
+
+	struct _drm_i915_gem_exec_object2 {
+		uint32_t handle;
+		uint32_t relocation_count;
+		uint64_t relocs_ptr;
+		uint64_t alignment;
+		uint64_t offset;
+		uint64_t flags;
+		uint64_t rsvd1;
+		uint64_t rsvd2;
+	} execobj[1] = { { 0, } };
+
+	struct _drm_i915_gem_create {
+		uint64_t size;
+		uint32_t handle;
+		uint32_t pad;
+	} createobj = { 0, };
+
+	struct _drm_i915_gem_pwrite {
+		uint32_t handle;
+		uint32_t pad;
+		uint64_t offset;
+		uint64_t size;
+		uint64_t data_ptr;
+	} pwrite = { 0, };
+
+	const uint32_t batch[] = {
+		MI_LOAD_REGISTER_IMM,
+		0x2221c,
+		0x0,
+		0,
+		MI_BATCH_BUFFER_END,
+	};
+
+	createobj.handle = 0;
+	createobj.size = 4096;
+
+	ret = do_ioctl(fd, _IOWR(0x40, 0x40+0x1b, struct _drm_i915_gem_create), &createobj);
+	ASSERT(ret == 0, "create object");
+
+	handle = createobj.handle;
+
+	pwrite.handle = handle;
+	pwrite.size = sizeof(batch);
+	pwrite.data_ptr = (uintptr_t)batch;
+
+	ret = do_ioctl(fd, _IOWR(0x40, 0x40+0x1d, struct _drm_i915_gem_pwrite), &pwrite);
+	ASSERT(ret == 0, "write object");
+
+	execobj[0].handle = handle;
+
+	execbuf.buffers_ptr = (uintptr_t)execobj;
+	execbuf.buffer_count = 1;
+	execbuf.flags = 3; /* select blitter engine (bcs0) */
+
+	ret = do_ioctl(fd, _IOWR(0x40, 0x40+0x29, struct _drm_i915_gem_execbuffer2), &execbuf);
+	if (ret) {
+		if (errno == EACCES || errno == EINVAL)
+			return 1;
+	}
+
+	return 0;
+}
+
+#define INTEL_VGA_DEVICE(x, y) (x)
+
+static const uint32_t gen9_ids[] = {
+
+	INTEL_VGA_DEVICE(0x1906, info), /* ULT GT1 */
+
+	INTEL_VGA_DEVICE(0x190E, info), /* ULX GT1 */
+
+	INTEL_VGA_DEVICE(0x1902, info), /* DT  GT1 */
+	INTEL_VGA_DEVICE(0x190B, info), /* Halo GT1 */
+	INTEL_VGA_DEVICE(0x190A, info), /* SRV GT1 */
+
+	INTEL_VGA_DEVICE(0x1916, info), /* ULT GT2 */
+	INTEL_VGA_DEVICE(0x1921, info),  /* ULT GT2F */
+
+	INTEL_VGA_DEVICE(0x191E, info), /* ULX GT2 */
+
+	INTEL_VGA_DEVICE(0x1912, info), /* DT  GT2 */
+	INTEL_VGA_DEVICE(0x191B, info), /* Halo GT2 */
+	INTEL_VGA_DEVICE(0x191A, info), /* SRV GT2 */
+	INTEL_VGA_DEVICE(0x191D, info),  /* WKS GT2 */
+
+	INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */
+
+	INTEL_VGA_DEVICE(0x1923, info), /* ULT GT3 */
+	INTEL_VGA_DEVICE(0x1927, info), /* ULT GT3 */
+	INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */
+	INTEL_VGA_DEVICE(0x192D, info),  /* SRV GT3 */
+
+	INTEL_VGA_DEVICE(0x1932, info), /* DT GT4 */
+	INTEL_VGA_DEVICE(0x193B, info), /* Halo GT4 */
+	INTEL_VGA_DEVICE(0x193D, info), /* WKS GT4 */
+	INTEL_VGA_DEVICE(0x192A, info), /* SRV GT4 */
+	INTEL_VGA_DEVICE(0x193A, info),  /* SRV GT4e */
+
+	INTEL_VGA_DEVICE(0x0A84, info),
+	INTEL_VGA_DEVICE(0x1A84, info),
+	INTEL_VGA_DEVICE(0x1A85, info),
+	INTEL_VGA_DEVICE(0x5A84, info), /* APL HD Graphics 505 */
+	INTEL_VGA_DEVICE(0x5A85, info),  /* APL HD Graphics 500 */
+
+	INTEL_VGA_DEVICE(0x3184, info),
+	INTEL_VGA_DEVICE(0x3185, info),
+
+	INTEL_VGA_DEVICE(0x5906, info), /* ULT GT1 */
+	INTEL_VGA_DEVICE(0x5913, info),  /* ULT GT1.5 */
+
+	INTEL_VGA_DEVICE(0x590E, info), /* ULX GT1 */
+	INTEL_VGA_DEVICE(0x5915, info),  /* ULX GT1.5 */
+
+	INTEL_VGA_DEVICE(0x5902, info), /* DT  GT1 */
+	INTEL_VGA_DEVICE(0x5908, info), /* Halo GT1 */
+	INTEL_VGA_DEVICE(0x590B, info), /* Halo GT1 */
+	INTEL_VGA_DEVICE(0x590A, info), /* SRV GT1 */
+
+	INTEL_VGA_DEVICE(0x5916, info), /* ULT GT2 */
+	INTEL_VGA_DEVICE(0x5921, info),  /* ULT GT2F */
+
+	INTEL_VGA_DEVICE(0x591E, info), /* ULX GT2 */
+
+	INTEL_VGA_DEVICE(0x5917, info), /* Mobile GT2 */
+	INTEL_VGA_DEVICE(0x5912, info), /* DT  GT2 */
+	INTEL_VGA_DEVICE(0x591B, info), /* Halo GT2 */
+	INTEL_VGA_DEVICE(0x591A, info), /* SRV GT2 */
+	INTEL_VGA_DEVICE(0x591D, info), /* WKS GT2 */
+
+	INTEL_VGA_DEVICE(0x5926, info), /* ULT GT3 */
+
+	INTEL_VGA_DEVICE(0x5923, info), /* ULT GT3 */
+	INTEL_VGA_DEVICE(0x5927, info), /* ULT GT3 */
+
+	INTEL_VGA_DEVICE(0x593B, info), /* Halo GT4 */
+
+	INTEL_VGA_DEVICE(0x591C, info),  /* ULX GT2 */
+	INTEL_VGA_DEVICE(0x87C0, info), /* ULX GT2 */
+
+	INTEL_VGA_DEVICE(0x87CA, info),
+
+	INTEL_VGA_DEVICE(0x9B21, info),
+	INTEL_VGA_DEVICE(0x9BAA, info),
+	INTEL_VGA_DEVICE(0x9BAB, info),
+	INTEL_VGA_DEVICE(0x9BAC, info),
+	INTEL_VGA_DEVICE(0x9BA0, info),
+	INTEL_VGA_DEVICE(0x9BA5, info),
+	INTEL_VGA_DEVICE(0x9BA8, info),
+	INTEL_VGA_DEVICE(0x9BA4, info),
+	INTEL_VGA_DEVICE(0x9BA2, info),
+
+	INTEL_VGA_DEVICE(0x9B41, info),
+	INTEL_VGA_DEVICE(0x9BCA, info),
+	INTEL_VGA_DEVICE(0x9BCB, info),
+	INTEL_VGA_DEVICE(0x9BCC, info),
+	INTEL_VGA_DEVICE(0x9BC0, info),
+	INTEL_VGA_DEVICE(0x9BC5, info),
+	INTEL_VGA_DEVICE(0x9BC8, info),
+	INTEL_VGA_DEVICE(0x9BC4, info),
+	INTEL_VGA_DEVICE(0x9BC2, info),
+	INTEL_VGA_DEVICE(0x9BC6, info),
+	INTEL_VGA_DEVICE(0x9BE6, info),
+	INTEL_VGA_DEVICE(0x9BF6, info),
+
+	INTEL_VGA_DEVICE(0x3E90, info), /* SRV GT1 */
+	INTEL_VGA_DEVICE(0x3E93, info), /* SRV GT1 */
+	INTEL_VGA_DEVICE(0x3E99, info),  /* SRV GT1 */
+
+	INTEL_VGA_DEVICE(0x3E91, info), /* SRV GT2 */
+	INTEL_VGA_DEVICE(0x3E92, info), /* SRV GT2 */
+	INTEL_VGA_DEVICE(0x3E96, info), /* SRV GT2 */
+	INTEL_VGA_DEVICE(0x3E98, info), /* SRV GT2 */
+	INTEL_VGA_DEVICE(0x3E9A, info),  /* SRV GT2 */
+
+	INTEL_VGA_DEVICE(0x3E9C, info),
+
+	INTEL_VGA_DEVICE(0x3E9B, info), /* Halo GT2 */
+	INTEL_VGA_DEVICE(0x3E94, info),  /* Halo GT2 */
+
+	INTEL_VGA_DEVICE(0x3EA9, info),
+
+	INTEL_VGA_DEVICE(0x3EA5, info), /* ULT GT3 */
+	INTEL_VGA_DEVICE(0x3EA6, info), /* ULT GT3 */
+	INTEL_VGA_DEVICE(0x3EA7, info), /* ULT GT3 */
+	INTEL_VGA_DEVICE(0x3EA8, info), /* ULT GT3 */
+
+	INTEL_VGA_DEVICE(0x3EA1, info),
+	INTEL_VGA_DEVICE(0x3EA4, info),
+
+	INTEL_VGA_DEVICE(0x3EA0, info),
+	INTEL_VGA_DEVICE(0x3EA3, info),
+
+	INTEL_VGA_DEVICE(0x3EA2, info),
+};
+
+static int is_platform_gen9(void)
+{
+	const char * const id_file =
+		"/sys/bus/pci/drivers/i915/0000:00:02.0/device";
+	char idstr[32] = {0, };
+	uint32_t id = 0;
+	int fd, ret, i;
+
+	fd = open(id_file, O_RDONLY);
+	if (fd == -1)
+		return -1;
+
+	ret = read(fd, idstr, 6);
+	if (ret != 6)
+		return -1;
+
+	close(fd);
+
+	idstr[6] = 0;
+
+	id = strtol(idstr, NULL, 16);
+
+	for (i = 0; i < sizeof(gen9_ids)/sizeof(uint32_t); i++)
+		if (id == gen9_ids[i])
+			return 1;
+
+	return 0;
+}
+
+static int is_fd_safe(const int fd)
+{
+	int parser_version = -1;
+	int write_block = 0;
+
+	parser_version = cmd_parser_version(fd);
+	printf("  Command parser version: %d\n", parser_version);
+	if (parser_version >= 10) {
+		printf("  Command parsing for blt engine supported\n");
+	} else if (!CHECK_WRITE_BLOCK_WITHOUT_PARSER) {
+		printf("  There is no blitter command parser\n");
+		return 0;
+	}
+
+	write_block = is_write_blocked(fd);
+
+	printf("  Unsafe write %s\n", write_block ? "blocked" : "possible!");
+
+	return write_block;
+}
+
+struct stats {
+	int checked;
+	int safe;
+	int failed;
+};
+
+static void check_path(const char *path, struct stats *stats)
+{
+	int fd;
+	int is_safe;
+
+	fd = open(path, O_RDWR);
+	if (fd == -1) {
+		if (errno != ENOENT) {
+			printf("Opening %s failed with %s (%d)\n",
+			       path, strerror(errno), errno);
+			stats->failed++;
+		}
+
+		return;
+	}
+
+	if (!is_driver_i915(fd)) {
+		close(fd);
+		return;
+	}
+
+	printf("Checking %s:\n", path);
+
+	is_safe = is_fd_safe(fd);
+	printf("  Device %s : %s\n\n", path, is_safe ? "SAFE" : "VULNERABLE");
+	if (is_safe)
+		stats->safe++;
+
+	stats->checked++;
+
+	close (fd);
+}
+
+static int check_devices(void)
+{
+	const char * const cardbase = "/dev/dri/card";
+	const char * const renderbase = "/dev/dri/renderD";
+	char path[256];
+	int i;
+	struct stats s = { 0, 0, 0 };
+
+	for (i = 0; i < 16; i++) {
+		sprintf(path, "%s%d", cardbase, i);
+		check_path(path, &s);
+
+		sprintf(path, "%s%d", renderbase, i + 128);
+		check_path(path, &s);
+	}
+
+	if (s.failed && !s.checked) {
+		printf("Failed to open devices, need root?\n");
+		return -1;
+	}
+
+	if (!s.checked) {
+		printf ("Didn't find anything to check\n");
+		return -1;
+	}
+
+	return s.checked == s.safe;
+}
+
+int main(int argc, char *argv[])
+{
+	int safe = 0;
+	int ret;
+
+	printf("Intel cve-2019-0155 (blt mmio vulnerability) checker version %d\n\n", VERSION);
+
+	sync();
+
+	ret = is_platform_gen9();
+	if (ret == 0) {
+		safe = 1;
+		printf("Your platform is not affected\n");
+	} else if (ret == -1) {
+		printf("Unable to determine platform type\n");
+	}
+
+	if (safe != 1)
+		safe = check_devices();
+
+	if (safe < 0) {
+		printf("Unable to determine system state due to errors\n");
+		return EXIT_FAILURE;
+	}
+
+	printf("\nYour system is %s against cve-2019-0155\n", safe ? "SAFE" : "VULNERABLE");
+
+	return safe ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/cve/meson.build b/cve/meson.build
new file mode 100644
index 00000000..990181c6
--- /dev/null
+++ b/cve/meson.build
@@ -0,0 +1,12 @@
+cve_progs = [
+	'cve-2019-0155',
+]
+
+cvedir = join_paths(libexecdir, 'cve')
+
+foreach prog : cve_progs
+	executable(prog, prog + '.c',
+		   install : true,
+		   install_dir : cvedir,
+		   dependencies : igt_deps)
+endforeach
diff --git a/meson.build b/meson.build
index 4d5003ba..27ad9567 100644
--- a/meson.build
+++ b/meson.build
@@ -302,6 +302,7 @@ if libdrm_intel.found()
 endif
 subdir('overlay')
 subdir('man')
+subdir('cve')
 
 gtk_doc = dependency('gtk-doc', required : build_docs)
 python3 = find_program('python3', required : build_docs)
-- 
2.17.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

             reply	other threads:[~2019-11-21 15:19 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-21 15:19 Mika Kuoppala [this message]
2019-11-21 15:19 ` [PATCH i-g-t] cve: Add checker for cve-2019-0155 Mika Kuoppala
2019-11-21 15:22 ` [igt-dev] " Chris Wilson
2019-11-21 15:22   ` [Intel-gfx] " Chris Wilson
2019-11-21 15:22   ` Chris Wilson
2019-11-21 15:27   ` [igt-dev] " Mika Kuoppala
2019-11-21 15:27     ` [Intel-gfx] " Mika Kuoppala
2019-11-21 15:27     ` Mika Kuoppala
2019-11-21 15:29 ` [igt-dev] " Chris Wilson
2019-11-21 15:29   ` [Intel-gfx] " Chris Wilson
2019-11-21 15:29   ` Chris Wilson
2019-11-21 16:07 ` [igt-dev] ✗ GitLab.Pipeline: warning for " Patchwork
2019-11-21 16:09 ` [igt-dev] ✓ Fi.CI.BAT: success " Patchwork
2019-11-22  9:14 ` [Intel-gfx] [PATCH i-g-t] " Petri Latvala
2019-11-22  9:14   ` Petri Latvala
2019-11-22  9:20   ` [igt-dev] [Intel-gfx] " Chris Wilson
2019-11-22  9:20     ` Chris Wilson
2019-11-22  9:20     ` Chris Wilson
2019-11-22  9:39     ` [Intel-gfx] [igt-dev] " Petri Latvala
2019-11-22  9:39       ` Petri Latvala

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=20191121151930.25464-1-mika.kuoppala@linux.intel.com \
    --to=mika.kuoppala@linux.intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=joonas.lahtinen@intel.com \
    /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.