scsi: mpt3sas: Fix out-of-bounds warnings in _ctl_addnl_diag_query
Subsystems (2)
PATCH 1/1 scsi: mpt3sas: Fix out-of-bounds warnings in _ctl_addnl_diag_query
Fix the following out-of-bounds warnings by embedding existing struct htb_rel_query into struct mpt3_addnl_diag_query, instead of duplicating its members:
include/linux/fortify-string.h:20:29: warning: '__builtin_memcpy' offset [19, 32] from the object at 'karg' is out of the bounds of referenced subobject 'buffer_rel_condition' with type 'short unsigned int' at offset 16 [-Warray-bounds] include/linux/fortify-string.h:22:29: warning: '__builtin_memset' offset [19, 32] from the object at 'karg' is out of the bounds of referenced subobject 'buffer_rel_condition' with type 'short unsigned int' at offset 16 [-Warray-bounds]
The problem is that the original code is trying to copy data into a bunch of struct members adjacent to each other in a single call to memcpy(). All those members are exactly the same contained in struct htb_rel_query, so instead of duplicating them into struct mpt3_addnl_diag_query, replace them with new member rel_query of type struct htb_rel_query. So, now that this new object is introduced, memcpy() doesn't overrun the length of &karg.buffer_rel_condition, because the address of the new struct object _rel_query_ is used as destination, instead. The same issue is present when calling memset(), and it is fixed with this same approach.
Below is a comparison of struct mpt3_addnl_diag_query, before and after this change (the size and cachelines remain the same):
$ pahole -C mpt3_addnl_diag_query drivers/scsi/mpt3sas/mpt3sas_ctl.o
struct mpt3_addnl_diag_query {
struct mpt3_ioctl_header hdr; /* 0 12 */
uint32_t unique_id; /* 12 4 */
uint16_t buffer_rel_condition; /* 16 2 */
uint16_t reserved1; /* 18 2 */
uint32_t trigger_type; /* 20 4 */
uint32_t trigger_info_dwords[2]; /* 24 8 */
uint32_t reserved2[2]; /* 32 8 *//* size: 40, cachelines: 1, members: 7 */ /* last cacheline: 40 bytes */ };
$ pahole -C mpt3_addnl_diag_query drivers/scsi/mpt3sas/mpt3sas_ctl.o
struct mpt3_addnl_diag_query {
struct mpt3_ioctl_header hdr; /* 0 12 */
uint32_t unique_id; /* 12 4 */
struct htb_rel_query rel_query; /* 16 16 */
uint32_t reserved2[2]; /* 32 8 *//* size: 40, cachelines: 1, members: 4 */ /* last cacheline: 40 bytes */ };
Also, this helps with the ongoing efforts to globally enable -Warray-bounds and get us closer to being able to tighten the FORTIFY_SOURCE routines on memcpy().
--- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 5 ++--- drivers/scsi/mpt3sas/mpt3sas_ctl.h | 12 ++++-------- 2 files changed, 6 insertions(+), 11 deletions(-)
drivers/scsi/mpt3sas/mpt3sas_ctl.c +2 -3
@@ -2507,7 +2507,7 @@ _ctl_addnl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg) __func__, karg.unique_id);return -EPERM ; } -memset (&karg.buffer_rel_condition,0 ,sizeof (struct htb_rel_query )); +memset (&karg.rel_query,0 ,sizeof (karg.rel_query));if ((ioc->diag_buffer_status[buffer_type] &MPT3_DIAG_BUFFER_IS_REGISTERED ) ==0 ) { ioc_info(ioc, "%s: buffer_type(0x%02x) is not registered\n",
@@ -2520,8 +2520,7 @@ _ctl_addnl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg) __func__, buffer_type);return -EPERM ; } -memcpy (&karg.buffer_rel_condition, &ioc->htb_rel, -sizeof (struct htb_rel_query )); +memcpy (&karg.rel_query, &ioc->htb_rel,sizeof (karg.rel_query)); out:if (copy_to_user (arg, &karg,sizeof (struct mpt3_addnl_diag_query ))) { ioc_err(ioc, "%s: unable to write mpt3_addnl_diag_query data @ %p\n",
drivers/scsi/mpt3sas/mpt3sas_ctl.h +4 -8
@@ -50,6 +50,8 @@#include <linux/miscdevice.h> #endif +#include "mpt3sas_base.h" +#ifndef MPT2SAS_MINOR #define MPT2SAS_MINOR (MPT_MINOR + 1)#endif
@@ -436,19 +438,13 @@ struct mpt3_diag_read_buffer {* struct mpt3_addnl_diag_query - diagnostic buffer release reason * @hdr - generic header * @unique_id - unique id associated with this buffer. -* @buffer_rel_condition - Release condition ioctl/sysfs/reset -* @reserved1 -* @trigger_type - Master/Event/scsi/MPI -* @trigger_info_dwords - Data Correspondig to trigger type +* @rel_query - release query. * @reserved2 */ struct mpt3_addnl_diag_query {struct mpt3_ioctl_header hdr;uint32_t unique_id; -uint16_t buffer_rel_condition; -uint16_t reserved1; -uint32_t trigger_type; -uint32_t trigger_info_dwords[2 ]; +struct htb_rel_query rel_query;uint32_t reserved2[2 ]; };
Signature · 1 line
2.27.0
Martin K. Petersen
AppliedGustavo,
Quoted 3 lines
Fix the following out-of-bounds warnings by embedding existing struct
htb_rel_queryinto structmpt3_addnl_diag_query, instead of duplicating its members:
Applied to 5.13/scsi-staging, thanks!
Signature · 1 line
Martin K. Petersen Oracle Linux Engineering
Martin K. Petersen
AppliedQuoted 8 lines · Gustavo A. R. Silva
Fix the following out-of-bounds warnings by embedding existing struct
htb_rel_queryinto structmpt3_addnl_diag_query, instead of duplicating its members:
include/linux/fortify-string.h:20:29: warning: '__builtin_memcpy' offset [19, 32] from the object at 'karg' is out of the bounds of referenced subobject 'buffer_rel_condition' with type 'short unsigned int' at offset 16 [-Warray-bounds]include/linux/fortify-string.h:22:29: warning: '__builtin_memset' offset [19, 32] from the object at 'karg' is out of the bounds of referenced subobject 'buffer_rel_condition' with type 'short unsigned int' at offset 16 [-Warray-bounds][...]
Applied to 5.13/scsi-queue, thanks!
[1/1] scsi: mpt3sas: Fix out-of-bounds warnings in _ctl_addnl_diag_query
https://git.kernel.org/mkp/scsi/c/16660db3fc2a
Signature · 1 line
Martin K. Petersen Oracle Linux Engineering