riscv: set the permission of vdso_data to read-only
authorVincent Chen <vincent.chen@sifive.com>
Tue, 9 Jun 2020 14:14:49 +0000 (22:14 +0800)
committerPalmer Dabbelt <palmerdabbelt@google.com>
Thu, 11 Jun 2020 02:47:35 +0000 (19:47 -0700)
The original vdso_data page is empty, so the permission of the vdso_data
page can be the same with the vdso text page. After introducing the vDSO
common flow, the vdso_data is not empty and the permission should be
changed to read-only.

Signed-off-by: Vincent Chen <vincent.chen@sifive.com>
Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
arch/riscv/kernel/vdso.c

index 70b6461a63877ef746cfd89dc2541badd8922748..94450332aa4f2f1ea3315896044b8d0d7b7a0ed4 100644 (file)
@@ -79,13 +79,22 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
         */
        mm->context.vdso = (void *)vdso_base;
 
-       ret = install_special_mapping(mm, vdso_base, vdso_len,
+       ret =
+          install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT,
                (VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC),
                vdso_pagelist);
 
-       if (unlikely(ret))
+       if (unlikely(ret)) {
                mm->context.vdso = NULL;
+               goto end;
+       }
 
+       vdso_base += (vdso_pages << PAGE_SHIFT);
+       ret = install_special_mapping(mm, vdso_base, PAGE_SIZE,
+               (VM_READ | VM_MAYREAD), &vdso_pagelist[vdso_pages]);
+
+       if (unlikely(ret))
+               mm->context.vdso = NULL;
 end:
        up_write(&mm->mmap_sem);
        return ret;
@@ -95,5 +104,8 @@ const char *arch_vma_name(struct vm_area_struct *vma)
 {
        if (vma->vm_mm && (vma->vm_start == (long)vma->vm_mm->context.vdso))
                return "[vdso]";
+       if (vma->vm_mm && (vma->vm_start ==
+                          (long)vma->vm_mm->context.vdso + PAGE_SIZE))
+               return "[vdso_data]";
        return NULL;
 }