Skip to content

Commit

Permalink
powerpc/pkeys: key allocation/deallocation must not change pkey regis…
Browse files Browse the repository at this point in the history
…ters

Key allocation and deallocation has the side effect of programming the
UAMOR/AMR/IAMR registers. This is wrong, since its the responsibility of
the application and not that of the kernel, to modify the permission on
the key.

Do not modify the pkey registers at key allocation/deallocation.

This patch also fixes a bug where a sys_pkey_free() resets the UAMOR
bits of the key, thus making its permissions unmodifiable from user
space. Later if the same key gets reallocated from a different thread
this thread will no longer be able to change the permissions on the key.

Fixes: cf43d3b ("powerpc: Enable pkey subsystem")
Cc: stable@vger.kernel.org # v4.16+
Reviewed-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Signed-off-by: Ram Pai <linuxram@us.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
  • Loading branch information
Ram Pai authored and Michael Ellerman committed Jul 24, 2018
1 parent de11325 commit 4a4a5e5
Show file tree
Hide file tree
Showing 2 changed files with 0 additions and 38 deletions.
11 changes: 0 additions & 11 deletions arch/powerpc/include/asm/pkeys.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ static inline bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey)
__mm_pkey_is_allocated(mm, pkey));
}

extern void __arch_activate_pkey(int pkey);
extern void __arch_deactivate_pkey(int pkey);
/*
* Returns a positive, 5-bit key on success, or -1 on failure.
* Relies on the mmap_sem to protect against concurrency in mm_pkey_alloc() and
Expand Down Expand Up @@ -124,11 +122,6 @@ static inline int mm_pkey_alloc(struct mm_struct *mm)
ret = ffz((u32)mm_pkey_allocation_map(mm));
__mm_pkey_allocated(mm, ret);

/*
* Enable the key in the hardware
*/
if (ret > 0)
__arch_activate_pkey(ret);
return ret;
}

Expand All @@ -140,10 +133,6 @@ static inline int mm_pkey_free(struct mm_struct *mm, int pkey)
if (!mm_pkey_is_allocated(mm, pkey))
return -EINVAL;

/*
* Disable the key in the hardware
*/
__arch_deactivate_pkey(pkey);
__mm_pkey_free(mm, pkey);

return 0;
Expand Down
27 changes: 0 additions & 27 deletions arch/powerpc/mm/pkeys.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,33 +218,6 @@ static inline void init_iamr(int pkey, u8 init_bits)
write_iamr(old_iamr | new_iamr_bits);
}

static void pkey_status_change(int pkey, bool enable)
{
u64 old_uamor;

/* Reset the AMR and IAMR bits for this key */
init_amr(pkey, 0x0);
init_iamr(pkey, 0x0);

/* Enable/disable key */
old_uamor = read_uamor();
if (enable)
old_uamor |= (0x3ul << pkeyshift(pkey));
else
old_uamor &= ~(0x3ul << pkeyshift(pkey));
write_uamor(old_uamor);
}

void __arch_activate_pkey(int pkey)
{
pkey_status_change(pkey, true);
}

void __arch_deactivate_pkey(int pkey)
{
pkey_status_change(pkey, false);
}

/*
* Set the access rights in AMR IAMR and UAMOR registers for @pkey to that
* specified in @init_val.
Expand Down

0 comments on commit 4a4a5e5

Please sign in to comment.