aboutsummaryrefslogtreecommitdiffstats
path: root/meta-snowyowl/recipes-kernel/linux/files/0176-crypto-Work-around-deallocated-stack-frame-reference.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-snowyowl/recipes-kernel/linux/files/0176-crypto-Work-around-deallocated-stack-frame-reference.patch')
-rwxr-xr-xmeta-snowyowl/recipes-kernel/linux/files/0176-crypto-Work-around-deallocated-stack-frame-reference.patch119
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
+