]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 3 Apr 2019 14:09:26 +0000 (16:09 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 3 Apr 2019 14:09:26 +0000 (16:09 +0200)
added patches:
ext4-cleanup-bh-release-code-in-ext4_ind_remove_space.patch
i2c-core-smbus-prevent-stack-corruption-on-read-i2c_block_data.patch

queue-3.18/ext4-cleanup-bh-release-code-in-ext4_ind_remove_space.patch [new file with mode: 0644]
queue-3.18/i2c-core-smbus-prevent-stack-corruption-on-read-i2c_block_data.patch [new file with mode: 0644]
queue-3.18/series [new file with mode: 0644]

diff --git a/queue-3.18/ext4-cleanup-bh-release-code-in-ext4_ind_remove_space.patch b/queue-3.18/ext4-cleanup-bh-release-code-in-ext4_ind_remove_space.patch
new file mode 100644 (file)
index 0000000..f4d2869
--- /dev/null
@@ -0,0 +1,163 @@
+From 5e86bdda41534e17621d5a071b294943cae4376e Mon Sep 17 00:00:00 2001
+From: "zhangyi (F)" <yi.zhang@huawei.com>
+Date: Sat, 23 Mar 2019 11:56:01 -0400
+Subject: ext4: cleanup bh release code in ext4_ind_remove_space()
+
+From: zhangyi (F) <yi.zhang@huawei.com>
+
+commit 5e86bdda41534e17621d5a071b294943cae4376e upstream.
+
+Currently, we are releasing the indirect buffer where we are done with
+it in ext4_ind_remove_space(), so we can see the brelse() and
+BUFFER_TRACE() everywhere.  It seems fragile and hard to read, and we
+may probably forget to release the buffer some day.  This patch cleans
+up the code by putting of the code which releases the buffers to the
+end of the function.
+
+Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Cc: Jari Ruusu <jari.ruusu@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/indirect.c |   47 ++++++++++++++++++++++-------------------------
+ 1 file changed, 22 insertions(+), 25 deletions(-)
+
+--- a/fs/ext4/indirect.c
++++ b/fs/ext4/indirect.c
+@@ -1312,6 +1312,7 @@ int ext4_ind_remove_space(handle_t *hand
+       ext4_lblk_t offsets[4], offsets2[4];
+       Indirect chain[4], chain2[4];
+       Indirect *partial, *partial2;
++      Indirect *p = NULL, *p2 = NULL;
+       ext4_lblk_t max_block;
+       __le32 nr = 0, nr2 = 0;
+       int n = 0, n2 = 0;
+@@ -1353,7 +1354,7 @@ int ext4_ind_remove_space(handle_t *hand
+               }
+-              partial = ext4_find_shared(inode, n, offsets, chain, &nr);
++              partial = p = ext4_find_shared(inode, n, offsets, chain, &nr);
+               if (nr) {
+                       if (partial == chain) {
+                               /* Shared branch grows from the inode */
+@@ -1378,13 +1379,11 @@ int ext4_ind_remove_space(handle_t *hand
+                               partial->p + 1,
+                               (__le32 *)partial->bh->b_data+addr_per_block,
+                               (chain+n-1) - partial);
+-                      BUFFER_TRACE(partial->bh, "call brelse");
+-                      brelse(partial->bh);
+                       partial--;
+               }
+ end_range:
+-              partial2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2);
++              partial2 = p2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2);
+               if (nr2) {
+                       if (partial2 == chain2) {
+                               /*
+@@ -1414,16 +1413,14 @@ end_range:
+                                          (__le32 *)partial2->bh->b_data,
+                                          partial2->p,
+                                          (chain2+n2-1) - partial2);
+-                      BUFFER_TRACE(partial2->bh, "call brelse");
+-                      brelse(partial2->bh);
+                       partial2--;
+               }
+               goto do_indirects;
+       }
+       /* Punch happened within the same level (n == n2) */
+-      partial = ext4_find_shared(inode, n, offsets, chain, &nr);
+-      partial2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2);
++      partial = p = ext4_find_shared(inode, n, offsets, chain, &nr);
++      partial2 = p2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2);
+       /* Free top, but only if partial2 isn't its subtree. */
+       if (nr) {
+@@ -1480,15 +1477,7 @@ end_range:
+                                          partial->p + 1,
+                                          partial2->p,
+                                          (chain+n-1) - partial);
+-                      while (partial > chain) {
+-                              BUFFER_TRACE(partial->bh, "call brelse");
+-                              brelse(partial->bh);
+-                      }
+-                      while (partial2 > chain2) {
+-                              BUFFER_TRACE(partial2->bh, "call brelse");
+-                              brelse(partial2->bh);
+-                      }
+-                      return 0;
++                      goto cleanup;
+               }
+               /*
+@@ -1503,8 +1492,6 @@ end_range:
+                                          partial->p + 1,
+                                          (__le32 *)partial->bh->b_data+addr_per_block,
+                                          (chain+n-1) - partial);
+-                      BUFFER_TRACE(partial->bh, "call brelse");
+-                      brelse(partial->bh);
+                       partial--;
+               }
+               if (partial2 > chain2 && depth2 <= depth) {
+@@ -1512,11 +1499,21 @@ end_range:
+                                          (__le32 *)partial2->bh->b_data,
+                                          partial2->p,
+                                          (chain2+n2-1) - partial2);
+-                      BUFFER_TRACE(partial2->bh, "call brelse");
+-                      brelse(partial2->bh);
+                       partial2--;
+               }
+       }
++
++cleanup:
++      while (p && p > chain) {
++              BUFFER_TRACE(p->bh, "call brelse");
++              brelse(p->bh);
++              p--;
++      }
++      while (p2 && p2 > chain2) {
++              BUFFER_TRACE(p2->bh, "call brelse");
++              brelse(p2->bh);
++              p2--;
++      }
+       return 0;
+ do_indirects:
+@@ -1524,7 +1521,7 @@ do_indirects:
+       switch (offsets[0]) {
+       default:
+               if (++n >= n2)
+-                      return 0;
++                      break;
+               nr = i_data[EXT4_IND_BLOCK];
+               if (nr) {
+                       ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 1);
+@@ -1532,7 +1529,7 @@ do_indirects:
+               }
+       case EXT4_IND_BLOCK:
+               if (++n >= n2)
+-                      return 0;
++                      break;
+               nr = i_data[EXT4_DIND_BLOCK];
+               if (nr) {
+                       ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 2);
+@@ -1540,7 +1537,7 @@ do_indirects:
+               }
+       case EXT4_DIND_BLOCK:
+               if (++n >= n2)
+-                      return 0;
++                      break;
+               nr = i_data[EXT4_TIND_BLOCK];
+               if (nr) {
+                       ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 3);
+@@ -1549,5 +1546,5 @@ do_indirects:
+       case EXT4_TIND_BLOCK:
+               ;
+       }
+-      return 0;
++      goto cleanup;
+ }
diff --git a/queue-3.18/i2c-core-smbus-prevent-stack-corruption-on-read-i2c_block_data.patch b/queue-3.18/i2c-core-smbus-prevent-stack-corruption-on-read-i2c_block_data.patch
new file mode 100644 (file)
index 0000000..a8d94f4
--- /dev/null
@@ -0,0 +1,70 @@
+From 89c6efa61f5709327ecfa24bff18e57a4e80c7fa Mon Sep 17 00:00:00 2001
+From: Jeremy Compostella <jeremy.compostella@intel.com>
+Date: Wed, 15 Nov 2017 12:31:44 -0700
+Subject: i2c: core-smbus: prevent stack corruption on read I2C_BLOCK_DATA
+
+From: Jeremy Compostella <jeremy.compostella@intel.com>
+
+commit 89c6efa61f5709327ecfa24bff18e57a4e80c7fa upstream.
+
+On a I2C_SMBUS_I2C_BLOCK_DATA read request, if data->block[0] is
+greater than I2C_SMBUS_BLOCK_MAX + 1, the underlying I2C driver writes
+data out of the msgbuf1 array boundary.
+
+It is possible from a user application to run into that issue by
+calling the I2C_SMBUS ioctl with data.block[0] greater than
+I2C_SMBUS_BLOCK_MAX + 1.
+
+This patch makes the code compliant with
+Documentation/i2c/dev-interface by raising an error when the requested
+size is larger than 32 bytes.
+
+Call Trace:
+ [<ffffffff8139f695>] dump_stack+0x67/0x92
+ [<ffffffff811802a4>] panic+0xc5/0x1eb
+ [<ffffffff810ecb5f>] ? vprintk_default+0x1f/0x30
+ [<ffffffff817456d3>] ? i2cdev_ioctl_smbus+0x303/0x320
+ [<ffffffff8109a68b>] __stack_chk_fail+0x1b/0x20
+ [<ffffffff817456d3>] i2cdev_ioctl_smbus+0x303/0x320
+ [<ffffffff81745aed>] i2cdev_ioctl+0x4d/0x1e0
+ [<ffffffff811f761a>] do_vfs_ioctl+0x2ba/0x490
+ [<ffffffff81336e43>] ? security_file_ioctl+0x43/0x60
+ [<ffffffff811f7869>] SyS_ioctl+0x79/0x90
+ [<ffffffff81a22e97>] entry_SYSCALL_64_fastpath+0x12/0x6a
+
+Signed-off-by: Jeremy Compostella <jeremy.compostella@intel.com>
+Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
+Cc: stable@kernel.org
+[connoro@google.com: 4.9 backport: adjust filename]
+Signed-off-by: Connor O'Brien <connoro@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/i2c/i2c-core.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/i2c/i2c-core.c
++++ b/drivers/i2c/i2c-core.c
+@@ -2762,16 +2762,16 @@ static s32 i2c_smbus_xfer_emulated(struc
+                                  the underlying bus driver */
+               break;
+       case I2C_SMBUS_I2C_BLOCK_DATA:
++              if (data->block[0] > I2C_SMBUS_BLOCK_MAX) {
++                      dev_err(&adapter->dev, "Invalid block %s size %d\n",
++                              read_write == I2C_SMBUS_READ ? "read" : "write",
++                              data->block[0]);
++                      return -EINVAL;
++              }
+               if (read_write == I2C_SMBUS_READ) {
+                       msg[1].len = data->block[0];
+               } else {
+                       msg[0].len = data->block[0] + 1;
+-                      if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 1) {
+-                              dev_err(&adapter->dev,
+-                                      "Invalid block write size %d\n",
+-                                      data->block[0]);
+-                              return -EINVAL;
+-                      }
+                       for (i = 1; i <= data->block[0]; i++)
+                               msgbuf0[i] = data->block[i];
+               }
diff --git a/queue-3.18/series b/queue-3.18/series
new file mode 100644 (file)
index 0000000..049e9b1
--- /dev/null
@@ -0,0 +1,2 @@
+ext4-cleanup-bh-release-code-in-ext4_ind_remove_space.patch
+i2c-core-smbus-prevent-stack-corruption-on-read-i2c_block_data.patch