]> Git Repo - linux.git/commitdiff
powerpc/mm/pkeys: Make pkey access check work on execute_only_key
authorAneesh Kumar K.V <[email protected]>
Sat, 27 Jun 2020 07:01:46 +0000 (12:31 +0530)
committerMichael Ellerman <[email protected]>
Mon, 29 Jun 2020 06:17:02 +0000 (16:17 +1000)
Jan reported that LTP mmap03 was getting stuck in a page fault loop
after commit c46241a370a6 ("powerpc/pkeys: Check vma before returning
key fault error to the user"), as well as a minimised reproducer:

  #include <fcntl.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <unistd.h>
  #include <sys/mman.h>

  int main(int ac, char **av)
  {
   int page_sz = getpagesize();
   int fildes;
   char *addr;

   fildes = open("tempfile", O_WRONLY | O_CREAT, 0666);
   write(fildes, &fildes, sizeof(fildes));
   close(fildes);

   fildes = open("tempfile", O_RDONLY);
   unlink("tempfile");

   addr = mmap(0, page_sz, PROT_EXEC, MAP_FILE | MAP_PRIVATE, fildes, 0);

   printf("%d\n", *addr);
   return 0;
  }

And noticed that access_pkey_error() in page fault handler now always
seem to return false:

  __do_page_fault
    access_pkey_error(is_pkey: 1, is_exec: 0, is_write: 0)
      arch_vma_access_permitted
pkey_access_permitted
  if (!is_pkey_enabled(pkey))
    return true
      return false

pkey_access_permitted() should not check if the pkey is available in
UAMOR (using is_pkey_enabled()). The kernel needs to do that check
only when allocating keys. This also makes sure the execute_only_key
which is marked as non-manageable via UAMOR is handled correctly in
pkey_access_permitted(), and fixes the bug.

Fixes: c46241a370a6 ("powerpc/pkeys: Check vma before returning key fault error to the user")
Reported-by: Jan Stancek <[email protected]>
Signed-off-by: Aneesh Kumar K.V <[email protected]>
[mpe: Include bug report details etc. in the change log]
Signed-off-by: Michael Ellerman <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
arch/powerpc/mm/book3s64/pkeys.c

index 1199fc2bfaec9185ec36f8f6bc564287beacfb68..ca5fcb4bff32604cd32be9a9086ec88d37d4304f 100644 (file)
@@ -353,9 +353,6 @@ static bool pkey_access_permitted(int pkey, bool write, bool execute)
        int pkey_shift;
        u64 amr;
 
-       if (!is_pkey_enabled(pkey))
-               return true;
-
        pkey_shift = pkeyshift(pkey);
        if (execute && !(read_iamr() & (IAMR_EX_BIT << pkey_shift)))
                return true;
This page took 0.057059 seconds and 4 git commands to generate.