Commit 3f777e19 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'cve-2020-11884' from emailed bundle

Pull s390 fix from Christian Borntraeger:
 "Fix a race between page table upgrade and uaccess on s390.

  This fixes CVE-2020-11884 which allows for a local kernel crash or
  code execution"

* tag 'cve-2020-11884' from emailed bundle:
  s390/mm: fix page table upgrade vs 2ndary address mode accesses
parents 51184ae3 316ec154
...@@ -64,10 +64,13 @@ mm_segment_t enable_sacf_uaccess(void) ...@@ -64,10 +64,13 @@ mm_segment_t enable_sacf_uaccess(void)
{ {
mm_segment_t old_fs; mm_segment_t old_fs;
unsigned long asce, cr; unsigned long asce, cr;
unsigned long flags;
old_fs = current->thread.mm_segment; old_fs = current->thread.mm_segment;
if (old_fs & 1) if (old_fs & 1)
return old_fs; return old_fs;
/* protect against a concurrent page table upgrade */
local_irq_save(flags);
current->thread.mm_segment |= 1; current->thread.mm_segment |= 1;
asce = S390_lowcore.kernel_asce; asce = S390_lowcore.kernel_asce;
if (likely(old_fs == USER_DS)) { if (likely(old_fs == USER_DS)) {
...@@ -83,6 +86,7 @@ mm_segment_t enable_sacf_uaccess(void) ...@@ -83,6 +86,7 @@ mm_segment_t enable_sacf_uaccess(void)
__ctl_load(asce, 7, 7); __ctl_load(asce, 7, 7);
set_cpu_flag(CIF_ASCE_SECONDARY); set_cpu_flag(CIF_ASCE_SECONDARY);
} }
local_irq_restore(flags);
return old_fs; return old_fs;
} }
EXPORT_SYMBOL(enable_sacf_uaccess); EXPORT_SYMBOL(enable_sacf_uaccess);
......
...@@ -70,8 +70,20 @@ static void __crst_table_upgrade(void *arg) ...@@ -70,8 +70,20 @@ static void __crst_table_upgrade(void *arg)
{ {
struct mm_struct *mm = arg; struct mm_struct *mm = arg;
if (current->active_mm == mm) /* we must change all active ASCEs to avoid the creation of new TLBs */
set_user_asce(mm); if (current->active_mm == mm) {
S390_lowcore.user_asce = mm->context.asce;
if (current->thread.mm_segment == USER_DS) {
__ctl_load(S390_lowcore.user_asce, 1, 1);
/* Mark user-ASCE present in CR1 */
clear_cpu_flag(CIF_ASCE_PRIMARY);
}
if (current->thread.mm_segment == USER_DS_SACF) {
__ctl_load(S390_lowcore.user_asce, 7, 7);
/* enable_sacf_uaccess does all or nothing */
WARN_ON(!test_cpu_flag(CIF_ASCE_SECONDARY));
}
}
__tlb_flush_local(); __tlb_flush_local();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment