scsi: lpfc: Use struct_group() to initialize struct lpfc_cgn_info
authorKees Cook <keescook@chromium.org>
Wed, 8 Dec 2021 19:59:57 +0000 (11:59 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 14 Dec 2021 04:30:30 +0000 (23:30 -0500)
In preparation for FORTIFY_SOURCE performing compile-time and run-time
field bounds checking for memset(), avoid intentionally writing across
neighboring fields.

Add struct_group() to mark "stat" region of struct lpfc_cgn_info that
should be initialized to zero, and refactor the "data" region memset()
to wipe everything up to the cgn_stats region.

Link: https://lore.kernel.org/r/20211208195957.1603092-1-keescook@chromium.org
Reviewed-by: James Smart <jsmart2021@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/lpfc/lpfc.h
drivers/scsi/lpfc/lpfc_init.c

index 3faadcf..4878c94 100644 (file)
@@ -496,52 +496,50 @@ struct lpfc_cgn_info {
        __le32   cgn_alarm_hr[24];
        __le32   cgn_alarm_day[LPFC_MAX_CGN_DAYS];
 
-       /* Start of congestion statistics */
-       uint8_t  cgn_stat_npm;          /* Notifications per minute */
-
-       /* Start Time */
-       uint8_t  cgn_stat_month;
-       uint8_t  cgn_stat_day;
-       uint8_t  cgn_stat_year;
-       uint8_t  cgn_stat_hour;
-       uint8_t  cgn_stat_minute;
-       uint8_t  cgn_pad2[2];
-
-       __le32   cgn_notification;
-       __le32   cgn_peer_notification;
-       __le32   link_integ_notification;
-       __le32   delivery_notification;
-
-       uint8_t  cgn_stat_cgn_month; /* Last congestion notification FPIN */
-       uint8_t  cgn_stat_cgn_day;
-       uint8_t  cgn_stat_cgn_year;
-       uint8_t  cgn_stat_cgn_hour;
-       uint8_t  cgn_stat_cgn_min;
-       uint8_t  cgn_stat_cgn_sec;
-
-       uint8_t  cgn_stat_peer_month; /* Last peer congestion FPIN */
-       uint8_t  cgn_stat_peer_day;
-       uint8_t  cgn_stat_peer_year;
-       uint8_t  cgn_stat_peer_hour;
-       uint8_t  cgn_stat_peer_min;
-       uint8_t  cgn_stat_peer_sec;
-
-       uint8_t  cgn_stat_lnk_month; /* Last link integrity FPIN */
-       uint8_t  cgn_stat_lnk_day;
-       uint8_t  cgn_stat_lnk_year;
-       uint8_t  cgn_stat_lnk_hour;
-       uint8_t  cgn_stat_lnk_min;
-       uint8_t  cgn_stat_lnk_sec;
-
-       uint8_t  cgn_stat_del_month; /* Last delivery notification FPIN */
-       uint8_t  cgn_stat_del_day;
-       uint8_t  cgn_stat_del_year;
-       uint8_t  cgn_stat_del_hour;
-       uint8_t  cgn_stat_del_min;
-       uint8_t  cgn_stat_del_sec;
-#define LPFC_CGN_STAT_SIZE     48
-#define LPFC_CGN_DATA_SIZE     (sizeof(struct lpfc_cgn_info) -  \
-                               LPFC_CGN_STAT_SIZE - sizeof(uint32_t))
+       struct_group(cgn_stat,
+               uint8_t  cgn_stat_npm;          /* Notifications per minute */
+
+               /* Start Time */
+               uint8_t  cgn_stat_month;
+               uint8_t  cgn_stat_day;
+               uint8_t  cgn_stat_year;
+               uint8_t  cgn_stat_hour;
+               uint8_t  cgn_stat_minute;
+               uint8_t  cgn_pad2[2];
+
+               __le32   cgn_notification;
+               __le32   cgn_peer_notification;
+               __le32   link_integ_notification;
+               __le32   delivery_notification;
+
+               uint8_t  cgn_stat_cgn_month; /* Last congestion notification FPIN */
+               uint8_t  cgn_stat_cgn_day;
+               uint8_t  cgn_stat_cgn_year;
+               uint8_t  cgn_stat_cgn_hour;
+               uint8_t  cgn_stat_cgn_min;
+               uint8_t  cgn_stat_cgn_sec;
+
+               uint8_t  cgn_stat_peer_month; /* Last peer congestion FPIN */
+               uint8_t  cgn_stat_peer_day;
+               uint8_t  cgn_stat_peer_year;
+               uint8_t  cgn_stat_peer_hour;
+               uint8_t  cgn_stat_peer_min;
+               uint8_t  cgn_stat_peer_sec;
+
+               uint8_t  cgn_stat_lnk_month; /* Last link integrity FPIN */
+               uint8_t  cgn_stat_lnk_day;
+               uint8_t  cgn_stat_lnk_year;
+               uint8_t  cgn_stat_lnk_hour;
+               uint8_t  cgn_stat_lnk_min;
+               uint8_t  cgn_stat_lnk_sec;
+
+               uint8_t  cgn_stat_del_month; /* Last delivery notification FPIN */
+               uint8_t  cgn_stat_del_day;
+               uint8_t  cgn_stat_del_year;
+               uint8_t  cgn_stat_del_hour;
+               uint8_t  cgn_stat_del_min;
+               uint8_t  cgn_stat_del_sec;
+       );
 
        __le32   cgn_info_crc;
 #define LPFC_CGN_CRC32_MAGIC_NUMBER    0x1EDC6F41
index 2fe7d9d..c18000d 100644 (file)
@@ -13483,7 +13483,7 @@ lpfc_init_congestion_buf(struct lpfc_hba *phba)
        phba->cgn_evt_minute = 0;
        phba->hba_flag &= ~HBA_CGN_DAY_WRAP;
 
-       memset(cp, 0xff, LPFC_CGN_DATA_SIZE);
+       memset(cp, 0xff, offsetof(struct lpfc_cgn_info, cgn_stat));
        cp->cgn_info_size = cpu_to_le16(LPFC_CGN_INFO_SZ);
        cp->cgn_info_version = LPFC_CGN_INFO_V3;
 
@@ -13542,7 +13542,7 @@ lpfc_init_congestion_stat(struct lpfc_hba *phba)
                return;
 
        cp = (struct lpfc_cgn_info *)phba->cgn_i->virt;
-       memset(&cp->cgn_stat_npm, 0, LPFC_CGN_STAT_SIZE);
+       memset(&cp->cgn_stat, 0, sizeof(cp->cgn_stat));
 
        ktime_get_real_ts64(&cmpl_time);
        time64_to_tm(cmpl_time.tv_sec, 0, &broken);