{"id":1093,"date":"2018-01-04T13:43:41","date_gmt":"2018-01-04T21:43:41","guid":{"rendered":"https:\/\/outflux.net\/blog\/?p=1093"},"modified":"2018-01-04T13:43:41","modified_gmt":"2018-01-04T21:43:41","slug":"smep-emulation-in-pti","status":"publish","type":"post","link":"https:\/\/outflux.net\/blog\/archives\/2018\/01\/04\/smep-emulation-in-pti\/","title":{"rendered":"SMEP emulation in PTI"},"content":{"rendered":"<p>An nice additional benefit of the recent <a href=\"https:\/\/git.kernel.org\/pub\/scm\/linux\/kernel\/git\/tip\/tip.git\/commit\/?h=x86\/pti&#038;id=385ce0ea4c078517fa51c261882c4e72fba53005\">Kernel Page Table Isolation<\/a> (<code>CONFIG_PAGE_TABLE_ISOLATION<\/code>) patches (to defend against <a href=\"https:\/\/googleprojectzero.blogspot.com\/2018\/01\/reading-privileged-memory-with-side.html\">CVE-2017-5754<\/a>, the speculative execution &#8220;rogue data cache load&#8221; or &#8220;Meltdown&#8221; flaw) is that the userspace page tables visible while running in kernel mode <a href=\"https:\/\/git.kernel.org\/pub\/scm\/linux\/kernel\/git\/tip\/tip.git\/commit\/?h=x86\/pti&#038;id=1c4de1ff4fe50453b968579ee86fac3da80dd783\">lack the executable bit<\/a>. As a result, systems without the SMEP CPU feature (before Ivy-Bridge) get it emulated for &#8220;free&#8221;.<\/p>\n<p>Here&#8217;s a non-SMEP system with PTI disabled (booted with &#8220;<code>pti=off<\/code>&#8220;), running the <code>EXEC_USERSPACE<\/code> LKDTM test:<\/p>\n<blockquote>\n<pre>\r\n# grep smep \/proc\/cpuinfo\r\n# dmesg -c | grep isolation\r\n[    0.000000] Kernel\/User page tables isolation: disabled on command line.\r\n# cat <(echo EXEC_USERSPACE) > \/sys\/kernel\/debug\/provoke-crash\/DIRECT\r\n# dmesg\r\n[   17.883754] lkdtm: Performing direct entry EXEC_USERSPACE\r\n[   17.885149] lkdtm: attempting ok execution at ffffffff9f6293a0\r\n[   17.886350] lkdtm: attempting bad execution at 00007f6a2f84d000\r\n<\/pre>\n<\/blockquote>\n<p>No crash! The kernel was happily executing userspace memory.<\/p>\n<p>But with PTI enabled:<\/p>\n<blockquote>\n<pre>\r\n# grep smep \/proc\/cpuinfo\r\n# dmesg -c | grep isolation\r\n[    0.000000] Kernel\/User page tables isolation: enabled\r\n# cat <(echo EXEC_USERSPACE) > \/sys\/kernel\/debug\/provoke-crash\/DIRECT\r\nKilled\r\n# dmesg\r\n[   33.657695] lkdtm: Performing direct entry EXEC_USERSPACE\r\n[   33.658800] lkdtm: attempting ok execution at ffffffff926293a0\r\n[   33.660110] lkdtm: attempting bad execution at 00007f7c64546000\r\n[   33.661301] BUG: unable to handle kernel paging request at 00007f7c64546000\r\n[   33.662554] IP: 0x7f7c64546000\r\n...\r\n<\/pre>\n<\/blockquote>\n<p>It should only take a little more work to leave the userspace page tables entirely unmapped while in kernel mode, and only map them in during <code>copy_to_user()<\/code>\/<code>copy_from_user()<\/code> as ARM already does with <code>ARM64_SW_TTBR0_PAN<\/code> (or <code>CONFIG_CPU_SW_DOMAIN_PAN<\/code> on arm32).<\/p>\n<p style='text-align:left'>&copy; 2018, <a href=\"https:\/\/outflux.net\/blog\/\">Kees Cook<\/a>. This work is licensed under a <a rel=\"license\" href=\"http:\/\/creativecommons.org\/licenses\/by-sa\/4.0\/\">Creative Commons Attribution-ShareAlike 4.0 License<\/a>.<br \/><a rel=\"license\" href=\"http:\/\/creativecommons.org\/licenses\/by-sa\/4.0\/\"><img decoding=\"async\" alt=\"CC BY-SA 4.0\" style=\"border-width:0\" src=\"https:\/\/i.creativecommons.org\/l\/by-sa\/4.0\/88x31.png\" \/><\/a> <\/p>\n","protected":false},"excerpt":{"rendered":"<p>An nice additional benefit of the recent Kernel Page Table Isolation (CONFIG_PAGE_TABLE_ISOLATION) patches (to defend against CVE-2017-5754, the speculative execution &#8220;rogue data cache load&#8221; or &#8220;Meltdown&#8221; flaw) is that the userspace page tables visible while running in kernel mode lack the executable bit. As a result, systems without the SMEP CPU feature (before Ivy-Bridge) get [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20,18,21,6,14,19],"tags":[],"_links":{"self":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts\/1093"}],"collection":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/comments?post=1093"}],"version-history":[{"count":5,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts\/1093\/revisions"}],"predecessor-version":[{"id":1098,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts\/1093\/revisions\/1098"}],"wp:attachment":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/media?parent=1093"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/categories?post=1093"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/tags?post=1093"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}