From: Greg Kroah-Hartman Date: Wed, 3 Apr 2019 14:09:26 +0000 (+0200) Subject: 3.18-stable patches X-Git-Tag: v4.9.168~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7af3135f6f2cf8b57aa5b1da364b349cf974acc6;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches 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 --- 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 index 00000000000..f4d2869c2e2 --- /dev/null +++ b/queue-3.18/ext4-cleanup-bh-release-code-in-ext4_ind_remove_space.patch @@ -0,0 +1,163 @@ +From 5e86bdda41534e17621d5a071b294943cae4376e Mon Sep 17 00:00:00 2001 +From: "zhangyi (F)" +Date: Sat, 23 Mar 2019 11:56:01 -0400 +Subject: ext4: cleanup bh release code in ext4_ind_remove_space() + +From: zhangyi (F) + +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) +Signed-off-by: Theodore Ts'o +Reviewed-by: Jan Kara +Cc: Jari Ruusu +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a8d94f4aa16 --- /dev/null +++ b/queue-3.18/i2c-core-smbus-prevent-stack-corruption-on-read-i2c_block_data.patch @@ -0,0 +1,70 @@ +From 89c6efa61f5709327ecfa24bff18e57a4e80c7fa Mon Sep 17 00:00:00 2001 +From: Jeremy Compostella +Date: Wed, 15 Nov 2017 12:31:44 -0700 +Subject: i2c: core-smbus: prevent stack corruption on read I2C_BLOCK_DATA + +From: Jeremy Compostella + +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: + [] dump_stack+0x67/0x92 + [] panic+0xc5/0x1eb + [] ? vprintk_default+0x1f/0x30 + [] ? i2cdev_ioctl_smbus+0x303/0x320 + [] __stack_chk_fail+0x1b/0x20 + [] i2cdev_ioctl_smbus+0x303/0x320 + [] i2cdev_ioctl+0x4d/0x1e0 + [] do_vfs_ioctl+0x2ba/0x490 + [] ? security_file_ioctl+0x43/0x60 + [] SyS_ioctl+0x79/0x90 + [] entry_SYSCALL_64_fastpath+0x12/0x6a + +Signed-off-by: Jeremy Compostella +Signed-off-by: Wolfram Sang +Cc: stable@kernel.org +[connoro@google.com: 4.9 backport: adjust filename] +Signed-off-by: Connor O'Brien +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..049e9b1a4d7 --- /dev/null +++ b/queue-3.18/series @@ -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