powerpc: add sys_pkey_modify() system call
RFC 1/1 powerpc: add sys_pkey_modify() system call
sys_pkey_modify() is powerpc specific system call. It
enables the ability to modify *any* attribute of a key.
Since powerpc disallows modification of IAMR from user space an application is unable to change a key's execute-attribute.
This system call helps accomplish the above.
Signed-off-by Ram Pai <[email protected]>
--- arch/powerpc/include/asm/systbl.h | 1 + arch/powerpc/include/asm/unistd.h | 2 +- arch/powerpc/include/uapi/asm/unistd.h | 1 + arch/powerpc/kernel/entry_64.S | 9 +++++++++ arch/powerpc/mm/pkeys.c | 29 +++++++++++++++++++++++++++++ 5 files changed, 41 insertions(+), 1 deletions(-)
arch/powerpc/include/asm/systbl.h +1 -0
@@ -391,3 +391,4 @@ SYSCALL(pkey_alloc) SYSCALL(pkey_free) SYSCALL(pkey_mprotect) +PPC64ONLY(pkey_modify)
arch/powerpc/include/asm/unistd.h +1 -1
@@ -12,7 +12,7 @@#include <uapi/asm/unistd.h> -#define NR_syscalls 387 +#define NR_syscalls 388#define __NR__exit __NR_exit
arch/powerpc/include/uapi/asm/unistd.h +1 -0
@@ -397,5 +397,6 @@#define __NR_pkey_alloc 384#define __NR_pkey_free 385#define __NR_pkey_mprotect 386 +#define __NR_pkey_modify 387#endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
arch/powerpc/kernel/entry_64.S +9 -0
@@ -455,6 +455,15 @@ _GLOBAL(ppc_switch_endian) bl sys_switch_endian b .Lsyscall_exit +_GLOBAL(ppc_pkey_modify) + bl save_nvgprs +#ifdef CONFIG_PPC64_MEMORY_PROTECTION_KEYS + bl sys_pkey_modify +#else + bl sys_ni_syscall +#endif + b .Lsyscall_exit + _GLOBAL(ret_from_fork) bl schedule_tail REST_NVGPRS(r1)
arch/powerpc/mm/pkeys.c +29 -0
@@ -364,3 +364,32 @@ bool arch_vma_access_permitted(struct vm_area_struct *vma,return pkey_access_permitted (pkey, write, execute); } + +unsigned int arch_usable_pkeys (void ) +{ +unsigned int reserved; + +if (!pkey_inited) +return 0 ; + +/* Reserve one more to account for the execute-only pkey. */ + reserved =hweight32 (initial_allocation_mask) +1 ; + +return pkeys_total > reserved ? pkeys_total - reserved :0 ; +} + +bool arch_supports_pkeys (int cap) +{ +if (cap &PKEY_DISABLE_EXECUTE ) +return pkey_execute_disable_support; +return (cap & (PKEY_DISABLE_ACCESS |PKEY_DISABLE_WRITE )); +} + +long sys_pkey_modify (int pkey,unsigned long new_val) +{ +/* check for unsupported init values */ +if (new_val & ~PKEY_ACCESS_MASK ) +return -EINVAL ; + +return __arch_set_user_pkey_access (current, pkey, new_val); +}
Signature · 1 line
1.7.1