mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
s390x/mm/uaccess: Fix race between page table upgrade and uaccess
This fixes CVE-2020-11884 which allows for a local kernel crash or code execution. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJeny8gAAoJEBF7vIC1phx8eWYP/2R8iLZIKrpb58PVQFAECJYp EIiiZ3b68AdlKUa52iLXt+WYC2RDIrNdSIsUXVWtXSGPfuE/vsY2fF4seUfrAzzu 2usvjcJA3y7l32Xmlqz1WPK+6JBfxjGvLM80pHTD3bQpOEymJ4ODhWlbDwmBVl6U oYRMZfNyy/J+xOE0P6XRewllq9Vbx6xBX2CVIV8PDM1ktrAj/Q4e9CqMBx7RT3Vf 36/CR3numLA6l6xktFoqfs2WV85uORfC7+tuHXepmEartfLu2109WW+H8aNd33Bj wuKTMi5IJbvToRhL6tBY0yhTGxwVwhoD/CDFEl1Qdf8yJfaNHjlzzncEsZPBJxu2 cOyaTNZgHbcg7EteSpB8l/VAS7aaVoeQ+oKHKstjsHzfLE5UGItcF92BWUVYuHlx UcOcbDC9glLgfFIujAfsaVnS+iLxz+tV7ftfzFZTNl4ZF568f2urMNQF5RbOVip2 RZZz/7wxE22VwNRilM+8bqriW0or4zr/Wo1cZan+dZxNUDzT+uFlDrWrUGTKeNwf Fe7DplD82FVYGrbC66huVzq40/31TTKo8dxpAXK79ETJ53qKP3vAGJ0TOyrc4fHP 9VdErI7Ij+igfnQdBzdJYNuQmFT2gbeoNfqU4eam4sYSFik/1jrqiJgUfUmjW0no ugnUhVZ13vkE+ZjYlP2W =F1vM -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
3f777e19d1
@ -64,10 +64,13 @@ mm_segment_t enable_sacf_uaccess(void)
|
||||
{
|
||||
mm_segment_t old_fs;
|
||||
unsigned long asce, cr;
|
||||
unsigned long flags;
|
||||
|
||||
old_fs = current->thread.mm_segment;
|
||||
if (old_fs & 1)
|
||||
return old_fs;
|
||||
/* protect against a concurrent page table upgrade */
|
||||
local_irq_save(flags);
|
||||
current->thread.mm_segment |= 1;
|
||||
asce = S390_lowcore.kernel_asce;
|
||||
if (likely(old_fs == USER_DS)) {
|
||||
@ -83,6 +86,7 @@ mm_segment_t enable_sacf_uaccess(void)
|
||||
__ctl_load(asce, 7, 7);
|
||||
set_cpu_flag(CIF_ASCE_SECONDARY);
|
||||
}
|
||||
local_irq_restore(flags);
|
||||
return old_fs;
|
||||
}
|
||||
EXPORT_SYMBOL(enable_sacf_uaccess);
|
||||
|
@ -70,8 +70,20 @@ static void __crst_table_upgrade(void *arg)
|
||||
{
|
||||
struct mm_struct *mm = arg;
|
||||
|
||||
if (current->active_mm == mm)
|
||||
set_user_asce(mm);
|
||||
/* we must change all active ASCEs to avoid the creation of new TLBs */
|
||||
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();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user