aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2019-02-16 08:51:25 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2019-02-21 23:40:56 -0500
commit69216a545cf81b2b32d01948f7039315abaf75a0 (patch)
tree7349952f2c445784ee53b3e32d2b19763121ca22
parentf1071c3e2473ae19a7f5d892a187c4cab1a61f2e (diff)
crypto: sha256/arm - fix crash bug in Thumb2 build
The SHA256 code we adopted from the OpenSSL project uses a rather peculiar way to take the address of the round constant table: it takes the address of the sha256_block_data_order() routine, and substracts a constant known quantity to arrive at the base of the table, which is emitted by the same assembler code right before the routine's entry point. However, recent versions of binutils have helpfully changed the behavior of references emitted via an ADR instruction when running in Thumb2 mode: it now takes the Thumb execution mode bit into account, which is bit 0 af the address. This means the produced table address also has bit 0 set, and so we end up with an address value pointing 1 byte past the start of the table, which results in crashes such as Unable to handle kernel paging request at virtual address bf825000 pgd = 42f44b11 [bf825000] *pgd=80000040206003, *pmd=5f1bd003, *pte=00000000 Internal error: Oops: 207 [#1] PREEMPT SMP THUMB2 Modules linked in: sha256_arm(+) sha1_arm_ce sha1_arm ... CPU: 7 PID: 396 Comm: cryptomgr_test Not tainted 5.0.0-rc6+ #144 Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 PC is at sha256_block_data_order+0xaaa/0xb30 [sha256_arm] LR is at __this_module+0x17fd/0xffffe800 [sha256_arm] pc : [<bf820bca>] lr : [<bf824ffd>] psr: 800b0033 sp : ebc8bbe8 ip : faaabe1c fp : 2fdd3433 r10: 4c5f1692 r9 : e43037df r8 : b04b0a5a r7 : c369d722 r6 : 39c3693e r5 : 7a013189 r4 : 1580d26b r3 : 8762a9b0 r2 : eea9c2cd r1 : 3e9ab536 r0 : 1dea4ae7 Flags: Nzcv IRQs on FIQs on Mode SVC_32 ISA Thumb Segment user Control: 70c5383d Table: 6b8467c0 DAC: dbadc0de Process cryptomgr_test (pid: 396, stack limit = 0x69e1fe23) Stack: (0xebc8bbe8 to 0xebc8c000) ... unwind: Unknown symbol address bf820bca unwind: Index not found bf820bca Code: 441a ea80 40f9 440a (f85e) 3b04 ---[ end trace e560cce92700ef8a ]--- Given that this affects older kernels as well, in case they are built with a recent toolchain, apply a minimal backportable fix, which is to emit another non-code label at the start of the routine, and reference that instead. (This is similar to the current upstream state of this file in OpenSSL) Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--arch/arm/crypto/sha256-armv4.pl3
-rw-r--r--arch/arm/crypto/sha256-core.S_shipped3
2 files changed, 4 insertions, 2 deletions
diff --git a/arch/arm/crypto/sha256-armv4.pl b/arch/arm/crypto/sha256-armv4.pl
index b9ec44060ed3..a03cf4dfb781 100644
--- a/arch/arm/crypto/sha256-armv4.pl
+++ b/arch/arm/crypto/sha256-armv4.pl
@@ -212,10 +212,11 @@ K256:
212.global sha256_block_data_order 212.global sha256_block_data_order
213.type sha256_block_data_order,%function 213.type sha256_block_data_order,%function
214sha256_block_data_order: 214sha256_block_data_order:
215.Lsha256_block_data_order:
215#if __ARM_ARCH__<7 216#if __ARM_ARCH__<7
216 sub r3,pc,#8 @ sha256_block_data_order 217 sub r3,pc,#8 @ sha256_block_data_order
217#else 218#else
218 adr r3,sha256_block_data_order 219 adr r3,.Lsha256_block_data_order
219#endif 220#endif
220#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) 221#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
221 ldr r12,.LOPENSSL_armcap 222 ldr r12,.LOPENSSL_armcap
diff --git a/arch/arm/crypto/sha256-core.S_shipped b/arch/arm/crypto/sha256-core.S_shipped
index 3b58300d611c..054aae0edfce 100644
--- a/arch/arm/crypto/sha256-core.S_shipped
+++ b/arch/arm/crypto/sha256-core.S_shipped
@@ -93,10 +93,11 @@ K256:
93.global sha256_block_data_order 93.global sha256_block_data_order
94.type sha256_block_data_order,%function 94.type sha256_block_data_order,%function
95sha256_block_data_order: 95sha256_block_data_order:
96.Lsha256_block_data_order:
96#if __ARM_ARCH__<7 97#if __ARM_ARCH__<7
97 sub r3,pc,#8 @ sha256_block_data_order 98 sub r3,pc,#8 @ sha256_block_data_order
98#else 99#else
99 adr r3,sha256_block_data_order 100 adr r3,.Lsha256_block_data_order
100#endif 101#endif
101#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__) 102#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
102 ldr r12,.LOPENSSL_armcap 103 ldr r12,.LOPENSSL_armcap