The bug exists in the memcmp in which the length passed in must be guaranteed to be 1. This bug currently exists because the second pointer passed in, can be smaller than the cmd->data_length, which causes a fortify_panic.
The fix is to use memchr_inv instead to find whether or not a 0 exists instead of using memcmp. This way you dont have to worry about buffer overflow which is the reason for the fortify_panic.
The bug was found by running a block backstore via LIO.
[ 496.212958] Call Trace: [ 496.212960] [c0000007e58e3800] [c000000000cbbefc] fortify_panic+0x24/0x38 (unreliable) [ 496.212965] [c0000007e58e3860] [d00000000f150c28] iblock_execute_write_same+0x3b8/0x3c0 [target_core_iblock] [ 496.212976] [c0000007e58e3910] [d000000006c737d4] __target_execute_cmd+0x54/0x150 [target_core_mod] [ 496.212982] [c0000007e58e3940] [d000000006d32ce4] ibmvscsis_write_pending+0x74/0xe0 [ibmvscsis] [ 496.212991] [c0000007e58e39b0] [d000000006c74fc8] transport_generic_new_cmd+0x318/0x370 [target_core_mod] [ 496.213001] [c0000007e58e3a30] [d000000006c75084] transport_handle_cdb_direct+0x64/0xd0 [target_core_mod] [ 496.213011] [c0000007e58e3aa0] [d000000006c75298] target_submit_cmd_map_sgls+0x1a8/0x320 [target_core_mod] [ 496.213021] [c0000007e58e3b30] [d000000006c75458] target_submit_cmd+0x48/0x60 [target_core_mod] [ 496.213026] [c0000007e58e3bd0] [d000000006d34c20] ibmvscsis_scheduler+0x370/0x600 [ibmvscsis] [ 496.213031] [c0000007e58e3c90] [c00000000013135c] process_one_work+0x1ec/0x580 [ 496.213035] [c0000007e58e3d20] [c000000000131798] worker_thread+0xa8/0x600 [ 496.213039] [c0000007e58e3dc0] [c00000000013a468] kthread+0x168/0x1b0 [ 496.213044] [c0000007e58e3e30] [c00000000000b528] ret_from_kernel_thread+0x5c/0xb4
Fixes: 2237498f0b5c ("target/iblock: Convert WRITE_SAME to blkdev_issue_zeroout") Signed-off-by: Bryant G. Ly bryantly@linux.vnet.ibm.com Reviewed-by: Steven Royer seroyer@linux.vnet.ibm.com Tested-by: Taylor Jakobson tjakobs@us.ibm.com Cc: Christoph Hellwig hch@lst.de Cc: Nicholas Bellinger nab@linux-iscsi.org Cc: stable@vger.kernel.org --- drivers/target/target_core_iblock.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 07c814c..6042901 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -427,8 +427,8 @@ iblock_execute_zero_out(struct block_device *bdev, struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; struct scatterlist *sg = &cmd->t_data_sg[0]; - unsigned char *buf, zero = 0x00, *p = &zero; - int rc, ret; + unsigned char *buf, *not_zero; + int ret;
buf = kmap(sg_page(sg)) + sg->offset; if (!buf) @@ -437,10 +437,10 @@ iblock_execute_zero_out(struct block_device *bdev, struct se_cmd *cmd) * Fall back to block_execute_write_same() slow-path if * incoming WRITE_SAME payload does not contain zeros. */ - rc = memcmp(buf, p, cmd->data_length); + not_zero = memchr_inv(buf, 0x00, cmd->data_length); kunmap(sg_page(sg));
- if (rc) + if (not_zero) return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
ret = blkdev_issue_zeroout(bdev,
Bryant,
The bug exists in the memcmp in which the length passed in must be guaranteed to be 1. This bug currently exists because the second pointer passed in, can be smaller than the cmd->data_length, which causes a fortify_panic.
The fix is to use memchr_inv instead to find whether or not a 0 exists instead of using memcmp. This way you dont have to worry about buffer overflow which is the reason for the fortify_panic.
Clarified the commit description a bit and applied the patch 4.17/scsi-fixes. Thanks!
linux-stable-mirror@lists.linaro.org