1. 20 7月, 2020 17 次提交
  2. 16 7月, 2020 13 次提交
  3. 15 7月, 2020 2 次提交
  4. 13 7月, 2020 1 次提交
    • A
      powerpc/book3s64/pkeys: Fix pkey_access_permitted() for execute disable pkey · 192b6a78
      Aneesh Kumar K.V 提交于
      Even if the IAMR value denies execute access, the current code returns
      true from pkey_access_permitted() for an execute permission check, if
      the AMR read pkey bit is cleared.
      
      This results in repeated page fault loop with a test like below:
      
        #define _GNU_SOURCE
        #include <errno.h>
        #include <stdio.h>
        #include <stdlib.h>
        #include <signal.h>
        #include <inttypes.h>
      
        #include <assert.h>
        #include <malloc.h>
        #include <unistd.h>
        #include <pthread.h>
        #include <sys/mman.h>
      
        #ifdef SYS_pkey_mprotect
        #undef SYS_pkey_mprotect
        #endif
      
        #ifdef SYS_pkey_alloc
        #undef SYS_pkey_alloc
        #endif
      
        #ifdef SYS_pkey_free
        #undef SYS_pkey_free
        #endif
      
        #undef PKEY_DISABLE_EXECUTE
        #define PKEY_DISABLE_EXECUTE	0x4
      
        #define SYS_pkey_mprotect	386
        #define SYS_pkey_alloc		384
        #define SYS_pkey_free		385
      
        #define PPC_INST_NOP		0x60000000
        #define PPC_INST_BLR		0x4e800020
        #define PROT_RWX		(PROT_READ | PROT_WRITE | PROT_EXEC)
      
        static int sys_pkey_mprotect(void *addr, size_t len, int prot, int pkey)
        {
        	return syscall(SYS_pkey_mprotect, addr, len, prot, pkey);
        }
      
        static int sys_pkey_alloc(unsigned long flags, unsigned long access_rights)
        {
        	return syscall(SYS_pkey_alloc, flags, access_rights);
        }
      
        static int sys_pkey_free(int pkey)
        {
        	return syscall(SYS_pkey_free, pkey);
        }
      
        static void do_execute(void *region)
        {
        	/* jump to region */
        	asm volatile(
        		"mtctr	%0;"
        		"bctrl"
        		: : "r"(region) : "ctr", "lr");
        }
      
        static void do_protect(void *region)
        {
        	size_t pgsize;
        	int i, pkey;
      
        	pgsize = getpagesize();
      
        	pkey = sys_pkey_alloc(0, PKEY_DISABLE_EXECUTE);
        	assert (pkey > 0);
      
        	/* perform mprotect */
        	assert(!sys_pkey_mprotect(region, pgsize, PROT_RWX, pkey));
        	do_execute(region);
      
        	/* free pkey */
        	assert(!sys_pkey_free(pkey));
      
        }
      
        int main(int argc, char **argv)
        {
        	size_t pgsize, numinsns;
        	unsigned int *region;
        	int i;
      
        	/* allocate memory region to protect */
        	pgsize = getpagesize();
        	region = memalign(pgsize, pgsize);
        	assert(region != NULL);
        	assert(!mprotect(region, pgsize, PROT_RWX));
      
        	/* fill page with NOPs with a BLR at the end */
        	numinsns = pgsize / sizeof(region[0]);
        	for (i = 0; i < numinsns - 1; i++)
        		region[i] = PPC_INST_NOP;
        	region[i] = PPC_INST_BLR;
      
        	do_protect(region);
      
        	return EXIT_SUCCESS;
        }
      
      The fix is to only check the IAMR for an execute check, the AMR value
      is not relevant.
      
      Fixes: f2407ef3 ("powerpc: helper to validate key-access permissions of a pte")
      Cc: stable@vger.kernel.org # v4.16+
      Reported-by: NSandipan Das <sandipan@linux.ibm.com>
      Signed-off-by: NAneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
      [mpe: Add detail to change log, tweak wording & formatting]
      Signed-off-by: NMichael Ellerman <mpe@ellerman.id.au>
      Link: https://lore.kernel.org/r/20200712132047.1038594-1-aneesh.kumar@linux.ibm.com
      192b6a78
  5. 29 6月, 2020 1 次提交
    • A
      powerpc/mm/pkeys: Make pkey access check work on execute_only_key · 19ab500e
      Aneesh Kumar K.V 提交于
      Jan reported that LTP mmap03 was getting stuck in a page fault loop
      after commit c46241a3 ("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: c46241a3 ("powerpc/pkeys: Check vma before returning key fault error to the user")
      Reported-by: NJan Stancek <jstancek@redhat.com>
      Signed-off-by: NAneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
      [mpe: Include bug report details etc. in the change log]
      Signed-off-by: NMichael Ellerman <mpe@ellerman.id.au>
      Link: https://lore.kernel.org/r/20200627070147.297535-1-aneesh.kumar@linux.ibm.com
      19ab500e
  6. 22 6月, 2020 4 次提交
  7. 11 6月, 2020 1 次提交
  8. 10 6月, 2020 1 次提交