Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752851AbbBXPrn (ORCPT ); Tue, 24 Feb 2015 10:47:43 -0500 Received: from mail-qc0-f170.google.com ([209.85.216.170]:36437 "EHLO mail-qc0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750925AbbBXPrl (ORCPT ); Tue, 24 Feb 2015 10:47:41 -0500 MIME-Version: 1.0 In-Reply-To: References: From: Denys Vlasenko Date: Tue, 24 Feb 2015 16:47:20 +0100 Message-ID: Subject: Re: [PATCH 3.2 055/152] x86_64, switch_to(): Load TLS descriptors before switching DS and ES To: Ben Hutchings Cc: Linux Kernel Mailing List , stable@vger.kernel.org, Andrew Morton , Ingo Molnar , Andy Lutomirski , Andi Kleen , Linus Torvalds Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3107 Lines: 99 On Tue, Feb 17, 2015 at 2:46 AM, Ben Hutchings wrote: > 3.2.67-rc1 review patch. If anyone has any objections, please let me know. > > ------------------ > > From: Andy Lutomirski > > commit f647d7c155f069c1a068030255c300663516420e upstream. > > Otherwise, if buggy user code points DS or ES into the TLS > array, they would be corrupted after a context switch. > > This also significantly improves the comments and documents some > gotchas in the code. > > Before this patch, the both tests below failed. With this > patch, the es test passes, although the gsbase test still fails. > > ----- begin es test ----- > > /* > * Copyright (c) 2014 Andy Lutomirski > * GPL v2 > */ > > static unsigned short GDT3(int idx) > { > return (idx << 3) | 3; > } > > static int create_tls(int idx, unsigned int base) > { > struct user_desc desc = { > .entry_number = idx, > .base_addr = base, > .limit = 0xfffff, > .seg_32bit = 1, > .contents = 0, /* Data, grow-up */ > .read_exec_only = 0, > .limit_in_pages = 1, > .seg_not_present = 0, > .useable = 0, > }; > > if (syscall(SYS_set_thread_area, &desc) != 0) > err(1, "set_thread_area"); > > return desc.entry_number; > } > > int main() > { > int idx = create_tls(-1, 0); > printf("Allocated GDT index %d\n", idx); > > unsigned short orig_es; > asm volatile ("mov %%es,%0" : "=rm" (orig_es)); > > int errors = 0; > int total = 1000; > for (int i = 0; i < total; i++) { > asm volatile ("mov %0,%%es" : : "rm" (GDT3(idx))); > usleep(100); > > unsigned short es; > asm volatile ("mov %%es,%0" : "=rm" (es)); > asm volatile ("mov %0,%%es" : : "rm" (orig_es)); > if (es != GDT3(idx)) { > if (errors == 0) > printf("[FAIL]\tES changed from 0x%hx to 0x%hx\n", > GDT3(idx), es); > errors++; > } > } > > if (errors) { > printf("[FAIL]\tES was corrupted %d/%d times\n", errors, total); > return 1; > } else { > printf("[OK]\tES was preserved\n"); > return 0; > } > } > > ----- end es test ----- This currently fails in 32-bit kernels (at least in qemu): / # ./es_test Allocated GDT index 7 [FAIL] ES changed from 0x3b to 0x7b [FAIL] ES was corrupted 1000/1000 times / # uname -a Linux (none) 4.0.0-rc1 #1 SMP Tue Feb 24 16:41:58 CET 2015 i686 GNU/Linux -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/