From 614303b861fc75485f6c1c01f89e26c334f22c93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20D=C3=ADaz?= Date: Mon, 3 Sep 2018 11:29:37 -0500 Subject: ltp: Add cve/meltdown patch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As stated here: https://bugs.linaro.org/show_bug.cgi?id=3985 if running kernels >= v4.16-2291-g8c06c7740d19, then LTP needs this patch. It's safe to use that code with all kernels, even older versions. Change-Id: I40c10664081fd1030c18add9ac9829ccf7d44bc9 Signed-off-by: Daniel Díaz (cherry picked from commit d24e7bd30333cb778f76b7e2c9b36de75757d9fd) --- ...0042-cve-meltdown-read-saved_command_line.patch | 155 +++++++++++++++++++++ core/recipes-extended/ltp/ltp_20180515.bb | 1 + 2 files changed, 156 insertions(+) create mode 100644 core/recipes-extended/ltp/ltp/0042-cve-meltdown-read-saved_command_line.patch diff --git a/core/recipes-extended/ltp/ltp/0042-cve-meltdown-read-saved_command_line.patch b/core/recipes-extended/ltp/ltp/0042-cve-meltdown-read-saved_command_line.patch new file mode 100644 index 0000000..05b274a --- /dev/null +++ b/core/recipes-extended/ltp/ltp/0042-cve-meltdown-read-saved_command_line.patch @@ -0,0 +1,155 @@ +From 16cf0c9220897f1cb312c7d9531cedf2049479ad Mon Sep 17 00:00:00 2001 +From: Jan Stancek +Date: Wed, 20 Jun 2018 13:51:58 +0200 +Subject: [PATCH] cve/meltdown: read *saved_command_line + +After commit 8c06c7740d19 ("x86/pti: Leave kernel text global for !PCID"), +kernel can now map all of kernel text into the user page tables. +So, read of "linux_proc_banner" can succeed and report a false positive. + +This patch changes the test to read value of "saved_command_line" +pointer and then also memory pointed to by it. And compares result +(first 32 bytes) to /proc/cmdline. saved_command_line string is +allocated dynamically and falls outside of (_text, _end) area: + crash> p/x _text + $2 = 0xffffffff81000000 + crash> p/x _end + $3 = 0xffffffff82411000 + crash> p/x &saved_command_line + $4 = 0xffffffff81cf3008 + crash> p/x saved_command_line + $5 = 0xffff88007ff55100 +so test should work on kernels with and without the patch. + +saved_command_line is allocated dynamically since 2.6.21: + 30d7e0d466b3 ("[PATCH] Dynamic kernel command-line: common") + +Signed-off-by: Jan Stancek +Reviewed-by: Li Wang +Reviewed-by: Petr Vorel +Acked-by: Cyril Hrubis + +Upstream-Status: Backport [https://github.com/linux-test-project/ltp/commit/4db15cd7922a3880cd63b3a6aed77b85eecb9e47] +--- + testcases/cve/meltdown.c | 64 ++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 48 insertions(+), 16 deletions(-) + +diff --git a/testcases/cve/meltdown.c b/testcases/cve/meltdown.c +index dce84a0..a53ea9b 100644 +--- a/testcases/cve/meltdown.c ++++ b/testcases/cve/meltdown.c +@@ -189,7 +189,7 @@ readbit(int fd, unsigned long addr, char bit) + for (i = 0; i < CYCLES; i++) { + ret = pread(fd, buf, sizeof(buf), 0); + if (ret < 0) +- tst_res(TBROK | TERRNO, "can't read /proc/version"); ++ tst_res(TBROK | TERRNO, "can't read fd"); + + clflush_target(); + +@@ -298,17 +298,17 @@ find_kernel_symbol(const char *name) + return addr; + } + +-unsigned long linux_proc_banner_addr; +-int banner_fd; ++static unsigned long saved_cmdline_addr; ++static int spec_fd; + + static void setup(void) + { + set_cache_hit_threshold(); + +- linux_proc_banner_addr = find_kernel_symbol("linux_proc_banner"); +- tst_res(TINFO, "linux_proc_banner is at %lx", linux_proc_banner_addr); ++ saved_cmdline_addr = find_kernel_symbol("saved_command_line"); ++ tst_res(TINFO, "&saved_command_line == 0x%lx", saved_cmdline_addr); + +- banner_fd = SAFE_OPEN("/proc/version", O_RDONLY); ++ spec_fd = SAFE_OPEN("/proc/cmdline", O_RDONLY); + + memset(target_array, 1, sizeof(target_array)); + +@@ -316,37 +316,69 @@ static void setup(void) + tst_res(TBROK | TERRNO, "set_signal"); + } + ++#define READ_SIZE 32 ++ + static void run(void) + { +- unsigned int i, score, ret; +- static char expected[] = "%s version %s"; +- static char read[32]; +- unsigned long addr = linux_proc_banner_addr; +- unsigned long size = sizeof(expected) - 1; +- ++ unsigned int i, score = 0, ret; ++ unsigned long addr; ++ unsigned long size; ++ char read[READ_SIZE] = { 0 }; ++ char expected[READ_SIZE] = { 0 }; ++ int expected_len; ++ ++ expected_len = pread(spec_fd, expected, sizeof(expected), 0); ++ if (expected_len < 0) ++ tst_res(TBROK | TERRNO, "can't read test fd"); ++ ++ /* read address of saved_cmdline_addr */ ++ addr = saved_cmdline_addr; ++ size = sizeof(addr); + for (i = 0; i < size; i++) { +- ret = readbyte(banner_fd, addr); ++ ret = readbyte(spec_fd, addr); + + read[i] = ret; +- tst_res(TINFO, "read %lx = 0x%x %c", addr, ret, ++ tst_res(TINFO, "read %lx = 0x%02x %c", addr, ret, + isprint(ret) ? ret : ' '); + + addr++; + } + +- for (score = 0, i = 0; i < size; i++) ++ /* read value pointed to by saved_cmdline_addr */ ++ memcpy(&addr, read, sizeof(addr)); ++ memset(read, 0, sizeof(read)); ++ tst_res(TINFO, "save_command_line: 0x%lx", addr); ++ size = expected_len; ++ ++ if (!addr) ++ goto done; ++ ++ for (i = 0; i < size; i++) { ++ ret = readbyte(spec_fd, addr); ++ ++ read[i] = ret; ++ tst_res(TINFO, "read %lx = 0x%02x %c | expected 0x%02x |" ++ " match: %d", addr, ret, isprint(ret) ? ret : ' ', ++ expected[i], read[i] == expected[i]); ++ ++ addr++; ++ } ++ ++ for (i = 0; i < size; i++) + if (expected[i] == read[i]) + score++; + ++done: + if (score > size / 2) + tst_res(TFAIL, "I was able to read your kernel memory!!!"); + else + tst_res(TPASS, "I was not able to read your kernel memory"); ++ tst_res(TINFO, "score(matched/all): %u / %lu", score, size); + } + + static void cleanup(void) + { +- SAFE_CLOSE(banner_fd); ++ SAFE_CLOSE(spec_fd); + } + + static struct tst_test test = { +-- +2.7.4 + diff --git a/core/recipes-extended/ltp/ltp_20180515.bb b/core/recipes-extended/ltp/ltp_20180515.bb index 7dff388..3b5d461 100644 --- a/core/recipes-extended/ltp/ltp_20180515.bb +++ b/core/recipes-extended/ltp/ltp_20180515.bb @@ -49,6 +49,7 @@ SRC_URI = "git://github.com/linux-test-project/ltp.git \ file://0039-commands-ar01-Fix-for-test-in-deterministic-mode.patch \ file://0040-read_all-Define-FNM_EXTMATCH-if-not-already-like-und.patch \ file://0041-cve-2017-5669-shmat-for-0-or-PAGESIZE-with-RND-flag-.patch \ + file://0042-cve-meltdown-read-saved_command_line.patch \ " S = "${WORKDIR}/git" -- cgit v1.2.3