diff options
Diffstat (limited to 'meta-snowyowl/recipes-kernel/linux/files/0176-crypto-Work-around-deallocated-stack-frame-reference.patch')
-rwxr-xr-x | meta-snowyowl/recipes-kernel/linux/files/0176-crypto-Work-around-deallocated-stack-frame-reference.patch | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/meta-snowyowl/recipes-kernel/linux/files/0176-crypto-Work-around-deallocated-stack-frame-reference.patch b/meta-snowyowl/recipes-kernel/linux/files/0176-crypto-Work-around-deallocated-stack-frame-reference.patch new file mode 100755 index 00000000..c1370fee --- /dev/null +++ b/meta-snowyowl/recipes-kernel/linux/files/0176-crypto-Work-around-deallocated-stack-frame-reference.patch @@ -0,0 +1,119 @@ +From ab03c8d27dd8c8f17ea773d34cc3e69af89c911f Mon Sep 17 00:00:00 2001 +From: David Miller <davem@davemloft.net> +Date: Fri, 2 Jun 2017 11:28:54 -0400 +Subject: [PATCH 028/331] crypto: Work around deallocated stack frame reference + gcc bug on sparc. + +commit d41519a69b35b10af7fda867fb9100df24fdf403 upstream. + +On sparc, if we have an alloca() like situation, as is the case with +SHASH_DESC_ON_STACK(), we can end up referencing deallocated stack +memory. The result can be that the value is clobbered if a trap +or interrupt arrives at just the right instruction. + +It only occurs if the function ends returning a value from that +alloca() area and that value can be placed into the return value +register using a single instruction. + +For example, in lib/libcrc32c.c:crc32c() we end up with a return +sequence like: + + return %i7+8 + lduw [%o5+16], %o0 ! MEM[(u32 *)__shash_desc.1_10 + 16B], + +%o5 holds the base of the on-stack area allocated for the shash +descriptor. But the return released the stack frame and the +register window. + +So if an intererupt arrives between 'return' and 'lduw', then +the value read at %o5+16 can be corrupted. + +Add a data compiler barrier to work around this problem. This is +exactly what the gcc fix will end up doing as well, and it absolutely +should not change the code generated for other cpus (unless gcc +on them has the same bug :-) + +With crucial insight from Eric Sandeen. + +Reported-by: Anatoly Pugachev <matorola@gmail.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Sudheesh Mavila <sudheesh.mavila@amd.com> +--- + fs/btrfs/hash.c | 5 ++++- + fs/f2fs/f2fs.h | 5 ++++- + lib/libcrc32c.c | 6 ++++-- + 3 files changed, 12 insertions(+), 4 deletions(-) + +diff --git a/fs/btrfs/hash.c b/fs/btrfs/hash.c +index a97fdc1..baacc18 100644 +--- a/fs/btrfs/hash.c ++++ b/fs/btrfs/hash.c +@@ -38,6 +38,7 @@ u32 btrfs_crc32c(u32 crc, const void *address, unsigned int length) + { + SHASH_DESC_ON_STACK(shash, tfm); + u32 *ctx = (u32 *)shash_desc_ctx(shash); ++ u32 retval; + int err; + + shash->tfm = tfm; +@@ -47,5 +48,7 @@ u32 btrfs_crc32c(u32 crc, const void *address, unsigned int length) + err = crypto_shash_update(shash, address, length); + BUG_ON(err); + +- return *ctx; ++ retval = *ctx; ++ barrier_data(ctx); ++ return retval; + } +diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h +index 3a1640b..4051c24 100644 +--- a/fs/f2fs/f2fs.h ++++ b/fs/f2fs/f2fs.h +@@ -948,6 +948,7 @@ static inline u32 f2fs_crc32(struct f2fs_sb_info *sbi, const void *address, + { + SHASH_DESC_ON_STACK(shash, sbi->s_chksum_driver); + u32 *ctx = (u32 *)shash_desc_ctx(shash); ++ u32 retval; + int err; + + shash->tfm = sbi->s_chksum_driver; +@@ -957,7 +958,9 @@ static inline u32 f2fs_crc32(struct f2fs_sb_info *sbi, const void *address, + err = crypto_shash_update(shash, address, length); + BUG_ON(err); + +- return *ctx; ++ retval = *ctx; ++ barrier_data(ctx); ++ return retval; + } + + static inline bool f2fs_crc_valid(struct f2fs_sb_info *sbi, __u32 blk_crc, +diff --git a/lib/libcrc32c.c b/lib/libcrc32c.c +index 74a54b7..9f79547 100644 +--- a/lib/libcrc32c.c ++++ b/lib/libcrc32c.c +@@ -43,7 +43,7 @@ static struct crypto_shash *tfm; + u32 crc32c(u32 crc, const void *address, unsigned int length) + { + SHASH_DESC_ON_STACK(shash, tfm); +- u32 *ctx = (u32 *)shash_desc_ctx(shash); ++ u32 ret, *ctx = (u32 *)shash_desc_ctx(shash); + int err; + + shash->tfm = tfm; +@@ -53,7 +53,9 @@ u32 crc32c(u32 crc, const void *address, unsigned int length) + err = crypto_shash_update(shash, address, length); + BUG_ON(err); + +- return *ctx; ++ ret = *ctx; ++ barrier_data(ctx); ++ return ret; + } + + EXPORT_SYMBOL(crc32c); +-- +2.7.4 + |