Skip to content

Commit

Permalink
powerpc/32s: Fix kuap_kernel_restore()
Browse files Browse the repository at this point in the history
[ Upstream commit d93f9e2 ]

At interrupt exit, kuap_kernel_restore() calls kuap_unlock() with the
value contained in regs->kuap. However, when regs->kuap contains
0xffffffff it means that KUAP was not unlocked so calling kuap_unlock()
is unrelevant and results in jeopardising the contents of kernel space
segment registers.

So check that regs->kuap doesn't contain KUAP_NONE before calling
kuap_unlock(). In the meantime it also means that if KUAP has not
been correcly locked back at interrupt exit, it must be locked
before continuing. This is done by checking the content of
current->thread.kuap which was returned by kuap_get_and_assert_locked()

Fixes: 1613252 ("powerpc/32s: Rework Kernel Userspace Access Protection")
Reported-by: Stan Johnson <userm57@yahoo.com>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/0d0c4d0f050a637052287c09ba521bad960a2790.1631715131.git.christophe.leroy@csgroup.eu
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
chleroy authored and gregkh committed Oct 13, 2021
1 parent d7a8e38 commit da0cb12
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions arch/powerpc/include/asm/book3s/32/kup.h
Expand Up @@ -136,6 +136,14 @@ static inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap)
if (kuap_is_disabled())
return;

if (unlikely(kuap != KUAP_NONE)) {
current->thread.kuap = KUAP_NONE;
kuap_lock(kuap, false);
}

if (likely(regs->kuap == KUAP_NONE))
return;

current->thread.kuap = regs->kuap;

kuap_unlock(regs->kuap, false);
Expand Down

0 comments on commit da0cb12

Please sign in to comment.