Message ID | 1402935456-69638-1-git-send-email-tim.gardner@canonical.com |
---|---|
State | New |
Headers | show |
Will this patch be superseeded by espfix64 when that lands? --chris On 06/16/2014 11:17 AM, Tim Gardner wrote: > From: Linus Torvalds <torvalds@linux-foundation.org> > > BugLink: http://bugs.launchpad.net/bugs/1328965 > > Checkin: > > b3b42ac2cbae x86-64, modify_ldt: Ban 16-bit segments on 64-bit kernels > > disabled 16-bit segments on 64-bit kernels due to an information > leak. However, it does seem that people are genuinely using Wine to > run old 16-bit Windows programs on Linux. > > A proper fix for this ("espfix64") is coming in the upcoming merge > window, but as a temporary fix, create a sysctl to allow the > administrator to re-enable support for 16-bit segments. > > It adds a "/proc/sys/abi/ldt16" sysctl that defaults to zero (off). If > you hit this issue and care about your old Windows program more than > you care about a kernel stack address information leak, you can do > > echo 1 > /proc/sys/abi/ldt16 > > as root (add it to your startup scripts), and you should be ok. > > The sysctl table is only added if you have COMPAT support enabled on > x86-64, but I assume anybody who runs old windows binaries very much > does that ;) > > Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> > Link: http://lkml.kernel.org/r/CA%2B55aFw9BPoD10U1LfHbOMpHWZkvJTkMcfCs9s3urPr1YyWBxw@mail.gmail.com > Cc: <stable@vger.kernel.org> > (cherry picked from commit fa81511bb0bbb2b1aace3695ce869da9762624ff) > Signed-off-by: Tim Gardner <tim.gardner@canonical.com> > --- > arch/x86/kernel/ldt.c | 4 +++- > arch/x86/vdso/vdso32-setup.c | 8 ++++++++ > 2 files changed, 11 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c > index af1d14a..dcbbaa1 100644 > --- a/arch/x86/kernel/ldt.c > +++ b/arch/x86/kernel/ldt.c > @@ -20,6 +20,8 @@ > #include <asm/mmu_context.h> > #include <asm/syscalls.h> > > +int sysctl_ldt16 = 0; > + > #ifdef CONFIG_SMP > static void flush_ldt(void *current_mm) > { > @@ -234,7 +236,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) > * IRET leaking the high bits of the kernel stack address. > */ > #ifdef CONFIG_X86_64 > - if (!ldt_info.seg_32bit) { > + if (!ldt_info.seg_32bit && !sysctl_ldt16) { > error = -EINVAL; > goto out_unlock; > } > diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c > index d6bfb87..f1d633a 100644 > --- a/arch/x86/vdso/vdso32-setup.c > +++ b/arch/x86/vdso/vdso32-setup.c > @@ -41,6 +41,7 @@ enum { > #ifdef CONFIG_X86_64 > #define vdso_enabled sysctl_vsyscall32 > #define arch_setup_additional_pages syscall32_setup_pages > +extern int sysctl_ldt16; > #endif > > /* > @@ -380,6 +381,13 @@ static struct ctl_table abi_table2[] = { > .mode = 0644, > .proc_handler = proc_dointvec > }, > + { > + .procname = "ldt16", > + .data = &sysctl_ldt16, > + .maxlen = sizeof(int), > + .mode = 0644, > + .proc_handler = proc_dointvec > + }, > {} > }; > >
You're gonna have to provide a bit more detail 'cause I don't know anything about espfix64. rtg On 06/16/2014 10:24 AM, Chris J Arges wrote: > Will this patch be superseeded by espfix64 when that lands? > --chris > > On 06/16/2014 11:17 AM, Tim Gardner wrote: >> From: Linus Torvalds <torvalds@linux-foundation.org> >> >> BugLink: http://bugs.launchpad.net/bugs/1328965 >> >> Checkin: >> >> b3b42ac2cbae x86-64, modify_ldt: Ban 16-bit segments on 64-bit kernels >> >> disabled 16-bit segments on 64-bit kernels due to an information >> leak. However, it does seem that people are genuinely using Wine to >> run old 16-bit Windows programs on Linux. >> >> A proper fix for this ("espfix64") is coming in the upcoming merge >> window, but as a temporary fix, create a sysctl to allow the >> administrator to re-enable support for 16-bit segments. >> >> It adds a "/proc/sys/abi/ldt16" sysctl that defaults to zero (off). If >> you hit this issue and care about your old Windows program more than >> you care about a kernel stack address information leak, you can do >> >> echo 1 > /proc/sys/abi/ldt16 >> >> as root (add it to your startup scripts), and you should be ok. >> >> The sysctl table is only added if you have COMPAT support enabled on >> x86-64, but I assume anybody who runs old windows binaries very much >> does that ;) >> >> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> >> Link: http://lkml.kernel.org/r/CA%2B55aFw9BPoD10U1LfHbOMpHWZkvJTkMcfCs9s3urPr1YyWBxw@mail.gmail.com >> Cc: <stable@vger.kernel.org> >> (cherry picked from commit fa81511bb0bbb2b1aace3695ce869da9762624ff) >> Signed-off-by: Tim Gardner <tim.gardner@canonical.com> >> --- >> arch/x86/kernel/ldt.c | 4 +++- >> arch/x86/vdso/vdso32-setup.c | 8 ++++++++ >> 2 files changed, 11 insertions(+), 1 deletion(-) >> >> diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c >> index af1d14a..dcbbaa1 100644 >> --- a/arch/x86/kernel/ldt.c >> +++ b/arch/x86/kernel/ldt.c >> @@ -20,6 +20,8 @@ >> #include <asm/mmu_context.h> >> #include <asm/syscalls.h> >> >> +int sysctl_ldt16 = 0; >> + >> #ifdef CONFIG_SMP >> static void flush_ldt(void *current_mm) >> { >> @@ -234,7 +236,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) >> * IRET leaking the high bits of the kernel stack address. >> */ >> #ifdef CONFIG_X86_64 >> - if (!ldt_info.seg_32bit) { >> + if (!ldt_info.seg_32bit && !sysctl_ldt16) { >> error = -EINVAL; >> goto out_unlock; >> } >> diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c >> index d6bfb87..f1d633a 100644 >> --- a/arch/x86/vdso/vdso32-setup.c >> +++ b/arch/x86/vdso/vdso32-setup.c >> @@ -41,6 +41,7 @@ enum { >> #ifdef CONFIG_X86_64 >> #define vdso_enabled sysctl_vsyscall32 >> #define arch_setup_additional_pages syscall32_setup_pages >> +extern int sysctl_ldt16; >> #endif >> >> /* >> @@ -380,6 +381,13 @@ static struct ctl_table abi_table2[] = { >> .mode = 0644, >> .proc_handler = proc_dointvec >> }, >> + { >> + .procname = "ldt16", >> + .data = &sysctl_ldt16, >> + .maxlen = sizeof(int), >> + .mode = 0644, >> + .proc_handler = proc_dointvec >> + }, >> {} >> }; >> >>
On 06/16/2014 12:01 PM, Tim Gardner wrote: > You're gonna have to provide a bit more detail 'cause I don't know > anything about espfix64. > > rtg From the the commit message: > A proper fix for this ("espfix64") is coming in the upcoming merge > window, but as a temporary fix, create a sysctl to allow the > administrator to re-enable support for 16-bit segments. Which leads to this: http://comments.gmane.org/gmane.linux.kernel.commits.head/452742 In addition looking at the thread it looks like this commit potentially broke something Wine related: http://marc.info/?l=linux-kernel&m=139990057717709&w=2 I'm not sure how that bug was hit since the default functionality should not change anything. --chris > > On 06/16/2014 10:24 AM, Chris J Arges wrote: >> Will this patch be superseeded by espfix64 when that lands? >> --chris >> >> On 06/16/2014 11:17 AM, Tim Gardner wrote: >>> From: Linus Torvalds <torvalds@linux-foundation.org> >>> >>> BugLink: http://bugs.launchpad.net/bugs/1328965 >>> >>> Checkin: >>> >>> b3b42ac2cbae x86-64, modify_ldt: Ban 16-bit segments on 64-bit kernels >>> >>> disabled 16-bit segments on 64-bit kernels due to an information >>> leak. However, it does seem that people are genuinely using Wine to >>> run old 16-bit Windows programs on Linux. >>> >>> A proper fix for this ("espfix64") is coming in the upcoming merge >>> window, but as a temporary fix, create a sysctl to allow the >>> administrator to re-enable support for 16-bit segments. >>> >>> It adds a "/proc/sys/abi/ldt16" sysctl that defaults to zero (off). If >>> you hit this issue and care about your old Windows program more than >>> you care about a kernel stack address information leak, you can do >>> >>> echo 1 > /proc/sys/abi/ldt16 >>> >>> as root (add it to your startup scripts), and you should be ok. >>> >>> The sysctl table is only added if you have COMPAT support enabled on >>> x86-64, but I assume anybody who runs old windows binaries very much >>> does that ;) >>> >>> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> >>> Link: >>> Cc: <stable@vger.kernel.org> >>> (cherry picked from commit fa81511bb0bbb2b1aace3695ce869da9762624ff) >>> Signed-off-by: Tim Gardner <tim.gardner@canonical.com> >>> --- >>> arch/x86/kernel/ldt.c | 4 +++- >>> arch/x86/vdso/vdso32-setup.c | 8 ++++++++ >>> 2 files changed, 11 insertions(+), 1 deletion(-) >>> >>> diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c >>> index af1d14a..dcbbaa1 100644 >>> --- a/arch/x86/kernel/ldt.c >>> +++ b/arch/x86/kernel/ldt.c >>> @@ -20,6 +20,8 @@ >>> #include <asm/mmu_context.h> >>> #include <asm/syscalls.h> >>> >>> +int sysctl_ldt16 = 0; >>> + >>> #ifdef CONFIG_SMP >>> static void flush_ldt(void *current_mm) >>> { >>> @@ -234,7 +236,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) >>> * IRET leaking the high bits of the kernel stack address. >>> */ >>> #ifdef CONFIG_X86_64 >>> - if (!ldt_info.seg_32bit) { >>> + if (!ldt_info.seg_32bit && !sysctl_ldt16) { >>> error = -EINVAL; >>> goto out_unlock; >>> } >>> diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c >>> index d6bfb87..f1d633a 100644 >>> --- a/arch/x86/vdso/vdso32-setup.c >>> +++ b/arch/x86/vdso/vdso32-setup.c >>> @@ -41,6 +41,7 @@ enum { >>> #ifdef CONFIG_X86_64 >>> #define vdso_enabled sysctl_vsyscall32 >>> #define arch_setup_additional_pages syscall32_setup_pages >>> +extern int sysctl_ldt16; >>> #endif >>> >>> /* >>> @@ -380,6 +381,13 @@ static struct ctl_table abi_table2[] = { >>> .mode = 0644, >>> .proc_handler = proc_dointvec >>> }, >>> + { >>> + .procname = "ldt16", >>> + .data = &sysctl_ldt16, >>> + .maxlen = sizeof(int), >>> + .mode = 0644, >>> + .proc_handler = proc_dointvec >>> + }, >>> {} >>> }; >>> >>> > >
Basically just adds an interface to re-configure the kernel to the old behaviour of allowing 16bit segments (with the downside of having a potential information leak). From the stable discussion that I remember, running some Windows programs through wine was one thing that still needed those. Maybe it can be replaced by the proper fix they promise but then postponing it till after the merge window re-opens sounds like it could be non-trivial. -Stefan
On 06/16/2014 09:17 AM, Tim Gardner wrote: > From: Linus Torvalds <torvalds@linux-foundation.org> > > BugLink: http://bugs.launchpad.net/bugs/1328965 > > Checkin: > > b3b42ac2cbae x86-64, modify_ldt: Ban 16-bit segments on 64-bit kernels > > disabled 16-bit segments on 64-bit kernels due to an information > leak. However, it does seem that people are genuinely using Wine to > run old 16-bit Windows programs on Linux. > > A proper fix for this ("espfix64") is coming in the upcoming merge > window, but as a temporary fix, create a sysctl to allow the > administrator to re-enable support for 16-bit segments. > > It adds a "/proc/sys/abi/ldt16" sysctl that defaults to zero (off). If > you hit this issue and care about your old Windows program more than > you care about a kernel stack address information leak, you can do > > echo 1 > /proc/sys/abi/ldt16 > > as root (add it to your startup scripts), and you should be ok. > > The sysctl table is only added if you have COMPAT support enabled on > x86-64, but I assume anybody who runs old windows binaries very much > does that ;) > > Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> > Link: http://lkml.kernel.org/r/CA%2B55aFw9BPoD10U1LfHbOMpHWZkvJTkMcfCs9s3urPr1YyWBxw@mail.gmail.com > Cc: <stable@vger.kernel.org> > (cherry picked from commit fa81511bb0bbb2b1aace3695ce869da9762624ff) > Signed-off-by: Tim Gardner <tim.gardner@canonical.com> > --- > arch/x86/kernel/ldt.c | 4 +++- > arch/x86/vdso/vdso32-setup.c | 8 ++++++++ > 2 files changed, 11 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c > index af1d14a..dcbbaa1 100644 > --- a/arch/x86/kernel/ldt.c > +++ b/arch/x86/kernel/ldt.c > @@ -20,6 +20,8 @@ > #include <asm/mmu_context.h> > #include <asm/syscalls.h> > > +int sysctl_ldt16 = 0; > + > #ifdef CONFIG_SMP > static void flush_ldt(void *current_mm) > { > @@ -234,7 +236,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) > * IRET leaking the high bits of the kernel stack address. > */ > #ifdef CONFIG_X86_64 > - if (!ldt_info.seg_32bit) { > + if (!ldt_info.seg_32bit && !sysctl_ldt16) { > error = -EINVAL; > goto out_unlock; > } > diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c > index d6bfb87..f1d633a 100644 > --- a/arch/x86/vdso/vdso32-setup.c > +++ b/arch/x86/vdso/vdso32-setup.c > @@ -41,6 +41,7 @@ enum { > #ifdef CONFIG_X86_64 > #define vdso_enabled sysctl_vsyscall32 > #define arch_setup_additional_pages syscall32_setup_pages > +extern int sysctl_ldt16; > #endif > > /* > @@ -380,6 +381,13 @@ static struct ctl_table abi_table2[] = { > .mode = 0644, > .proc_handler = proc_dointvec > }, > + { > + .procname = "ldt16", > + .data = &sysctl_ldt16, > + .maxlen = sizeof(int), > + .mode = 0644, > + .proc_handler = proc_dointvec > + }, > {} > }; > >
Chris - even if this regresses with some Wine users, it at least preserves existing behavior since they have to change a sysctl to enable the functionality. rtg
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index af1d14a..dcbbaa1 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c @@ -20,6 +20,8 @@ #include <asm/mmu_context.h> #include <asm/syscalls.h> +int sysctl_ldt16 = 0; + #ifdef CONFIG_SMP static void flush_ldt(void *current_mm) { @@ -234,7 +236,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) * IRET leaking the high bits of the kernel stack address. */ #ifdef CONFIG_X86_64 - if (!ldt_info.seg_32bit) { + if (!ldt_info.seg_32bit && !sysctl_ldt16) { error = -EINVAL; goto out_unlock; } diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c index d6bfb87..f1d633a 100644 --- a/arch/x86/vdso/vdso32-setup.c +++ b/arch/x86/vdso/vdso32-setup.c @@ -41,6 +41,7 @@ enum { #ifdef CONFIG_X86_64 #define vdso_enabled sysctl_vsyscall32 #define arch_setup_additional_pages syscall32_setup_pages +extern int sysctl_ldt16; #endif /* @@ -380,6 +381,13 @@ static struct ctl_table abi_table2[] = { .mode = 0644, .proc_handler = proc_dointvec }, + { + .procname = "ldt16", + .data = &sysctl_ldt16, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec + }, {} };